Skip to content

Central egress boundary (P2-23)

CortexBuild routes every byte bound for an external model/provider through a single, enforced choke-point so secrets, PII, and proprietary rule text cannot leak — even by accident or via a future call-site.

The single choke-point

cortexbuild_core.llm.get_llm() never returns a raw provider client. It always returns a RedactingLLMClient wrapper whose complete(prompt) runs the prompt through cortexbuild_core.security.egress.redact_for_egress() before the underlying client can hand it to the provider SDK (chat.completions.create).

  • Callers cannot obtain a raw, non-redacting client.
  • Direct provider SDK egress (chat.completions.create) is PROHIBITED anywhere except inside the wrapper module (cortexbuild_core/llm/__init__.py). A guard test (tests/unit/test_p2_23_egress_redaction.py) greps the package and fails if that call appears anywhere else, so a new call-site cannot bypass redaction.

Defence-in-depth, fail-closed

Redaction is on top of offline-by-default — it is not the only line of defence:

  1. Offline by default (the real gate). With CORTEXBUILD_LLM unset, get_llm() returns None and zero bytes leave the machine, regardless of redaction. Enforcement keys off this env gate (CORTEXBUILD_LLM + the [llm] extra), not a separate flag.
  2. Redaction (B5). redact_for_egress() is a vetted, ReDoS-safe, pure-re detector set (AWS keys/secrets/ARNs, GitHub/GitLab/Slack tokens, Bearer/JWT, connection strings, PEM private keys, emails, IPv4, internal hostnames, high-entropy hex/base64, and absolute paths containing a username). Each hit becomes a stable typed placeholder such as «REDACTED:AWS_KEY». ""/None pass through unchanged.
  3. Proprietary-origin classification (B3). origin_may_egress() permits only FOUNDATIONAL and ORG_STANDARDS rule text to leave by default. Everything else — CUSTOMER_ADOPTED, IMPORTED_OSS, SYNTHESIZED, USER, and anything unknown/unclassified — is treated as proprietary and offline-only. Unknown never resolves to foundational.
  4. Unified scoped consent (B4). assert_egress_allowed() reuses the frozen ConsentRecord (it already carries scope). The consent's scope must match the operation purpose, so a shared-memory-write consent can never authorise an llm-assist-egress (purpose constant EGRESS_LLM_ASSIST) and vice-versa. Record an llm-egress consent at .cortexbuild/egress-consent.json.

Live synthesis egress

cortexbuild synthesize-rules --no-dry-run enforces the gate: before any text egresses to a live provider it calls assert_rule_text_egress_allowed(). Without a scoped consent the run is blocked (fail-closed) with an actionable message. The default --dry-run uses the offline fake LLM and never calls a paid API.