Skip to content

GA Completion: Security — Root-of-Trust, PII Coverage & External Validation

Document ID: GA-003 File Path: docs/18-roadmap/v1.0/A3-security-completion.md Version: 1.2.0 Status: In progress — KMS live + pen-tested + compliance-mapped; all three §4.1 hardening-pass residual findings (anonymous default-tenant RBAC bypass, kms.json file permissions, non-Unix root-key/kms.json ACL) are now closed; root-of-trust and external validation remain Owner: Security Team Last Updated: 2026-07-09


Turn the “Security: Root-of-Trust, PII Coverage, and External Validation” GA gap (PRD-002 §5.3, v1.0 §3 Security row) into a delivery plan.

Committed GA-completion work. The envelope-encryption slice is done; what remains is the production root-of-trust, broader PII coverage, and external validation.


  • KMS is live across three consumers — wovyr-secrets (EncryptedFileSecretStore), wovyr-memory (EncryptingMemoryStore), and wovyr-events (EncryptedFileWebhookStore) — with a key-management surface (/api/v1/kms/tenant-key/rotate|destroy, wovyr kms rotate|destroy), audited (kms.tenant_key.*). See encryption §5.
  • Pen-tested and compliance-mapped. crates/wovyr-kms/tests/adversarial.rs attacks the key boundary (cross-tenant laundering, tamper/forgery, post-crypto-shred replay); compliance-mapping.md maps SOC 2 / ISO 27001 / GDPR controls to the implementation — as an internal self-assessment.
  • All three hardening-pass residual findings are now closed (compliance-mapping §7): the anonymous default-tenant RBAC bypass reaching kms:admin is fixed (tenant_authorize’s short-circuit deleted — see §3 item 3 below); kms.json file permissions are now owner-only after every write; and the non-Unix root-key/kms.json ACL gap is closed too — authored and verified live on a real Windows host via a new shared wovyr_common::fs::restrict_to_owner primitive (Unix: chmod 0600; Windows: icacls /inheritance:r /grant:r).
  • The root key is a single-host stand-in. LocalKms holds it in-process (root::from_env / root::from_file); no cloud-KMS/HSM backing.

  1. No cloud-KMS-/HSM-backed root — production deployments need a managed root-of-trust, not an in-process key.
  2. PII field encryption covers secrets/memory/webhook-secrets but not future PII resources (e.g. a User.emailusers.md).
  3. The documented residual findings are unaddressed by design (scoped out of the pen-test slice, deferred to a hardening pass). Done (2026-07-09) for all three: tenant_authorize (tenancy.rs) no longer short-circuits RBAC for an anonymous caller against the default tenant (WOVYR_ALLOW_ANONYMOUS=1 now governs only whether such a request reaches a handler at all, never its authorization outcome); kms.json is now chmod 0600-equivalent after every write; and the non-Unix ACL gap for both root.key and kms.json is closed via wovyr_common::fs::restrict_to_owner (icacls on Windows), authored and proven live on a real Windows host.
  4. No external pen test or formal compliance audit has occurred — the current mapping is a self-assessment.

  • A cloud-KMS-/HSM-backed Kms implementation behind the existing trait boundary — only tenant-key wrap/unwrap changes, since Kms is the port (documented explicitly in encryption §5).
  • Field-level encryption for any PII-bearing resource added later, reusing the envelope::seal/open pattern already proven in three consumers.
  • A scoped hardening pass closing the residual findings — notably narrowing the anonymous default-tenant bypass (a systemic change across every tenant-scoped route, deliberately deferred from the pen-test slice). Done for all three residual findings (2026-07-09).
  • Engagement of an external penetration test and a formal compliance-mapping audit.
  • The hardening pass must preserve back-compat where the anonymous default-tenant mode is currently relied upon, or migrate callers deliberately. Resolved by migrating callers: local/dev convenience for tenant-scoped routes now requires a real credential (WOVYR_PLATFORM_ADMINS
    • a principal header) rather than bare anonymity — the same path a real deployment already uses. ~10 wovyr-server tests that relied on the bypass were migrated to this pattern rather than left passing on stale assumptions.
  • New backends implement the trait; the spine does not change.

An external pen-test report with no unresolved high/critical findings, and a third-party control-mapping review completed — replacing today’s internal self-assessment. Plus a production root-of-trust backed by a managed KMS/HSM.

This is the direct input to the v1.0 exit criterion “passes security review and external pen test” (v1.0 §5).


  • Cloud KMS/HSM and external audit/pen-test vendors are real-world engagements not available in the dev environment — the trait-level implementation can be authored here, but validation against a live managed KMS cannot.
  • The User resource for PII field encryption does not exist yet; that sub-item is contingent on the resource being added.
  • Interacts with A2 backup/restore: a managed root changes what the KMS-catalog backup must cover.

RiskMitigation
Anonymous-bypass fix breaks back-compat callersMaterialized as expected, resolved by migration: ~10 wovyr-server tests (mostly workflow_runner.rs, plus a handful in lib.rs) asserted success for a credential-less caller against a tenant_authorize-gated route; all migrated to a real WOVYR_PLATFORM_ADMINS principal rather than left passing on stale assumptions
Self-assessment mistaken for certificationcompliance-mapping.md is explicit it is not an attestation; this doc’s exit criteria require external validation
PII item blocked on a non-existent resourceScope it contingent on the User resource; don’t claim coverage that has no target


VersionDateDescription
1.2.02026-07-09Closed the remaining two §4.1 hardening-pass residual findings: kms.json is now owner-only after every write (already landed separately), and the non-Unix root-key/kms.json ACL gap is closed via a new shared wovyr_common::fs::restrict_to_owner primitive (icacls /inheritance:r /grant:r on Windows), authored and proven live on a real Windows host rather than left as a documented-but-unbuildable gap. Cloud-KMS/HSM and external validation remain
1.1.02026-07-09Closed the anonymous default-tenant RBAC bypass (§3 item 3 / §4.1’s hardening pass): deleted tenant_authorize’s short-circuit in crates/wovyr-server/src/tenancy.rs so WOVYR_ALLOW_ANONYMOUS=1 no longer implies any RBAC grant, only authentication pass-through. Migrated ~10 tests that relied on the old permissive behavior to a real WOVYR_PLATFORM_ADMINS principal. kms.json permissions and the non-Unix root-key ACL remain open, as does cloud-KMS/HSM and external validation
1.0.02026-07-05Initial GA-completion delivery doc for security; records the live+pen-tested+mapped KMS slice and scopes the root-of-trust, PII, hardening, and external-validation remainder