# audit-core tenancy posture # # Declared per NetKingdom Tenancy Posture v0.1 (draft-7), # net-kingdom/canon/standards/tenancy-posture_v0.1.md. # Location and schema per Decision 5.4; per-path detail per Decision 5.2; # provider block per Decision 5.5. # # Conformance is accuracy, not altitude (§6). Nothing here is claimed above # what this repo can evidence today, and two rungs are deliberately declared # lower than the mechanism in place — see `gap.E` and `gap.R`. tenancy: reviewed: "2026-08-17" service_class: batch # §8.3.2. Co-resident with latency-critical # tenant-engine on platform-pg; the mixture is # reported by the platform, not hidden. current: { I: 1, A: 2, E: 1, P: 1, R: 1 } target: { I: 1, A: 2, E: 3, P: 1, R: 2 } # §5.2 — declare per path, quote the minimum. The quoted E above is the # minimum across paths. As of AUDIT-WP-0008-T04 both paths carry the same # mechanism; the quoted level stays at 1 for the evidence reason in gap.E, # not because a path is weaker. paths: E: write: 2 # Sender credential bound to the sources and tenants it may # claim; checked at one choke point (audit_core/ingestion.py). read: 2 # Event reads filtered to permitted tenants; surfaces with no # tenant key require full scope. Cross-tenant fetch returns # 404, not 403, so the surface is not an existence oracle. placement_exceptions: [] # No tenant is on dedicated substrate. All # tenants share database audit_core on # platform-pg. gap: I: >- I1 is accurate and is not currently a target. Senders authenticate with bearer tokens and the tenant arrives in the request body, checked against an allowlist bound to the credential (§4.1 places request-supplied tenant identifiers at I1 however canonical the string). The allowlist is a real control, but it is an A-axis control; it does not make the identity verified. Moving to I2 means senders carrying a verified token with a tenant claim, which is a change to every sender and not audit-core's to make alone. Recorded as accurate, not as ambition. A: >- A2 is accurate. Authorization is a single local boundary — permitted sources, permitted tenants, may_write, may_read — bound once and centrally. No flex-auth delegation. A3 is not a near-term target: flex-auth is itself at A0 on its own self-report (/v1/check authenticates no caller), so delegating to it today would lower this service's assurance, not raise it. E: >- The E2 mechanism is in place on both paths as of AUDIT-WP-0008-T04, and the quoted level is still 1. This is deliberate. §13.2 states that a passing CI run is not E2 evidence: the E2 artifact is adversarial, needs separate tenant contexts compared against each other, and carries a review date rather than a green build. The repo's cross-tenant tests are mechanical. Under §13.1 the level is not claimable until that artifact exists, so E stays at 1 until AUDIT-WP-0008-T05 produces it with whitehat-security. Declaring E2 on the strength of unit tests would be the overclaim §6 prohibits, and the read-path defect this repo just fixed was found precisely by refusing that kind of reasoning. E_target: >- E3 (row-level security per rapp-postgres ADR-0003) targeted 2027-03-31. Blocked behind the E2 artifact — §4.3 requires E2 evidence alongside any E3 claim — and needs the EXPLAIN comparison first, since RLS disables functional indexes built on non-leakproof functions. E4 is unreachable at P1 by the §3.2 coupling and is not a target. R: >- R1 today: the platform default 30-day window applies and audit-core has declared nothing above it. R2 is requested and in flight — audit-core has asked rapp-postgres to add `backupRetentionDays: 30` to consumers/audit-core.yaml, making the window declared rather than inherited. That file is rapp-postgres's, so R2 is not audit-core's to declare unilaterally. The erasure horizon is published on /readyz as recoverable_days. R_ceiling: >- R4 is unreachable under the current design and is not a target. Per Decision 4.5.3 — which this repo found — the hash chain commits to a SHA-256 of the cleartext record, which survives key destruction as a confirmation oracle over low-entropy fields. A fleet R4 target must exempt this service explicitly. See docs/erasure-and-audit.md (AUDIT-WP-0008-T03). credentials: >- Stated gap against Decision 9.2 rather than a silent exclusion. Database credentials comply with 9.1: dynamic leases re-read from a mounted Secret at connection time, no restart on rotation. Ingest credentials do not: they are static long-lived bearer tokens, rotated overlap-first by publishing a replacement alongside the incumbent and then dropping the predecessor. audit-core raised this omission during review and is not exempting itself from the rule it asked for. No dated remedy yet; leasing consumer-facing credentials needs a broker path that does not exist. retention_placement: >- audit-core's INTENT wants unbounded WORM archive. That is data.archive in ITC-CAP terms, recorded as an unmet requirement in data/capability/audit-core-operational.json, and it is deliberately not a backup-window question: a 30-day WAL window is not an archive, is not searchable, and restores instance-wide. Reviewed 2026-12-31. If no data.archive provision is procured by then, audit-core reopens placement under the §4.5 retention trigger, with P2 as the fallback — a worse answer than archive, named now so it is not improvised later. # §5.5 — audit-core provisions operations.audit to senders, so it declares # what it makes reachable for a consumer's audit trail, not only where it # sits. A sender's tenant separation inside the trail is audit-core's to # enforce; the sender cannot reach a level this service does not offer. provides: capability: operations.audit profile: administrative reachable: E2: >- Reachable now. A sender credential is bound to the tenants it may write for and, if it may read, to the tenants it may read back. E3: >- Not reachable yet. Requires rapp-postgres's ADR-0003 GUC contract applied to the audit_core schema. Targeted 2027-03-31. E4: >- Unreachable. One database, one runtime credential, no per-tenant credential and no per-tenant substrate. A sender needing a structural guarantee that another tenant cannot reach its audit records cannot get it here, and should be told so rather than sold E2 in E4's language (§11.4). R2: >- Reachable once the declared window lands; the horizon is already published on /readyz. R4: >- Unreachable by design, per R_ceiling above. A consumer with a verified erasure obligation over its audit trail cannot discharge it here.