[AAASM-4655] 🔒 (core): Enforce non-loopback TLS guard on register endpoint#259
Conversation
resolve_gateway_grpc_endpoint derived a plaintext http:// register target for a non-loopback gateway with no refusal, unlike the op-control path (require_secure_grpc_target) and the go-sdk. The Register call carries the agent identity, so mirror op-control's non-loopback→TLS contract: refuse a derived plaintext endpoint to a remote host unless allow_insecure is set. https:// and loopback still pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMnPRm9T3fdrS4uNYXkzg6
Cover resolve_gateway_grpc_endpoint's non-loopback TLS guard: loopback plaintext allowed, non-loopback plaintext allowed with allow_insecure, and non-loopback plaintext without opt-in raises the same secure-transport error op_control raises via require_secure_grpc_target. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMnPRm9T3fdrS4uNYXkzg6
The AAASM-4655 register-endpoint TLS guard fail-closes a plaintext http:// register channel to a non-loopback host. Existing tests that used a non-loopback plaintext gateway as an incidental fixture now hit the guard. Preserve each test's intent: switch remote-host fixtures to https:// (still a non-loopback host, so the host→gRPC-port substitution stays exercised), and assert the plaintext-warning test now fail-closes after its warning fires. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMnPRm9T3fdrS4uNYXkzg6
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
🤖 Claude Code — PR review (post CI-fix)Verdict: ✅ Ready to approve & merge (fail-closed security fix). 1. CI: Now green — 19 SUCCESS / 7 SKIPPED / 0 FAILURE ( 2. Side-effect caught & corrected: the fail-closed guard initially broke 21 existing unit tests (init_registration/spawn_context/assembly) whose fixtures used a non-loopback plaintext gateway — they began raising 3. Scope vs AAASM-4655: covered — register endpoint resolution now refuses non-loopback plaintext by default (parity with op-control + go-sdk), regression test added. Production code unchanged at the call site — default stays fail-closed; zero-config loopback ( 4. Design note (for a human decision, non-blocking): 5. Front-end: N/A. No changes requested. |



Description
resolve_gateway_grpc_endpoint(the agent-registration :50051 endpoint resolver used by the register path inassembly.py) derived a plaintexthttp://remotehost:50051register target for a non-loopback gateway with no refusal — unlike the op-control path, which callsrequire_secure_grpc_target(transport_security.py), and unlike the go-sdk, which enforces non-loopback→TLS for all targets. TheRegistercall carries the agent identity, so it must not travel unencrypted to a remote host by default.This change applies the existing
require_secure_grpc_targethelper to the derived endpoint branch, honouring the sameallow_insecureopt-out op-control uses:localhost/127.0.0.1/::1) plaintext — still allowed (documented dev default).https://(TLS) non-loopback — still allowed (carries its own TLS).http://(plaintext) non-loopback — refused with the sameValueErrorop-control raises, unlessallow_insecure=Trueis passed.AA_GATEWAY_ENDPOINTexplicit operator override is honoured verbatim (thechannel_factoryescape-hatch analogue), unchanged.Reuses the existing helper — no TLS logic is reimplemented. Defense-in-depth / TLS parity with the op-control path and the go-sdk.
Type of Change
Breaking Changes
Does this PR introduce any breaking changes?
Registration against a non-loopback plaintext
http://gateway now raisesValueErrorinstead of silently registering over an unencrypted channel. This is the intended security fix — use anhttps://endpoint, or passallow_insecure=Trueto opt in (loopback dev / trusted-network only). Loopback andhttps://behaviour is unchanged.Related Issues
Testing
Describe the testing performed for this PR:
New
TestResolveGatewayGrpcEndpointTlsGuardcovers: loopback plaintext allowed, non-loopback plaintext allowed withallow_insecure=True, and non-loopback plaintext without opt-in raising the same secure-transport error op-control raises. The existingtest_derives_host_and_substitutes_grpc_portwas updated to opt in for its non-loopback plaintext case (port-substitution behaviour unchanged). Local:ruff check,ruff format,mypy agent_assembly(only pre-existing native_core/grpc-stub baseline errors), and the new/affected tests all pass.Checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01HMnPRm9T3fdrS4uNYXkzg6