Skip to content

Commit c7b7771

Browse files
committed
Replace transition:generic with permission sets scopes
1 parent 9765fd8 commit c7b7771

5 files changed

Lines changed: 26 additions & 9 deletions

File tree

.agents/skills/epds-login/SKILL.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ AT Protocol universe (a DID, a handle, a data repository) automatically provisio
1515
From your app's perspective, ePDS uses standard AT Protocol OAuth (PAR + PKCE + DPoP).
1616
The reference implementation is `packages/demo` in the [ePDS repository](https://github.com/hypercerts-org/ePDS).
1717

18+
For protocol-level detail beyond ePDS specifics — DPoP proof mechanics, granular
19+
scope design (`repo:`/`rpc:`/`blob:`/`account:`), identity verification after token
20+
exchange, and refresh-token race handling — see the `atproto-oauth` skill. This skill
21+
covers only what is ePDS-specific.
22+
1823
## Two Flows
1924

2025
| Flow | App provides | How user starts | Implementation |
@@ -57,7 +62,7 @@ are mutually exclusive:
5762
"client_id": "https://yourapp.example.com/client-metadata.json",
5863
"client_name": "Your App",
5964
"redirect_uris": ["https://yourapp.example.com/api/oauth/callback"],
60-
"scope": "atproto transition:generic",
65+
"scope": "atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite",
6166
"grant_types": ["authorization_code", "refresh_token"],
6267
"response_types": ["code"],
6368
"token_endpoint_auth_method": "private_key_jwt",
@@ -67,6 +72,17 @@ are mutually exclusive:
6772
}
6873
```
6974

75+
> **On the `scope` value:** `atproto` is mandatory and must be listed first; the
76+
> remaining entries request only the permissions your app needs. The examples here
77+
> reference three hypercerts specific permission sets via the `include:` prefix —
78+
> `include:org.hypercerts.authWrite`, `include:org.hyperboards.authWrite`, and
79+
> `include:app.certified.authWrite`; substitute the permission sets your own app defines. A
80+
> permission set that bundles `rpc:` service calls also needs an
81+
> `?aud=<service-did>` parameter (with `#` percent-encoded as `%23`); these are
82+
> write-only sets, so no `aud` is required. Avoid the legacy `transition:generic`
83+
> catch-all. See the `atproto-oauth` skill's "Scopes and Permission Sets" for the
84+
> grammar.
85+
7086
Alternatively, replace `jwks_uri` with an inline `jwks` object containing
7187
the public key directly — see
7288
[client-metadata.md](references/client-metadata.md) for both forms, the
@@ -85,7 +101,7 @@ const client = new NodeOAuthClient({
85101
client_id: 'https://yourapp.example.com/client-metadata.json',
86102
client_name: 'Your App',
87103
redirect_uris: ['https://yourapp.example.com/api/oauth/callback'],
88-
scope: 'atproto transition:generic',
104+
scope: 'atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite',
89105
grant_types: ['authorization_code', 'refresh_token'],
90106
response_types: ['code'],
91107
token_endpoint_auth_method: 'private_key_jwt',

.agents/skills/epds-login/references/client-metadata.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ mutually exclusive — the PDS rejects metadata that has both.
5353
"client_id": "https://yourapp.example.com/client-metadata.json",
5454
"client_name": "Your App Name",
5555
"redirect_uris": ["https://yourapp.example.com/api/oauth/callback"],
56-
"scope": "atproto transition:generic",
56+
"scope": "atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite",
5757
"grant_types": ["authorization_code", "refresh_token"],
5858
"response_types": ["code"],
5959
"token_endpoint_auth_method": "private_key_jwt",
@@ -70,7 +70,7 @@ mutually exclusive — the PDS rejects metadata that has both.
7070
"client_id": "https://yourapp.example.com/client-metadata.json",
7171
"client_name": "Your App Name",
7272
"redirect_uris": ["https://yourapp.example.com/api/oauth/callback"],
73-
"scope": "atproto transition:generic",
73+
"scope": "atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite",
7474
"grant_types": ["authorization_code", "refresh_token"],
7575
"response_types": ["code"],
7676
"token_endpoint_auth_method": "private_key_jwt",
@@ -96,14 +96,15 @@ host — useful for simpler setups. See
9696
[Publishing the JWKS document](#publishing-the-jwks-document) below for
9797
key generation and serving details.
9898

99+
99100
## All supported fields
100101

101102
| Field | Required | Description |
102103
| --------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
103104
| `client_id` | Yes | Must match the URL where this file is hosted |
104105
| `client_name` | Yes | Shown on the login page and in OTP emails |
105106
| `redirect_uris` | Yes | Array of allowed callback URLs after login |
106-
| `scope` | Yes | Always `"atproto transition:generic"` |
107+
| `scope` | Yes | Space-separated list. `atproto` is required and must come first; add the scopes/permission sets your app needs (the examples use `include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite`). Avoid the legacy `transition:generic` catch-all — see the `atproto-oauth` skill. |
107108
| `grant_types` | Yes | Always `["authorization_code", "refresh_token"]` |
108109
| `response_types` | Yes | Always `["code"]` |
109110
| `token_endpoint_auth_method` | Yes | `"private_key_jwt"` (recommended) or `"none"` — see above |
@@ -266,7 +267,7 @@ above for the trade-offs.
266267
"client_id": "https://yourapp.example.com/client-metadata.json",
267268
"client_name": "Your App Name",
268269
"redirect_uris": ["https://yourapp.example.com/api/oauth/callback"],
269-
"scope": "atproto transition:generic",
270+
"scope": "atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite",
270271
"grant_types": ["authorization_code", "refresh_token"],
271272
"response_types": ["code"],
272273
"token_endpoint_auth_method": "none",

.agents/skills/epds-login/references/flows.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export async function handleLogin(email: string) {
156156
client_id: CLIENT_ID,
157157
redirect_uri: REDIRECT_URI,
158158
response_type: 'code',
159-
scope: 'atproto transition:generic',
159+
scope: 'atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite',
160160
state,
161161
code_challenge: codeChallenge,
162162
code_challenge_method: 'S256',

packages/demo/src/app/api/oauth/login/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export async function GET(request: Request) {
150150
client_id: clientId,
151151
redirect_uri: redirectUri,
152152
response_type: 'code',
153-
scope: 'atproto transition:generic',
153+
scope: 'atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite',
154154
state,
155155
code_challenge: codeChallenge,
156156
code_challenge_method: 'S256',

packages/demo/src/app/client-metadata.json/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export async function GET() {
5050
client_uri: baseUrl,
5151
logo_uri: `${baseUrl}/certified-logo.png`,
5252
redirect_uris: [`${baseUrl}/api/oauth/callback`],
53-
scope: 'atproto transition:generic',
53+
scope: 'atproto include:org.hypercerts.authWrite include:org.hyperboards.authWrite include:app.certified.authWrite',
5454
grant_types: ['authorization_code', 'refresh_token'],
5555
response_types: ['code'],
5656
...(isConfidential

0 commit comments

Comments
 (0)