feat(runtime): enforce Gate-mediated ingress and add relay route#13
Conversation
Add Gate-mediation provenance enforcement so worker nodes only accept packets that were resolved and routed by the Gate, and reject external or peer traffic that targets a node directly. - transport: add RoutingProvenance.route_kind (external_ingress|gate_relay) with validation; reflect in contracts spec + JSON schema - runtime: add inbound_policy validators (validate_execute_ingress_packet, validate_relay_ingress_packet) and export them - runtime/app: enforce gate-only ingress on /v1/execute and add /v1/relay for Gate-authored relay dispatch - runtime/config: add enforce_gate_only_ingress + relay route toggles - runtime/execution: thread execution_mode through execution path - runtime/preflight + observability: align with new ingress posture - tests: gate-only ingress, relay route, and integration coverage for external-direct-blocked and gate-relay-allowed flows Co-authored-by: Cursor <cursoragent@cursor.com>
ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (17)
📝 WalkthroughWalkthroughThe PR adds a ChangesGate Ingress Enforcement and Relay Route
Sequence Diagram(s)sequenceDiagram
participant ExternalClient
participant GateNode
participant NodeApp
participant validate_execute_ingress_packet
participant execute_transport_packet
rect rgba(255, 100, 100, 0.5)
Note over ExternalClient,NodeApp: Blocked: direct external ingress
ExternalClient->>NodeApp: POST /v1/execute (resolved_by_gate=False)
NodeApp->>validate_execute_ingress_packet: enforce_gate_only_ingress check
validate_execute_ingress_packet-->>NodeApp: raises ValueError (not from gate)
NodeApp-->>ExternalClient: failure TransportPacket (status=failed, error=ValueError)
end
rect rgba(100, 200, 100, 0.5)
Note over GateNode,NodeApp: Allowed: gate-mediated execute ingress
GateNode->>NodeApp: POST /v1/execute (route_kind=external_ingress, resolved_by_gate=True)
NodeApp->>validate_execute_ingress_packet: enforce_gate_only_ingress check
validate_execute_ingress_packet-->>NodeApp: ok
NodeApp->>execute_transport_packet: execution_mode="execute"
execute_transport_packet-->>NodeApp: response packet
NodeApp-->>GateNode: 200 success TransportPacket
end
rect rgba(100, 150, 255, 0.5)
Note over GateNode,NodeApp: Allowed: gate relay
GateNode->>NodeApp: POST /v1/relay (route_kind=gate_relay, resolved_by_gate=True)
NodeApp->>validate_execute_ingress_packet: validate_relay_ingress_packet check
validate_execute_ingress_packet-->>NodeApp: ok
NodeApp->>execute_transport_packet: execution_mode="relay"
execute_transport_packet-->>NodeApp: response packet
NodeApp-->>GateNode: 200 success TransportPacket
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Note 🎁 Summarized by CodeRabbit FreeYour organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a new /v1/relay route and inbound policy validation to enforce gate-mediated routing and separate external ingress from internal relay traffic. Key changes include updates to the transport packet schema, configuration model, and the addition of robust integration tests. Feedback highlights a discrepancy between the updated action regex and the JSON schema, a security vulnerability where empty relay actions bypass validation, an unused execution_mode parameter, and a regression in JSON parsing error handling that could affect HTTP status codes and metrics.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88f4d53422
ℹ️ 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".
…ngress Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # src/constellation_node_sdk/runtime/app.py # src/constellation_node_sdk/runtime/config.py # src/constellation_node_sdk/runtime/execution.py # src/constellation_node_sdk/runtime/preflight.py # src/constellation_node_sdk/transport/models.py # tests/runtime/test_preflight.py
…/relay Post-merge cleanup after merging main into feat/gate-mediation-ingress: - relay(): add missing -> JSONResponse return type annotation - relay route: apply the same str()-cast + not-None guard on signing_private_key that main independently applied to /v1/execute (field is str | None; passing raw response_signing_key could be bytes) - ruff format pass on 4 files Co-authored-by: Cursor <cursoragent@cursor.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
…cute and /v1/relay The two route handlers were near-identical copies (packet parsing, route-aware signing/validation resolution, execute_transport_packet call, response/error handling), flagged by SonarCloud at 15.4% code duplication on new code (threshold 3%). Extracted the shared body into _handle_transport_request(), parameterized by execution_mode and a per-route ingress validator callback. Both routes are now thin wrappers. No behavior change; all 89 tests (83 unit + 6 integration) still pass. Co-authored-by: Cursor <cursoragent@cursor.com>
…tency, dead code) - Restore global-allowlist fallback for relay allowed_actions/allowed_packet_types (both in route validation and ingress policy call) so an empty relay_allowed_actions no longer disables action restrictions entirely (Gemini). - Add preflight check: enforce_gate_only_ingress=true now requires a verified signature on /v1/execute (and /v1/relay when enabled) outside dev_mode, since Gate-trust claims (source_node, provenance.resolved_by_gate) are otherwise caller-supplied and unauthenticated (Codex P1). - Fold execute_allowed_actions into idempotency-action validation (both the Pydantic model validator and run_preflight), so execute-only allowlists work without a legacy allowed_actions entry (Codex P2). - Restore explicit invalid_json request-parsing branch (400 + "invalid_json" metric status) that the _parse_transport_packet helper had silently dropped (Gemini). - Remove unused execution_mode parameter from execute_transport_packet (Gemini). - Sync stale regex comment in worker_node_template.py with the current action pattern (dots/underscores already allowed in schema + model) (Gemini/Codex). Note: the two "explicit vs implicit return" code-quality bot findings on the old execute/relay route bodies were already resolved by the earlier _handle_transport_request extraction (single try/except with a NoReturn raise_http_exception on every non-success path). Co-authored-by: Cursor <cursoragent@cursor.com>
…ngress Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # src/constellation_node_sdk/runtime/app.py
|



Summary
Adds Gate-mediation provenance enforcement to the node runtime so worker
nodes only accept packets resolved and routed by the Gate, and reject
external/peer traffic that targets a node directly. Also adds a Gate-authored
relay route. This is the SDK-side companion to the L9-Node-Template Gate
integration layer.
RoutingProvenance.route_kind(external_ingress|gate_relay) with validation; reflect inTRANSPORT_PACKET_SPEC.mdand the JSON schema (on top of the existing hardened schema).validate_execute_ingress_packetandvalidate_relay_ingress_packetGate-mediation validators, exported fromruntime.POST /v1/execute; addPOST /v1/relayfor Gate-authored relay dispatch.enforce_gate_only_ingress+ relay-route toggles.execution_modethrough the execution path.Test plan
python3 scripts/validate_contracts.py— all checks pass (schema parity + provenance enum constraints)PYTHONPATH=src pytest tests -q— 83 passedorigin/main; schema change is the minimalroute_kindaddition layered on the existing hardened schema (no revert of prior hardening)Made with Cursor
Summary by CodeRabbit
Release Notes
New Features
/v1/relayendpoint for gate-mediated packet routingroute_kindfield to distinguish between external client ingress and internal relay trafficImprovements