Skip to content

fix(trust): enforce §3 invariant 3 — ignore X-Trust-Level from non-loopback callers#107

Closed
hyperpolymath wants to merge 1 commit into
mainfrom
fix/trust-policy-s3-clause
Closed

fix(trust): enforce §3 invariant 3 — ignore X-Trust-Level from non-loopback callers#107
hyperpolymath wants to merge 1 commit into
mainfrom
fix/trust-policy-s3-clause

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

  • Adds the one clause def satisfies?(_required, _trust, false), do: false to BojRest.TrustPolicy.satisfies?/3 — the BoJ-side enforcement of http-capability-gateway contract §3 invariant 3.
  • Flips 5 previously-skipped phase_c_seam_test.exs tests to live (they pass unchanged as the comment promised); updates 3 pre-existing tests that asserted the leak (trust_policy_test.exs:52, router_test.exs:404/417) to assert the §3-conformant behavior.
  • Defence-in-depth pair: gateway-side half landed in http-capability-gateway#11; §4 (back-side bind isolation) continues to defend in depth.

Test plan

  • mix test test/phase_c_seam_test.exs test/trust_policy_test.exs — 20/20 green (the 4 new live §3 router tests, the 1 new live §3 function-level test, plus the unchanged positive controls and pre-existing TrustPolicy unit tests).
  • Full mix test — 184/186. Two pre-existing failures (catalog_test/catalog_properties_test flagging qdrant-mcp and whisper-mcp auth.method values api_key/optional_api_key not in the schema's known set) confirmed red on clean main; baseline rot, unrelated to §3. Should be tracked separately if not already.

Why these three pre-existing tests had to flip

trust_policy_test.exs:52 and router_test.exs:404,417 literally asserted the §3 leak (non-loopback caller with X-Trust-Level: authenticated|internal allowed through). They were written before the §3 finding surfaced; the §3 fix necessarily inverts their expected outcome.

Refs hyperpolymath/standards#98 (Phase C close-out).
Refs hyperpolymath/standards#91 (HCG tier-2 channel).

🤖 Generated with Claude Code

…opback callers

`BojRest.TrustPolicy.satisfies?/3` previously accepted `X-Trust-Level:
authenticated|internal` from any caller, leaving §3 invariant 3 of the
http-capability-gateway contract unenforced at the BoJ side. Adds a clause
between `:public` and `:authenticated` that rejects every non-loopback
non-`:public` request regardless of header value:

    def satisfies?(_required, _trust, false), do: false

This is the BoJ-side half of the defence-in-depth pair whose gateway-side
half landed in http-capability-gateway#11. §4 (back-side bind isolation)
still defends in depth in practice.

Test updates
------------
* `phase_c_seam_test.exs` — 5 previously `@tag skip:` tests now live and
  passing (4 router-level + 1 function-level §3 invariant assertions).
* `trust_policy_test.exs:52` — pre-existing test asserted the leak; flipped
  to refute, plus a companion test for the loopback-honours path.
* `router_test.exs:404,417` — pre-existing tests asserted the leak via
  `assert conn.status in [200, 500]`; flipped to `assert conn.status == 403`
  with the §3-conformant body assertions.

Verification
------------
* §3-specific suites (`phase_c_seam_test` + `trust_policy_test`): 20/20.
* Full `mix test`: 184/186 (2 pre-existing failures in `catalog_test`/
  `catalog_properties_test` re: `qdrant-mcp`/`whisper-mcp` having
  `auth.method` values `api_key`/`optional_api_key` not in the schema's
  known set — confirmed red on clean main; baseline rot, unrelated).

Refs hyperpolymath/standards#98 (Phase C close-out).
Refs hyperpolymath/standards#91 (HCG tier-2 channel).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath

Copy link
Copy Markdown
Owner Author

Superseded by #106 (parallel session landed the equivalent fix earlier today, merged at 08:02Z). Verified identical: same one-line clause def satisfies?(_required, _trust, false), do: false between :public and :authenticated, same test inversions in trust_policy_test/router_test/phase_c_seam_test. Closing as duplicate; §3 enforcement is now on main via #106.

@hyperpolymath hyperpolymath deleted the fix/trust-policy-s3-clause branch May 20, 2026 08:06
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