Name trusted and untrusted metadata
List every metadata key the service reads. Client-set keys such as tenant, role, and user ID are untrusted even when sent over TLS. The gateway can verify a token and set internal context, but the service must know which upstream calls are trusted. Test a direct call from another workload in staging. If that call reaches the service, its metadata should not become an identity without verification.
Test cases and proof
| Case | Expected result | Proof to keep |
|---|---|---|
| Client sets x-tenant-id to another tenant | Ignore untrusted value | Returned object owner |
| Gateway strips token but keeps role header | Deny | Service response |
| Streaming call changes access midstream | Close or recheck per policy | Stream event log |
Synthetic example
A client sends x-tenant-id: B in gRPC metadata while its verified token belongs to A. The service should use A from the verified token. Repeat through the gateway and by calling the service directly in a controlled test network.
Evidence to keep
Capture the metadata sent by the test client and the identity the server actually used. Keep the gateway path and direct-service path separate. A direct-service denial may be caused by network policy, which is useful but does not prove the service handles spoofed metadata. Run the authorization case where the service can be reached in a controlled environment.
Streaming RPCs need a separate check. Authorization at stream start may not cover a tenant change or new message later in the stream. Send two messages with different account or tenant fields in their payload, then inspect what the service used. Initial RPC metadata stays fixed for that stream. Keep network policy and application authorization findings separate.
Keep transport and app trust separate
TLS can protect the connection from outside changes, but it does not turn a value chosen by the client into a trusted role. A gateway may verify a token and add internal identity metadata. The service must distinguish that value from a client field with the same name. Strip or overwrite identity-like keys at the edge, and check direct service access under the network policy. For a long-lived stream, decide whether a revoked role ends the stream or is checked before each sensitive message.
Related reading
Why these checks matter
The gRPC guide says metadata carries key-value information attached to calls. OWASP’s authorization guide requires a decision for each request. Ordinary metadata supplied by a client is input, so a tenant or role value in it must be tied to verified identity before the service uses it.
Keep stream metadata separate from message fields
gRPC request metadata is sent before the RPC’s initial message. It does not change for each message in one stream. The server sends trailing metadata when the RPC ends. If your stream carries a tenant or account ID in each message, that value is message payload, not fresh metadata. Test that payload against the principal established at stream start.
Synthetic stream uses A’s token and initial x-tenant-id: B. Expect the service to derive A from verified identity or deny the conflicting claim. Send message one for account A1 and message two for account B1 on the same stream. Message two must be denied under A’s rights. Start a separate RPC to test a changed metadata header; that is a new call.
Handle duplicate claims and revocation
Use the real gateway and an authorized direct-service staging path. Try duplicate identity-like metadata values as well as one forged value. Define whether conflicts are rejected or overwritten by the trusted gateway; first-value parsing in one component and last-value parsing in another can produce different identities. Do not invent a client-controlled reserved header as an authentication method.
Revoke A during the stream, then send another sensitive message. Measure the documented recheck or close interval. Deadline and retry tests must keep the same verified caller and business operation ID. Capture metadata keys without secrets, initial principal, message account ID, decision time, and gRPC status. The gRPC metadata guide defines header timing; the per-message gate is application authorization.