feat(egress): draft EgressPolicy schema + decide/3 (audit #31, P1)#32
Merged
Conversation
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)
This was referenced Jun 2, 2026
🔍 Hypatia Security ScanFindings: 65 issues detected
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
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 gatewayand have the same declarative policy bound what leaves the box. Needed for
neurophone's data-egress obligation #84-3.1.
Scope (small + intentional)
HttpCapabilityGateway.EgressPolicywithvalidate/1+decide/3capability+classificationlabelsdesign (explicit listing is safer for an egress allowlist)
decide allow/deny on listed / unlisted host + verb pairs
PROOF-NEEDS.mdwith 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)
Proxy.egress/2) — this PR is policy + schemaPolicyLoader/Application.start/2Test plan
mix test test/egress_policy_test.exsEgressPolicy.validate(nil)returns thedeny-by-defaultempty allowlist (so existing inbound-only policies keep working)
API.ANTHROPIC.COMcase
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-relevantinPROOF-NEEDS.md. Egress decision is a pure first-order predicate; no L3obligation is in scope.
Refs: #31