learn.openapis.org icon indicating copy to clipboard operation
learn.openapis.org copied to clipboard

Add descriptions and examples of common API authentication scenarios

Open mikekistler opened this issue 9 months ago • 9 comments

There are a number of common approaches for authenticating/authorizing requests to an API. The OpenAPI securitySchemes and security requirements are intended to document the authn/authz requirements of operations in an API description. I think we should develop practical guidance for how the common authn/authz mechanisms should be or can be described in OpenAPI documents.

Some of the common approaches that should be described are:

  • Authentication through log in on a web page, possibly with two-factor auth, that generates a cookie that is used as proof of authentication on subsequent requests.
  • OAuth2 authentication that produces a JWT or other token as proof of auth
  • OIDC authentication that produces a JWT
  • Bearer token authentication where the token is obtained from some known source

mikekistler avatar Feb 27 '25 19:02 mikekistler

This is great, and I think there are a lot of people who can share their experiences to help us here! Could everyone please add a comment? We need to know:

  • what security method you're using (including/especially if it's not already listed)
  • snippets of your OpenAPI description showing how you define and use that method
  • if you can't describe it with OpenAPI 3.1, tell us why not

lornajane avatar Mar 05 '25 14:03 lornajane

Can this be moved to a discussion, so it's possible to respond in a thready fashion to each individual post?

karenetheridge avatar Mar 07 '25 01:03 karenetheridge

Good suggestion @karenetheridge. I don't see an option to do that, but maybe I just don't have permissions?

mikekistler avatar Mar 07 '25 02:03 mikekistler

We don't currently use discussions on this repo and I'm not sure we have the volunteer bandwidth to monitor another forum. I suggest if there's anything we want to get into in more detail, we create an issue for that thing and maintain a list in the description.

@SensibleWood I'm particularly looking for examples to include in the documentation of things that do work. Please share snippets if you have them.

lornajane avatar Mar 07 '25 09:03 lornajane

@lornajane sorry that wasn't clear from what @mikekistler originally asked. I've removed my comments.

SensibleWood avatar Mar 07 '25 09:03 SensibleWood

Ah! That's not at all what I intended, @SensibleWood - your examples are good and valuable, and since we'll need to find or create supporting OpenAPI examples for each of the entries we can come up with then yours would have given us a great start if you had them! The goal is to list the things that are supported, with examples, and identify what isn't easy to express with a view to updating the specification in a future release to accommodate more options.

lornajane avatar Mar 13 '25 09:03 lornajane

@SensibleWood Yes these were definitely valuable and I'm sorry I have been slow to add my own.

mikekistler avatar Mar 13 '25 11:03 mikekistler

Here's a very common scenario in apps that use the ASP.NET web application framework:

  • The app serves web pages (html + js + css) that require authentication
  • The authentication is a "cookie" -- an opaque value to the client, because the server has encrypted it to protect its contents and prevent manipulation by the client
  • The cookie was set by the server, and automatically sent back on subsequent requests by the browser (user-agent)
  • The cookie has a fixed name but the client does not particularly need to know it, since it is set by the server
  • When the cookie is not present on a request that requires the cookie auth, the response is not a "401" but a redirect to an endpoint, the "challenge endpoint", that authenticates the user.
  • The "challenge endpoint" does not require auth, since its purpose is to authenticate
  • When the "challenge endpoint" is in the same web app as the endpoints it covers, a successful authentication will set the cookie needed for the other endpoints.
  • When the "challenge endpoint" is an external side, like a third party OIDC provider, a successful authentication redirects back to an "auth redirect" endpoint with a token that demonstrates (cryptographically) that the user was authenticated and then the "auth redirect" endpoint sets the cookie for the other endpoints.

Here I have not really covered the details of how authentication is done at the challenge endpoint -- there are many various options there, including username/password, two-factor / multi-factor auth, passkeys, proof of possession, etc.

For the endpoints that just require the cookie, the only way to describe this in OpenAPI (as best I could determine), is:

  securitySchemes:
    cookieAuth:
      type: apiKey
      in: cookie
      name: session_id  # Name of the cookie used for authentication

This feels woefully inadequate at expressing the actual auth mechanism described above.

mikekistler avatar Mar 13 '25 11:03 mikekistler

@lornajane @mikekistler Reposted for posterity - not supported, but wouldn't they be nice?

Surely SAML?

I don't use it in API design as I am OAuth/OIDC in nature, but I see so many (enterprise) APIs in action that do it. Based on your bullets @lornajane:

SAML

  • I do not, as it does not exist.
  • It is not a Security Scheme, hence cannot be described.
  • If there is interest we should find an expert, as I am not one of those.

This guy: https://datatracker.ietf.org/doc/rfc7523/ (JSON Web Token (JWT) Profile)

It's a relatively straightforward proof-of-possession authentication mechanism used in open banking standards, but has specific semantics that require a specific description over above "just" describing a JWT.

JSON Web Token (JWT) Profile

  • I do not, as it does not exist.
  • I fudge together the JWT description, where an open banking ecosystem is using 3.1 (most don't) and then write some documentation.
  • Most of the time, just write some documentation

This guy: https://datatracker.ietf.org/doc/html/rfc9449 (Demonstrating proof-of-possession)

Takes the JWT Profile about and add a standardised header to indicate consistency between token request and resource server in OAuth/OIDC flows.

  • Demonstrating proof-of-possession
  • Easy enough, as its a HTTP header field. Same constraints above with JWT and needing 3.1 for it.
  • Write some docs to go with it as the DPOP Header is a JWT, but a Security Scheme would be great

SensibleWood avatar Mar 19 '25 08:03 SensibleWood

I'm not sure if this helpful other than to validate the examples already provided and identify gaps. I recently went through trying to identify all the common API authentication methods and the fields expected. The schema column has the fields that would be required for that particular auth_type. Only some of them actually overlap with how the credential is sent once authenticated which is why it might not be exactly relevant.

auth_type Examples Payload Schema
api_key X-API-Key header, Jira PAT, GitHub PAT { key, in:"header"⏐"query", name }
basic Basic Auth, JDBC { username, password }
digest HTTP Digest { username, password, realm?, nonce?, algorithm?, qop?, nc?, cnonce?, opaque? }
ntlm Windows NTLM { username, password, domain?, workstation? }
aws_sigv4 AWS APIs { access_key, secret_key, region, service }
hawk old Mozilla/HAPI services { id, key, algorithm:"sha256"⏐"sha1", user?, nonce?, ext?, app?, dlg?, include_payload_hash?:bool }
jwt_bearer Google SA JWT, custom { issuer, subject?, audience, private_key, alg:"RS256" }
oauth2 Shopify, Google { grant_type:"authorization_code"⏐"client_credentials"⏐"refresh_token"⏐"jwt_bearer", access_token?, add_auth_to?: "header"⏐"url", refresh_token?, expires_at?, scope?, client_auth_method:"basic"⏐"body", extra_params?:object }
oauth2_pkce Mobile apps, SPAs, public clients { grant_type:"authorization_code", access_token?, refresh_token?, expires_at?, scope?, code_verifier, code_challenge?, code_challenge_method:"S256"⏐"plain", client_auth_method:"basic"⏐"body"⏐"none", extra_params?:object }
oauth1 Jira Server, Twitter legacy { consumer_key, consumer_secret, token, token_secret, signature_method:"HMAC-SHA1" }

winklerj avatar Jun 30 '25 15:06 winklerj

@winklerj Thanks for sharing this! I have not previously seen such a clear presentation of the options in this way.

mikekistler avatar Jun 30 '25 21:06 mikekistler