Skip to content

System architecture

Egress Gate has one transport adapter and one protobuf-free pipeline processor.

Inside Egress Gate, the gRPC service adapter is separate from the protobuf-free pipeline processor and request gates.
The external OpenShell supervisor talks only to the Egress Gate service adapter. The pipeline processor and gates use local domain models.

Component ownership

Module Responsibility
request.py Immutable request, headers, and RequestMutations
request_content/ Reusable text parsers, strict JSON documents, typed selection, source-preserving edits, and normalized message blocks
result.py Gate evaluations, five-field findings, provenance, traces, and result invariants
gates/base.py Gate lifecycle, capabilities, output validation, and UTF-8 helper
gates/registry.py Trusted registration, exact pipeline schema, resources, discovery, and processor preparation
gates/regex_scans.py Typed regex scan and action policy configuration
gates/regex.py Content-parser composition, non-body text adaptation, pattern catalogs, bounded matching, finding aggregation, and gate evaluation
config.py Strict ordered gates and required default decision
request_processor.py Shared deadline, immutable snapshot construction, control flow, aggregation, and provenance
service/ Protobuf validation/conversion, worker slots, lifecycle, and wire serialization

The CLI's offline evaluator parses bounded YAML. It uses GateRegistry.prepare_processor() and the production RequestProcessor. It does not add a second execution path or import the transport adapter.

Only service/ imports generated protobuf/gRPC bindings. The pipeline processor and gates receive domain values and can be tested offline.

The request body remains canonical immutable bytes. A configured gate can interpret the current body snapshot as strict JSON and select text nodes, then optionally adapt those nodes to normalized message blocks. These views remain local to one gate evaluation. The pipeline processor does not parse bodies or cache request state across reusable gate instances.

Regex scan models remain declarative Pydantic configuration. During gate preparation, body-based variants compose a reusable RequestContentParser: Utf8TextParser, JsonFieldsParser, or MessageBlocksParser. Each parser owns text extraction and how immutable TextReplacement values become bounded body bytes. MessageBlocksParser composes a MessageBlockExtractor to normalize a parsed JSON document without conflating that semantic step with body parsing. The regex gate only adapts path, query, and header values itself, then applies matching and actions uniformly to the text targets it receives.

Pipeline execution

A request moves through pipeline processor controls and an ordered gate pipeline before Egress Gate returns a result.
Each gate proposes changes to its current snapshot. The pipeline processor builds the next snapshot, the service adapter maps the final mutations, and the OpenShell supervisor applies them.

Trust and state

Registry factories and custom gate modules are trusted deployment code. Capabilities mechanically constrain outputs but do not sandbox Python reads. Prepared gates can use application-owned resources that are safe for concurrent use. Egress Gate does not close these resources.

One validated policy and one prepared pipeline processor (RequestProcessor) are active at a time. Preparation is serialized and a complete candidate is published only after the shared deadline checks. A failed candidate leaves the existing policy unchanged. Gate instances are reused across worker threads, so per-request state must remain local to evaluate.

See Request lifecycle and Service boundary.