agent-substrate / agent-substrate/substrate

Support SNI-level MITM Disablement

Open
#1,574 0 comments 1 reaction 0 assignees View on GitHub
area/identity area/network kind/feature
Dominant language
Go
Stars
1.8k
Forks
316
Avg merge
2d 43m
Merged PRs (30d)
287

Description

### Problem

With `--experimental-use-sdsmint`, the egress gateway intercepts every TLS connection an actor originates: it terminates the actor's TLS, presents a leaf minted for the requested name (SNI), applies the egress policy to the decrypted request, and re-originates the request to the origin.

Interception does not work for:

1. origins whose certificate the actor pins, and
2. origins that authenticate the actor with a client certificate this gateway does not hold.

Both fail the handshake, at opposite ends. A pinning client rejects the gateway's minted leaf on the inbound leg. An origin requiring client authentication rejects the gateway on the outbound leg, because the gateway holds no credential that origin would accept — and cannot borrow the actor's, since TLS client authentication signs the handshake transcript with a private key that stays inside the actor's sandbox.

The egress gateway should stop intercepting those destinations — to relay the connection untouched, so the actor's TLS session runs end to end.

### Proposed Solution

We can introduce a new field, `tls_interception_exemptions`, to the EgressPolicy to allow users to specify a TLS interception exemption list. For every TCP connection from an actor, the egress gateway compares the SNI in the ClientHello against that list. On a match the gateway relays the connection to the origin without terminating its TLS; everything else is intercepted.

Setting `tls_interception_exemptions` in every actor manually is tedious. A default egress policy in ActorTemplate (tracked in issue [#1324](https://github.com/agent-substrate/substrate/issues/1324)) should reduce the work.

### Alternative \- Putting `tls_interception_exemptions` under EgressRule directly

EgressRule currently has three fields: `hostnames`, `ip_blocks`, and `all`. 

We could consider adding a new field under EgressRule, `TLSInterceptionExemptionRule`. The downside of this is that to get the complete TLS interception exemption list, we will need to scan through all the EgressRules in an EgressPolicy and merge all the `TLSInterceptionExemptionRules`.

### Alternative \- Putting `tls_interception_exemptions` under HostnameRule directly

`hostnameRule` looks like a good home, but the two decisions do not share an evaluation point. A hostname rule is defined to be evaluated per HTTP request, at the request checkpoint, against the request hostname (Host/:authority). Interception is decided once per connection, from the ClientHello, against the SNI — before any request exists. A single connection carries many requests, with hostname values that need not agree with each other or with the SNI, so a per-request matcher cannot source a per-connection decision. 

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.