Release automatic callback setup in SDK 0.2.0

Hop-State: A_06FPARPGMNVEAN3XBVH0QD8
Hop-Proposal: R_06FPARNXMP3DGP5VQGGX4Z8
Hop-Task: T_06FPAR9KH2V5ED7V65JEN00
Hop-Attempt: AT_06FPAR9KH3NZ1CV8RGPJDSG
This commit is contained in:
2026-07-15 03:46:42 -07:00
committed by Hop
parent 73a3279d5c
commit bb04d47a29
9 changed files with 88 additions and 33 deletions
+11 -13
View File
@@ -20,14 +20,11 @@ Clients must not parse the human message. Branch on `error.code`. A `429` respon
- `assets:write` — create and complete upload sessions.
- `assets:delete` — tombstone assets and delete their stored objects.
## Register and connect an application
## Connect an application
Stuffbox supports two application identities:
There is no manual application-registration step. On the first connection request, Stuffbox creates or reuses a public identity bound to the submitted exact callback URL and returns its `client_id`. An app can send that client ID on later requests for the same callback.
- A conventional hosted application is registered once in the Stuffbox developer dashboard. Stuffbox assigns a public `client_id` and stores one or more exact callback URLs.
- A self-hosted application registers itself during its first connection request. Stuffbox creates or reuses an identity for that exact callback URL and returns its public `client_id`; the person running the installation does not visit Stuffbox to register it manually.
A client ID identifies routing and policy state; it is not a secret. Automatic self-hosted registration does not assert ownership of the callback domain. Exact callback binding, PKCE, state verification, user consent, and scoped tokens protect the flow.
A client ID identifies routing and policy state; it is not a secret, and the callback-derived identity does not assert ownership of the callback domain. Exact callback binding, PKCE, state verification, user consent, and scoped tokens protect the flow.
The application creates and retains a random PKCE verifier (43128 RFC 7636 unreserved characters), its S256 challenge, and a random state value.
@@ -35,11 +32,10 @@ The application creates and retains a random PKCE verifier (43128 RFC 7636 un
No bearer credential. Rate limited.
A conventional hosted application, or a returning self-hosted installation, sends its persisted client ID:
On the first connection, send the exact callback with no identity field:
```json
{
"client_id": "app_public-client-id",
"callback_url": "https://node.example/settings/stuffbox/callback",
"code_challenge": "base64url-sha256-challenge",
"code_challenge_method": "S256",
@@ -48,11 +44,11 @@ A conventional hosted application, or a returning self-hosted installation, send
}
```
A self-hosted installation without a persisted client ID sends:
A returning app may also send the public client ID Stuffbox returned for that callback:
```json
{
"registration_mode": "self_hosted",
"client_id": "app_public-client-id",
"callback_url": "https://node.example/settings/stuffbox/callback",
"code_challenge": "base64url-sha256-challenge",
"code_challenge_method": "S256",
@@ -75,9 +71,9 @@ Both forms return:
}
```
Persist the returned `client_id` and canonical `callback_url` before redirecting the user's browser to `authorization_url`. Use that pair for the authorization-code exchange and all later connection requests. If a self-hosted installation moves to a different callback URL, begin a new self-hosted registration for that exact URL.
Persist the returned `client_id` and canonical `callback_url` before redirecting the user's browser to `authorization_url`. Use that pair for the authorization-code exchange and later connection requests. If an app moves to a different callback URL, omit the old client ID so Stuffbox can create or reuse the identity for the new exact callback.
For a managed application, the callback must exactly match one registered for its client ID. For a self-hosted application, Stuffbox creates or reuses the identity for the submitted exact callback. HTTPS callbacks are mandatory except loopback `http://localhost`, `127.0.0.1`, and `[::1]` URLs used for development. URLs cannot contain credentials or fragments.
When a client ID is sent, the callback must exactly match the URL bound to that identity. HTTPS callbacks are mandatory except loopback `http://localhost`, `127.0.0.1`, and `[::1]` URLs used for development. URLs cannot contain credentials, query strings, or fragments.
The consent page requires a Stuffbox login and identifies the application by the exact callback domain, alongside every requested permission. Approval redirects only to the stored callback with `code` and the original `state`. The application must compare state before exchanging the code.
@@ -106,6 +102,8 @@ Refresh rotation:
The `client_id` and `redirect_uri` must be the values persisted from the connection-request response. The response contains `access_token`, `refresh_token`, `token_type: "Bearer"`, `expires_in`, and a space-delimited `scope`. Replace the old refresh token atomically with the returned one. Reuse of a consumed token revokes the entire grant and returns `refresh_token_reuse`; the application must reconnect.
For compatibility, Stuffbox still accepts the deprecated `registration_mode: "self_hosted"` field sent by SDK 0.1.0. New integrations should omit it.
### `POST /api/v1/revoke`
```json
@@ -116,7 +114,7 @@ Revokes the token's whole grant. Unknown values return success to avoid becoming
## Direct upload
All asset and upload endpoints use `Authorization: Bearer {access_token}`. The browser should normally call the node's same-origin upload-session proxy; the node calls Stuffbox and returns only the signed upload details.
All asset and upload endpoints use `Authorization: Bearer {access_token}`. The browser should normally call the app's same-origin upload-session proxy; the app calls Stuffbox and returns only the signed upload details.
### `POST /api/v1/uploads`