Skip to content

In-Transit Event Redaction #86

Description

@tsutomi

Extend the redaction pipeline to the publish path itself, so that the CloudEvent delivered to outbound channels (RabbitMQ, Azure Service Bus, Webhook, etc.) is the redacted form — for use cases where downstream consumers should not receive the clear-text payload at all.

The problem today: Items 24 and 25 redact at the storage boundary of the audit trail and the delivery log. The CloudEvent that flows through the publish pipeline and out to RabbitMQ, Azure Service Bus, or any other outbound channel is still the original clear-text payload. This is acceptable when consumers are trusted and need the full data, but several real-world scenarios require the opposite:

  • A consumer is a third-party SaaS integration that must not see PCI-DSS-regulated fields.
  • A partner service subscribes only to a redacted projection of an internal event.
  • A regulated deployment mandates that confidential data never leaves the originating trust boundary, period.

What we will build: A new Hermodr.Publisher.Compliance package that introduces a publish-pipeline redaction pass, composed of two opt-in mechanisms:

  • RedactingEventMiddleware. A new IEventMiddleware that runs after enrichment and before channel dispatch, evaluates the redaction policy against the current CloudEvent, resolves the schema, applies the redactor, and replaces the CloudEvent reference on the EventContext.Event property. The in-flight event for the rest of the pipeline (channels, error handlers, downstream middleware) is the redacted form; the original is never observable from that point on. The middleware is fully opt-in: builder.UseCompliance() registers it, and the per-call options control the mode (Disabled / WhenSensitive / Always).
  • Per-channel redaction profiles. A first-class way to express that this outbound channel gets the redacted event and that one gets the full event. The mechanism reuses the existing EventPublishOptions / CombinedPublishOptions plumbing: an IEventPublishChannelFilter is introduced that returns RedactionMode.Always or RedactionMode.Disabled based on the resolved options for the channel, so a webhook channel to a third party can be redacted while an internal RabbitMQ exchange keeps the full event. Channels without an explicit profile inherit the publisher-level default.

Benefits:

  • Completes the compliance story: storage-only (items 24 and 25) for the "write only redacted" case, in-transit (item 26) for the "send only redacted" case, both layered on the same redactor, the same IEventSchemaRegistry, and the same Microsoft.Extensions.Compliance engine.
  • Per-channel profiles avoid the all-or-nothing trap: a single publish call can deliver the redacted event to a SaaS partner and the full event to an internal service without code duplication.
  • Backwards compatible: when UseCompliance() is not called, the publish pipeline is bit-identical to today.

Depends on #83. See ROADMAP.md item 26 for the full design.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions