Skip to content

Quick Start

This guide walks you through installing the operator, creating an OIDCClient custom resource, and verifying that credentials are synced into a Kubernetes Secret.

Before you begin

Make sure you have completed all steps in the Prerequisites page, including creating the bootstrap secret and setting up OIDC applications in Authentik.


Step 1: Install the Operator

Install AuthentikOperator using Helm:

Bash
helm install authentik-operator \
  oci://ghcr.io/kettleofketchup/authentik-operator \
  --version 0.1.2 \
  --set authentik.url=https://auth.example.com \
  --namespace authentik-operator \
  --create-namespace

Verify the operator pod is running:

Bash
kubectl get pods -n authentik-operator

You should see output similar to:

Text Only
NAME                                  READY   STATUS    RESTARTS   AGE
authentik-operator-6d4b8f7c9f-x2k4p   1/1     Running   0          30s

Step 2: Verify Bootstrap Completed

The operator runs a bootstrap Job on first install to create its Authentik API token. Verify it completed successfully:

Bash
kubectl get jobs -n authentik-operator

Expected output:

Text Only
NAME                            COMPLETIONS   DURATION   AGE
authentik-operator-bootstrap    1/1           8s         45s

You can also confirm the API token secret was created:

Bash
kubectl get secret authentik-operator-token -n authentik-operator

Note

If the bootstrap Job fails, check its logs for details:

Bash
kubectl logs job/authentik-operator-bootstrap -n authentik-operator

Common causes include an incorrect bootstrap token value or the Authentik instance being unreachable.


Step 3: Create Your First OIDCClient

Apply an OIDCClient custom resource to sync Grafana's OIDC credentials. This example uses the built-in grafana profile and triggers a rollout restart when the secret changes.

YAML
apiVersion: auth.kettleofketchup/v1alpha1
kind: OIDCClient
metadata:
  name: grafana-oidc
spec:
  authentik:
    applicationSlug: grafana
  target:
    namespace: monitoring
    secretName: grafana-oauth
  secretProfile: grafana
  secretOverrides:
    GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH: >-
      contains(groups, 'admins') && 'Admin' || 'Viewer'
    GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP: "true"
  rolloutRestart:
    enabled: true
    targetRef:
      kind: Deployment
      name: kube-prometheus-stack-grafana
      namespace: monitoring

Save the above to a file and apply it:

Bash
kubectl apply -f grafana-oidc.yaml

Tip

OIDCClient CRs are cluster-scoped in terms of what they can target -- the CR itself lives in the operator's namespace (or any namespace), but it can create Secrets in any namespace specified by spec.target.namespace.


Step 4: Verify the Secret Was Created

Check that the operator created the Secret in the target namespace:

Bash
kubectl get secret grafana-oauth -n monitoring

Inspect the Secret keys to confirm they match the Grafana profile:

Bash
kubectl get secret grafana-oauth -n monitoring -o jsonpath='{.data}' | jq 'keys'

Expected keys:

JSON
[
  "GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP",
  "GF_AUTH_GENERIC_OAUTH_API_URL",
  "GF_AUTH_GENERIC_OAUTH_AUTH_URL",
  "GF_AUTH_GENERIC_OAUTH_CLIENT_ID",
  "GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET",
  "GF_AUTH_GENERIC_OAUTH_ENABLED",
  "GF_AUTH_GENERIC_OAUTH_NAME",
  "GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH",
  "GF_AUTH_GENERIC_OAUTH_SCOPES",
  "GF_AUTH_GENERIC_OAUTH_TOKEN_URL"
]

Step 5: Check CR Status

Inspect the OIDCClient status to confirm everything synced correctly:

Bash
kubectl get oidc grafana-oidc -o yaml

Look for the status section:

YAML
status:
  conditions:
    - type: AuthentikProviderFound
      status: "True"
      reason: ProviderFound
      message: "Successfully retrieved provider for application 'grafana'"
    - type: SecretSynced
      status: "True"
      reason: SecretCreated
      message: "Secret monitoring/grafana-oauth created successfully"
    - type: RolloutTriggered
      status: "True"
      reason: RolloutRestarted
      message: "Restarted Deployment monitoring/kube-prometheus-stack-grafana"
  lastSyncTime: "2026-03-20T10:30:00Z"
  secretHash: "sha256:..."

You can also use the short-form table view:

Bash
kubectl get oidc
Text Only
NAME           SLUG      PROFILE   TARGET NS    READY   SYNCED   AGE
grafana-oidc   grafana   grafana   monitoring   True    True     2m

Tip

The oidc short name is registered for the OIDCClient resource, so you can use kubectl get oidc instead of kubectl get oidcclients.


What's Next

  • Add more OIDCClient resources for other applications using the openwebui, argocd, or generic profiles
  • Use secretOverrides to add application-specific configuration keys
  • Enable rolloutRestart to automatically restart workloads when credentials change