Skip to content

Commit 618fd4e

Browse files
authored
Merge pull request #1041 from dahlia/fep-938-map-local-vector
Support map-local compound proofs
2 parents c5c9d61 + 23f1d76 commit 618fd4e

17 files changed

Lines changed: 4040 additions & 78 deletions

‎CHANGES.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,22 @@ To be released.
127127
`esnext.temporal` lib reference.
128128
[[#823], [#925]]
129129

130+
- Security: Inbox processing now independently verifies each portable actor,
131+
activity, and object in a compound JSON document against its own map-local
132+
Object Integrity Proof before dispatch. A valid outer proof no longer
133+
authenticates an unsigned or invalid nested portable object.
134+
Portable documents with proof sets or which exceed the inbox compound
135+
traversal limits are rejected as unsupported.
136+
[[#288], [#938], [#1041]]
137+
130138
[key–value store guide]: https://fedify.dev/manual/kv
131139
[FEP-ef61]: https://w3id.org/fep/ef61
132140
[FEP-8b32]: https://w3id.org/fep/8b32
133141
[FEP-fe34]: https://w3id.org/fep/fe34
134142
[ActivityPub Media Upload extension]: https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload
135143
[Standard Schema]: https://standardschema.dev/
136144
[#206]: https://github.com/fedify-dev/fedify/issues/206
145+
[#288]: https://github.com/fedify-dev/fedify/issues/288
137146
[#754]: https://github.com/fedify-dev/fedify/issues/754
138147
[#797]: https://github.com/fedify-dev/fedify/issues/797
139148
[#798]: https://github.com/fedify-dev/fedify/issues/798
@@ -152,9 +161,11 @@ To be released.
152161
[#927]: https://github.com/fedify-dev/fedify/pull/927
153162
[#930]: https://github.com/fedify-dev/fedify/issues/930
154163
[#934]: https://github.com/fedify-dev/fedify/pull/934
164+
[#938]: https://github.com/fedify-dev/fedify/issues/938
155165
[#968]: https://github.com/fedify-dev/fedify/pull/968
156166
[#1017]: https://github.com/fedify-dev/fedify/issues/1017
157167
[#1027]: https://github.com/fedify-dev/fedify/pull/1027
168+
[#1041]: https://github.com/fedify-dev/fedify/pull/1041
158169

159170
### @fedify/adonisjs
160171

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
links:
3+
'#1041': https://github.com/fedify-dev/fedify/pull/1041
4+
'#288': https://github.com/fedify-dev/fedify/issues/288
5+
'#938': https://github.com/fedify-dev/fedify/issues/938
6+
---
7+
- Security: Inbox processing now independently verifies each portable actor,
8+
activity, and object in a compound JSON document against its own map-local
9+
Object Integrity Proof before dispatch. A valid outer proof no longer
10+
authenticates an unsigned or invalid nested portable object.
11+
Portable documents with proof sets or which exceed the inbox compound
12+
traversal limits are rejected as unsupported.
13+
[[#288], [#938], [#1041]]

‎docs/manual/inbox.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ why some activities are rejected, you can turn on [logging](./log.md) for
3737
[Linked Data Signatures]: https://web.archive.org/web/20170923124140/https://w3c-dvcg.github.io/ld-signatures/
3838
[FEP-8b32]: https://w3id.org/fep/8b32
3939

40+
### Compound portable objects
41+
42+
The inbox independently verifies every JSON map with an [FEP-ef61] portable
43+
`id` or `@id`, including embedded collections, with the
44+
[map-local compound-proof profile](./send.md#compound-portable-objects). A
45+
valid proof on the outer activity does not authenticate an unsigned or invalid
46+
portable object embedded within it. The gateway trust allowance for an
47+
unsigned top-level portable collection does not apply inside a compound
48+
document; an embedded portable collection needs its own proof and `@context`.
49+
50+
This check uses the original received JSON after the normal outer
51+
authentication and actor ownership checks. Fedify consumes a deferred
52+
signature nonce only after the entire compound document passes verification.
53+
It also verifies the complete result before dispatching the activity through a
54+
queue, route, or listener. Unsupported proof shapes and documents that exceed
55+
the inspection or verification limits receive `401 Unauthorized`. Fedify does
56+
not dispatch any part of those documents to application code.
57+
58+
[FEP-ef61]: https://w3id.org/fep/ef61
59+
4060
### `Accept-Signature` challenges
4161

4262
*This API is available since Fedify 2.1.0.*

‎docs/manual/send.md‎

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,51 @@ caller can apply the separate gateway trust policy allowed by [FEP-ef61].
11391139
embedded portable object needs its own verification; success for an outer
11401140
activity does not authenticate portable objects nested inside it.
11411141

1142+
[FEP-8b32]: https://w3id.org/fep/8b32
1143+
[FEP-ef61]: https://w3id.org/fep/ef61
1144+
[FEP-fe34]: https://w3id.org/fep/fe34
1145+
1146+
### Compound portable objects
1147+
1148+
For compound documents containing [FEP-ef61] portable objects, Fedify inboxes
1149+
use a bounded, map-local interoperability profile. Neither [FEP-8b32] nor
1150+
Verifiable Credential Data Integrity currently specifies this compound-document
1151+
algorithm.
1152+
1153+
The profile treats each JSON map with a direct literal `proof` property as a
1154+
separate secured document. Verification removes only that map's `proof` and
1155+
leaves proofs on descendant maps in place. Replacing a valid child proof
1156+
therefore invalidates an outer proof that covered the original secured child.
1157+
Fedify requires a direct proof. It does not treat proof aliases, sets, chains,
1158+
or remote references as alternatives.
1159+
1160+
Every embedded portable map needs one direct inline proof and its own explicit
1161+
`@context`. Fedify verifies each map against an immutable copy of the received
1162+
JSON and applies the FEP-ef61 portable-ID and controlling-DID policy to that
1163+
map. It does not copy a parent's context into a child, try several
1164+
proof-removal rules, or fetch an unpinned context from the live network.
1165+
Inputs that exceed the traversal limits are rejected. Fedify does not return
1166+
authentication results for only part of a compound document.
1167+
1168+
This profile authenticates JSON snapshots. A child proof may be valid when
1169+
verified in isolation even if the parent's active context causes the embedded
1170+
JSON-LD to expand differently. Proof success does not establish that the
1171+
isolated and embedded expansions are equivalent.
1172+
1173+
> [!WARNING]
1174+
> Typed vocabulary serialization can change the secured representation of a
1175+
> signed embedded object. Signing a typed child, assigning it to a typed
1176+
> parent, and serializing the parent can remove the child's document and proof
1177+
> contexts while retaining its `proofValue`. Do not serialize a signed typed
1178+
> child through a typed parent when producing a map-local compound document.
1179+
> The profile also accepts exactly one direct proof per map, while Fedify's
1180+
> ordinary activity signer creates one proof for each Ed25519 key. A sender
1181+
> producing a portable compound document must arrange for exactly one direct
1182+
> proof on each map.
1183+
> When forwarding an already signed payload, use
1184+
> [`forwardActivity()`](./outbox.md#federating-posted-activities) to avoid a
1185+
> vocabulary-object round trip.
1186+
11421187
> [!TIP]
11431188
> HTTPS Signatures, Linked Data Signatures, and Object Integrity Proofs can
11441189
> coexist in an application and be used together for maximum compatibility.
@@ -1154,10 +1199,6 @@ activity does not authenticate portable objects nested inside it.
11541199
> Proofs simultaneously, you need to generate both RSA-PKCS#1-v1.5 and Ed25519
11551200
> key pairs for each actor, and store them in the database.
11561201
1157-
[FEP-8b32]: https://w3id.org/fep/8b32
1158-
[FEP-ef61]: https://w3id.org/fep/ef61
1159-
[FEP-fe34]: https://w3id.org/fep/fe34
1160-
11611202

11621203
Activity transformers
11631204
---------------------

‎packages/fedify/deno.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"src/testing/",
4747
"tsdown.config.ts",
4848
"scripts/",
49+
"test-vectors/",
4950
"wrangler.toml"
5051
]
5152
},

0 commit comments

Comments
 (0)