Skip to content

Commit cb7411e

Browse files
feat: add cryptographic signature support to all lexicons
Add optional cryptographic signature support to all record lexicons, enabling platform attestation and verification that records were created through trusted services. Inspired by: - ATProtocol Attestation Specification by Nick Gerakines - The platformAttestation pattern from app.bumicerts.link.evm New lexicons: - app.certified.signature.inline: Inline signature with JOSE algorithm IDs - app.certified.signature.list: Container with signatures array (open union) - app.certified.signature.proof: Remote attestation proof record All 20 record lexicons now include an optional signatureData property: - org.hypercerts.claim.* (activity, contribution, contributorInformation, rights) - org.hypercerts.collection - org.hypercerts.context.* (acknowledgement, attachment, evaluation, measurement) - org.hypercerts.funding.receipt - org.hypercerts.workscope.tag - org.hyperboards.* (board, displayProfile) - app.certified.badge.* (award, definition, response) - app.certified.actor.* (profile, organization) - app.certified.location - app.certified.link.evm Design decisions: - Uses ref to app.certified.signature.list for DRY structure - JOSE algorithm identifiers (ES256K, ES256, Ed25519) per ATProto convention - Supports both inline signatures and remote attestations via strongRef
1 parent 81b1213 commit cb7411e

28 files changed

Lines changed: 447 additions & 68 deletions

