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

Support describing security keys in OAS #1881

Open
whitlockjc opened this issue Mar 28, 2019 · 9 comments
Open

Support describing security keys in OAS #1881

whitlockjc opened this issue Mar 28, 2019 · 9 comments
Assignees
Labels
enhancement security: encryption Support for encryption in headers, payloads, etc. security

Comments

@whitlockjc
Copy link
Member

whitlockjc commented Mar 28, 2019

Often times when interacting with APIs, security keys are involved. From a JWT perspective, keys are used for encrypting, signing and verifying tokens. In issue #1464, keys are used for encrypting and signing requests/responses. I would like to propose that we officially support describing security keys in OAS, starting with JSON Web Keys.

Shooting from the hip, here is a first-pass example:

# ...
components:
  keys:
    # Keys taken from Google's OIDC Discover Document (https://accounts.google.com/.well-known/openid-configuration)
    google-oauth-v3-1:
      description: "JSON Web Key used by Google for signing JWTs: https://www.googleapis.com/oauth2/v3/certs#/keys/0"
      type: JWK
      metadata:
        kid: 0905d6f9cd9b0f1f852e8b207e8f673abca4bf75
        e: AQAB
        kty: RSA
        alg: RS256
        n: yyeEmeK35F8P54ozfpsF79n59ZsOrcZdxQWsxrzm0qjdA5r_b-be-cQnWAw_2AoGdeWHX-Cz7uPFDMdEwzLGlpv3SELi34h8PkzjyO7xlbhsNs-ICnqUyUTA7CovKtpJ47PjiQnXcaRNCFUQbli8VlEqbVLuqFjC98igICpNYR-iiVIm0VCFtkq0p8vf1yQ493Pnx2Bm8fUx6SkeJ7wKPWQq_K4e6ZH40JWLk6c1U9W5qPKeckevdNLrdZY5lsTZ5zrRvuRBoIeZfp9bKSZGMtEja4xSCDKLrkcpb4qf6Ywx9rsZ4b8eHSLpVvUzNsj3GS7qK5flHzoccovhPVBbbQ
        use: sig
    google-oauth-v3-2:
      description: "JSON Web Key used by Google for signing JWTs: https://www.googleapis.com/oauth2/v3/certs#/keys/1"
      type: JWK
      metadata:
        kid: a4313e7fd1e9e2a4ded3b292d2a7f4e519574308
        e: AQAB
        kty: RSA
        alg: RS256
        n: lO3_QoRd_D8UHAjFcdg0_8GOiLyWo4Viiy8cDLNGf8T1eQlqqhPYZmvGOPhyILWZ9FInOXT9AzH5KPfeOnMEzy4TqfGLtdcAlufqALe_qusmq7SSNIVfSw5iPZjzXk3BXjzoFNZLfqsoqheGzek-sJV1Ti5JQQ2hRPSZQhba9xVn6G8Uxr5ugVhHQ25P6HL4acjhuvpSPEFn7tivEIhWZEL35CeqHelf-48WA4PLzRVvfFMS-hW6erjX7uxT9mj8uT7zGl41_zBd9lMn2CQeP3aLDeQFoFaLaX2NZctRASErz6H9MIXQngM1piKnc84hmify-ZAsPpBcxw7heFpYRw
        use: sig
# ...

As you can see, each key has three common properties:

  • description: A human-readable description of the key
  • type: The type of the key (One could argue that JSON Web Keys are capable of describing any key and only JSON Web Keys should be supported but for now, this value would be free-form and it would be tooling specific as to how the values are validated.)
  • metadata: This is the information describing the key based on the key type (This field must be free-form to allow for future expansion)

Once we have a common way to describe security keys, you have the ability to reference them using JSON References to use. Here are two examples:

