## 1. Create Kanidm service account + OAuth2 client ```bash # Create a service account for CI kanidm service-account create gitea_ci "Gitea CI Deploy" idm_admins --name idm_admin # Create a group and add the service account kanidm group create k8s_deployers kanidm group add-members k8s_deployers gitea_ci # Create the OAuth2 client (or reuse existing k8s one) # If you already have a k8s OIDC client, just add scope maps: kanidm system oauth2 update-scope-map k8s k8s_deployers openid groups # Generate an API token for the service account kanidm service-account api-token generate --name idm_admin gitea_ci "gitea-ci-token" # ⚠️ Save the output token — this is the subject_token for exchange ``` ## 2. RBAC in Kubernetes ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: gitea-ci-deploy subjects: - kind: User name: "gitea_ci@idm.home.hrajfrisbee.cz" # matches preferred_username claim apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: edit # scope down as needed apiGroup: rbac.authorization.k8s.io ``` ## 3. Token exchange + kubeconfig setup (test in bash) ```bash vault-login # prepared alias #!/usr/bin/env bash # set -euo pipefail KANIDM_URL="https://idm.home.hrajfrisbee.cz" OAUTH2_CLIENT_ID="k8s" # your k8s OIDC client name in Kanidm API_TOKEN=$(vault kv get -format=json -mount="secret" "k8s_home/gitea/gitea-ci-token" |jq -r .data.data.token) K8S_API="https://192.168.0.31:6443" # Exchange the API token for an OIDC token via RFC 8693 RESPONSE=$(curl -sf -X POST "${KANIDM_URL}/oauth2/token" \ -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "client_id=${OAUTH2_CLIENT_ID}" \ -d "subject_token=${API_TOKEN}" \ -d "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \ -d "audience=${OAUTH2_CLIENT_ID}" \ -d "scope=openid groups") ID_TOKEN=$(echo "$RESPONSE" | jq -r '.id_token') # Inspect claims (sanity check) echo "$ID_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq . # Build kubeconfig export KUBECONFIG=$(mktemp) kubectl config set-cluster mycluster \ --server="${K8S_API}" \ --certificate-authority=/path/to/ca.crt kubectl config set-credentials gitea-ci \ --token="${ID_TOKEN}" kubectl config set-context gitea-ci \ --cluster=mycluster \ --user=gitea-ci kubectl config use-context gitea-ci # Test kubectl auth whoami kubectl get ns ```