...
Resolving the issues stated above simply make the authentication process more secureprovides additional flexibility, and provides users with additional protections, with the trade-off being increased susceptibility to replay attacks (which should be prevented by https).
This sample scenario identified by Jordan Kiang (Unlicensed) is useful as it helps determine additional requirements:
...
A user must be able to issue multiple access tokens
A user must be able to view metadata about their active tokens, e.g. scope, a custom name/identifier
A user must be able to revoke an individual access token
Generated access tokens must use scopes as defined in the OAuth 2 implementation
Generated access tokens should only expire if unused for 180 days or manually revokedFrom the perspective of
a client application, access tokens must be “stateless”, i.e. they are not single use or rotatingA client application should be able to access a token from a read-only key store and multiple, parallel client processes should be able to use the token without being concerned about concurrency issues.
Generated access tokens should be bearer tokens
A password/session token must not be required to use an access token
Functionality identical to OAuth access tokens is preferred
It should be impossible for any actor to determine the token other than the issuer at creation time (i.e. store a hash).
...
Service | Request Parameters | Response Body | Notes |
---|---|---|---|
POST /auth/v1/userGeneratedTokenpersonalAccessToken | Body: AccessTokenGenerationRequest {
} | AccessTokenGenerationResponse {
) } | Generates a token that users can copy and paste into the command line client. |
GET /auth/v1/userGeneratedToken personalAccessToken | None | Paginated list of AccessTokenRecord: {
} | Retrieves a paginated list of the user’s generated access tokens. Tokens that are active or expired will appear. Tokens that have been revoked (deleted) will not appear. |
DELETE /auth/v1/personalAccessToken/userGeneratedToken Param (only one is required){id} | Path param: id: the id of the token to deleteOR token: the token to delete | None | Revokes the token if it’s a valid access token. |
How to use a personal access token
The personal access token can be used by doing two things
...
Put a valid identifier, (e.g. username) in the userId
header (just like API keys)
...
putting the token in the Authorization header with the ‘Bearer’ keyword preceding the token (Authorization: Bearer <token>
)
Open Questions
Which of these services be accessible via scoped access tokens?
...
What should the token look like? Some options
Opaque token
With or without additional userId header?
Non-expiring, signed JWT (containing a an integer token ID and a user ID)
Opaque token
With or without additional userId header?
This is partially an implementation question. The ability to revoke tokens requires storing tokens or token identifiers in persistent storage. Performance is critical because a database lookup will be done for every authenticated request made by a programmatic clientusing one of these tokens.