Signed Reqeusts/Responses (#1464)

# ...
keys:
  payment-signing-key:
    description: The payment signing JSON Web Key
    type: JWK
    metadata:
      kty: EC
      crv: P-256
      x: PxlJQu9Q6dOvM4LKoZUh2XIe9-pdcLkvKfBfQk11Sb0
      y: 6IDquxrbdq5ABe4-HQ78_dhM6eEBUbvDtdqK31YfRP8
# ...
  @context: https://example.com/paymentStandard/pay,
  amount: 255.00
  currency: USD
  signature:
    # Likely unnecessary as the key describes its algorithm
    alg": ES256
    jwk:
      $ref: "#/components/keys/payment-signing-key"
    val": "RSLmFihg8QmXxM .... N0lGIdSEYvMMLTL8hEaYV9kW6A"
# ...

JWT-based Security Scheme

Note: This example uses a JWT-based Security Scheme that DOES NOT exist yet and is only for example purposes. There is an ongoing discussion about supporting JWT for security in OAS but this is not indicative of what will be supported if/when a decision is made.

# ...
components:
  keys:
    # Keys taken from Google's OIDC Discovery Document (https://accounts.google.com/.well-known/openid-configuration)
    google-oauth-v3-1:
      description: "JSON Web Key used by Google for signing JWTs: https://www.googleapis.com/oauth2/v3/certs#/keys/0"
      type: JWK
      metadata:
        kid: 0905d6f9cd9b0f1f852e8b207e8f673abca4bf75
        e: AQAB
        kty: RSA
        alg: RS256
        n: yyeEmeK35F8P54ozfpsF79n59ZsOrcZdxQWsxrzm0qjdA5r_b-be-cQnWAw_2AoGdeWHX-Cz7uPFDMdEwzLGlpv3SELi34h8PkzjyO7xlbhsNs-ICnqUyUTA7CovKtpJ47PjiQnXcaRNCFUQbli8VlEqbVLuqFjC98igICpNYR-iiVIm0VCFtkq0p8vf1yQ493Pnx2Bm8fUx6SkeJ7wKPWQq_K4e6ZH40JWLk6c1U9W5qPKeckevdNLrdZY5lsTZ5zrRvuRBoIeZfp9bKSZGMtEja4xSCDKLrkcpb4qf6Ywx9rsZ4b8eHSLpVvUzNsj3GS7qK5flHzoccovhPVBbbQ
        use: sig
# ...
security:
  google-oath:
    type: http
    scheme: bearer
    bearerFormat: JWT
    jwk:
      $ref: '#/components/keys/google-oauth-v3-1'
# ...

Now that we have some examples, let's get the conversation started.

@whitlockjc
Copy link
Member Author

I realize that we want to make this forward thinking and not lock ourselves into one implementation but JSON Web Keys (JWK) allow for describing all key types I interact with. So my question is can't we treat JWK as the description format for security keys and go from there?

@MikeRalphson
Copy link
Member

JSON Web Keys (JWK) allow for describing all key types I interact with. So my question is can't we treat JWK as the description format for security keys

Conversely, if we find that JWKs satisfy all likely general requirements for secure-keys, can't we still use a more generic term for both the property which defines or points to one, and the same for the container within components and our definition will then 'just happen' to allow for everything a JWK needs?

@whitlockjc
Copy link
Member Author

Agreed. I want the top-level security key properties to be implementation agnostic.

@cmheazel
Copy link
Contributor

cmheazel commented Apr 2, 2019

A JWT describes a cryptographic instance. We need to describe the space of acceptable cryptographic instances. For example, an API may accept requests signed using RS256, RS384, and RS512. That would require three different JWT objects. What if we tried a JWT-like structure describing the names and valid values for the JOSE JWE and JOSE JWS parameters as well as the JWT claims? Each entry could identify the parameter/claim name and list the valid values for the entry. It should also indicate if it is protected or unprotected.

@whitlockjc
Copy link
Member Author

I'm not following, JWS already has a "JWT-like" structure where the algorithm and key details are describes. So what's missing?

@cmheazel
Copy link
Contributor

First of all, JWT describes the encryption operations that HAVE been performed. We need to describe the operations that CAN be formed. For example, how do I tell a user that they can use HS256, HS384, or HS512 to generate their signatures?

Second, OpenAPI is not restricted to JSON payloads. If I support XML signatures, how do I tell users which canonicalization algorithms my API supports?

I'm not saying that JWT is not a good place to start. But there is still more to do.

@whitlockjc
Copy link
Member Author

whitlockjc commented Apr 11, 2019

I think your crossing the streams, if I understand you correctly. I'm talking about JSON Web Keys (JWS) and not JSON Web Tokens (JWT). You're right about JWT, they are encrypted/signed and the JWT self-describes what was used to encrypt/sign the key. My proposal is for defining JWS (not JWT) that are used for secure interactions with an API, like a JWS used to verify a JWT or like a JWS used to encrypt/sign a request/response. How an operation dictates that it's encrypted/signed, and how, is a consumer of keys and is yet to be decided. Security Schemes will need a way to consume keys as well.

@fosrias
Copy link

fosrias commented Jan 7, 2020

@whitlockjc I think you need to expand your example to include the following (oneOf jwk or jwks_uri):

security:
  jwks-oath:
    type: http
    scheme: bearer
    bearerFormat: JWT
    jwks_uri: https://example.com/.well-known/jwks.json

This then works with Oauth2 providers that use JWTs and enables using JWKs with remote look up for key rotation.

@SensibleWood
Copy link

@whitlockjc I think you need to expand your example to include the following (oneOf jwk or jwks_uri):

security:
  jwks-oath:
    type: http
    scheme: bearer
    bearerFormat: JWT
    jwks_uri: https://example.com/.well-known/jwks.json

This then works with Oauth2 providers that use JWTs and enables using JWKs with remote look up for key rotation.

As an addendum to this, a good shout would be to ensure that the jwks_uri can be reflective of different environments in an API providers promotional model. For example, in the EU many banks are implementing JWKS for PSD2/open banking and they have several JWKS across their sandbox and production. For those doing OpenID Connect obvs it can be defined and exposed in Discovery endpoint but for those not this would be a good feature.

Simplest approach probably in the style of a Server object I guess

@handrews handrews added the security: encryption Support for encryption in headers, payloads, etc. label Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement security: encryption Support for encryption in headers, payloads, etc. security
Projects
None yet
Development

No branches or pull requests

6 participants