Implement AUDIT-WP-0006 honest operational custody.
Postgres now reports custody_class=operational with a cited 30-day recoverable window. Join ITC-CAP operations.audit at D4, publish the interface card, and overlay user-engine tenants [*] from Git so an ExternalSecret refresh cannot shrink it.
This commit is contained in:
parent
0a3d05ff1c
commit
ded432a63f
25 changed files with 832 additions and 94 deletions
|
|
@ -38,6 +38,7 @@ from audit_core.interface import (
|
|||
EventConflictError,
|
||||
EventValidationError,
|
||||
IdempotentAuditBackend,
|
||||
custody_class_satisfies,
|
||||
)
|
||||
from audit_core.redaction import (
|
||||
POLICY_REDACT,
|
||||
|
|
@ -102,10 +103,13 @@ class IngestionApplication:
|
|||
require_custody_class: str | None = None,
|
||||
) -> None:
|
||||
policy = backend.retention_policy
|
||||
if require_custody_class and policy.custody_class != require_custody_class:
|
||||
if require_custody_class and not custody_class_satisfies(
|
||||
policy.custody_class, require_custody_class
|
||||
):
|
||||
# Production sets this. Without it, losing AUDIT_CORE_DATABASE_URL
|
||||
# silently downgrades custody to the development store instead of
|
||||
# failing to start.
|
||||
# failing to start. ``operational`` and ``archive`` alias each
|
||||
# other for one mixed-rollout deploy (AUDIT-WP-0006-T01).
|
||||
raise ValueError(
|
||||
f"backend custody_class={policy.custody_class!r} does not meet the "
|
||||
f"required {require_custody_class!r}; refusing to start"
|
||||
|
|
@ -330,11 +334,10 @@ class IngestionApplication:
|
|||
return self._json(
|
||||
start_response, HTTPStatus.SERVICE_UNAVAILABLE, {"status": "unavailable"}
|
||||
)
|
||||
policy = self.backend.retention_policy
|
||||
return self._json(
|
||||
start_response,
|
||||
HTTPStatus.OK,
|
||||
{"status": "ok", "custody_class": policy.custody_class, "durable": policy.durable},
|
||||
self.backend.retention_policy.as_readiness(),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -490,11 +493,15 @@ def build_backend() -> IdempotentAuditBackend:
|
|||
else "AUDIT_CORE_DATABASE_URL" if url
|
||||
else "brokered libpq environment")
|
||||
log.info("custody backend: postgresql (%s)", source)
|
||||
recoverable = os.environ.get("AUDIT_CORE_RECOVERABLE_DAYS")
|
||||
return PostgresAuditBackend(
|
||||
url or "",
|
||||
credential_dir=credential_dir,
|
||||
schema=os.environ.get("AUDIT_CORE_DATABASE_SCHEMA", "audit_core"),
|
||||
retention_days=int(retention) if retention else None,
|
||||
recoverable_days=(
|
||||
int(recoverable) if recoverable else 30
|
||||
),
|
||||
max_size=int(os.environ.get("AUDIT_CORE_DB_POOL_MAX", "8")),
|
||||
statement_timeout_ms=int(
|
||||
os.environ.get("AUDIT_CORE_DB_STATEMENT_TIMEOUT_MS", "30000")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue