Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
389 changes: 229 additions & 160 deletions docs/astro.config.mjs

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/src/content/docs/concepts/amounts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import {
} from '@interledger/docs-design-system'
import { Steps } from '@astrojs/starlight/components'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
Amounts in Open Payments define monetary values using asset codes and asset scales. They provide a standardized way to represent money across different currencies and payment scenarios.
:::
Expand Down
8 changes: 8 additions & 0 deletions docs/src/content/docs/concepts/auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ parent: Concepts

import { LinkOut, Tooltip } from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
Authorization in Open Payments refers to the process by which a client obtains permission from a resource owner to access and perform operations on protected resources.
:::
Expand All @@ -15,6 +19,10 @@ Open Payments leverages the <LinkOut href='https://datatracker.ietf.org/doc/html

The authorization server grants permission for a client to access the Open Payments APIs and the `incoming-payment`, `quote`, and `outgoing-payment` resources. It does this by issuing access tokens, which represent a set of access rights and/or attributes granted to the client. With the appropriate access tokens, the client can perform allowed operations, such as creating incoming and outgoing payments, on behalf of the resource owner (RO).

:::note[For ASEs deploying an authorization server]
ASEs should refer to the [authorization server page](/implement/auth-server/) under the For ASEs section.
:::

### Relationship between grants and access tokens

A **grant** is an authorization issued by the RO that allows a client to access specific resources. The grant specifies the type of actions the client is allowed to perform. Grants may require user interaction and can be contingent on the RO's consent. The authorization server validates the grant each time the client uses their access token.
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/concepts/op-flow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import {
} from '@interledger/docs-design-system'
import Interactive from '/src/content/docs/partials/_diagram-interactive-grant.mdx'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
When a client issues payment instructions, numerous interactions between the client and servers are needed to obtain grants, verify identities, and create the resources required to complete a transaction.
:::
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/concepts/payments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ parent: Concepts

import { LinkOut } from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

The payment method is the means by which the sender's ASE will fulfill its payment obligations to the recipient's ASE. Cash, credit/debit cards, bank transfers, gift cards and mobile money can all be considered different payment methods.

When an `outgoing-payment` is completed against an open and active `incoming-payment`, the sender's ASE becomes obligated to make payment using the payment method initially specified in the `incoming-payment` response.
Expand Down
8 changes: 8 additions & 0 deletions docs/src/content/docs/concepts/resources.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ tableOfContents:

import { LinkOut, Tooltip } from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

The Open Payments APIs are served by a resource server. Operations on the APIs require the client to have a valid access token issued by a trusted authorization server.

## Resource types
Expand All @@ -15,6 +19,10 @@ An Open Payments resource server hosts three sets of APIs, those for incoming pa

Each set of APIs has its own resource type: `incoming-payment`, `quote`, and `outgoing-payment`.

:::note[For ASEs deploying a resource server]
ASEs should refer to the [resource server page](/implement/resource-server/) under the For ASEs section.
:::

### incoming-payment

An `incoming-payment` resource is often the first resource created in a payment flow, by way of the <LinkOut href='/apis/resource-server/operations/create-incoming-payment'>Create Incoming Payment API</LinkOut>. The resource is created on the recipient's account.
Expand Down
8 changes: 8 additions & 0 deletions docs/src/content/docs/concepts/wallet-addresses.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ title: Wallet addresses
parent: Concepts
---

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
A wallet address is a secure, sharable identifier for an Open Payments-enabled account. Each wallet address acts a service endpoint into the APIs, allowing clients to interact with the underlying account.
:::
Expand Down Expand Up @@ -50,6 +54,10 @@ When setting up a payment, the client must obtain the wallet address for both th

A wallet address server is an API endpoint that retrieves public information about a wallet address, including its associated public keys. For more technical details, visit the [wallet address server API docs](/apis/wallet-address-server/operations/get-wallet-address/).

:::note[For ASEs deploying a wallet address server]
ASEs should refer to the [wallet address architecture page](/implement/wallet-address-architecture/) under the For ASEs section.
:::

## Privacy and security

