mTLS and propagating identity
An encrypted channel proves the server to the client, but it does not tell the server who called; making both sides present certificates gives each a verified workload identity, and that original caller's identity must ride every hop — because no hop shares memory with the one that started the call.
We can now move bytes fast, fairly, and resiliently — but we've never asked who is on the other end of the wire; and because no hop shares memory with the one before it, each hop must carry both a proof of who it is AND the original caller's identity forward, exactly the way it carried the deadline.
Scene 11
mTLS and propagating identity
- Watch
- Try it
- Predict
- Capture
First, separate two ideas people constantly conflate. Encrypting the wire — what HTTPS does — scrambles the bytes so an eavesdropper can't read them, and it proves the SERVER is who it claims (your browser checks the server's certificate). That's the padlock. A per-call token is a different thing entirely: a credential placed in the call's metadata that says 'this specific call is allowed.' That's the badge. The diagram draws them as two distinct objects on purpose. Now the gap: under plain TLS the badge and padlock prove the server to the client, but the server has no proof of who the CLIENT is — it sees only an IP address. When we make both sides present a certificate, each peer gets a cryptographically verified name we'll call its workload identity — a stable proof like prod/frontend of which service this is, not just where it's connecting from. Watch the slider move from TLS to that mutual-cert mode.
Highlighted lines are the ones running in the diagram right now.
def establish(server_addr):conn = tls_handshake(server_addr)# server's cert always verified by the clientconn.server_id = verify_cert(conn.server_cert)if mutual_tls:# client ALSO presents a cert: both sides namedpresent_cert(conn, self.cert) # e.g. SPIFFE/SVIDconn.client_id = self.workload_identityelse:conn.client_id = None # caller is just a peer IPreturn conn
def call(conn, method, req, ctx):md = {}md['authorization'] = mint_token() # per-call badgeif propagate_identity:# carry who STARTED the call, like grpc-timeout doesmd['origin-principal'] = ctx.origin or self.id# HTTP/2 HEADERS frame carries the metadatareturn conn.invoke(method, req, metadata=md)
def authorize(conn, md, action):caller = conn.client_id # verified by mTLSorigin = md.get('origin-principal')if origin is not None:# authorize on who STARTED the callreturn policy.allow(origin, action)# no origin forwarded: fall back to immediate callerreturn policy.allow(caller, action)
Where this sits in Build a gRPC-style RPC framework
Scene 11 of 14, in the Secure & ship act — mTLS identity, then configure the whole stack.. TLS encrypts and proves the server; mTLS proves both peers with a workload identity. The original caller's identity must propagate across hops, just like a deadline.
Up next. Codec, transport, deadlines, retries, balancing, security — every layer was a forced choice with a trade-off; the last move is to put them all on one canvas and pick a coherent posture for a real workload, defending each choice with the scene that taught it.
All 14 scenes in Build a gRPC-style RPC framework · Every curriculum