-
Notifications
You must be signed in to change notification settings - Fork 62
docs: ase-developer-journeys #794
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
Open
hajjimo
wants to merge
8
commits into
main
Choose a base branch
from
DOC-41-option-3
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+931
−162
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
028234b
docs: ase-developer-journeys
hajjimo 9e8c55f
docs: ase-new-content
hajjimo 34de358
docs: ase-content-updates
hajjimo a0d7868
Merge branch 'main' into DOC-41-option-3
hajjimo 3db4c47
docs: ase-content-updates
hajjimo b26a79e
docs: ase-content-updates
hajjimo 23121d6
Merge branch 'main' into DOC-41-option-3
hajjimo ce6d941
docs: ase_content_updates
hajjimo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| --- | ||
| title: Authorization server | ||
| --- | ||
|
|
||
| import { LinkOut } from '@interledger/docs-design-system' | ||
|
|
||
| :::tip[Summary] | ||
| The authorization server processes grant requests under GNAP, issues access tokens, and coordinates user consent for interactive grants. This page describes what the ASE's authorization server must do. | ||
| ::: | ||
|
|
||
| ## What the authorization server does | ||
|
|
||
| An ASE's authorization server is the single entry point for clients seeking permission to call the resource server. It: | ||
|
|
||
| - Accepts grant requests at a single grant endpoint URI. | ||
| - Verifies the client's identity and the signature on each request. | ||
| - Decides whether the requested access is permitted, including whether interaction with the resource owner is required. | ||
| - Issues, rotates, and revokes access tokens. | ||
| - Coordinates the interactive flow with the ASE's identity provider when consent is needed. | ||
|
|
||
| The wallet address response returns the grant endpoint URI in the `authServer` field. Clients send all grant requests to that URI. The GNAP specification uses a single endpoint per authorization server rather than a different endpoint per grant type. | ||
|
|
||
| ## Grants and access tokens | ||
|
|
||
| The authorization server's job is to translate a **grant**, an authorization issued by the resource owner, into one or more **access tokens** that the client uses against the resource server. From the authorization server's perspective: | ||
|
|
||
| - A grant is durable state held by the authorization server. It records what the resource owner consented to and is the basis on which tokens are issued. | ||
| - An access token is a short-lived credential bound to a grant. The authorization server must be able to validate it when the resource server asks. | ||
| - The authorization server validates the grant each time the client uses its access token. Revoking the grant must revoke every token bound to it. | ||
|
|
||
| ASEs decide the token lifetime and whether tokens are opaque (validated by callback to the authorization server) or self-contained (validated locally by the resource server using shared key material). | ||
|
|
||
| ## Grant request processing | ||
|
|
||
| Every grant request must be signed by the client. The authorization server's first job is to verify the signature. Refer to [Security](/implement/security/) for the verification rules. | ||
|
|
||
| After signature verification, the authorization server inspects the request to determine the grant type and whether interaction is required. | ||
|
|
||
| ### incoming-payment grants | ||
|
|
||
| Non-interactive. The authorization server may issue an access token immediately if the request is well-formed and the client is trusted. | ||
|
|
||
| The client may include directed identity (a public key in the request body rather than a wallet address). The authorization server uses the embedded key for signature verification and does not require a wallet address or key registry lookup for this grant type. | ||
|
|
||
| The authorization server may issue a single grant whose access token covers multiple incoming payments at this ASE, as long as the additional incoming payments are for accounts that belong to this ASE. | ||
|
|
||
| ### quote grants | ||
|
|
||
| Non-interactive. Same handling as incoming-payment grants. Directed identity is also permitted. | ||
|
|
||
| The authorization server may issue a single grant whose access token covers multiple quotes at this ASE, subject to the same single-ASE constraint. | ||
|
|
||
| ### outgoing-payment grants | ||
|
|
||
| **Interactive.** The authorization server must not issue an access token until the resource owner has explicitly consented to the outgoing payment. | ||
|
|
||
| When the authorization server receives an outgoing-payment grant request: | ||
|
|
||
| 1. Verify the request signature and the client's identity. | ||
| 2. Persist the grant in a `pending` state, including the requested limits (amounts, expiry). | ||
| 3. Return an `interact.redirect` URI (the redirect to the start of the interaction flow) and a `continue` URI with a continuation token. The client uses the redirect URI to send the resource owner into the consent flow. | ||
| 4. When the resource owner reaches the redirect URI, start the interaction session and forward the resource owner to the identity provider (IdP). Refer to [Identity provider integration](/implement/identity-provider/). | ||
| 5. When the IdP returns the resource owner's decision, finalize the session. If consent was granted, advance the grant from `pending` to `approved`. | ||
| 6. Redirect the resource owner back to the client's `interact.finish` URI with an `interact_ref` and a hash computed from the original nonce values and the grant URI. Refer to [Security](/implement/security/) for the hash generation rules. | ||
| 7. When the client posts to the continuation URI with the continuation token, issue the access token if the grant is `approved`. If the grant is still `pending` or was denied, return the appropriate GNAP error. | ||
|
|
||
| ## Continuation and polling | ||
|
|
||
| In headless or non-browser scenarios, the client may not have a return URI for the authorization server to redirect to. The authorization server must allow the client to poll the continuation URI to check whether interaction has completed. ASEs define a sensible minimum polling interval and return it to the client in the continuation response. | ||
|
|
||
| ## Token rotation and revocation | ||
|
|
||
| ASEs must support: | ||
|
|
||
| - **Rotation**: The client may request a new access token bound to the same grant. The authorization server issues a new token and invalidates the previous one. Tokens bound to grants that have themselves expired must not be rotatable. | ||
| - **Revocation**: The client (or, in some flows, the resource owner) may revoke an access token. After revocation, the resource server must reject any subsequent use of the token. If tokens are validated locally at the resource server, the authorization server must propagate revocation quickly enough that stale tokens cannot be used for unauthorized operations. | ||
|
|
||
| The relevant client-facing endpoints are <LinkOut href='/apis/auth-server/operations/post-token'>Rotate access token</LinkOut> and <LinkOut href='/apis/auth-server/operations/delete-token'>Revoke access token</LinkOut>. | ||
|
|
||
| ## Token validation for the resource server | ||
|
|
||
| When the resource server receives a request from a client, it must validate the access token. ASEs choose one of two patterns: | ||
|
|
||
| - **Introspection**: The resource server calls the authorization server for each request to check the token. Simple to reason about; cost scales with traffic. | ||
| - **Self-contained tokens**: The authorization server signs tokens that the resource server can validate locally using shared key material. Cheaper at scale; requires careful handling of revocation propagation. | ||
|
|
||
| Either way, the authorization server is the source of truth for whether a token is currently valid. | ||
|
|
||
| ## Reference implementation | ||
|
|
||
| <LinkOut href="https://rafiki.dev">Rafiki</LinkOut> provides an open-source | ||
| implementation of an Open Payments authorization server. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On this page, we have this section:
Technically, it is the ASEs responsibility to allow clients to register their public keys, and host them at the jwks.json endpoint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated text in docs/identity/client-keys.mdx:
For clients that identify themselves with a wallet address, the ASE provides a way for clients to register public keys and hosts the client’s key registry at WALLET_ADDRESS/jwks.json. An authorization server can retrieve the client’s key registry from that endpoint.
Updated text in docs/implement/security.mdx:
ASEs must provide a key registration flow for clients and host each client's JWKS at
WALLET_ADDRESS/jwks.json.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should write as though this is the default, because providing a key directly won't be common, given it's only for specific purposes.