Created
November 29, 2024 11:18
-
-
Save simonfelding/2e702ea355dbec67e7fcb35b4d10a576 to your computer and use it in GitHub Desktop.
Simple and repeatable single sign-on for Kubernetes >= 1.31 using the new AuthenticationConfiguration resource and Azure AD aka Entra ID
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###################################################################################### | |
### This sets up OIDC authentication, essentially a federated login with Azure AD. ### | |
###################################################################################### | |
## Walkthrough #################### | |
### ----- Setting up authentication in Azure ----- | |
### 1. Register a new App in Azure (https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) | |
### 1.1. Replace the variables in this config with the following: | |
### | |
### - Application (client) ID == $CLIENT_ID | |
### - Directory (tenant) ID = $TENANT_ID | |
### | |
### 1.2. In the Manage->Authentication tab, add a redirect URI to http://localhost:8000/ | |
### 1.2.1 | |
### 1.2.2. In the Manage->Token configuration tab, add a groups claim. Check "Groups assigned to the application" and check "sAMAccountName" under ID. Do NOT check "Emit groups as role claims". | |
### 1.2.3. In the Manage->API Permissions tab, Add a permission. "Microsoft Graph" - "Delegated permission". Check openid and "profile" under "OpenID permissions". | |
### 1.2.4. In the Manage->App Roles tab, create a new app role with the name "can login" and the value "system:authenticated", allow it for Both | |
### 1.2.5. Create another app role with the name "global admin" and the value "system:masters", aIf llow it for Users/Groups only. | |
### | |
### 2. Find your new app under Enterprise Applications | |
### 2.1. In the Manage->Users and Groups tab, add the groups you want to be able to login and assign the suitable roles. These are global roles, meaning they apply to all clusters with this config. | |
### | |
### -------- Setting up the kube-apiserver ------- | |
### 3. Save this file (with the correct $CLIENT_ID and $TENANT_ID set) somewhere your kube-apiserver can access it. RKE2 example: /var/lib/rancher/rke2/server/ad-federation.yaml | |
### 3.1. Add this to your apiserver arguments: --authentication-config=/var/lib/rancher/rke2/server/ad-federation.yaml | |
### 3.2. If you use RKE2, add this to your RKE2 server config: kube-apiserver-extra-mount: /var/lib/rancher/rke2/server/ad-federation.yaml:/var/lib/rancher/rke2/server/ad-federation.yaml:ro | |
### | |
### | |
### -------- Setting up kubectl ------------------ | |
### 4. Install https://github.com/int128/kubelogin on your own computer | |
### 4.1. Run and follow the instructions from kubectl-oidc_login setup --oidc-issuer-url=https://sts.windows.net/$TENANT_ID --oidc-client-id='$CLIENT_ID' | |
### | |
### 5. Onboard users by having them install kubectl and kubelogin (as above). | |
### If you delete your kubernetes admin account, you can give them the same kubeconfig file as you use. | |
### | |
############################################################################################### | |
### REMEMBER THE APP ROLES SET IN THE AZURE APP ARE GLOBAL ROLES THAT APPLY TO ALL CLUSTERS ### | |
### ### | |
### --- It tells Kubernetes what groups a user is in, so just do regular rbac with that --- ### | |
############################################################################################### | |
## | |
# kubernetes documentation: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration | |
# MS token claims reference: https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference | |
## | |
apiVersion: apiserver.config.k8s.io/v1beta1 | |
kind: AuthenticationConfiguration | |
jwt: | |
- issuer: | |
url: https://sts.windows.net/$TENANT_ID/ | |
audiences: # Same as --oidc-client-id | |
- $CLIENT_ID | |
claimMappings: | |
username: | |
expression: 'claims.upn' | |
groups: | |
expression: '(claims.roles + claims.groups)' | |
uid: | |
expression: 'claims.oid' | |
extra: # extra attributes to be added to the UserInfo object. Keys must be domain-prefix path and must be unique. | |
- key: 'azure.com/ipaddr' | |
valueExpression: 'claims.ipaddr' | |
- key: 'azure.com/name' | |
valueExpression: 'claims.name' | |
# Validation rules must evaluate to true for the token to be considered valid. | |
claimValidationRules: | |
- expression: '"mfa" in claims.amr || !("system:masters" in (claims.roles + claims.groups))' | |
message: 'Cluster admins must authenticate with MFA' | |
- expression: 'cidr("192.168.1.0/24").containsIP(claims.ipaddr)' | |
message: 'User must log on from a whitelisted network' | |
userValidationRules: | |
- expression: "!user.username.startsWith('system:')" # if the username starts with 'system:', it is a reserved system account | |
message: 'username cannot used reserved system: prefix' | |
- expression: '"system:masters" in user.groups || "system:monitoring" in user.groups || user.groups.all(group, !group.startsWith("system:"))' | |
message: 'We only allow system:masters and system:monitoring as OIDC claimed roles' | |
################## | |
### Sample token # | |
################## | |
#{ | |
# "aud": "$CLIENT_ID", | |
# "iss": "https://sts.windows.net/$TENANT_ID/", | |
# "iat": 1732803134, | |
# "nbf": 1732803134, | |
# "exp": 1732807034, | |
# "amr": [ | |
# "pwd", | |
# "mfa" | |
# ], | |
# "family_name": "Doe", | |
# "given_name": "John", | |
# "groups": [ | |
# "everyone", | |
# "admins" | |
# ], | |
# "ipaddr": "192.168.1.2", | |
# "name": "John Doe", | |
# "oid": "42a13622-1274-1111-1111-7beb5d091503", | |
# "onprem_sid": "S-1-5-10-1111111111-1469251426-2251862497-111111", | |
# "roles": [ | |
# "access", | |
# "system:masters" | |
# ], | |
# "unique_name": "[email protected]", | |
# "upn": "[email protected]", | |
# "ver": "1.0" | |
#} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment