You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(permissions): implement org.hypercerts and app.certified write permission sets
Add the two permission-set lexicons designed in docs/design/permission-sets.md:
- org.hypercerts.permissions.crud — write (create/update/delete) over all
org.hypercerts.* record collections
- app.certified.permissions.crud — write (create/update/delete) over all
app.certified.* record collections
TWO sets, not one combined set, because the spec mandates it: a permission set
"is limited to expressing permissions that reference resources under the same
NSID namespace as the set itself" and "can not address 'sibling groups' or
'parents'" (https://atproto.com/specs/permission#permission-sets).
org.hypercerts and app.certified are different namespace authorities, so they
cannot legally be combined in one set. An app needing both requests both
include: scopes. Each set also enumerates its collections explicitly (the spec
forbids wildcards inside a permission set).
permission-set is a lexicon primitive that lex gen-api cannot codegen (it has
no TypeScript shape), so these files are published as-is but excluded from the
codegen globs (gen-api/gen-md/gen-ts) and from generated/exports.ts (filtered
by main def type, parsing each lexicon once). They still appear in SCHEMAS.md
and are JSON-parsed by the schema/test pipeline. The full `npm run check`
(gen-api, lint, typecheck, build, test, style) passes.
The human-readable title/detail are written as authorization-dialog consent
copy: plain-language, concise, naming recognizable record categories.
Also documents the permission sets in the building-with-hypercerts-lexicons
skill (how to request them as OAuth scopes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|`org.hypercerts.permissions.crud`| all `org.hypercerts.*` record collections |
204
+
|`app.certified.permissions.crud`| all `app.certified.*` record collections |
205
+
206
+
In your OAuth client's authorization request, ask for the set(s) you need:
207
+
208
+
```text
209
+
scope: include:org.hypercerts.permissions.crud
210
+
```
211
+
212
+
The user's PDS resolves the published set and expands it into the underlying
213
+
`repo:` scopes on the consent screen, where the user sees the set's plain-language
214
+
description (e.g. "Manage your Hypercerts data"). Notes:
215
+
216
+
-**Two sets, never one.** A permission set may only reference its own namespace
217
+
authority (atproto permission spec), so `org.hypercerts.*` and
218
+
`app.certified.*` cannot share a set. An app needing both requests **both**
219
+
`include:` scopes.
220
+
-**Writes only.** These cover create/update/delete. **Reading** records needs no
221
+
scope at all — atproto repo records are public.
222
+
-**`repo:` scopes carry no `aud`** — request the `include:` without an `?aud=`.
223
+
- These same published sets are also consumed by the Certified group service
224
+
(CGS) when it expands an API key's `include:` scope — see the CGS integration
225
+
guide.
226
+
193
227
## Lexicon Overview
194
228
195
229
### Claims — the core impact record
@@ -673,6 +707,8 @@ avoid typos.
673
707
## Further Reading
674
708
675
709
-[SCHEMAS.md](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/SCHEMAS.md) — full property-level documentation for every lexicon
710
+
-[docs/design/permission-sets.md](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/docs/design/permission-sets.md) — the permission sets and how they are consumed (OAuth + CGS API keys)
711
+
-[ATProto permission spec](https://atproto.com/specs/permission#permission-sets) — OAuth scopes and permission sets
676
712
-[CHANGELOG.md](https://github.com/hypercerts-org/hypercerts-lexicon/blob/main/CHANGELOG.md) — version history and migration guides
677
713
-[ATProto Lexicon Guide](https://atproto.com/guides/lexicon) — AT Protocol lexicon fundamentals
Add two permission-set lexicons — `org.hypercerts.permissions.crud` and `app.certified.permissions.crud` — each granting create/update/delete over every record collection in its namespace.
6
+
7
+
A [permission set](https://atproto.com/specs/permission#permission-sets) lets any AT Protocol app request a whole bundle of `repo:` scopes with a single `include:<nsid>` OAuth scope, instead of enumerating each collection by hand. The user's PDS resolves and expands the set during the OAuth grant; the same published set can also be consumed by services (e.g. the Certified group service) when expanding API-key scopes.
8
+
9
+
There are **two** sets rather than one because the spec requires it: a permission set "is limited to expressing permissions that reference resources under the same NSID namespace as the set itself" and "can not address 'sibling groups' or 'parents'". `org.hypercerts` and `app.certified` are separate namespace authorities, so they cannot be combined in a single set — an app needing both requests both `include:` scopes.
10
+
11
+
Permission sets are published as-is (they are the source of truth for what gets published to AT Protocol) but have no TypeScript shape — `lex gen-api` cannot generate code for `permission-set` defs. They are therefore excluded from the codegen globs (`gen-api`/`gen-md`/`gen-ts`) and from `generated/exports.ts`, while still shipping as raw lexicon JSON.
12
+
13
+
Collection lists are enumerated explicitly because the spec forbids wildcards inside a permission set; they must be kept in sync as record types are added. See `docs/design/permission-sets.md`.
"//permissions": "permission-set lexicons (lexicons/**/permissions/*.json) are published as-is but have no TS shape; lex gen-* cannot codegen them, so they are excluded from the codegen globs below.",
0 commit comments