[mirror] Normalize outgoing JSON-LD for Pixelfed interop#3
[mirror] Normalize outgoing JSON-LD for Pixelfed interop#3yashwant86 wants to merge 13 commits intomm-base-721from
Conversation
Move outgoing JSON-LD compatibility adjustments into a dedicated layer so send and proof creation use the same wire representation. Keep the existing public audience workaround and add attachment array preservation for Pixelfed compatibility, while skipping attachment rewrites that would change JSON-LD semantics. Document the distinction from activity transformers and cover the new normalization behavior in send and proof tests. pixelfed/pixelfed#6588 Assisted-by: Codex:gpt-5.5
Skip the JSON-LD canonicalization equivalence check when scalar attachment wrapping runs under an ActivityStreams-only context without nested context scopes. Also make the fallback log messages context neutral, since the helper can run from proof verification as well as send paths. References fedify-dev#721 (comment) References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Keep the fast path semantics-preserving by leaving JSON-LD list objects unwrapped, since array-wrapping list objects can change their meaning. Broaden the known-safe context check to allow additional preloaded contexts alongside ActivityStreams, and avoid allocating a replacement object until the attachment walker actually changes a subtree. References fedify-dev#721 (comment) References fedify-dev#721 (comment) References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Do not recurse into `@value` payloads while normalizing attachment properties. Those payloads can carry raw JSON data, such as `@json` values, where a sibling key named `attachment` is not an ActivityStreams term and must not be wrapped by the outgoing compatibility layer. References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Make the send documentation explicit that internal JSON-LD wire-format fixes are applied automatically after serialization, and that the `activityTransformers` option configures only activity transformers. References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Make the attachment normalization walker allocate replacement arrays only after a child changes, matching the existing lazy object cloning path. This avoids unnecessary allocations for unchanged arrays on the send, sign, and verification paths. References fedify-dev#721 (comment) References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Try the received JSON-LD form before computing Fedify's outgoing compatibility form during proof verification. This avoids traversing or canonicalizing the document on the common path where the on-wire bytes already verify. References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Skip outgoing JSON-LD normalization for activities that arrive at FederationImpl.sendActivity() with an existing proof, so the send path does not mutate the JSON-LD bytes after an external signing step. Keep normalization enabled for proofs Fedify created during its own fanout pre-signing path and cover the pre-signed attachment case. References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Skip attachment array normalization when a JSON-LD document exceeds the safe traversal depth, instead of falling through to URDNA2015 canonicalization. This keeps adversarial deep documents from forcing expensive canonicalization work in verification fallback paths. Document that custom or inline contexts may require canonicalization to prove that an outgoing wire-format fix preserves JSON-LD semantics. References fedify-dev#721 (comment) References fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Share the preloaded-only context loader between outgoing JSON-LD compatibility helpers so security-sensitive fallback behavior cannot drift. Keep the proof verification fallback on that restricted loader instead of reusing a caller-provided context loader for inbound JSON-LD. Also document the attachment normalization loader contract, add safe correlation metadata to the semantic-divergence warning, and tighten the pathological nesting regression assertion. fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Add a public sendActivity option for callers that pre-sign activities with Fedify and need the outgoing compact JSON-LD to match the normalized bytes covered by the proof. Preserve existing proofs by default, and document that trade-off in the send path, queue message type, and manual. fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Enforce the preloaded context invariant that keeps the attachment term compatible with ActivityStreams before using the known-safe fast path. Also keep JSON-LD value payloads out of the nested-context detector, fix the newly added option's release annotation, and cover queued fanout for pre-signed activities that opt into existing-proof normalization. Addresses review comments: fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
Build the known-safe preloaded context set by filtering contexts that keep ActivityStreams attachment semantics intact instead of failing at module load. The check now descends into scoped context definitions so future preloaded contexts cannot silently bypass canonicalization when they redefine attachment locally. Pass the restricted preloaded-only loader explicitly in proof verification fallbacks so inbound JSON-LD normalization cannot start depending on a network-capable default after future refactors. Addresses review comments: fedify-dev#721 (comment) fedify-dev#721 (comment) fedify-dev#721 (comment) Assisted-by: Codex:gpt-5
⚡ Risk Assessment —
|
| Files | Summary |
|---|---|
Outgoing JSON-LD Normalization Corepackages/fedify/src/compat/outgoing-jsonld.ts, outgoing-jsonld.test.ts, preloaded-context-loader.ts |
Adds attachment array normalization and public audience fixes for outgoing activities. Wraps scalar attachments in arrays when semantically safe, with depth-bounded traversal and JSON-LD canonicalization validation. Preloaded-only context loader prevents network fetches on adversarial JSON-LD. |
Public Audience Normalization Refactorpackages/fedify/src/compat/public-audience.ts |
Extracts preloaded-only document loader to shared module for reuse in proof verification and attachment normalization. |
Proof Creation & Verificationpackages/fedify/src/sig/proof.ts, proof.test.ts |
Updates createProof() to normalize outgoing JSON-LD before signing. Refactors verifyProofInternal() to use preloaded-only loader for fallback normalization, preventing attacker-controlled context URLs from triggering network fetches. Adds test coverage for attachment normalization in signed objects. |
Activity Sending & Fanoutpackages/fedify/src/federation/middleware.ts, context.ts, queue.ts |
Adds normalizeExistingProofs option to sendActivity() and fanout queue. Conditionally applies outgoing JSON-LD normalization based on proof creation state: normalizes unsigned activities and Fedify-created proofs, preserves existing proofs unless explicitly opted in. Propagates flag through fanout pipeline. |
Documentation & Configurationdocs/manual/send.mdCHANGES.md |
Documents JSON-LD normalization configuration and wire-format interoperability fixes. |
Sequence Diagram
sequenceDiagram
participant Caller
participant sendActivity
participant createProof
participant normalizeOutgoing
participant verifyProof
Caller->>sendActivity: activity, keys, options
alt has existing proof
sendActivity->>sendActivity: check normalizeExistingProofs flag
alt flag true or proof created by Fedify
sendActivity->>normalizeOutgoing: normalize JSON-LD
else flag false
sendActivity->>sendActivity: skip normalization
end
else no proof
sendActivity->>createProof: sign activity
createProof->>normalizeOutgoing: normalize before signing
normalizeOutgoing-->>createProof: normalized bytes
createProof->>createProof: sign normalized form
end
sendActivity->>sendActivity: serialize to compact JSON-LD
sendActivity-->>Caller: send to inbox
Caller->>verifyProof: received JSON-LD, proof
verifyProof->>verifyProof: try verify on-wire form
alt verification fails
verifyProof->>normalizeOutgoing: normalize with preloaded-only loader
verifyProof->>verifyProof: try verify normalized form
end
verifyProof-->>Caller: verification result
Dig Deeper With Commands
/review <file-path> <function-optional>/chat <file-path> "<question>"/roast <file-path>
Runs only when explicitly triggered.
Mirror of upstream fedify-dev#721 for benchmark. Do not merge.
Summary by MergeMonkey