diff --git a/lib/federation-setup.js b/lib/federation-setup.js index faaaf51..7eb075e 100644 --- a/lib/federation-setup.js +++ b/lib/federation-setup.js @@ -171,7 +171,16 @@ export function setupFederation(options) { }; if (keyPairs.length > 0) { appOptions.publicKey = keyPairs[0].cryptographicKey; - appOptions.assertionMethods = keyPairs.map((k) => k.multikey); + // Only include Ed25519 keys in assertionMethod (Object Integrity Proofs). + // RSA keys belong only in publicKey (HTTP Signatures). Putting the RSA + // Multikey in assertionMethod with the same #main-key id as the + // CryptographicKey in publicKey causes id collisions — servers that + // traverse JSON-LD properties alphabetically (assertionMethod before + // publicKey) find the Multikey first, which has no publicKeyPem, + // and fail signature verification. + appOptions.assertionMethods = keyPairs + .filter((k) => k.privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") + .map((k) => k.multikey); } return new Application(appOptions); } @@ -809,7 +818,12 @@ export async function buildPersonActor( if (keyPairs.length > 0) { personOptions.publicKey = keyPairs[0].cryptographicKey; - personOptions.assertionMethods = keyPairs.map((k) => k.multikey); + // Only include Ed25519 keys in assertionMethod (Object Integrity Proofs). + // RSA keys belong only in publicKey (HTTP Signatures). See instance actor + // above for the full explanation of why this filter is necessary. + personOptions.assertionMethods = keyPairs + .filter((k) => k.privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") + .map((k) => k.multikey); } // Build profile field attachments (PropertyValue). diff --git a/package.json b/package.json index 4aa72a5..9603821 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rmdes/indiekit-endpoint-activitypub", - "version": "3.8.2", + "version": "3.8.3", "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.", "keywords": [ "indiekit",