Skip to main content
Normative reference for the Managed Rule envelope — the signed wire format the AEGIS promoter writes to Workers KV and R2 and the gateway reads at request time. This is the wire surface the gateway consumes during failover; it is not a customer-side verification surface (see §4 below). The canonical implementation is in mnemom-api/src/composition/envelope-signer.ts (signer) and mnemom-platform/gateway/src/aegis-recipes.ts (verifier). Both envelopes — the KV variant and the R2 variant — share the same shape; only the signing key (key_id) differs.

1. Top-level structure

Canonical-hash message

The signature is computed over the UTF-8 bytes of the dotted message:
where canonical_json recursively sorts object keys and emits compact JSON (no whitespace, no insignificant separators). The resulting digest is the SHA-256 hash in lowercase hex. The signature wraps key_id and signed_at in the message, so an attacker that obtained the per-row recipe payload but did not produce the signature cannot replay the envelope under a different signed_at.

2. The two envelope variants

The promoter writes two parallel envelopes in the same canonical recipe set. They differ only in the key they use: The two signing chains are independent. KV poisoning degrades gracefully to R2; the gateway’s tiered read pipeline (see Managed Rules) verifies each tier with its own JWKS binding and fails over on signature failure.

3. Per-recipe row shape

Each entry in recipes carries the wire-readable subset of the recipe row. Customer-readable fields are limited to:

Terminology note: severity_p vs “tier”

Concept-level docs (for example Managed Rules and AEGIS) use the words tier 1, tier 2, tier 3. The database canonical is the column severity_p with values p0 / p1 / p2. The two vocabularies refer to the same dimension; spec pages use the database canonical so wire-format consumers can map directly. The bridge is fixed:

Per-row promotion signature

Each recipe row also carries a per-row Ed25519 signature, written into the internal detection_recipes.promotion_signature column. The signature is computed over the canonical-hash inputs recipe_id, version, composition_scope, surface, severity_p, scope, created_by, created_at. The per-row signature is not carried inline in the envelope; the envelope signature wraps the recipe set, and the gateway re-checks the per-row signature against the canonical inputs after envelope verification succeeds. Internal detection-routing fields are out of scope for this spec. The detection-engine internal vocabulary (the per-checkpoint detection routing fields) persists on the internal detection_recipes table but is not part of the wire-format envelope; the spec documents what the gateway reads from the envelope, not what the platform writes into the internal table.

4. Signature verification — internal-resilience, not customer-side

At GA, the envelope signature exists for gateway-internal verification only. There is no public JWKS endpoint at which customers can independently verify a Managed Rule envelope signature.
The verification model and what it does and does not provide:
  • What the envelope signature provides. Defense in depth between the KV and R2 read tiers. The gateway verifies on every read; a poisoned KV envelope (whose signature does not verify against kvVerifyJwks) falls through to R2 (a different signing chain). A poisoned R2 envelope falls through to the last-known-good in-isolate cache.
  • What it does not provide. Customer-side cryptographic attestation. The verify halves — kvVerifyJwks and r2VerifyJwks — are passed in as worker bindings; they are secrets in the gateway’s worker environment, not customer-reachable URLs.
  • The customer-facing transparency surface. The append-only audit chain on recipe_review_actions is the recipe-level provenance trail, verifiable via the admin API surface. The published /trust/slos describe propagation, freshness, and failover commitments. The advisory and IoC surfaces describe the network-level signal output.
  • /v1/.well-known/jwks.json publishes a different set of keys. That endpoint publishes AAP attestation keys (the aap_signing_keys table). Recipe-set signing keys are escrowed in 1Password under the operator’s rotation policy and are not part of the public JWKS.
A future public JWKS surface for recipe-set verification keys is not currently on the roadmap; if and when one ships, this section is updated and a customer-side verification guide lands.

5. Three independent signing chains

The full rule plane uses three Ed25519 keys, each rotated under Class A annual rotation (90-day JWKS overlap): Three independent compromise paths required to fully poison the pipeline. KV poisoning degrades gracefully to R2 (different signing chain). KV + R2 compromise is still defeated by the per-row promotion signature: the gateway re-checks each row against the promotion signature after envelope verification, and a forged row will not match.

6. Failover behavior

The gateway’s tiered read pipeline at request time:
  1. In-isolate memory cache — fresh entries (< 60 s) served from in-isolate state.
  2. Workers KV primary — 300 s TTL; signed with RECIPE_KV_SIGNING_KEY.
  3. R2 secondary — per-promotion refresh; signed with RECIPE_R2_SIGNING_KEY (independent chain).
  4. Last-known-good in-isolate — staleness up to 24 hours; fail-closed on safety-critical checkpoints at 24 h.
  5. Fail-closed 503 with X-Mnemom-Reason: aegis-data-plane-unavailable.
Customers MUST NOT depend on the failover path; the SLO is rule-set freshness P99 ≤ 5 min under normal operation. See /trust/slos for the published commitments.
Honest GA disclosure. The production R2 binding deploys at the Phase 4 production cutover (2026-05-29). Until then the R2 tier is staging-bound; the KV tier is the primary production path. The published SLOs apply once the R2 binding is live.

7. Failover alert tags

The gateway emits stable alert tags on the failover path. These are operator-facing diagnostic tags drawn from the cell-matrix vocabulary; customers may see the corresponding SLO impact on /trust/slos but do not consume these tag values directly.

8. Example — a signed envelope at GA

The Day-1 envelope carries the five GA-seeded synthetic Managed Rules. Signatures, identifiers, and signed-at are placeholder-shaped here; production envelopes carry the real cryptographic values.

9. Validation notes

  • Versioning. key_id includes the rotation cohort. The gateway verifies against the JWKS bound in its worker env, never a hardcoded key.
  • Signature failure is loud. The gateway emits P0_kv_sig_fail or P0_r2_sig_fail on signature failure and falls through to the next tier. It does not silently accept an envelope whose signature did not verify.
  • Replay defense. The signed message includes key_id and signed_at — an envelope captured at time T cannot be replayed under a different signed_at because the signature would not verify.

See also