apollographql / router

A configurable, high-performance routing runtime for Apollo Federation 🚀
https://www.apollographql.com/docs/router/
Other
813 stars 271 forks source link

YAML options for JWT claims validation #2867

Open Geal opened 1 year ago

Geal commented 1 year ago

validating claims requires a rhai script: https://github.com/apollographql/router/blob/dev/docs/source/configuration/authn-jwt.mdx#example-throwing-errors-for-invalid-claims

We should have YAML options to validate them. Example for restricting the list of allowed audiences:

authentication:
  jwt:
    jwks: # This key is required.
      - url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json
        issuer: <optional name of issuer>
    claims:
      - aud: ["subgraphA", "subgraphB"]

which other types of validations should we have? Do we support some kind of predicate? Where is the limit between what we want in yaml, and what should be done in rhai?

garypen commented 1 year ago

I think it makes sense to have "standard" claims in config. We could look at adding non-standard claims later, but for now it feels acceptable to process those from rhai.

prasek commented 1 year ago

@garypen audience is in the list of standard claims: https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-token-claims

@Geal should aud be per issuer or global?

Generally audience seems to be set to a specific application, a set of applications, or the general public.

https://community.auth0.com/t/what-is-the-audience/71414

Geal commented 1 year ago

I though about this a bit more, and I think we need:

so that would ressemble what we have with header propagation:

authentication:
  jwt:
    claims:
      - aud:
        in: ["subgraphA", "subgraphB"]
    jwks: # This key is required.
      - url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json
        issuer: <optional name of issuer>
        claims:
          - email:
            matching: "*@example.com"
          - aud:
            is: "subgraphA"

We can add more ways to validate claims later, especially for claims like act which are not just strings: https://www.rfc-editor.org/rfc/rfc8693.html#name-act-actor-claim

garypen commented 1 year ago

I though about this a bit more, and I think we need:

  • both global and per issuer. Example: the aud claim could be the same across providers, but iss would be different for each IdP (we already have an option to check the issuer though)
  • global and per issuer has the same override behaviour we have with global/per subgraph configuration
  • require the presence of a claim, without more validation
  • exact match for the claim's value
  • the claim's value is in a set of accepted values
  • the claims value matches a regex

so that would ressemble what we have with header propagation:

authentication:
  jwt:
    claims:
      - aud:
        in: ["subgraphA", "subgraphB"]
    jwks: # This key is required.
      - url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json
        issuer: <optional name of issuer>
        claims:
          - email:
            matching: "*@example.com"
          - aud:
            is: "subgraphA"

We can add more ways to validate claims later, especially for claims like act which are not just strings: https://www.rfc-editor.org/rfc/rfc8693.html#name-act-actor-claim

Perhaps this would be better to leave to a rhai script rather than via configuration? At least until we have a clear picture of what kinds of validation customers would like to express in config. One thing that is a particular concern is many useful comparisons (see next para) would be excluded by this mechanism.

If we are going to do a limited/simpler set of claim validation in config, we should clearly document that more complex validations are possible in rhai. e.g.: compound comparisons, logical comparison, type checking, numeric comparisons etc...