mirror of
https://github.com/agent-substrate/substrate.git
synced 2026-10-02 03:24:42 +08:00
**BREAKING** API changes prior in preparation for GA. ~This PR has proto-only change to the EgressPolicy API. No implementation; the gateway, store contract, and e2e helpers stop compiling until the follow-up lands.~ Note: Impl is only to make ci green. Full implementation of the api is a fast follow - `EgressRule` is now a union of protocols: `http`, `https`, `tls_passthrough`. Allow-only, deny by default. - The `hostnames`, `cidrs`, and `all` rule kinds are removed. **No field numbers or names are reserved: we are pre-GA and existing policies must be recreated.** - `rules` is an **unordered set**. When more than one rule matches, precedence is decided by two criteria, in order: a pattern without a wildcard wins over one with a wildcard, then a port other than `"*"` wins over `"*"`. This applies within a protocol and across `https` and `tls_passthrough` on the same SNI. Two rules with the same pattern on the same port are rejected on write. Only the winning rule's effects apply. - `http`: cleartext HTTP, matched per request on the authority and port. Carries `effects`. - `https`: MITMed HTTPS that the gateway intercepts. Matched on SNI and port at the ClientHello, then per request on the authority. Carries `effects`. MITM is off unless a name is listed here. - `tls_passthrough`: TLS forwarded without decryption, matched once per connection on SNI and port. No effects. Implicit TLS only; STARTTLS does not match. - Protocols are told apart by what the Actor sends first, a ClientHello or an HTTP request. Anything else, or a server-first protocol, is closed. - Name fields are `host_patterns` on `http` and `https`, `sni_patterns` on `tls_passthrough`. Same wildcard grammar as before, documented once on `HTTPRule.host_patterns`. - `ports` on all three protocols are strings: a port number, or `"*"` alone for any port. `http` defaults to `["80"]` and `https` to `["443"]` when empty; `tls_passthrough` requires at least one. The port is the destination the Actor connected to. A port in a request's authority is neither matched nor dialed. Format documented once on `HTTPRule.ports`. - `inject_static_headers` is renamed to `replace_headers`, since the behavior is replacement and the name leaves room for other header operations later. The `CredentialHeaderInjection` message keeps its name. Replacement is conditional: a header is replaced only when the Actor's request already carries it, with any placeholder value. Requests without the header pass unchanged. - Unsupported in v1 rules for arbitrary TCP, non-TCP protocols. - `google/protobuf/empty.proto` import dropped; nothing uses it now. Questions - The handler is called `https`, not `mitmHttps`. Everything in an `https` block is intercepted. is that clear enough? follow-ups - align egress implementation - named CONNECT, or some way to preserve what the actor dialed. - add tcp support - hand-written validators for the new fields (`host_patterns`, `sni_patterns`, `ports`, the rule conflict check) and regenerate `zz_generated.validation.go` > It's a good idea to open an issue first for discussion. - [x] Tests pass - [x] Appropriate changes to documentation are included in the PR Fixes: #823 (there are probably more issues that i need to find)