Skip to content

feat(egress): draft EgressPolicy schema + decide/3 (audit #31, P1)#32

Merged
hyperpolymath merged 1 commit into
mainfrom
audit/egress-mode-scaffold
Jun 2, 2026
Merged

feat(egress): draft EgressPolicy schema + decide/3 (audit #31, P1)#32
hyperpolymath merged 1 commit into
mainfrom
audit/egress-mode-scaffold

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Audit issue: #31 (priority 1 — OUTBOUND/egress mode is entirely absent).

This PR adds a deny-by-default outbound policy module so estate apps (e.g.
hyperpolymath/neurophone) can route cloud/LLM calls through the gateway
and have the same declarative policy bound what leaves the box. Needed for
neurophone's data-egress obligation #84-3.1.

Scope (small + intentional)

  • HttpCapabilityGateway.EgressPolicy with validate/1 + decide/3
  • Host + verb allowlist with optional capability + classification labels
  • Host comparison is exact-string lowercased; no wildcard matching by
    design (explicit listing is safer for an egress allowlist)
  • 87 LoC of tests covering validate happy path, all four error shapes, and
    decide allow/deny on listed / unlisted host + verb pairs
  • PROOF-NEEDS.md with the echo-types audit (record-as-not-relevant)

Diff: 3 files, +293 LoC (under the 300-LoC PR ceiling).

NOT in scope (deliberate follow-ups)

  • Actual outbound forwarder (Proxy.egress/2) — this PR is policy + schema
  • Wiring into PolicyLoader / Application.start/2
  • chimichanga-style capability attenuation on the matched entry

Test plan

  • mix test test/egress_policy_test.exs
  • Confirm EgressPolicy.validate(nil) returns the deny-by-default
    empty allowlist (so existing inbound-only policies keep working)
  • Sanity-check host-lowercasing on ingest covers the API.ANTHROPIC.COM
    case
  • Status: DRAFT — please do not auto-merge. Owner review only.

Echo-types audit

Per estate convention (feedback_proofs_must_check_and_cross_doc_echo_types.md),
echo-types was audited and recorded as record-as-not-relevant in
PROOF-NEEDS.md. Egress decision is a pure first-order predicate; no L3
obligation is in scope.

Refs: #31

Adds a deny-by-default outbound policy module so estate apps can route
cloud/LLM calls *through* the gateway and have the same declarative
policy bound what leaves the box. Needed by hyperpolymath/neurophone for
its data-egress obligation (#84-3.1).

Scope (DRAFT — small intentional surface):
* HttpCapabilityGateway.EgressPolicy with validate/1 + decide/3
* Host+verb allowlist with optional capability + classification labels
* Host comparison is exact-string lowercased; no wildcard matching by
  design (explicit listing is safer for egress)
* 87 LoC of tests covering validate happy path, all four error shapes,
  and decide allow/deny on listed/unlisted host+verb pairs

NOT in scope (follow-ups):
* Actual outbound forwarder (Proxy.egress/2) — this PR is policy + schema
* Wiring into PolicyLoader / Application start
* chimichanga-style capability attenuation on the matched entry

Echo-types audit: record-as-not-relevant for this PR (see PROOF-NEEDS.md).

Refs: #31 (self-audit, priority 1)
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

🔍 Hypatia Security Scan

Findings: 65 issues detected

Severity Count
🔴 Critical 6
🟠 High 17
🟡 Medium 42

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in boj-build.yml",
    "type": "missing_timeout_minutes",
    "file": "boj-build.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "missing_timeout_minutes",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "missing_timeout_minutes",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "missing_timeout_minutes",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "missing_timeout_minutes",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "missing_timeout_minutes",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "missing_timeout_minutes",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "missing_timeout_minutes",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "missing_timeout_minutes",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in governance.yml",
    "type": "missing_timeout_minutes",
    "file": "governance.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath marked this pull request as ready for review June 2, 2026 10:17
@hyperpolymath hyperpolymath merged commit 6faa7d5 into main Jun 2, 2026
18 checks passed
@hyperpolymath hyperpolymath deleted the audit/egress-mode-scaffold branch June 2, 2026 10:17
hyperpolymath added a commit that referenced this pull request Jun 2, 2026
…audit #31, P3) (#34)

Pure documentation — no code change. Adds docs/CAPABILITY-INTEGRATION.md
describing the contract surfaces by which the gateway connects (or, in
v0.x, *will connect*) to:

* the estate capability model (chimichanga capability attenuation,
  boj-server cartridges already partially wired via
  PolicyLoader.load_from_boj_catalog/1)
* service discovery via groove-protocol

Documented as a CONTRACT, not a feature list, because:
1. The cross-repo contracts are still stabilising
2. The compiler-side schema change is in flight in #33
3. The egress mode in #32 is the more urgent consumer

Also extends PROOFS_NEEDED.md with the two open obligations and a fresh
echo-types record-as-not-relevant audit per estate convention.

Refs: #31 (self-audit, priority 3), related to #32, #33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant