Token introspection not working

Hi all!

I have just started trying to use Hydra and I’m struggling with token introspection. No matter what, I get a {"active":false} response from the /oauth2/introspect endpoint of the private API.

Here’s a minimal example reproducing the issue, I’m using versions v1.0.1, Git hash 937cb2e473c525d4e546bf34c5be1dd8ffcade28. In my test setup, the public API is available at https://localhost:8000 and the administrative API at https://localhost:4445. Hydra listens on Unix sockets and I have an nginx instance terminating the TLS connections with a certificate considered valid in this test setup.

$ hydra clients create \
    --endpoint https://localhost:4445 \
    --id example-client \
    --secret example-client_secret \
    --grant-types client_credentials \
    --token-endpoint-auth-method client_secret_post \
    --response-types token
You should not provide secrets using command line flags, the secret might leak to bash history and similar systems
OAuth 2.0 Client ID: example-client

$ hydra token client \
     --endpoint https://localhost:8000 \
     --client-id example-client \
     --client-secret example-client_secret
E_ZoI_III1L5gP7OQ-2wT8_bK-IipwHz9HbXC0pDokE.l3oqH_PJGyfeI-MleSGLv-chILSN7wmoQN6_apDvl24

$ curl https://localhost:4445/oauth2/introspect -d '{"token": "E_ZoI_III1L5gP7OQ-2wT8_bK-IipwHz9HbXC0pDokE.l3oqH_PJGyfeI-MleSGLv-chILSN7wmoQN6_apDvl24"}'
{"active":false}

Hydra produced the following logs:

INFO[0000] No tracer configured - skipping tracing setup 
INFO[0000] Establishing connection with SQL database backend  dsn="postgres://*:*@localhost:5432/hydra?"
INFO[0000] Successfully connected to SQL database backend  dsn="postgres://*:*@localhost:5432/hydra?"
Thank you for using ORY Hydra v1.0.1!

Take security seriously and subscribe to the ORY Security Newsletter. Stay on top of new patches and security insights.

>> Subscribe now: http://eepurl.com/di390P <<
INFO[0000] Software quality assurance features are enabled. Learn more at: https://www.ory.sh/docs/ecosystem/sqa 
INFO[0000] Setting up http server on unix:/run/hydra/public.sock 
INFO[0000] Setting up http server on unix:/run/hydra/private.sock 
INFO[0362] started handling request                      method=POST remote=127.0.0.1 request=/clients
INFO[0362] completed handling request                    measure#hydra/admin: https://localhost:8000/.latency=96987214 method=POST remote=127.0.0.1 request=/clients status=201 text_status=Created took=96.987214ms
INFO[0457] started handling request                      method=POST remote=127.0.0.1 request=/oauth2/token
ERRO[0457] An error occurred                             description="Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)" error=invalid_client hint="The OAuth 2.0 Client supports client authentication method \"client_secret_post\", but method \"client_secret_basic\" was requested. You must configure the OAuth 2.0 client's \"token_endpoint_auth_method\" value to accept \"client_secret_basic\"."
INFO[0457] completed handling request                    measure#hydra/public: https://localhost:8000/.latency=2051555 method=POST remote=127.0.0.1 request=/oauth2/token status=401 text_status=Unauthorized took=2.051555ms
INFO[0457] started handling request                      method=POST remote=127.0.0.1 request=/oauth2/token
INFO[0457] completed handling request                    measure#hydra/public: https://localhost:8000/.latency=94919982 method=POST remote=127.0.0.1 request=/oauth2/token status=200 text_status=OK took=94.919982ms
INFO[0518] started handling request                      method=POST remote=127.0.0.1 request=/oauth2/introspect
ERRO[0518] An error occurred                             debug=": not_found" description="The request could not be authorized" error=request_unauthorized hint="Check that you provided valid credentials in the right format."
INFO[0518] completed handling request                    measure#hydra/admin: https://localhost:8000/.latency=3192427 method=POST remote=127.0.0.1 request=/oauth2/introspect status=200 text_status=OK took=3.192427ms

My understanding is that the administrative API has no access control (the documentation mentions “None of the administrative endpoints have any built-in access control. You can do simple curl or Postman requests to talk to them.”) So why is Hydra indicating “The request could not be authorized”?

Does someone have any idea what is going on? Or maybe has any hint regarding to what should be investigated first to understand this behavior?

Try hydra token introspect --client-id example-client --client-secret example-client-secret E_ZoI_III1L5gP7OQ-2wT8_bK-IipwHz9HbXC0pDokE.l3oqH_PJGyfeI-MleSGLv-chILSN7wmoQN6_apDvl24 for a sanity check

(And keep in mind that tokens are valid only for an hour)

Oh and yeah - the documentation is actually incorrect - Token Introspection requires (per specification) the client id and client secret in order to validate a token - so that’s the issue here!

Would be awesome if you could clarify the documentation there with a PR :slight_smile:

Thank you for the replies.

I created a new access token, to make sure that I have a non-expired access token and then the following is able to introspect the access token:

hydra token introspect
–endpoint https://localhost:4445
–client-id example-client
–client-secret example-client_secret

-kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4

Now, with curl, as to be aware of what the actual requests are:

Posting a form and using basic auth with the client secret is able to introspect the token:

curl https://localhost:4445/oauth2/introspect
-F “token=-kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4”
-u “example-client:example-client_secret”

Posting a form using basic auth with an access token is also able to introspect the token:

curl https://localhost:4445/oauth2/introspect
-F “token=-kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4”
-u “example-client:-kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4”

Posting a form using an access token in the authorization header is also able to introspect the token:

curl https://localhost:4445/oauth2/introspect
-F “token=-kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4”
-H “Authorization: Bearer -kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4”

As expected, it also works when using another client to introspect the token.

So what is problematic with the requests in my opening message is:

  • The client must be authenticated.
  • The request must be a form, not a JSON document.

I’m going to read the documentation again and then open a PR with clarifications.

Thank you for the analysis! In fact, I believe that you can even leave out the -u because “example-client:-kFrbpWTxDiyKP4Jot6fOE3e0VnRnagFmkj9FIvwR3c.wM7kNSHQzzSh18mp8yoPHxmJ-NffLNP-rHNzx4bY_Q4” should actually not work, indicating that you don’t need authorization.