Authentik is an open-source Identity Provider that provides single sign-on with support for SAML, OAuth2/OIDC, LDAP, and RADIUS protocols.
Chainguard Containers are regularly-updated, secure-by-default container images.
For those with access, this container image is available on cgr.dev:
docker pull cgr.dev/ORGANIZATION/authentik:latest
Be sure to replace the ORGANIZATION placeholder with the name used for your organization's private repository within the Chainguard Registry.
To run Authentik with Docker, you'll need to set up a PostgreSQL database and configure both the server and worker components. Authentik requires a shared network for the containers to communicate.
docker network create authentik
docker run -d -p 5432:5432 \
--name authentik-postgres \
--network authentik \
-e POSTGRES_DB=authentik \
-e POSTGRES_USER=authentik \
-e POSTGRES_PASSWORD=changeme \
cgr.dev/ORGANIZATION/postgres:latest
docker run -d -p 9000:9000 -p 9443:9443 \
--name authentik-server \
--network authentik \
-e AUTHENTIK_SECRET_KEY=your-very-long-secret-key-at-least-50-characters-long \
-e AUTHENTIK_POSTGRESQL__HOST=authentik-postgres \
-e AUTHENTIK_POSTGRESQL__NAME=authentik \
-e AUTHENTIK_POSTGRESQL__USER=authentik \
-e AUTHENTIK_POSTGRESQL__PASSWORD=changeme \
cgr.dev/ORGANIZATION/authentik:latest server
docker run -d \
--name authentik-worker \
--network authentik \
-e AUTHENTIK_SECRET_KEY=your-very-long-secret-key-at-least-50-characters-long \
-e AUTHENTIK_POSTGRESQL__HOST=authentik-postgres \
-e AUTHENTIK_POSTGRESQL__NAME=authentik \
-e AUTHENTIK_POSTGRESQL__USER=authentik \
-e AUTHENTIK_POSTGRESQL__PASSWORD=changeme \
-e AUTHENTIK_BOOTSTRAP_PASSWORD=bootstraptestpassword \
-e AUTHENTIK_BOOTSTRAP_TOKEN=bootstraptesttoken \
cgr.dev/ORGANIZATION/authentik:latest worker
The Authentik UI will be accessible at http://localhost:9000.
To view logs from the server or worker:
docker logs -f authentik-server
docker logs -f authentik-worker
Authentik can be deployed to Kubernetes using the official Helm chart.
Startup postgres pod and expose the service inside the cluster.
kubectl run postgres-test \
--image=cgr.dev/ORGANIZATION/postgres:latest \
--port=5432 \
--labels='app=postgres-test' \
--env='POSTGRES_DB=authentik' \
--env='POSTGRES_USER=authentik' \
--env='POSTGRES_PASSWORD=changeme' \
--restart=Never
kubectl expose pod postgres-test \
--name=postgres-test \
--port=5432 --target-port=5432 \
--type=ClusterIP
Wait for Postgres pod to be ready.
kubectl wait --for=condition=ready pod \
--selector app=postgres-test \
--timeout=30s
helm repo add authentik https://charts.goauthentik.io
helm repo update
cat <<EOF > authentik-values.yaml
global:
image:
repository: cgr.dev/ORGANIZATION/authentik
tag: latest
authentik:
secret_key: "your-very-long-secret-key-at-least-50-characters-long"
bootstrap_password: "bootstraptestpassword"
bootstrap_token: "bootstraptesttoken"
postgresql:
host: "postgres-test.default.svc.cluster.local"
name: "authentik"
user: "authentik"
password: "changeme"
server:
service:
servicePortHttp: 9000
servicePortHttps: 9443
EOF
helm install authentik authentik/authentik -f authentik-values.yaml
Wait for the Authentik server and worker to be ready:
kubectl rollout status deployment/authentik-server --timeout=30s
kubectl wait --for=condition=ready pod --selector app.kubernetes.io/component=server --timeout=30s
kubectl rollout status deployment/authentik-worker --timeout=30s
kubectl wait --for=condition=ready pod --selector app.kubernetes.io/component=worker --timeout=30s
Port-forward the authentik-server service to access the Authentik UI:
kubectl port-forward svc/authentik-server 9000:9000
The UI can now be accessed at http://localhost:9000
Authentik can act as an identity provider for other applications using OAuth2 and OpenID Connect. This section demonstrates how to configure Authentik to provide authentication for Grafana.
To integrate Grafana with Authentik OAuth, you need to:
- Retrieve Authentik's default flow and property mapping IDs
- Create an OAuth2 provider with client credentials
- Create an application in Authentik that links the provider
- Deploy Grafana with OAuth configuration pointing to Authentik
Before configuring the OAuth2 provider, ensure you have:
- Authentik server running and accessible
- The bootstrap token configured during installation
curl and jq installed for API calls
Set environment variables for the API calls:
Use the bootstrap token from your installation
export AUTHENTIK_URL="http://localhost:9000"
export TOKEN="bootstraptesttoken"
First, retrieve the default flows and property mappings that Authentik uses for OAuth:
# Get authentication flow ID (handles user login)
AUTH_FLOW_PK=$(curl -sk "${AUTHENTIK_URL}/api/v3/flows/instances/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.slug=="default-authentication-flow") | .pk')
# Get authorization flow ID (handles OAuth consent)
AUTHZ_FLOW_PK=$(curl -sk "${AUTHENTIK_URL}/api/v3/flows/instances/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.slug=="default-provider-authorization-implicit-consent") | .pk')
# Get invalidation flow ID (handles logout)
INVAL_FLOW_PK=$(curl -sk "${AUTHENTIK_URL}/api/v3/flows/instances/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.slug=="default-provider-invalidation-flow") | .pk')
# Get property mappings for OAuth scopes
EMAIL_MAPPING=$(curl -sk "${AUTHENTIK_URL}/api/v3/propertymappings/all/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.managed=="goauthentik.io/providers/oauth2/scope-email") | .pk')
OPENID_MAPPING=$(curl -sk "${AUTHENTIK_URL}/api/v3/propertymappings/all/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.managed=="goauthentik.io/providers/oauth2/scope-openid") | .pk')
PROFILE_MAPPING=$(curl -sk "${AUTHENTIK_URL}/api/v3/propertymappings/all/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.managed=="goauthentik.io/providers/oauth2/scope-profile") | .pk')
Create an OAuth2 provider for Grafana with the retrieved IDs:
Update the redirect_uris URL to match your Grafana deployment URL.
The Grafana redirect URL used in this guide is set to:
http://localhost:3000/login/generic_oauth
curl -sk -X POST "${AUTHENTIK_URL}/api/v3/providers/oauth2/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "grafana-provider",
"authentication_flow": "'"${AUTH_FLOW_PK}"'",
"authorization_flow": "'"${AUTHZ_FLOW_PK}"'",
"invalidation_flow": "'"${INVAL_FLOW_PK}"'",
"property_mappings": [
"'"${EMAIL_MAPPING}"'",
"'"${OPENID_MAPPING}"'",
"'"${PROFILE_MAPPING}"'"
],
"client_type": "confidential",
"client_id": "grafana-client-id",
"client_secret": "grafana-client-secret",
"access_code_validity": "minutes=1",
"access_token_validity": "minutes=5",
"refresh_token_validity": "days=30",
"include_claims_in_id_token": true,
"redirect_uris": [
{
"matching_mode": "strict",
"url": "http://localhost:3000/login/generic_oauth"
}
],
"sub_mode": "hashed_user_id",
"issuer_mode": "per_provider"
}'
Retrieve the provider ID and create an application that links it:
# Get the provider ID
PROVIDER_PK=$(curl -sk "${AUTHENTIK_URL}/api/v3/providers/all/" \
-H "Authorization: Bearer $TOKEN" | \
jq -r '.results[] | select(.name=="grafana-provider") | .pk')
# Create the application
curl -sk -X POST "${AUTHENTIK_URL}/api/v3/core/applications/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "grafana",
"slug": "grafana",
"provider": '"${PROVIDER_PK}"',
"launch_url": "http://grafana.default.svc.cluster.local:3000",
"open_in_new_tab": false,
"policy_engine_mode": "any"
}'
Create a Kubernetes secret for Grafana OAuth credentials:
kubectl create secret generic grafana-oauth \
--from-literal=GF_AUTH_GENERIC_OAUTH_CLIENT_ID=grafana-client-id \
--from-literal=GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=grafana-client-secret
Create a Grafana values file with OAuth configuration:
Update the root_url to match your Grafana deployment URL.
The Grafana root_url used in this guide is set to:
http://localhost:3000/
Also update the signout_redirect_url and auth_url to match your Authentik deployment URL.
The Authentik signout_redirect_url and auth_url used in this guide is set to:
http://localhost:9000/
cat <<EOF > grafana-values.yaml
image:
registry: cgr.dev/ORGANIZATION
repository: grafana
tag: latest
envFromSecret: grafana-oauth
service:
port: 3000
targetPort: 3000
grafana.ini:
server:
root_url: http://grafana.default.svc.cluster.local:3000
auth:
signout_redirect_url: http://localhost:9000/application/o/grafana/end-session/
auth.generic_oauth:
name: authentik
enabled: true
disable_login_form: true
scopes: openid profile email
auth_url: http://localhost:9000/application/o/authorize/
token_url: http://authentik-server.default.svc.cluster.local:9000/application/o/token/
api_url: http://authentik-server.default.svc.cluster.local:9000/application/o/userinfo/
role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer'
EOF
Install Grafana using Helm:
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install grafana grafana/grafana -f grafana-values.yaml
Wait for Grafana to be ready:
kubectl rollout status deployment/grafana --timeout=30s
kubectl wait --for=condition=ready pod --selector app.kubernetes.io/name=grafana --timeout=30s
Port-forward the grafana service to access the Grafana UI:
kubectl port-forward svc/grafana 3000:3000
The UI can now be accessed at http://localhost:3000
To test the integration:
- Access the Grafana UI at
http://localhost:3000
- Click "Sign in with authentik"
- You'll be redirected to Authentik's login page
- Log in with the bootstrap admin credentials:
- Username:
akadmin
- Password:
bootstraptestpassword (or your configured password)
- After successful authentication, you'll be redirected back to Grafana
For a complete list of configuration options, refer to the Authentik configuration documentation.
Chainguard's free tier of Starter container images are built with Wolfi, our minimal Linux undistro.
All other Chainguard Containers are built with Chainguard OS, Chainguard's minimal Linux operating system designed to produce container images that meet the requirements of a more secure software supply chain.
The main features of Chainguard Containers include:
For cases where you need container images with shells and package managers to build or debug, most Chainguard Containers come paired with a development, or -dev, variant.
In all other cases, including Chainguard Containers tagged as :latest or with a specific version number, the container images include only an open-source application and its runtime dependencies. These minimal container images typically do not contain a shell or package manager.
Although the -dev container image variants have similar security features as their more minimal versions, they include additional software that is typically not necessary in production environments. We recommend using multi-stage builds to copy artifacts from the -dev variant into a more minimal production image.
To improve security, Chainguard Containers include only essential dependencies. Need more packages? Chainguard customers can use Custom Assembly to add packages, either through the Console, chainctl, or API.
To use Custom Assembly in the Chainguard Console: navigate to the image you'd like to customize in your Organization's list of images, and click on the Customize image button at the top of the page.
Refer to our Chainguard Containers documentation on Chainguard Academy. Chainguard also offers VMs and Libraries — contact us for access.
This software listing is packaged by Chainguard. The trademarks set forth in this offering are owned by their respective companies, and use of them does not imply any affiliation, sponsorship, or endorsement by such companies.