Safeguard
Vulnerability Analysis•

authentik CVE-2026-94611: View Permission Was Enough to Read Secrets

authentik's API returned stored credentials to any account with view permission on providers, sources and outposts. Fixed in 2026.2.7, 2026.5.7 and 2026.8.2.

Safeguard Security Team
5 min read

The authentik maintainers published GHSA-m9h4-7j9c-55x9 (CVE-2026-94611) on 9 September 2026, and the OSV record followed on 24 September. Several authentik configuration types store credentials, and reading one of them through the API returned those credentials in the response. Any account with view permission on the object could collect them, even if it had no right to edit the object.

It is rated High, CVSS 3.1 8.1, with weaknesses CWE-200 and CWE-522.

What's affected

authentik, on three release lines:

Release lineAffected up toFixed in
2026.22026.2.62026.2.7
2026.52026.5.62026.5.7
2026.82026.8.12026.8.2

The advisory lists the configuration areas that returned stored credentials:

  • One-time code delivery by mail or SMS
  • Outbound provisioning targets
  • Device trust integrations
  • Identity sources
  • The Kubernetes outpost integration
  • Applications that authenticate with a client or shared secret
  • Applications that use a proxy provider

That is a broad set. In practice it covers SMTP and SMS gateway credentials, the tokens authentik uses to push users into downstream apps, upstream identity provider client secrets, OAuth2 and OIDC client secrets for your own applications, and the credentials for outposts running in Kubernetes.

The advisory is explicit about scope: you are affected only if you granted view permission on these objects to accounts that should not see the secrets. If everyone with view access is already trusted with them, nothing new leaked.

How to check if you're exposed

First, the version. For a Docker Compose install:

docker inspect --format '{{.Config.Image}}' $(docker compose ps -q server)

For Helm:

helm list -A | grep -i authentik
kubectl get pods -A -l app.kubernetes.io/name=authentik \
  -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}'

Second, find who holds view permissions without being a superuser. In the admin interface, go to Directory, Roles, and open each role's Permissions tab. Look for any view_ permission on providers, sources, stages, outposts or connections. Do the same for groups and for individual users with directly assigned permissions.

Third, look for evidence of reads. If you ship authentik's event log to a SIEM, search for API reads of provider, source and outpost objects by non-admin accounts over the period since you granted those permissions. API reads are not always logged as events, so absence of evidence here is weak.

What to do now

  1. Upgrade to 2026.2.7, 2026.5.7 or 2026.8.2, matching your release line.
  2. Apply the workaround now if you can't upgrade. The advisory's workaround is to remove view permissions from every user, role and group that does not need them.
  3. Rotate exposed credentials wherever a non-trusted account held view access. Prioritise in this order: OAuth2 and OIDC client secrets for production apps, upstream source client secrets (for example a social login or enterprise IdP app), provisioning target tokens, SMTP and SMS gateway credentials, and the Kubernetes outpost integration credentials.
  4. Check delegated admin designs. If you created read-only "helpdesk" or "auditor" roles, decide whether they really need to see provider objects at all.

Why it matters

Identity providers hold the keys to everything they federate with. A read-only role on an IdP sounds harmless, but when the objects being read contain client secrets, read access becomes impersonation access. An attacker with a client secret can request tokens as that application, and with a source secret they can sit in the middle of an upstream login.

The deeper lesson is about API serializers. Frameworks make it easy to expose a model through an API by listing its fields, and a secret field added later gets returned by default. Write-only fields for secrets should be the rule, with tests asserting that a GET never echoes them back. If you build your own admin APIs, this bug is worth a quick grep of your serializers.

Try it yourself

Pick one OAuth2 provider in a test authentik instance on an affected version. Create a role with only view permission on providers, assign it to a test user, and call the providers API with that user's token:

curl -s -H "Authorization: Bearer $TEST_TOKEN" \
  https://authentik.example.com/api/v3/providers/oauth2/ | jq '.results[0] | keys'

On a fixed version, compare the fields returned. Then do the same audit for every secret you'd need to rotate, and record it as a risk with an owner and a due date. The demo below shows how that tracking looks.

Click through it at your own pace, or open it full screen.

Quick check

Only superusers can see providers in our authentik. Are we affected?

According to the advisory, deployments where every account with view permission is already allowed to read the credentials are not affected. Upgrade anyway so a future role change doesn't reopen it.

Is upgrading enough?

Upgrading stops further exposure. It doesn't un-leak secrets that a non-trusted viewer already read. Rotate anything that was visible to accounts outside your trusted admin group.

Which fixed version do I need?

The one on your current line: 2026.2.7, 2026.5.7 or 2026.8.2.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.