Skip to content
Authentication

OIDC

OIDC authentication validates JWTs against a provider's JWKS endpoint. kobe caches JWKS keys in memory and refreshes them automatically when a key rotation is detected.

GitHub Actions

GitHub Actions issues short-lived OIDC tokens that contain repository, ref, and workflow metadata. No secrets need to be stored — the token is minted fresh for each job.

apiVersion: kobe.kunobi.ninja/v1alpha1
kind: AccessPolicy
metadata:
  name: github-ci
  namespace: kobe
spec:
  auth:
    oidc:
      issuer: https://token.actions.githubusercontent.com
      audience: ["https://kobe.example.com"]
  identity: "{repository}"
  rules:
    - match:
        claim: repository
        value: my-org/api-service
      pools: ["ci-*"]
      maxTtl: 30m
      maxConcurrentLeases: 5
      maxExtensions: 0
    - match:
        claim: repository_owner
        value: my-org
      pools: ["ci-small"]
      maxTtl: 20m
      maxConcurrentLeases: 2
      maxExtensions: 0

In your GitHub Actions workflow, request the token and pass it to kobe:

jobs:
  test:
    permissions:
      id-token: write    # required to request the OIDC token
    steps:
      - name: Claim cluster
        run: |
          TOKEN=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=https://kobe.example.com" | jq -r .value)
          LEASE=$(curl -s -X POST https://kobe.example.com/v1/leases \
            -H "Authorization: Bearer $TOKEN" \
            -d '{"pool": "ci-small", "ttl": "20m"}')
          echo "LEASE_ID=$(echo $LEASE | jq -r .id)" >> $GITHUB_ENV
          echo "$LEASE" | jq -r .kubeconfig > /tmp/kube.yaml

Clerk

Clerk issues JWTs for authenticated users. Use this for developer-facing tooling where users log in with their Clerk account.

spec:
  auth:
    oidc:
      issuer: https://your-instance.clerk.accounts.dev
      audience: []    # Clerk tokens don't include an audience claim by default
      authorizedParties: ["https://app.example.com"]
  identity: "{sub}"
  rules:
    - pools: ["dev-*"]
      maxTtl: 4h
      maxConcurrentLeases: 1
      maxExtensions: 2

Custom OIDC provider

For any JWKS-compatible provider:

spec:
  auth:
    oidc:
      issuer: https://auth.example.com
      jwksUrl: https://auth.example.com/.well-known/jwks.json    # optional override
      audience: ["kobe"]
      algorithms: ["RS256"]    # default; also supports ES256, RS384, ES384
  identity: "{sub}"
  rules:
    - pools: ["*"]
      maxTtl: 1h
      maxConcurrentLeases: 2
      maxExtensions: 1

If jwksUrl is not set, kobe derives it as {issuer}/.well-known/jwks.json.

Multi-role policies

When a single OIDC provider issues tokens for users with different roles, use match clauses to apply different rules per role:

spec:
  auth:
    oidc:
      issuer: https://auth.example.com
      audience: ["kobe"]
  identity: "{private_metadata.team}:{sub}"
  rules:
    - match:
        claim: private_metadata.role
        value: admin
      pools: ["*"]
      maxTtl: 8h
      maxConcurrentLeases: 10
      maxExtensions: 5
    - match:
        claim: private_metadata.role
        value: developer
      pools: ["dev-*"]
      maxTtl: 2h
      maxConcurrentLeases: 2
      maxExtensions: 2

The match clause supports dot-path traversal into nested JWT claims.

Available for:
Apple macOS logomacOSMicrosoft Windows logoWindowsLinux logoLinux
Download Kunobi