| AUTH-2FA-01 | Local login returns TWO_FACTOR_REQUIRED when 2FA enabled | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ❌ No | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Implement 2FA enrollment path; prove TWO_FACOR_REQUIRED 403 |
| AUTH-2FA-02 | TOTP enrollment or sandbox-safe seed available | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ❌ No | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Implement TOTP enrollment; seed must be sandbox-safe for testing |
| AUTH-2FA-03 | Invalid OTP rejected | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ✅ Yes | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Implement OTP verification with rejection of invalid codes |
| AUTH-2FA-04 | Valid OTP completes authentication | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ✅ Yes | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Implement OTP verification with acceptance of valid codes |
| AUTH-2FA-05 | /me endpoint succeeds after 2FA | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ✅ Yes | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Verify authenticated /me call succeeds after 2FA completion |
| AUTH-2FA-06 | Authenticated route matrix succeeds after 2FA | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ✅ Yes | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Verify route access after 2FA for all V1 routes |
| AUTH-2FA-07 | 2FA enrollment/success/failure emits audit/security event | N/A — event path | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ❌ No | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Wire audit event emission for 2FA lifecycle events |
| AUTH-2FA-08 | Recovery/reset path exists or is operator-controlled | N/A — runtime endpoint | ~/zenmesh/docs/docs/80-EVIDENCE/docsai/r5-2fa-v1-security-contract/ | ❌ No | ❌ No | ❌ No | Hermes | ❌ V1_BLOCKER | Document recovery path; operator-controlled reset for V1 |
| ---- | ------- | --------------- | --------------- | ------------- | ------------------- | ------------- | ------- | -------- | ------------- |
| TS-001 | Replay attack rejection (Stripe) | testdata/stripe/stale_signature.* + go test | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-002 | Replay attack rejection (Shopify) | N/A — dedup only | N/A | ❌ No | ❌ No | ❌ No | Hermes | ❌ PENDING | Blocked on SH-01 (HMAC enforcement) |
| TS-003 | Replay attack rejection (Twilio) | N/A — dedup only | N/A | ❌ No | ❌ No | ❌ No | Hermes | ❌ PENDING | Blocked on TW-01 (signature enforcement) |
| TS-004 | Invalid signature rejection (Stripe) | testdata/stripe/invalid_signature.* + go test | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-005 | Invalid signature rejection (Shopify) | N/A — HMAC not implemented | N/A | ❌ No | ❌ No | ❌ No | Hermes | ❌ PENDING | Blocked on SH-01 |
| TS-006 | Invalid signature rejection (Twilio) | N/A — signature not implemented | N/A | ❌ No | ❌ No | ❌ No | Hermes | ❌ PENDING | Blocked on TW-01 |
| TS-007 | Expired timestamp rejection (Stripe) | testdata/stripe/stale_signature.* + go test | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-008 | Missing signature header rejection | testdata/stripe/missing_id.* + go test | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-009 | Payload tampering rejection (Stripe) | Covered by HMAC validation | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-010 | Payload tampering rejection (Shopify) | Blocked on SH-01 | N/A | ❌ No | ❌ No | ❌ No | Hermes | ❌ PENDING | Blocked on SH-01 |
| TS-011 | Payload tampering rejection (Twilio) | Blocked on TW-01 | N/A | ❌ No | ❌ No | ❌ No | Hermes | ❌ PENDING | Blocked on TW-01 |
| TS-012 | Malformed request rejection (Stripe) | testdata/stripe/malformed_payload.* + go test | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-013 | Duplicate delivery behavior (Stripe) | testdata/stripe/payment_intent_succeeded_duplicate.* + go test | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-014 | Duplicate delivery behavior (Shopify) | Dedup via idempotency key | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-015 | Duplicate delivery behavior (Twilio) | Dedup via MessageSid/CallSid | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-016 | Oversized payload rejection | Payload size enforcement | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ❌ No | Hermes | ✅ DONE | Maintain |
| TS-017 | Unknown event type rejection | Event type validation | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-018 | IP allowlist enforcement | IP allowlist validator | docs/providerflow/ | ✅ Yes | ✅ Yes | ❌ No | Hermes | ✅ DONE | Maintain |
| TS-019 | Missing required event fields | Schema validation | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ✅ Yes | Hermes | ✅ DONE | Maintain |
| TS-020 | Invalid content-type rejection | Content-type validation | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ❌ No | Hermes | ✅ DONE | Maintain |
| TS-021 | Delivery timeout enforcement | Timeout handling | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ❌ No | Hermes | ✅ DONE | Maintain |
| TS-022 | Unknown provider endpoint rejection | Provider routing | zen-platform docs/80-EVIDENCE/ | ✅ Yes | ❌ No | ❌ No | Hermes | ✅ DONE | Maintain |