Summary
PR #566 promotes keys[] to the canonical profile signing-key field and removes signing_keys[] entirely, with no migration window specified. On current main grep -rn signing_keys docs/ source/ returns nothing. The change also removed the dual-publication contract that had preceded it, in which a profile published both signing_keys[] (canonical) and a keys[] mirror, with explicit rules that both arrays list the same set and that a key is not effectively revoked until it is absent from both. That transition mechanism is now gone rather than retained for a window.
Observed vs expected
Both request-signature and webhook verification resolve the signing key from the root profile (not a version-mapped URL). The verifier algorithm on main reads:
Locate the key list. The profile's top-level keys[]
(docs/specification/overview.md, verifier algorithm)
and the order webhook verification reads:
Locate key in keys with matching kid
(docs/specification/order.md, Webhook Signature Verification)
The released 2026-04-08 algorithm reads the same step from signing_keys on the root profile.
Because the field name changed and the old one was removed, mixed-version parties fail verification in both directions during any rollout window:
- A 2026-04-08 verifier fetches an upgraded business root profile, finds no
signing_keys[], and returns key-not-found.
- An upgraded verifier fetches a 2026-04-08 party profile, finds no
keys[], and fails the same way.
No acceptance window or fallback is specified.
Possible resolution
Either specify a bounded dual-publication window (businesses publish both arrays during migration; verifiers fall back to signing_keys[] when keys[] is absent), or route signing-key lookup through the version-mapped profile so each side reads the field that matches the negotiated version. A short migration note in the release would also help early adopters.
Possibly adjacent to #614 (versioning contract). The signature-key-lookup break itself does not appear to be tracked elsewhere. Happy to open a PR once the intended direction is clear.
Summary
PR #566 promotes
keys[]to the canonical profile signing-key field and removessigning_keys[]entirely, with no migration window specified. On current maingrep -rn signing_keys docs/ source/returns nothing. The change also removed the dual-publication contract that had preceded it, in which a profile published bothsigning_keys[](canonical) and akeys[]mirror, with explicit rules that both arrays list the same set and that a key is not effectively revoked until it is absent from both. That transition mechanism is now gone rather than retained for a window.Observed vs expected
Both request-signature and webhook verification resolve the signing key from the root profile (not a version-mapped URL). The verifier algorithm on main reads:
and the order webhook verification reads:
The released 2026-04-08 algorithm reads the same step from
signing_keyson the root profile.Because the field name changed and the old one was removed, mixed-version parties fail verification in both directions during any rollout window:
signing_keys[], and returns key-not-found.keys[], and fails the same way.No acceptance window or fallback is specified.
Possible resolution
Either specify a bounded dual-publication window (businesses publish both arrays during migration; verifiers fall back to
signing_keys[]whenkeys[]is absent), or route signing-key lookup through the version-mapped profile so each side reads the field that matches the negotiated version. A short migration note in the release would also help early adopters.Possibly adjacent to #614 (versioning contract). The signature-key-lookup break itself does not appear to be tracked elsewhere. Happy to open a PR once the intended direction is clear.