Home > Blockchain >  What's the proper way to implement a "static" authorization token feature using OIDC
What's the proper way to implement a "static" authorization token feature using OIDC

Time:01-11

I am exploring possible solutions for creating something like "API Keys" to consume my API. The goal is to allow for users to generate one or many "API Keys" from the web app and use the static generated key from the CLI app.

The web app and the client app are already using standard OIDC with JWT tokens for authentication and authorization using RBAC (role-based access control). The CLI app can already authenticate the user through the standard browser flow (redirects the user to the browser to authenticate and exchange the token back to the client).

The "API Keys" solution I am trying to achieve should have some fine-grained options where it won't authenticate as the user, but will authorize the client on behalf of the user (something like the GitHub Personal Access Token).

To me it seems like a "solved problem" as multiple services provide this kind of feature and my goal is to do it the most standard way possible using the Oauth2/OIDC protocols but I can't find details on what parts of the protocols should be used.

Can anybody provide any guidance on how it is supposed to be done using the Oauth2/OIDC entities?

Can I achieve it by only using Role-based access control or do I need Resource-based access control?

It went through the path of creating a new client for each "API Key" created, but it didn't feel right to create so many clients in the realm.

Any guidance or links to any materials are appreciated.

CodePudding user response:

Can anybody provide any guidance on how it is supposed to be done using the Oauth2/OIDC entities?

OIDC is based on OAUth 2.0 so after user login you have id tokens, access token and refresh token on the backend side. To generate new access token without asking user for authentication data you should use refresh token: https://oauth.net/2/refresh-tokens/

Can I achieve it by only using Role-based access control or do I need Resource-based access control?

resource-based access control is more flexible solution here, but if you business requirement is not complex, then role based might be enough.

It went through the path of creating a new client for each "API Key" created, but it didn't feel right to create so many clients in the realm.

It is one application so you should use one client with specific configuration for access token and roles/permissions for users.

Update: We can use GitHub as an example:

  1. User is authenticated during login
  • for OIDC code is exchanged for id token, access token and refresh token
  • session for user is set for web browser
  1. User can request access token
  • in GitHub authenticated user can request github.com/settings/personal-access-tokens/new endpoint
  • request is accepted, because user is authenticated based on session
  • backend service responsible for returning access token can obtain new access token using refresh token from point 1.
  • access token is returned to GitHub user

CodePudding user response:

To call your API in an OAuth way, CLI users must authenticate periodically. Resulting access tokens can be long lived, as for GitHub keys, if you judge that secure enough. The access token returned can be used exactly like an API key. There may be a little friction here between usability and security.

CONSOLE FLOW

The classic flow for a console app is to use the Native Apps Desktop Flow from RFC8252. This involves the user interactively signing in using the code flow, then receiving the response on a loopback URL. It is an interactive experience, but should only be required occasionally, as for GitHub tokens.

API KEYS

The access token returned is sent in the authorization header and you can use it as an API key.

API AUTHORIZATION

When your API is called, it must receive access tokens containing scopes and claims, that identify the user. This will enable you to authorize correctly.

DYNAMIC CLIENT REGISTRATION

In edge case scenarios, where long lived access tokens or interactive logins are not acceptable, another option in your toolbox is DCR. This is sometimes used to enable users to create dedicated clients:

  • User runs a standard authentication flow with a DCR scope
  • This returns an access token that enables client registration
  • The resulting token is used to register a new client
  • A client ID and client secret can be returned dynamically
  • Results could then be displayed, copied and used in a CLI

Afterwards, the user and client are bound together. At the time of token issuance you could potentially include a user claim in the access token, if the identity system had support for that. The CLI user could then do the periodic authentication silently.

SUMMARY

I would aim for the simplest and most standard option if possible. I'd recommend working backwards from how authorization will work in APIs.

  • Related