Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

let JWT validation call token instrospection #632

Open
johakoch opened this issue Nov 22, 2022 · 7 comments · May be fixed by #649
Open

let JWT validation call token instrospection #632

johakoch opened this issue Nov 22, 2022 · 7 comments · May be fixed by #649

Comments

@johakoch
Copy link
Collaborator

johakoch commented Nov 22, 2022

Use cases:

  • Tokens may be revoked at the authorization server; they should be considered invalid even if they are not expired.
  • "Use-once" tokens may be valid for several days; but they should be considered invalid after having been used once at the resource server.

This could be achieved by making the JWT validator call the token introspection endpoint at the authorization server.

OAuth2 Token Introspection: RFC 7662

Proposed new attributes for jwt block (or for a nested introspection block):

    introspection_endpoint = ""
    introspection_endpoint_auth_method = "" # see values for token_endpoint_auth_method
    client_id = ""                          # for authenticating at introspection_endpoint
    client_secret = ""                      # for authenticating at introspection_endpoint
    introspection_mode = "always|interval"
    # for introspection_mode = "interval":
    introspection_interval = "10m"          # max: exp - unixtime()

There are two introspection_modes:

  • "always": validator introspects the token each time it is validated
  • "interval": validator uses a cached introspection response OR introspects the token and caches the response for value of introspection_interval.
@filex
Copy link
Contributor

filex commented Nov 28, 2022

Do we need to store local data in Couper for this? E.g. a map of tokens and last check? Or a list of revoked tokens?

@johakoch
Copy link
Collaborator Author

Do we need to store local data in Couper for this? E.g. a map of tokens and last check? Or a list of revoked tokens?

In my proposal, in introspection_mode "interval", the response to the introspection request (containing the active property) is cached for a specified ttl (introspection_interval).
The cache key could be e.g. the token itself, or a combination of iss and jti (string identifier for the token) if available.

Additionally, revoked tokens (or, again, some identifier) could be stored, to further reduce traffic.

@johakoch
Copy link
Collaborator Author

johakoch commented Dec 5, 2022

If token is JWT:

  • if token is invalid (according to exp or other claims)
    • resource server denies access
  • otherwise:
    • if cache entry exists for token in introspection response cache:
      • resource server grants/denies access according to cache entry's active property
    • otherwise:
      • resource server sends token to authorization server (introspection endpoint)
      • authorization server responds with introspection response (including "active": true/false)
      • if token is active:
        • resource server caches introspection response for token for configured TTL (if exp is known: maximum exp - unixtime())
        • resource server grants access
      • otherwise:
        • if exp is known and (either nbf is unknown or unixtime() > nbf):
          • resource server caches introspection response for token for TTL = exp - unixtime() (active state will not change, and after expiry the token is invalid anyway)
        • otherwise:
          • resource server caches introspection response for token for configured TTL
        • resource server denies access

In this case, it would be sufficient to cache only the introspection response's active property.


If token is opaque:

  • if cache entry exists for token in introspection response cache:
    • resource server grants/denies access according to cache entry (active property and various claims properties)
  • otherwise:
    • resource server sends token to authorization server (introspection endpoint)
    • authorization server responds with introspection response (including "active": true/false)
    • resource server caches introspection response for token for configured TTL (if response contains exp: maximum exp - unixtime())
    • if token is active and valid according to introspection response's claims properties:
      • resource server grants access
    • otherwise:
      • resource server denies access

In this case, the whole introspection response has to be cached.

@johakoch johakoch linked a pull request Jan 4, 2023 that will close this issue
@johakoch johakoch changed the title idea: let JWT validation call token instrospection let JWT validation call token instrospection Jan 4, 2023
@johakoch
Copy link
Collaborator Author

johakoch commented Jan 4, 2023

Alternative configuration:

jwt "..." {
  # ...
  introspection {
    endpoint = "..." # the introspection endpoint at the authorization server
    backend = "..."  # or backend {}; for introspection request
    ttl = "..."      # duration; positive value: cache introspection response, otherwise do not cache
  }
}

@johakoch johakoch self-assigned this Jan 4, 2023
@malud malud added this to the 1.12 milestone Jan 20, 2023
@johakoch
Copy link
Collaborator Author

Should this be a beta feature (beta_introspection block)?
Is attribute name endpoint ok? Or should it be introspection_endpoint (parallel to token_endpoint in oauth, but maybe redundant here)?

@johakoch
Copy link
Collaborator Author

johakoch commented Feb 16, 2023

Token introspection is offered by e.g.

  • Okta
  • Connect2id
  • IdentityServer
  • Keycloak
  • PingIdentity

@johakoch
Copy link
Collaborator Author

VSCode: coupergateway/couper-vscode#132

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants