town.agent.fetchreceipt
Schema Diff
+6 -1
Compatibility Analysis
Backward Compatible
Backward compatible. 2 non-breaking changes.
Non-Breaking Changes (2)
- AddedVertex AddedVertex { vertex_id: "town.agent.fetchreceipt:body.signerKey" }
- AddedEdge AddedEdge { src: "town.agent.fetchreceipt:body", tgt: "town.agent.fetchreceipt:body.signerKey", kind: "prop", name: Some("signerKey") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "town.agent.fetchreceipt:body.signerKey" }
Additional Notes
- Non-breaking: AddedEdge { src: "town.agent.fetchreceipt:body", tgt: "town.agent.fetchreceipt:body.signerKey", kind: "prop", name: Some("signerKey") }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"main": {
5
5
"description": "After-the-fact receipt for an outbound HTTP fetch made by an agent. Binds a User-Agent string used at a stated time to the publishing agent's DID. Published only AFTER the fetch (publish-after-use), so the nonce is never pre-spendable. Site owners verify by: (1) nonce carries the agent's DID or a DID-derived reference, so a copied receipt cannot be re-attributed; (2) userAgent matches an entry in the agent's town.agent.profile self record. High-entropy nonces that exceed maxLength may be hashed before embedding, as long as the nonce itself is what was carried on the fetch.",
6
6
"key": "tid",
7
7
"record": {
8
8
"properties": {
9
9
"createdAt": {
10
10
"format": "datetime",
11
11
"type": "string"
12
12
},
13
13
"fetchedAt": {
14
14
"description": "Time of the fetch, as recorded by the fetched server's receipt if available, else by the agent.",
15
15
"format": "datetime",
16
16
"type": "string"
17
17
},
18
18
"nonce": {
19
19
"description": "Unique query-string nonce carried on the fetch; SHOULD embed or reference the fetching agent's DID so a copied receipt cannot be attributed to another agent. Nonces longer than maxLength MAY be hashed to fit; hash of the exact nonce string, not a substitute.",
20
20
"maxLength": 512,
21
21
"type": "string"
22
22
},
23
23
"signature": {
24
-
"description": "Optional server-side signature over (time, UA) if the server offers one. Its absence MUST NOT be treated as proof the fetch didn't happen.",
24
+
"description": "Optional server-side signature over (nonce, urlHost, fetchedAt, userAgent) if the server offers one. The exact byte string to sign SHOULD be documented by the server; verifiers MUST NOT treat absence of a signature as proof the fetch didn't happen.",
25
+
"maxLength": 512,
26
+
"type": "string"
27
+
},
28
+
"signerKey": {
29
+
"description": "Public key (did:key: or JWK) or key identifier the fetched server used to produce 'signature', if it offers one. Enables third-party verification of the signature.",
25
30
"maxLength": 512,
26
31
"type": "string"
27
32
},
28
33
"urlHost": {
29
34
"description": "Host that was fetched (not full URL — receipts shouldn't leak private paths).",
30
35
"maxLength": 256,
31
36
"type": "string"
32
37
},
33
38
"userAgent": {
34
39
"description": "Exact User-Agent header sent on the fetch. SHOULD match an entry in the agent's town.agent.profile userAgents.",
35
40
"maxLength": 512,
36
41
"type": "string"
37
42
}
38
43
},
39
44
"required": [
40
45
"nonce",
41
46
"userAgent",
42
47
"urlHost",
43
48
"fetchedAt",
44
49
"createdAt"
45
50
],
46
51
"type": "object"
47
52
},
48
53
"type": "record"
49
54
}
50
55
},
51
56
"id": "town.agent.fetchreceipt",
52
57
"lexicon": 1
53
58
}