2024.8.3 /o/application/introspect on OIDC tokens broken
Describe the bug
When I call into the OIDC provider's /o/application/introspect endpoint, or trigger it via the traefik-forward-auth outpost, it always return {"isActive":"false"}.
The bug happens in 2024.8.3 but is fine in 2024.8.2
To Reproduce Steps to reproduce the behavior: For distilled version:
- Create an OIDC provider that can login via Google or Facebook
- Login through the login with your UI until you hit your protected web page, get the
access_tokenin the chrome Developer tools Network tab when you call into the authentik endpoints to get user information; - Call into your
introspectendpoint like this:curl -XPOST "https://authentik.<your_domain>/application/o/introspect/" -d '{"client_id":"<your_client_id>","client_secret":"<your_client_secret>","token":"<access_token_from_ui>"}'
The above step is good enough to reproduce the bug. The <client_secret> is a bit hard to find sometimes, we may need to go into authentik database to get it but I believe the devs know how to get it even if it is a "public" OIDC that does not show secrets.
Expected behavior The response returns information json and "is_active" equals to true
Screenshots If applicable, add screenshots to help explain your problem.
Logs No logs Version and Deployment (please complete the following information):
- authentik version: [2024.8.3] - but not a bug in 2024.8.2
- Deployment: [kubernetes]
Additional context
Saw the same thing when I updated. Thankfully downgrading resolved it.
Likely describing a similar problem in #11618 as well.
I'm having the same issue, but in my case I cannot downgrade anymore. I'm on 2024.10.1 and when loading 2024.8.2 instead a few things seem to just break. Any ideas on how to fix this quick? It broke everything...
Edit: I have found the following solution: Apply custom introspection.py (before https://github.com/goauthentik/authentik/pull/11537) via Docker Compose volumes:
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.1}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./media:/media
- ./custom-templates:/templates
+ - ~/custom-src/introspection.py:/authentik/providers/oauth2/views/introspection.py
env_file:
- .env
ports:
- "${COMPOSE_PORT_HTTP:-9000}:9000"
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
depends_on:
- postgresql
- redis
When running Authentik as the IdP for a SPA, you need to be able to verify tokens issued to one Application using another one. For example, a token issued to the frontend SPA (public OIDC provider) is then verified by an API server protected by an outpost app/provider.
Is there an alternative way to set this up using only one Application, considering the API is a confidential client and the SPA is a public one?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This is not a stale issue, it just hasn't been responded to yet.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Not stale.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Not stale.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
The issue is still present with the newest version of Authentik. I will continue to patch my local installation by doing:
- access_token = AccessToken.objects.filter(token=raw_token, provider=provider).first()
+ access_token = AccessToken.objects.filter(token=raw_token).first()
if access_token:
return TokenIntrospectionParams(access_token, provider)
- refresh_token = RefreshToken.objects.filter(token=raw_token, provider=provider).first()
+ refresh_token = RefreshToken.objects.filter(token=raw_token).first()
if refresh_token:
return TokenIntrospectionParams(refresh_token, provider)
server:
command: server
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
env_file:
- .env
environment:
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.8.1}
ports:
- ${COMPOSE_PORT_HTTP:-9000}:9000
- ${COMPOSE_PORT_HTTPS:-9443}:9443
restart: unless-stopped
volumes:
- ./media:/media
- ./custom-templates:/templates
+ - ~/ccbluex/authentik/introspection.py:/authentik/providers/oauth2/views/introspection.py
This isn't helpful in terms of addressing the actual issue or looking into how to use the method properly. However, I feel that working endpoints should not suddenly break without notice and I hope this helps others to do a quick fix.
This functionality was purposefully removed, and more details are in the CVE https://docs.goauthentik.io/security/cves/CVE-2024-47077
There are options to still do this using client_credentials (see https://docs.goauthentik.io/add-secure-apps/providers/oauth2/client_credentials#machine-to-machine-authentication, especially https://docs.goauthentik.io/add-secure-apps/providers/oauth2/client_credentials#authentik-issued-jwts)
I agree that having to do all this extra stuff is not great, however we wanted to avoid adding another way to configure permissions between applications (and I know with the client_credentials option above there is something similar with needing to create a relation between providers, however requests still go through the policy engine). We are looking into maybe adding an option to a provider to "accept tokens from selected proviers" in the M2M section to not have to do an extra request