Skip to content

feat(reborn): add shared runtime HTTP egress#3098

Merged
serrrfirat merged 7 commits into
reborn-integrationfrom
issue-3085-runtime-egress
Apr 30, 2026
Merged

feat(reborn): add shared runtime HTTP egress#3098
serrrfirat merged 7 commits into
reborn-integrationfrom
issue-3085-runtime-egress

Conversation

@zmanian
Copy link
Copy Markdown
Collaborator

@zmanian zmanian commented Apr 29, 2026

Summary

  • Add shared RuntimeHttpEgress contracts in ironclaw_host_api and HostHttpEgressService in ironclaw_host_runtime.
  • Extend ironclaw_network from policy-only substrate to host-mediated HTTP egress with URL parsing, policy checks, DNS/private-IP protection, redirect-disabled transport, streaming response limits, and separate request/response byte accounting.
  • Add thin WASM, Script, and MCP runtime HTTP adapters; fail closed for external stdio MCP process egress until process controls land.
  • Add runtime-network ratchet tests, caller-level WASM/non-WASM coverage, encoded credential redaction coverage, and Reborn docs/WIT-plan updates.

Review notes

Verification

  • cargo test -p ironclaw_network
  • cargo test -p ironclaw_host_runtime
  • cargo test -p ironclaw_host_api
  • cargo test -p ironclaw_scripts -p ironclaw_mcp
  • cargo test -p ironclaw_wasm
  • cargo test -p ironclaw_architecture
  • cargo clippy -p ironclaw_host_api -p ironclaw_network -p ironclaw_host_runtime -p ironclaw_scripts -p ironclaw_mcp -p ironclaw_wasm -p ironclaw_architecture --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • git diff --check

@github-actions github-actions Bot added size: XL 500+ changed lines risk: medium Business logic, config, or moderate-risk modules scope: docs Documentation scope: dependencies Dependency updates contributor: core 20+ merged PRs labels Apr 29, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several core crates for the 'Reborn' architecture, including ironclaw_network for network policy and HTTP transport, ironclaw_secrets for scoped secret leasing, and a hardened ironclaw_wasm runtime. It also establishes a shared runtime HTTP egress service in ironclaw_host_runtime and updates the MCP runtime to utilize these new boundaries. Feedback focuses on improving error semantics in the MCP crate by using specific variants for unsupported transports and simplifying a redundant timeout check within the WASM host import thread limiter.

Comment thread crates/ironclaw_mcp/src/lib.rs
Comment thread crates/ironclaw_wasm/src/imports.rs Outdated
@henrypark133
Copy link
Copy Markdown
Collaborator

One test gap I would close before this lands: the host-runtime egress tests prove lease consumption and redaction, but they should also assert that the actual outbound NetworkHttpRequest receives the injected credential.

Suggested coverage: use the existing recording network around HostHttpEgressService, store api-token = sk-test-secret under the same ResourceScope, execute a RuntimeHttpEgressRequest with RuntimeCredentialInjection { handle: api-token, target: Header { name: "authorization", prefix: Some("Bearer ") }, required: true }, then assert the recorded request headers contain authorization: Bearer sk-test-secret. I would also keep/extend the negative cases so a missing required secret fails before network.execute, and query-param injection is verified against the recorded URL with raw and URL-encoded secret values redacted from errors.

That gives us caller-level proof that the external call receives the leased secret, not just helper-level proof that a lease was fetched and later redacted.

@henrypark133
Copy link
Copy Markdown
Collaborator

Core authority-boundary question for this slice: where is the decision made that a given external HTTP call should receive a given RuntimeCredentialInjection?

The host-runtime path looks like it can safely lease, consume, inject, and redact a requested secret. What I want to verify is that credential_injections is host-derived from an approved capability/obligation, not runtime/plugin-supplied authority. In other words, runtime code should be able to say "I want to call this URL", but it should not be able to arbitrarily say "attach secret handle X to this URL/header/query param".

