Skip to content

feat(transport): add HTTP/SSE transport support to pin and check (DSE-57)#74

Merged
ernestprovo23 merged 3 commits into
mainfrom
feat/dse-57-http-sse-transport
Jun 29, 2026
Merged

feat(transport): add HTTP/SSE transport support to pin and check (DSE-57)#74
ernestprovo23 merged 3 commits into
mainfrom
feat/dse-57-http-sse-transport

Conversation

@ernestprovo23

Copy link
Copy Markdown
Member

Summary

  • Add _capture_http_async() / capture_surface_http() / capture_surface_http_sync() using mcp.client.streamable_http.streamable_http_client (already available in the MCP SDK)
  • Extend CapturedSurface and ServerIdentity with optional url: str | None = None field — fully backward-compatible (old locks missing url parse cleanly)
  • Update _server_identity() in lockfile.py to hash {"url": url} as command_digest for HTTP-transport pins
  • Route check_core.run_check_full() through HTTP capture when url kwarg is set
  • Add --url option to pin and check CLI commands (mutually exclusive with positional server-cmd)
  • 6 new tests: async capture with mocked streamable_http_client, protocol version capture, tools/resources/prompts round-trip, connection error → CaptureError, timeout → CaptureError, sync wrapper

Notes

  • guard HTTP proxy (run an HTTP server as a proxy) is out of scope for this PR — it requires a local HTTP server which is a distinct architectural piece. Tracked separately.
  • MCP SDK ≥1.26.0 is required (already a project dep via mcp>=1.27.2)

Test plan

  • make test → 540 passed, 1 skipped
  • All 6 new tests pass (including async error and timeout paths)
  • Existing lock tests and drift tests unaffected
  • Backward compatibility: existing warden.lock files (no url field) still validate

Closes DSE-57 / GitHub issue #9

…FIL-DNS-SSRF, #11)

Closes the bypass where WRD-RES-EXFIL-IP-LITERAL could not fire because the
tools/call result contained a DNS hostname (e.g. 169.254.169.254.nip.io) rather
than a raw IP literal.

New rule WRD-RES-EXFIL-DNS-SSRF: guard resolves URL hostnames from result text at
runtime via concurrent.futures.ThreadPoolExecutor (bounded 1 s, fail-open) and
error-replaces when any resolved IP falls in SSRF_NETWORKS (link-local, loopback,
RFC1918, IPv6 ULA/link-local/loopback). Opt-out via --no-block-exfil-dns-ssrf or
--no-block-deterministic. Offline inspect command unchanged.

Files: res_dns.py (new), res_catalog.py, result_inspection.py, guard_loop.py,
guard_result.py, cli_guard.py, tests/test_res_dns.py (19 new), test_guard_posture.py
(+4). All 530 tests pass.

Closes DSE-58.
…workflow

The repo transferred to DataScience-EngineeringExperts but the
--certificate-identity flag still referenced the personal account
(ernestprovo23). Fulcio mints a cert whose SAN reflects the actual
org, so the exact-string equality check in sigstore 4.3.0 failed.
Updated both the verify and negative-proof steps.

Fixes Sigstore sign+verify (live) failure on PR #73.
…-57)

Add streamable_http_client path to capture.py (_capture_http_async,
capture_surface_http, capture_surface_http_sync). Extend CapturedSurface
and ServerIdentity with optional url field (backward-compat, defaults None).
Update _server_identity() to hash the URL when set. Route check_core
run_check_full() and cli pin/check commands through HTTP capture when
--url is provided; mutually exclusive with positional server-cmd.
6 new tests (async + sync, mocked transport, error paths).
@ernestprovo23 ernestprovo23 merged commit 76f496d into main Jun 29, 2026
9 checks passed
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