Last modified October 11, 2022
Authenticating with Microsoft Azure Active Directory
The Kubernetes API of workload clusters, by default, uses key pairs (X.509 private key and certificate) for authentication.
In order to use Microsoft Azure Active Directory (AAD) for authentication instead, Giant Swarm can configure your management cluster(s) so that all workload clusters use the same settings and users can authenticate kubectl
using their common identity (single sign-on, SSO) via OpenID Connect (OIDC).
Setting up kubectl
for Azure auth
1. Set up a user
kubectl config \
set-credentials "<username>" \
--auth-provider=azure \
--auth-provider-arg=environment=AzurePublicCloud \
--auth-provider-arg=client-id=<kubectl-app-id> \
--auth-provider-arg=tenant-id=<tenant-id> \
--auth-provider-arg=apiserver-id=<apiserver-app-id>
username
can be freely chosen, but must be unique within your localkubeconfig
.- The 3 IDs are global settings that are set by your company. You should be able to obtain those internally.
2. Set up a cluster
kubectl config \
set-cluster <clustername> \
--server=https://<api-server-endpoint> \
--certificate-authority=/path/to/ca.crt
clustername
can be freely chosen, but must be unique within your localkubeconfig
.- Kubernetes API Server endpoint and CA you can get from the web UI (Happa) or using
gsctl
.
3. Set up a context
kubectl config \
set-context <contextname> \
--cluster=<clustername> \
--user=<username>
contextname
can be freely chosen, but must be unique within your localkubeconfig
.clustername
andusername
are the names chosen in step 1 and 2.
4. Authenticate on your first command
When you run your first kubectl
command you will see something like the following:
$ kubectl get node
To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code DEHTRY693 to authenticate.
This step needs to be done only once and will register your kubectl as an authenticated device. From then on you can freely run commands against the cluster (limited only by the roles given to you on said cluster).
Note that in some cases (depending on AD settings) the device authentication can only be done in a Browser running on a Windows machine.
Creating a kubeconfig
for general usage
If you are a Cluster Admin and want to create kubeconfig
files to give out to your users you can use following template:
apiVersion: v1
kind: Config
clusters:
- cluster:
name: <clustername>
certificate-authority: /path/to/ca.crt
server: https://<api-server-endpoint>
users:
- name: <username>
user:
auth-provider:
name: azure
config:
apiserver-id: <apiserver-app-id>
client-id: <kubectl-app-id>
tenant-id: <tenant-id>
contexts:
- context:
cluster: <clustername>
user: <username>
name: <contextname>
current-context: <contextname>
If you set all the above names to something generic, you can send the same file to all your users. The actual identification of each user will happen through the device authentication request done with their first kubectl
command.
Furthermore, to make the kubeconfig
self-contained, you can replace /path/to/ca.crt
with an inline representation of the file. For that you need to base64-encode the contents of ca.crt
and paste them into the kubeconfig
.
Binding roles to users and groups coming from AAD
When authenticating with AAD your user identifies to Kubernetes with a username and the groups you are a member of in AAD. A Cluster Admin can bind roles to these to grant access on a specific cluster.
As explained in Securing your Cluster with RBAC and PSP you can either use the default roles or define custom Role
or ClusterRole
resources to bind to subjects.
In the following examples we’ll use one of the default cluster roles.
Note that you can only bind roles if your own role is wider defined than the role you want to bind for others. When in doubt use cluster-admin
to apply bindings.
Binding a single user
AAD prefixes usernames so that they look like the following:
https://sts.windows.net/<tenant-id>/#<username>
Note: Here, username
is not the freely chosen username you set in kubectl
, but the username claim set to a specific attribute of your AAD user. Usually this will be set to your username attribute in AAD.
Based on that, we bind the user like the following:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: username-global-admin
subjects:
- kind: User
name: https://sts.windows.net/<tenant-id>/#<username>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
Binding a group of users
Unlike usernames, groups are not prefixed. You can identify them by the Object ID of the group in AAD.
Based on that, we bind a group like the following:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: username-global-admin
subjects:
- kind: Group
name: <group-oid>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
Revoking access
Access is revoked as soon as the user has either been removed from a bound group or completely from the AAD tenant.
Further reading
- Securing your Cluster with RBAC and PSP
- Using RBAC Authorization
- Azure Active Directory plugin for client authentication
Need help, got feedback?
We listen to your Slack support channel. You can also reach us at support@giantswarm.io. And of course, we welcome your pull requests!