The invariant I would expect before SecretStore::lease_once is called:

  1. The extension/capability declared the secret handle.
  2. The caller was authorized/approved to use that secret.
  3. The outbound URL matches the secret or capability allowed destination/pattern.
  4. The injection shape is host-approved, not runtime-invented.
  5. The final request still passes the network policy boundary.

If that policy source is intentionally out of scope for this PR, can we document the expected upstream owner/contract so RuntimeCredentialInjection does not become an authority-bearing runtime input by accident?

@zmanian
Copy link
Copy Markdown
Collaborator Author

zmanian commented Apr 30, 2026

Addressed the review comments in ef4f2de.

  • Added caller-level host-runtime coverage that the outbound NetworkHttpRequest receives authorization: Bearer sk-test-secret.
  • Added a missing-required credential test that fails before network.execute.
  • Extended query-param credential coverage to assert the recorded URL and verify both raw and URL-encoded secret values are redacted from errors.
  • Documented that RuntimeCredentialInjection is an authority-bearing host-derived plan, not runtime/plugin-supplied authority, in the host API docs and Reborn secrets contract.

@zmanian zmanian marked this pull request as ready for review April 30, 2026 03:58
Copy link
Copy Markdown
Collaborator

@henrypark133 henrypark133 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: hold on runtime egress boundary

The overall direction is strong: the PR creates a clearer split where ironclaw_network owns URL/DNS/private-IP/transport enforcement, ironclaw_secrets owns scoped one-shot lease mechanics, and ironclaw_host_runtime composes the two for runtime HTTP egress.

What looks good:

  • The low-level ownership boundaries are mostly clean and backed by crate boundary tests.
  • Focused local tests pass for the new runtime, network, secrets, script, MCP, and WASM paths.
  • MCP stdio remains fail-closed until process-level egress controls exist, which is the right default.

Concerning: credential-injection authority boundary is still unresolved

I left a separate thread asking where the decision is made that a specific external HTTP call should receive a specific RuntimeCredentialInjection. The host-runtime path can safely lease, consume, inject, and redact a requested secret, but we need the upstream contract that proves the injection request is host-derived from an approved capability/obligation rather than invented by runtime/plugin code.

Before this lands, I would expect the contract to make clear that secret injection only happens after the host verifies the capability declared the secret, the caller was authorized/approved to use it, the outbound URL matches the allowed destination/pattern, the injection shape is host-approved, and the final request still passes network policy.

Concerning: host-runtime injection test should assert the actual outbound request

I also left a separate test-gap comment. The current host-runtime egress tests prove lease consumption and redaction, but they should also assert that the recorded outbound NetworkHttpRequest contains the injected header/query param. That gives caller-level proof that the external request receives the leased secret, not only helper-level proof that a lease was fetched.

Low-priority notes:

  • docs/reborn/contracts/network.md says response body limiting is a non-goal, but the code and tests implement response_body_limit. That non-goal should be corrected.
  • git diff --check origin/reborn-integration...HEAD currently fails on crates/ironclaw_wasm/src/constants.rs:25 due a blank line at EOF.
  • The PR is draft, merge-conflicting, and currently only has lightweight scope/classify checks, so I would hold until it has meaningful CI after conflict resolution.

Local verification:

  • Passed: cargo test -p ironclaw_host_runtime -p ironclaw_network -p ironclaw_secrets -p ironclaw_scripts -p ironclaw_mcp -p ironclaw_wasm
  • Passed: cargo test -p ironclaw_architecture reborn_runtime_http_egress_has_single_network_boundary
  • Failed: git diff --check origin/reborn-integration...HEAD

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ef4f2dea1e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/ironclaw_network/src/lib.rs Outdated
Comment thread crates/ironclaw_network/src/lib.rs
@zmanian
Copy link
Copy Markdown
Collaborator Author

zmanian commented Apr 30, 2026

Addressed the latest review follow-ups in 73a7447.

  • Preserved the full vetted resolved IP set through NetworkTransportRequest and pass it to reqwest with resolve_to_addrs for connector-level fallback.
  • Rejected caller-provided Host headers before transport so virtual-host routing cannot diverge from the URL host policy validated.
  • Updated the network contract docs to remove the stale response-body-limit non-goal and document the DNS fallback / Host-header behavior.
  • Removed the constants.rs trailing blank line; git diff --check origin/reborn-integration...HEAD is now clean.

The earlier credential-injection authority boundary and outbound-injection test concerns are covered by ef4f2de and remain present after the merge-resolution commit.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a shared, host-mediated HTTP egress path for Reborn runtimes, with common contracts in ironclaw_host_api, a composed implementation in ironclaw_host_runtime, and runtime-lane adapters/tests to ensure all outbound HTTP is routed through a single enforced boundary.

Changes:

  • Add RuntimeHttpEgress contracts to ironclaw_host_api and implement HostHttpEgressService in ironclaw_host_runtime (composing secrets + network).
  • Extend ironclaw_network to include host-mediated HTTP egress (URL parsing, DNS resolution, private-IP denial, redirect-disabled transport, response streaming limits, and request/response byte accounting).
  • Add WASM/Script/MCP thin adapters and contract tests, plus architecture ratchets to prevent direct HTTP/DNS usage outside the boundary.

Reviewed changes

Copilot reviewed 40 out of 41 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
docs/reborn/contracts/secrets.md Updates secrets contract text to reflect host-runtime injection composition responsibilities.
docs/reborn/contracts/network.md Updates network contract to include HTTP egress boundary behavior and test expectations.
docs/reborn/README.md Adds pointers to new/expanded Reborn crates (host_runtime, network, secrets, wasm, scripts, mcp).
docs/plans/2026-04-29-reborn-wasm-wit-compatibility.md Adds a detailed WIT-compatibility plan aligned with shared egress/secrets boundaries.
crates/ironclaw_host_api/src/lib.rs Exposes new shared HTTP egress contract module.
crates/ironclaw_host_api/src/http.rs Adds RuntimeHttpEgress* request/response/errors and credential injection plan types.
crates/ironclaw_host_runtime/src/lib.rs Implements shared host egress service composing ironclaw_network + ironclaw_secrets with redaction.
crates/ironclaw_network/src/lib.rs Adds network-owned HTTP egress types, DNS resolver, policy wrapper, and reqwest-based transport.
crates/ironclaw_network/Cargo.toml Adds reqwest + url dependencies for transport and parsing.
crates/ironclaw_wasm/src/* + tests/* Adds WASM runtime substrate + host import plumbing + contract tests, including HTTP adapter wiring.
crates/ironclaw_scripts/src/lib.rs + tests/script_http_adapter_contract.rs Adds Script HTTP adapter that delegates to shared runtime egress.
crates/ironclaw_mcp/src/lib.rs + tests/mcp_adapter_contract.rs Adds MCP HTTP adapter and fails closed for external stdio transport until process controls exist.
crates/ironclaw_architecture/tests/reborn_dependency_boundaries.rs Adds ratchet test to forbid direct reqwest/DNS/SSRF helpers in runtime crates.
Cargo.toml / Cargo.lock Wires new crates into the workspace and lockfile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/ironclaw_network/src/lib.rs Outdated
Comment thread crates/ironclaw_wasm/src/imports.rs Outdated
Comment thread crates/ironclaw_wasm/src/support.rs Outdated
Comment thread crates/ironclaw_network/src/lib.rs Outdated
Comment thread crates/ironclaw_network/src/lib.rs
@serrrfirat serrrfirat force-pushed the issue-3085-runtime-egress branch from 72cf5a1 to 3b6fdd8 Compare April 30, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: medium Business logic, config, or moderate-risk modules scope: ci CI/CD workflows scope: dependencies Dependency updates scope: docs Documentation size: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants