Designing Connection Authentication for C1 BridgeAnnouncing C1 Transform 2026Announcing C1 Transform 2026Request to join
Sign inBook a demo
c1@engineering ~<br>$ cd /engineering && cat ./designing-connection-authentication-for-c1-bridge.md<br>InfrastructureSecurityArchitecture<br>> Designing Connection Authentication for C1 Bridge<br>Julián González<br>|2026-08-11|5 min read<br>share:summarize:
width:
C1 Bridge extends C1's AI Access Management features to MCP servers running inside private networks, without exposing those servers to the public internet. The launch post describes the product well, but in short, Bridge is designed to be as lightweight and easy to operate as possible, with minimal configuration required. It's infrastructure in a distributed system. Like all infrastructure, you probably won't notice it if C1 does its job well.
That doesn't make it simple internally. As one software pioneer famously put:
A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable.<br>— Leslie Lamport, 1987 email, via Microsoft Research
A failure of a computer that you didn't even know existed tends to be something that gets you in trouble. Here, I want to shine a light on one technical challenge we solved while building Bridge: connection re-authentication and revocation.
Security is a hard problem™. In Bridge, we maintain long-lived TLS connections to software running on-prem. There are several reasonable ways to authenticate those connections initially but nothing blog-worthy. The hard question is what comes next. A Bridge connection crosses a potentially sensitive trust boundary. Asking the on-prem Bridge client to periodically re-authenticate is prudent and gives customers a way to revoke their trust in a Bridge at any time, for any reason. That trust must not be a static concept.
Connection (re)authentication: mTLS?#
Initially, we thought about using mTLS for connection authentication. The potential setup at least sounds simple enough: our on-prem Bridge client would acquire a certificate from C1 during setup, then present it to establish a connection.
The certificate check itself is not a huge problem. In fact, certificates are made to be checked cheaply and quickly, and their expiration fields give us dynamic control over the deadline for re-authentication. This is a great property when dealing with MCP servers: because traffic can be very intermittent, doing authentication at low-traffic times is a special kind of blessing.
For connection re-authentication, however, we still need a reliable way to force that repeated certificate check and tear down a connection that does not complete one. This is not fatal, but this does complicate the design.
Alas, certificates suffer from other issues. Certificate revocation is, let's say, fraught with peril. To readers whose eyes have already widened thinking about certificate revocation lists - I hear you, don't worry! We can mitigate some of this complexity by minting short-lived certificates. Then, with a well-synchronized clock, expiration bounds the revocation window for us.
Unfortunately, this trades away most of the flexibility about when to re-authenticate, which is what made this solution attractive in the first place. When a shorter certificate lifetime makes the system safer but more fragile, we've arrived at an undesirable trade-off between security and functionality. This is suddenly not as easy as we thought.
Tokens, Tokens Everywhere#
After ruling out mTLS, we next considered tokens. There are a variety of common flavors of tokens on the web, and several could fit our purpose: opaque bearer tokens, JWTs, or even macaroons if we wanted to encode finer-grained authorization. C1 already uses token-based authentication for a variety of purposes, so this approach also benefits from being relatively easy to implement.
Alas, the re-authentication question is not really answered by choosing tokens. One conceptually simple approach would be to send a token with every request on the bridge: without a valid token, the request is rejected. This might look like:
[token][request A] [token][request B] [token][request C]<br>| | |<br>validate validate validate<br>| | |<br>work work work
This gives tight control over what is sent over the bridge, at the wire cost of a token riding along with every data frame. While that may not feel expensive, tokens (like JWTs) can easily be hundreds of bytes long. These tokens are also often only minimally compressible. For small MCP tool calls, this can dramatically amplify the cost of making a request.
Another issue is conflating authentication with the ongoing data path. If a request is paired with a token, validation of that token must happen before the request is processed. This can also add work that must be performed before processing other requests. Since the bridge runs over TCP, bytes are delivered in order, so adding a token just adds overhead to every...