A wallet address acts as a proxy identifier (alias) for an underlying financial account. If permitted by an ASE, a single account can have multiple wallet addresses. Allowing account holders to generate unique wallet addresses for every client they interact with can help prevent a single address from becoming a tracking vector.
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/identity/client-keys.mdx
Copy link
Copy Markdown
Contributor

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:

Clients that identify themselves with a wallet address make their key registry publicly accessible via a jwks.json endpoint.

Technically, it is the ASEs responsibility to allow clients to register their public keys, and host them at the jwks.json endpoint.

Copy link
Copy Markdown
Contributor Author

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clients that identify themselves with a wallet address

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.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
MermaidWrapper
} from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
Client keys are unique identifiers that allow clients to sign Open Payments requests and verify the client's identity.
:::
Expand All @@ -18,14 +22,14 @@ All client requests in Open Payments are signed using a unique key that identifi

A key registry is a list of keys that are generated and stored by the client for when the client requires access to protected Open Payment resources. Grant requests are completed over multiple signed HTTP requests. As such, it's important that the client provides a way to consistently identify itself to an authorization server. The key registry allows the authorization server to verify that the client is who it says it is.

Clients that identify themselves with a [wallet address](/concepts/wallet-addresses/) make their key registry publicly accessible via a `jwks.json` endpoint. An authorization server can retrieve the client's key registry by accessing `WALLET_ADDRESS/jwks.json`.
Clients identify themselves with a [wallet address](/concepts/wallet-addresses/) and expose their public keys through a JWKS endpoint hosted by the ASE at `WALLET_ADDRESS/jwks.json`. Authorization servers fetch that registry to verify signed requests.

```http title="Example"
https://wallet.example.com/alice/jwks.json
```

:::note
Clients using directed identity for non-interactive grant requests provide their public key directly in the request body and do not require a key registry. See [Client requests](#client-requests) for more information.
Directed identity is supported only for certain non-interactive grants. In those cases, the client provides a `jwk` in the request body instead of using a wallet-address-hosted JWKS endpoint. Refer to [Client requests](#client-requests).
:::

### Registry structure
Expand Down
8 changes: 8 additions & 0 deletions docs/src/content/docs/identity/grants.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ title: Grant negotiation and authorization

import { CodeBlock, LinkOut, Tooltip } from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
A grant in Open Payments allows a client to obtain authorization from a resource owner to access and perform operations on protected resources. Open Payments uses the Grant Negotiation and Authorization Protocol (GNAP) to facilitate this process, allowing clients to securely interact with the API.
:::
Expand All @@ -30,6 +34,10 @@ An authorization server grants delegated privileges to a client in the form of a

An authorization server is uniquely identified by its grant endpoint URI, which is an absolute URI that a client calls to initiate a grant request.

:::note[For ASEs deploying an authorization server]
ASEs should refer to the [authorization server page](/implement/auth-server/) under the For ASEs section.
:::

### Key registries

A key registry is a list of keys associated with clients requiring access to protected Open Payments resources. Key registries are publicly exposed via a `jwks.json` endpoint and allows an authorization server to verify that a client is who it says it is.
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/identity/hash-verification.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ title: Hash verification

import { LinkOut, Tooltip } from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
After a resource owner allows a client to access their account, the client must verify that the resource owner provided their consent. The client verifies consent by calculating the hash issued by the authorization server.
:::
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/identity/http-signatures.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ title: HTTP message signatures

import { LinkOut } from '@interledger/docs-design-system'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
HTTP message signatures secure communications in Open Payments by verifying message authenticity and protecting against tampering.
:::
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/identity/idp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ title: Identity providers
import { CodeBlock, LinkOut } from '@interledger/docs-design-system'
import Interactive from '/src/content/docs/partials/_diagram-interactive-grant.mdx'

:::note[For client developers]
This page describes Open Payments from the client developer's perspective. ASEs should refer to the [For ASEs](/implement/) section.
:::

:::tip[Summary]
An identity provider (IdP) is a system or service that manages user authentication and consent during the interactive grant process.
:::
Expand Down
92 changes: 92 additions & 0 deletions docs/src/content/docs/implement/auth-server.mdx
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.
Loading
Loading