Own migrate objects as audit_core_migrate; pin snapshot-read image
SET ROLE during migrate so tables are not owned by a disposable lease. Current image sha256:aec5575. T02/T03 recorded done after live rotation and rollout undo. T05 remote run is partial (port-forward dropped).
This commit is contained in:
parent
c404c910cd
commit
53df641866
4 changed files with 42 additions and 13 deletions
|
|
@ -204,6 +204,13 @@ class PostgresAuditBackend:
|
|||
applied: list[str] = []
|
||||
try:
|
||||
with self.pool.connection() as conn:
|
||||
migrate_role = os.environ.get("AUDIT_CORE_MIGRATE_ROLE", "").strip()
|
||||
if migrate_role:
|
||||
if not migrate_role.isidentifier():
|
||||
raise ValueError(f"unsafe migrate role: {migrate_role!r}")
|
||||
# Leased login roles must SET ROLE to the group so new
|
||||
# objects are owned by audit_core_migrate, not the lease.
|
||||
conn.execute(f'SET ROLE "{migrate_role}"')
|
||||
conn.execute(f'CREATE SCHEMA IF NOT EXISTS "{self.schema}"')
|
||||
conn.execute(
|
||||
f'CREATE TABLE IF NOT EXISTS "{self.schema}".schema_migrations ('
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ spec:
|
|||
- name: audit-core
|
||||
# REPLACE at release time with the built digest. A mutable tag is not
|
||||
# an immutable image, and `:latest` must never be the only reference.
|
||||
image: forgejo.coulomb.social/coulomb/audit-core@sha256:41493cd5bbd86a3309af07b1a97d41343b91d758a300ad39d71e4a18c17de7cc
|
||||
image: forgejo.coulomb.social/coulomb/audit-core@sha256:aec5575ceadf1dc53d0892c0786f1fcd5cb38077ce36ba271ee7204aacd80df5
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ spec:
|
|||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: migrate
|
||||
image: forgejo.coulomb.social/coulomb/audit-core@sha256:41493cd5bbd86a3309af07b1a97d41343b91d758a300ad39d71e4a18c17de7cc
|
||||
image: forgejo.coulomb.social/coulomb/audit-core@sha256:aec5575ceadf1dc53d0892c0786f1fcd5cb38077ce36ba271ee7204aacd80df5
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["python", "-m", "audit_core", "migrate"]
|
||||
env:
|
||||
|
|
@ -41,6 +41,8 @@ spec:
|
|||
value: /etc/audit-core/db
|
||||
- name: AUDIT_CORE_DATABASE_SCHEMA
|
||||
value: audit_core
|
||||
- name: AUDIT_CORE_MIGRATE_ROLE
|
||||
value: audit_core_migrate
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ cluster and belongs to T05.
|
|||
|
||||
```task
|
||||
id: AUDIT-WP-0005-T02
|
||||
status: progress
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "831b2472-0d80-4369-a5e3-eb08ef3526b1"
|
||||
```
|
||||
|
|
@ -218,15 +218,29 @@ Mason plan approved 2026-08-13 and built: AppRole
|
|||
ClusterSecretStores on AppRole and `Valid`. Interim ESO token Secret
|
||||
removed. Receiver stayed Ready.
|
||||
|
||||
Remaining before T02 done: a live rotation drill (refresh lease, confirm
|
||||
no delivery gap). Empty senders KV path is a later wrap-migrate, not a
|
||||
founder paste.
|
||||
Live rotation 2026-08-13: ESO refresh while Ready; accept 202 before and
|
||||
after; both events readable; `/readyz` stayed `archive`. Fingerprint log
|
||||
was not seen on that refresh (lease may have been reused).
|
||||
|
||||
Findings fixed on the way:
|
||||
|
||||
- ESO AppRole login+discard **revokes** `database/creds` leases. Working
|
||||
client is a renewable orphan token. AppRole remains for a later
|
||||
lease-aware generator.
|
||||
- Mounted Secret reads must use Kubernetes `..data` or they can tear
|
||||
across two leases.
|
||||
- Migrate Job created tables owned by the ephemeral login role; catch-up
|
||||
GRANT + `REASSIGN OWNED` to `audit_core_migrate`. `SET ROLE
|
||||
audit_core_migrate` is now in migrate().
|
||||
|
||||
T02 done for the provisioned-lane + no-delivery-gap claim. Empty senders
|
||||
KV wrap-migrate is follow-on, not a founder paste.
|
||||
|
||||
## T03 - Deploy the receiver
|
||||
|
||||
```task
|
||||
id: AUDIT-WP-0005-T03
|
||||
status: progress
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "598af2ac-e772-4a4e-9a65-dde9d4ca167f"
|
||||
```
|
||||
|
|
@ -321,8 +335,11 @@ rapp-postgres isolation-test stub `events` table (3 columns, 2 fixture
|
|||
rows — not audit custody). Secret mounts use `fsGroup: 10001` and mode
|
||||
`0440` (0400 is unreadable as uid 10001).
|
||||
|
||||
Remaining before T03 done: pod delete/reschedule and `kubectl rollout undo`
|
||||
recorded as a tested rollback.
|
||||
Tested 2026-08-13: pod delete/recreate stayed Ready; `kubectl rollout undo`
|
||||
returned to `sha256:41493cd5…` Ready; undo again returned to
|
||||
`sha256:aec5575…` (snapshot-read image) Ready. Current pin is
|
||||
`forgejo.coulomb.social/coulomb/audit-core@sha256:aec5575ceadf1dc53d0892c0786f1fcd5cb38077ce36ba271ee7204aacd80df5`.
|
||||
T03 done.
|
||||
|
||||
## T04 - Migrate existing SQLite records
|
||||
|
||||
|
|
@ -440,10 +457,13 @@ against an unreachable receiver (it does not pass silently), and the emitted
|
|||
evidence JSON contains no tokens, credentials, or event payloads, so a run
|
||||
against the deployed receiver can go to NK-WP-0024 as-is.
|
||||
|
||||
Remaining before done: run it against the deployed receiver on railiance01 and
|
||||
hand the resulting evidence to NK-WP-0024. The local rehearsal is not a
|
||||
substitute — it does not exercise CNPG failover, NetworkPolicy enforcement, or
|
||||
OpenBao-leased credentials.
|
||||
Remote run 2026-08-13 (`evidence/failure-matrix-20260813T103540Z.json`,
|
||||
`MODE=remote DISRUPT=0`): **7 passed, 5 failed, 3 skipped**. S01–S07 passed
|
||||
on the live receiver (accept, duplicate, conflict, cross-tenant 400, dead
|
||||
letter, 401, redaction). S08–S12 failed with `status=0` (port-forward
|
||||
dropped mid-run), not a contract mismatch. S13–S15 skipped (`DISRUPT=0`,
|
||||
replay needs DB). Re-run through a stable operator path before handing
|
||||
NK-WP-0024; do not treat this JSON as closeout.
|
||||
|
||||
## T06 - Operational handover
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue