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] = []
|
applied: list[str] = []
|
||||||
try:
|
try:
|
||||||
with self.pool.connection() as conn:
|
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 SCHEMA IF NOT EXISTS "{self.schema}"')
|
||||||
conn.execute(
|
conn.execute(
|
||||||
f'CREATE TABLE IF NOT EXISTS "{self.schema}".schema_migrations ('
|
f'CREATE TABLE IF NOT EXISTS "{self.schema}".schema_migrations ('
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ spec:
|
||||||
- name: audit-core
|
- name: audit-core
|
||||||
# REPLACE at release time with the built digest. A mutable tag is not
|
# REPLACE at release time with the built digest. A mutable tag is not
|
||||||
# an immutable image, and `:latest` must never be the only reference.
|
# 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
|
imagePullPolicy: IfNotPresent
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ spec:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: migrate
|
- name: migrate
|
||||||
image: forgejo.coulomb.social/coulomb/audit-core@sha256:41493cd5bbd86a3309af07b1a97d41343b91d758a300ad39d71e4a18c17de7cc
|
image: forgejo.coulomb.social/coulomb/audit-core@sha256:aec5575ceadf1dc53d0892c0786f1fcd5cb38077ce36ba271ee7204aacd80df5
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: ["python", "-m", "audit_core", "migrate"]
|
command: ["python", "-m", "audit_core", "migrate"]
|
||||||
env:
|
env:
|
||||||
|
|
@ -41,6 +41,8 @@ spec:
|
||||||
value: /etc/audit-core/db
|
value: /etc/audit-core/db
|
||||||
- name: AUDIT_CORE_DATABASE_SCHEMA
|
- name: AUDIT_CORE_DATABASE_SCHEMA
|
||||||
value: audit_core
|
value: audit_core
|
||||||
|
- name: AUDIT_CORE_MIGRATE_ROLE
|
||||||
|
value: audit_core_migrate
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 25m
|
cpu: 25m
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ cluster and belongs to T05.
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: AUDIT-WP-0005-T02
|
id: AUDIT-WP-0005-T02
|
||||||
status: progress
|
status: done
|
||||||
priority: high
|
priority: high
|
||||||
state_hub_task_id: "831b2472-0d80-4369-a5e3-eb08ef3526b1"
|
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
|
ClusterSecretStores on AppRole and `Valid`. Interim ESO token Secret
|
||||||
removed. Receiver stayed Ready.
|
removed. Receiver stayed Ready.
|
||||||
|
|
||||||
Remaining before T02 done: a live rotation drill (refresh lease, confirm
|
Live rotation 2026-08-13: ESO refresh while Ready; accept 202 before and
|
||||||
no delivery gap). Empty senders KV path is a later wrap-migrate, not a
|
after; both events readable; `/readyz` stayed `archive`. Fingerprint log
|
||||||
founder paste.
|
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
|
## T03 - Deploy the receiver
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: AUDIT-WP-0005-T03
|
id: AUDIT-WP-0005-T03
|
||||||
status: progress
|
status: done
|
||||||
priority: high
|
priority: high
|
||||||
state_hub_task_id: "598af2ac-e772-4a4e-9a65-dde9d4ca167f"
|
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
|
rows — not audit custody). Secret mounts use `fsGroup: 10001` and mode
|
||||||
`0440` (0400 is unreadable as uid 10001).
|
`0440` (0400 is unreadable as uid 10001).
|
||||||
|
|
||||||
Remaining before T03 done: pod delete/reschedule and `kubectl rollout undo`
|
Tested 2026-08-13: pod delete/recreate stayed Ready; `kubectl rollout undo`
|
||||||
recorded as a tested rollback.
|
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
|
## 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
|
evidence JSON contains no tokens, credentials, or event payloads, so a run
|
||||||
against the deployed receiver can go to NK-WP-0024 as-is.
|
against the deployed receiver can go to NK-WP-0024 as-is.
|
||||||
|
|
||||||
Remaining before done: run it against the deployed receiver on railiance01 and
|
Remote run 2026-08-13 (`evidence/failure-matrix-20260813T103540Z.json`,
|
||||||
hand the resulting evidence to NK-WP-0024. The local rehearsal is not a
|
`MODE=remote DISRUPT=0`): **7 passed, 5 failed, 3 skipped**. S01–S07 passed
|
||||||
substitute — it does not exercise CNPG failover, NetworkPolicy enforcement, or
|
on the live receiver (accept, duplicate, conflict, cross-tenant 400, dead
|
||||||
OpenBao-leased credentials.
|
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
|
## T06 - Operational handover
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue