[Security] Add a durable transactional event bridge for automation triggers #270

Closed
opened 2026-07-28 14:02:53 +02:00 by zemion · 3 comments
Owner

Replace direct use of the transient in-process PlatformEvent bus for automated side effects with a durable, transaction-aware event delivery bridge.

Acceptance criteria:

  • committed domain events enter a transactional outbox with stable event, tenant, actor, classification, correlation, and causation identifiers
  • allowlisted consumers receive idempotent deliveries only after the producing transaction commits
  • bounded retries, quarantine/dead-letter state, replay controls, retention, and operational metrics are persisted
  • restricted/confidential payloads cannot be subscribed to or disclosed without an explicit policy decision
  • trigger filters are constrained data comparisons, never executable expressions
  • worker loss and duplicate delivery cannot start duplicate Dataflow or Workflow executions
  • the existing in-process bus remains suitable only for non-durable observers
Replace direct use of the transient in-process PlatformEvent bus for automated side effects with a durable, transaction-aware event delivery bridge. Acceptance criteria: - committed domain events enter a transactional outbox with stable event, tenant, actor, classification, correlation, and causation identifiers - allowlisted consumers receive idempotent deliveries only after the producing transaction commits - bounded retries, quarantine/dead-letter state, replay controls, retention, and operational metrics are persisted - restricted/confidential payloads cannot be subscribed to or disclosed without an explicit policy decision - trigger filters are constrained data comparisons, never executable expressions - worker loss and duplicate delivery cannot start duplicate Dataflow or Workflow executions - the existing in-process bus remains suitable only for non-durable observers
Author
Owner

No durable Core bridge is claimed in this slice. The new automation contract and Dataflow dispatcher are in govoplan-core@26ae034, but the existing PlatformEvent bus remains transient.

Current containment:

  • Dataflow event deliveries are durable and idempotent after ingress
  • direct ingress only accepts public/internal events and exact scalar equality filters
  • confidential/restricted automation events fail closed pending this issue
  • correlation, causation, event ID, tenant, and module provenance are retained

This issue remains the blocker for transactional after-commit delivery, retries/dead letters, restricted-event Policy decisions, replay, retention, and operational metrics.

No durable Core bridge is claimed in this slice. The new automation contract and Dataflow dispatcher are in govoplan-core@26ae034, but the existing PlatformEvent bus remains transient. Current containment: - Dataflow event deliveries are durable and idempotent after ingress - direct ingress only accepts public/internal events and exact scalar equality filters - confidential/restricted automation events fail closed pending this issue - correlation, causation, event ID, tenant, and module provenance are retained This issue remains the blocker for transactional after-commit delivery, retries/dead letters, restricted-event Policy decisions, replay, retention, and operational metrics.
Author
Owner

Codex State: progress

A first durable transactional bridge is now implemented through the Audit module: event IDs and payloads are persisted in SqlAuditOutbox, claims use short lock-safe transactions with retry backoff, and a Celery dispatcher publishes due events. Process-local delivery is no longer the only path for participating modules.

This issue remains open. Before closure it still needs maximum-attempt/dead-letter or quarantine behavior, operator replay, retention/cleanup, metrics/health visibility, an explicit policy for restricted/confidential event payloads, and multi-worker failure/recovery tests.

## Codex State: progress A first durable transactional bridge is now implemented through the Audit module: event IDs and payloads are persisted in `SqlAuditOutbox`, claims use short lock-safe transactions with retry backoff, and a Celery dispatcher publishes due events. Process-local delivery is no longer the only path for participating modules. This issue remains open. Before closure it still needs maximum-attempt/dead-letter or quarantine behavior, operator replay, retention/cleanup, metrics/health visibility, an explicit policy for restricted/confidential event payloads, and multi-worker failure/recovery tests.
Author
Owner

Completed by govoplan-core@a192a22 and govoplan-audit@f74e8cf. Core now exposes allowlisted durable consumers with stable : delivery keys and an explicit classified-data policy reference. Audit persists per-consumer attempts/status, bounded retry and quarantine, audited operator replay, metrics, and retention; Dataflow ingestion and delivery acknowledgement share the worker transaction, while the in-process bus is a non-durable observer. Celery routes/default queues and release/dev migrations are included. Verification: focused Core event/migration suites (38 tests), Audit full suite (8 tests), Ruff and Xenon pass; both release and dev migration tracks create the ledger.

Completed by govoplan-core@a192a22 and govoplan-audit@f74e8cf. Core now exposes allowlisted durable consumers with stable <event>:<consumer> delivery keys and an explicit classified-data policy reference. Audit persists per-consumer attempts/status, bounded retry and quarantine, audited operator replay, metrics, and retention; Dataflow ingestion and delivery acknowledgement share the worker transaction, while the in-process bus is a non-durable observer. Celery routes/default queues and release/dev migrations are included. Verification: focused Core event/migration suites (38 tests), Audit full suite (8 tests), Ruff and Xenon pass; both release and dev migration tracks create the ledger.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GovOPlaN/govoplan-core#270