name: Deploy to K8s on: workflow_dispatch: push: branches: - '**' jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Get Vault token run: | set -euxo pipefail IDTOKEN=$(curl -sS -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://vault.hrajfrisbee.cz/") TOKEN=$(echo "$IDTOKEN" | jq -r '.value') VAULT_TOKEN=$(curl -sS --request POST \ --data "{\"jwt\": \"$TOKEN\", \"role\": \"gitea-actions\"}" \ https://vault.hrajfrisbee.cz/v1/auth/jwt/login | jq -r '.auth.client_token') echo "VAULT_TOKEN=$VAULT_TOKEN" >> "$GITHUB_ENV" - name: Debug - print env and OIDC info run: | echo "=== Environment ===" env | sort echo "" echo "=== ID Token (decoded) ===" IDTOKEN=$(curl -sS -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://vault.hrajfrisbee.cz/") echo "$IDTOKEN" | jq -r '.value' | cut -d. -f2 | base64 -d 2>/dev/null | jq . - name: Read secret from Vault run: | SECRET=$(curl -sS -H "X-Vault-Token: $VAULT_TOKEN" \ https://vault.hrajfrisbee.cz//v1/secret/data/k8s_home/gitea/gitea-ci-token | jq -r '.data.data.token') echo "SECRET=$SECRET" >> "$GITHUB_ENV" - name: Install kubectl run: | curl -sfLO "https://dl.k8s.io/release/$(curl -sfL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" install kubectl /usr/local/bin/ - name: Get Kanidm token from Vault id: vault run: | set -euxo pipefail # Credentials come from runner host env vars (set via systemd EnvironmentFile), # not from Gitea repo secrets — so they never touch Gitea's secret store. VAULT_AUTH_RESPONSE=$(curl -f --request POST \ --data "{\"role_id\":\"${VAULT_ROLE_ID}\",\"secret_id\":\"${VAULT_SECRET_ID}\"}" \ https://vault.hrajfrisbee.cz/v1/auth/approle/login) echo "Vault auth response: $VAULT_AUTH_RESPONSE" >&2 VAULT_TOKEN=$(echo "$VAULT_AUTH_RESPONSE" | jq -r '.auth.client_token') # Read the kanidm API token SECRET_RESPONSE=$(curl -f \ -H "X-Vault-Token: ${VAULT_TOKEN}" \ https://vault.hrajfrisbee.cz/v1/secret/data/k8s_home/gitea/gitea-ci-token) echo "Secret response: $SECRET_RESPONSE" >&2 API_TOKEN=$(echo "$SECRET_RESPONSE" | jq -r '.data.data.token') echo "::add-mask::${API_TOKEN}" echo "api_token=${API_TOKEN}" >> "$GITHUB_OUTPUT" - name: Exchange for K8s OIDC token via Kanidm id: k8s run: | RESPONSE=$(curl -sf -X POST "https://idm.home.hrajfrisbee.cz/oauth2/token" \ -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ -d "client_id=k8s" \ -d "subject_token=${{ steps.vault.outputs.api_token }}" \ -d "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \ -d "audience=k8s" \ -d "scope=openid groups") ID_TOKEN=$(echo "$RESPONSE" | jq -r '.id_token') [ "$ID_TOKEN" != "null" ] && [ -n "$ID_TOKEN" ] || { echo "::error::Kanidm token exchange failed"; echo "$RESPONSE" | jq . >&2; exit 1; } echo "::add-mask::${ID_TOKEN}" echo "id_token=${ID_TOKEN}" >> "$GITHUB_OUTPUT" # Sanity check echo "$ID_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq '{sub, groups, exp}' - name: Configure kubectl & deploy run: | echo "${K8S_CA_CERT}" > /tmp/ca.crt kubectl config set-cluster mycluster \ --server=https://192.168.0.31:6443 \ --certificate-authority=/tmp/ca.crt \ --insecure-skip-tls-verify=true kubectl config set-credentials gitea-ci \ --token="${{ steps.k8s.outputs.id_token }}" kubectl config set-context gitea-ci \ --cluster=mycluster --user=gitea-ci kubectl config use-context gitea-ci kubectl auth whoami kubectl get ns # your deploy here # kubectl apply -f k8s/