Skip to content

Commit c2349cd

Browse files
Testclaude
authored andcommitted
fix(permissions): drop unsupported description field; document set-growth semantics
Two review points from Ashex on PR #222: - `description` is not a valid field on a `permission-set` def — the spec defines only `title`/`detail` (+ `:lang`) as user-facing consent copy, and it is not shown in the OAuth dialog. It was an AI hallucination in the original set files. Removed from all three sets, their JSONC examples in the design doc, and the generated SCHEMAS.md. All 182 tests still pass, confirming the field was never load-bearing. - Document what happens when a published set later grows: OAuth grants persist the raw `include:<nsid>` and re-expand it on token refresh, so existing sessions gain newly-added (same-authority) collections with no re-auth and no `.vN` NSID; CGS API keys stay a frozen snapshot until re-issued. Grounded in the permission spec and the reference PDS `rotateToken`/`buildTokenScope` path, with a caveat that non-reference Auth Servers should be verified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent bf1eef8 commit c2349cd

5 files changed

Lines changed: 44 additions & 12 deletions

File tree

SCHEMAS.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ Hypercerts-specific lexicons for tracking impact work and claims.
99

1010
### `org.hypercerts.authWrite`
1111

12-
**Description:** Permission set granting create, update, and delete on every Hypercerts (org.hypercerts) record collection.
13-
1412
---
1513

1614
### `org.hypercerts.claim.activity`
@@ -492,8 +490,6 @@ A labeled URL reference.
492490

493491
### `app.certified.authWrite`
494492

495-
**Description:** Permission set granting create, update, and delete on every Certified (app.certified) record collection.
496-
497493
---
498494

499495
### `app.certified.graph.follow`
@@ -736,8 +732,6 @@ Specifies the sub-string range a facet feature applies to. Start index is inclus
736732

737733
### `org.hyperboards.authWrite`
738734

739-
**Description:** Permission set granting create, update, and delete on every Hyperboards (org.hyperboards) record collection.
740-
741735
---
742736

743737
### `org.hyperboards.board`

docs/design/permission-sets.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ Enumerates every `type: "record"` collection under `org.hypercerts.*`:
112112
"defs": {
113113
"main": {
114114
"type": "permission-set",
115-
"description": "Permission set granting create, update, and delete on every Hypercerts (org.hypercerts) record collection.",
116115
"title": "Manage your Hypercerts data",
117116
"detail": "Create, edit, and delete your Hypercerts records (impact claims, evaluations, funding, and related data).",
118117
"permissions": [
@@ -151,7 +150,6 @@ Enumerates every `type: "record"` collection under `org.hyperboards.*`:
151150
"defs": {
152151
"main": {
153152
"type": "permission-set",
154-
"description": "Permission set granting create, update, and delete on every Hyperboards (org.hyperboards) record collection.",
155153
"title": "Manage your Hyperboards data",
156154
"detail": "Create, edit, and delete your Hyperboards records (board configurations and display profiles).",
157155
"permissions": [
@@ -181,7 +179,6 @@ Enumerates every `type: "record"` collection under `app.certified.*`:
181179
"defs": {
182180
"main": {
183181
"type": "permission-set",
184-
"description": "Permission set granting create, update, and delete on every Certified (app.certified) record collection.",
185182
"title": "Manage your Certified data",
186183
"detail": "Create, edit, and delete your Certified records (profile, badges, follows, wallet links, and related data).",
187184
"permissions": [
@@ -322,6 +319,50 @@ The `AGENTS.md` "Adding / modifying a lexicon" checklist calls this out. Worth a
322319
check in the release process too (and ideally an automated test asserting each
323320
set lists exactly the `type: "record"` defs in its namespace).
324321

322+
### Growing a set is safe: existing grants pick up new collections
323+
324+
Because we will keep adding lexicons, the key question is what happens to a grant
325+
a user already accepted when the set is later re-published with **more**
326+
collections. The answer differs for the two consumption paths:
327+
328+
- **OAuth grants are dynamic — no re-auth, no `.vN` NSID.** The user's
329+
Authorization Server (their PDS) persists the _raw_ `include:<nsid>` scope in
330+
the grant, not a frozen expansion of it, and **re-resolves the published set on
331+
each token refresh**. So adding a collection to a published set widens every
332+
existing session the next time it refreshes, without the user re-authorizing.
333+
The permission spec makes this explicit: _"The permissions associated with an
334+
Access Token should remain fixed, but when a client refreshes their tokens
335+
(obtaining a new access token), the computed permissions for the session may be
336+
updated to reflect changes to sets"_, so _"client software can then be updated
337+
to take advantage of those new lexicons, without requiring users to
338+
re-authenticate their sessions."_ In the reference PDS
339+
([`@atproto/oauth-provider`](https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-provider))
340+
this is the `rotateToken` path re-expanding `parameters.scope` via
341+
`buildTokenScope`. Propagation is bounded by the Auth Server's resolved-set
342+
cache (spec-recommended stale lifetime and firm upper bound: **24 h**) plus the
343+
access-token lifetime (~15–30 min); bumping the client-metadata
344+
`software_version` is the spec's cache-purge lever if a faster rollout is
345+
needed. This holds only because every collection we add stays under the set's
346+
**own namespace authority** (the [authority rule](#namespace-authority) both
347+
permits it and is why no cross-namespace addition can ever go into one of these
348+
sets — that still needs a separate `include:` and an explicit scope upgrade).
349+
350+
- **CGS API keys are a frozen snapshot** (see [Consumption by CGS](#consumption-by-cgs)):
351+
expansion happens once at key-creation time, so a re-published set does **not**
352+
retroactively widen already-issued keys. Growing access there means re-issuing
353+
the key — which is the intended workflow, since an API key's scope should be
354+
auditable and stable for its lifetime.
355+
356+
A new NSID (`*.authWrite2` / `.v2`) is therefore **not** needed to _add_
357+
collections. It would only be warranted to _remove or attenuate_ existing
358+
permissions, which the spec advises doing "very sparingly" precisely because it
359+
silently narrows live sessions.
360+
361+
> Caveat: the above is the behaviour of the reference PDS and any
362+
> spec-conformant Authorization Server. A non-reference or forked
363+
> implementation should be checked against this before relying on the dynamic
364+
> re-expansion.
365+
325366
## References
326367

327368
- AT Protocol permission spec — permission sets:

lexicons/app/certified/authWrite.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"defs": {
55
"main": {
66
"type": "permission-set",
7-
"description": "Permission set granting create, update, and delete on every Certified (app.certified) record collection.",
87
"title": "Manage your Certified data",
98
"detail": "Create, edit, and delete your Certified records (profile, badges, follows, wallet links, and related data).",
109
"permissions": [

lexicons/org/hyperboards/authWrite.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"defs": {
55
"main": {
66
"type": "permission-set",
7-
"description": "Permission set granting create, update, and delete on every Hyperboards (org.hyperboards) record collection.",
87
"title": "Manage your Hyperboards data",
98
"detail": "Create, edit, and delete your Hyperboards records (board configurations and display profiles).",
109
"permissions": [

lexicons/org/hypercerts/authWrite.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"defs": {
55
"main": {
66
"type": "permission-set",
7-
"description": "Permission set granting create, update, and delete on every Hypercerts (org.hypercerts) record collection.",
87
"title": "Manage your Hypercerts data",
98
"detail": "Create, edit, and delete your Hypercerts records (impact claims, evaluations, funding, and related data).",
109
"permissions": [

0 commit comments

Comments
 (0)