.changeset/fuzzy-pandas-smile.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
"@hypercerts-org/lexicon": minor
3+
---
4+
5+
Add cryptographic signature support to all lexicons
6+
7+
Adds optional cryptographic signature support to all record lexicons, enabling platform attestation and verification that records were created through trusted services. This is inspired by the [ATProtocol Attestation Specification](https://ngerakines.leaflet.pub/3m3idxul5hc2r) by Nick Gerakines.
8+
9+
**New lexicons:**
10+
11+
- `app.certified.signature.inline` - Inline cryptographic signature object with JOSE algorithm identifiers (ES256, ES256K, Ed25519)
12+
- `app.certified.signature.list` - Container object with `signatures` array supporting both inline signatures and remote attestation references
13+
- `app.certified.signature.proof` - Remote attestation proof record containing the CID of attested content
14+
15+
**Changes to existing lexicons:**
16+
17+
All 19 record lexicons now include an optional `signatureData` property that references `app.certified.signature.list`:
18+
19+
- `org.hypercerts.claim.activity`
20+
- `org.hypercerts.claim.contribution`
21+
- `org.hypercerts.claim.contributorInformation`
22+
- `org.hypercerts.claim.rights`
23+
- `org.hypercerts.collection`
24+
- `org.hypercerts.context.acknowledgement`
25+
- `org.hypercerts.context.attachment`
26+
- `org.hypercerts.context.evaluation`
27+
- `org.hypercerts.context.measurement`
28+
- `org.hypercerts.funding.receipt`
29+
- `org.hypercerts.workscope.tag`
30+
- `org.hyperboards.board`
31+
- `org.hyperboards.displayProfile`
32+
- `app.certified.badge.award`
33+
- `app.certified.badge.definition`
34+
- `app.certified.badge.response`
35+
- `app.certified.actor.profile`
36+
- `app.certified.actor.organization`
37+
- `app.certified.location`
38+
39+
**Design notes:**
40+
41+
This is a non-breaking extension - signatures are optional on all records. Two signature patterns are supported:
42+
43+
1. **Inline signatures** - Embedded directly in the record via `app.certified.signature.inline`
44+
2. **Remote attestations** - References to proof records in other repositories via `com.atproto.repo.strongRef`
45+
46+
Signature algorithm identifiers use [JOSE format](https://www.iana.org/assignments/jose/jose.xhtml) per ATProto convention:
47+
48+
- `ES256K` - secp256k1 (Ethereum/Bitcoin curve, ATProto default)
49+
- `ES256` - P-256 (NIST curve, WebCrypto compatible)
50+
- `Ed25519` - EdDSA

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ CERTIFIED ─ shared lexicons (certified.app)
4444
actor/profile (user profile)
4545
actor/organization (org metadata)
4646
badge/definition ──► badge/award ──► badge/response
47+
signature/inline (embedded cryptographic signature)
48+
signature/list (container for signatures array)
49+
signature/proof (remote attestation proof record)
4750
```
4851

4952
Every arrow (``) is a `strongRef` or union reference stored on the
@@ -149,6 +152,16 @@ await agent.api.com.atproto.repo.createRecord({
149152
| **Badge Response** | `app.certified.badge.response` | Recipient accepts or rejects a badge award. |
150153
| **EVM Link** | `app.certified.link.evm` | Verifiable ATProto DID ↔ EVM wallet link via EIP-712 signature. Extensible for future proof methods (e.g. ERC-1271, ERC-6492). |
151154

155+
### Signatures (`app.certified.signature.*`)
156+
157+
| Lexicon | NSID | Description |
158+
| -------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
159+
| **Inline Signature** | `app.certified.signature.inline` | An inline cryptographic signature for attesting to record content. Uses JOSE algorithm identifiers (ES256, ES256K, Ed25519). |
160+
| **Signature List** | `app.certified.signature.list` | Container object with a `signatures` array. Referenced by all record lexicons via `signatureData` property. |
161+
| **Proof** | `app.certified.signature.proof` | Remote attestation proof record containing the CID of attested content. Lives in the attestor's repository and can be referenced via strongRef. |
162+
163+
All record lexicons include an optional `signatureData` property that references `app.certified.signature.list`, enabling cryptographic attestations. See [Cryptographic Signatures](#cryptographic-signatures) for usage details.
164+
152165
> **Full property tables**[SCHEMAS.md](SCHEMAS.md)
153166
154167
## Entity Relationship Diagram
@@ -368,6 +381,73 @@ const attachment = {
368381
};
369382
```
370383

384+
### Cryptographic Signatures
385+
386+
All record lexicons support optional cryptographic signatures via the `signatureData` property. This enables platform attestation and verification that records were created through trusted services.
387+
388+
Signatures support two patterns:
389+
390+
1. **Inline signatures**: Embedded directly in the record
391+
2. **Remote attestations**: References to proof records in other repositories (via `strongRef`)
392+
393+
```typescript
394+
import { ACTIVITY_NSID } from "@hypercerts-org/lexicon";
395+
396+
// Activity with inline signature
397+
const signedActivity = {
398+
$type: ACTIVITY_NSID,
399+
title: "Verified Reforestation Project",
400+
shortDescription: "Planted 1,000 trees in partnership with local community",
401+
createdAt: new Date().toISOString(),
402+
signatureData: {
403+
signatures: [
404+
// Inline signature (embedded)
405+
{
406+
$type: "app.certified.signature.inline",
407+
signatureType: "ES256K", // JOSE algorithm: secp256k1
408+
signature: new Uint8Array([
409+
/* signature bytes */
410+
]),
411+
key: "did:plc:platform123#signing", // DID verification method
412+
},
413+
// Remote attestation (reference to proof in another repo)
414+
{
415+
$type: "com.atproto.repo.strongRef",
416+
uri: "at://did:plc:verifier/app.certified.signature.proof/abc123",
417+
cid: "bafy...",
418+
},
419+
],
420+
},
421+
};
422+
```
423+
424+
#### Signature Algorithm Identifiers
425+
426+
The `signatureType` property uses [JOSE algorithm identifiers](https://www.iana.org/assignments/jose/jose.xhtml):
427+
428+
| Value | Curve | Description |
429+
| --------- | --------- | --------------------------------------- |
430+
| `ES256` | P-256 | NIST curve, WebCrypto compatible |
431+
| `ES256K` | secp256k1 | Ethereum/Bitcoin curve, ATProto default |
432+
| `Ed25519` | Ed25519 | EdDSA, increasingly popular |
433+
434+
#### Remote Attestation Proofs
435+
436+
For remote attestations, create a proof record in the attestor's repository:
437+
438+
```typescript
439+
import { SIGNATURE_PROOF_NSID } from "@hypercerts-org/lexicon";
440+
441+
const proof = {
442+
$type: SIGNATURE_PROOF_NSID,
443+
cid: "bafy...", // CID of the attested content
444+
note: "Verified by platform quality assurance process",
445+
createdAt: new Date().toISOString(),
446+
};
447+
```
448+
449+
For the full specification, see Nick Gerakines' [ATProtocol Attestation Specification](https://ngerakines.leaflet.pub/3m3idxul5hc2r).
450+
371451
## Development
372452

373453
### Commands

0 commit comments

Comments
 (0)