In gRPC, what is the difference between channel credentials and call credentials, and why should call credentials only travel over a secured channel?
answer
- two lifetimes, two objects
- connection security versus per-request identity
- the token rides as request metadata
- composite: TLS plus token on every call
- headers are only as private as the channel
basics
~20 sChannel credentials, such as TLS, secure the whole connection and are set when the channel is created. Call credentials add authentication metadata, like an access token, to each call: a plain header that anyone on the path can read and replay without TLS.
solid answer
~50 s**Channel credentials** belong to the channel: typically TLS, which authenticates the server and encrypts everything, optionally with a client certificate for mutual TLS. They are set when the channel is created and apply to every call over it. **Call credentials** belong to a call: they produce **metadata** for the request headers, most often an access token under the `authorization` key, and they are consulted per call, so a refreshed token or a different principal needs no new connection. The two compose: TLS channel credentials plus token call credentials give a channel that sends the token on every call. Since that token is just a header, a channel without transport security exposes it to anyone watching, who can replay it. Many implementations refuse to send call credentials on an insecure channel, but that is an implementation safeguard, not a protocol rule.
code
http · 8 lines:method POST
:scheme https
:path /payouts.v1.PayoutService/ApprovePayout
:authority payouts.example.com
te: trailers
grpc-timeout: 2S
content-type: application/grpc+proto
authorization: Bearer 7Hq2xKd91mZpLw0go deeper
Recall the split: channel credentials secure the connection, call credentials attach an identity such as an access token to each call. Know that the token travels as request metadata.
Explain the lifetimes: channel credentials are fixed at channel creation, call credentials are consulted per call and emit metadata. Show how composite credentials give TLS plus a token on every call.
Show why a token on an insecure channel is replayable, and separate the implementation's refusal to send it from what the protocol itself requires. Place mutual TLS and tokens at their right layers.
Weigh which identity belongs where: workload identity on the connection through mutual TLS, user or scoped identity per call through tokens, and the cost of rotating each without disrupting long-lived channels.
## Two kinds of credentials, two jobs gRPC separates authentication into two objects with different lifetimes. **Channel credentials** are attached to a **channel** — the client's long-lived handle to a server, carried over one or more HTTP/2 connections. **Call credentials** are attached to a **call** — a single RPC. The split exists because the two jobs change at different rates: how the connection is secured is decided once, while *who is calling* can differ from one request to the next. | | channel credentials | call credentials | |---|---|---| | attached to | the channel | an individual call, or every call on a channel | | typical content | TLS settings: trusted roots, optionally a client certificate | an access token or another authentication value | | what they produce | an encrypted, server-authenticated connection | **metadata** sent as request headers on the call | | when they change | when a new channel is created | on any call, without touching the connection | ## Channel credentials: securing the connection The usual channel credential is **TLS**. It does two things for every byte that crosses the connection: - it **authenticates the server**, so the client knows it is talking to the host it meant to reach; - it **encrypts** everything exchanged — request headers, metadata, messages and trailers alike. With **mutual TLS** the client also presents a certificate, so the server learns which client *peer* opened the connection. That identity belongs to the connection: every call multiplexed over it inherits the same peer. Channel credentials are supplied when the channel is created. Changing them — new trusted roots, a different client certificate — means building a new channel, not adjusting a call. The opposite choice also exists: a channel with **no transport security**. Its requests carry `:scheme` `http` rather than `https`, and every header travels in the clear. ## Call credentials: attaching identity to each call A call credential is a source of **authentication metadata**. When a call starts, it supplies key-value pairs that are added to the call's request headers. The common case is an access token sent under the **`authorization`** metadata key: ```http authorization: Bearer <access token> ``` Nothing restricts it to that key. A call credential may set any metadata key the server expects — a custom ticket header, for instance — as long as the key follows the ordinary metadata rules. Because the credential is consulted per call, its output can differ between calls on the same channel. A token that is refreshed every hour is simply picked up by the next call; the TLS connection underneath is untouched. ## Composite credentials The two kinds are designed to be combined: 1. **Channel + call → composite channel credentials.** Combining TLS channel credentials with a token call credential produces a new channel credential. A channel built from it is secured by TLS *and* sends the token's metadata on **every call** made on it. 2. **Call + call → composite call credentials.** Two call credentials can be composed into one; a call using it sends the authentication data of both. 3. **Per-call override.** A call credential can also be supplied for one individual RPC, so a single channel can serve calls made on behalf of different principals. The result is a clean division of labour: the channel answers *"is this connection private and is the server who it claims to be?"*, and the call answers *"who is making this request?"* ## Why a token must not ride an unsecured channel Call credentials are, on the wire, nothing more than **request metadata** — HTTP/2 header fields. A bearer-style token grants access to whoever presents it. Send it over a channel without transport security and: - anyone who can observe the traffic can **read the token** from the request headers; - having read it, they can **replay it** on their own calls until it expires; - the client also has **no server authentication**, so it may be handing the token to an impostor in the first place. This is why the gRPC authentication guidance pairs token-based mechanisms with TLS on the channel. Many gRPC implementations go further and **refuse to send call credentials over an insecure channel** at all. Treat that refusal as an **implementation's safety check**, not a rule of the wire protocol: the protocol's header grammar has no clause that rejects an `authorization` key on an `http`-scheme request. The protection comes from configuring the channel correctly, not from the protocol stopping you. ## The judgment in practice - Use **channel credentials** for what is true of the whole connection: server identity, encryption, and — with mutual TLS — the calling workload's identity. - Use **call credentials** for what can vary per request: the end user, a scoped token, a credential that expires and is refreshed. - Use **both** when a service calls another on a user's behalf: mutual TLS proves *which service* connected, and the token in metadata says *whose request* it is. - Never answer "the token is in a header, so it is protected" — headers are protected only by the channel they travel on.
- A gRPC client already uses mutual TLS. Why would it still attach call credentials?Mutual TLS identifies the **peer that opened the connection**, once, for every call on it. Call credentials identify the principal **per call**. When a service calls another on a user's behalf, the certificate says which service connected and the token in metadata says whose request this is, and the token can change between calls without a new connection.
- A long-lived gRPC channel uses an access token that expires hourly. Must the channel be rebuilt when the token is refreshed?No. Call credentials are consulted for each call, so the credential source returns the refreshed token and the next call carries it in its `authorization` metadata. The channel and its TLS connection stay as they are; only channel credentials are tied to the channel's creation.
- Can a single gRPC call carry two call credentials at once?Yes. Call credentials can be composed into a composite call credential, and a call using it sends the authentication metadata of both, for example an access token plus a separate custom ticket key.
Channel credentials are the armoured van: arranged once, and everything inside travels protected. Call credentials are the signed authorisation slip on each parcel, saying who sent it. Put the same slip in an open cart and anyone on the road can copy it.
saying these in an interview costs you the question
- Call credentials are sent once when the connection opens and then remembered.
- Switching a call's access token means tearing down and recreating the channel.
- The gRPC wire protocol itself forbids an authorization header on a plaintext connection.
- A token in metadata is safe without TLS because HTTP/2 headers are binary-encoded.
- Composing call credentials onto a channel replaces its TLS settings with the token.