Identity & attribution
"Which agent called this tool?" is a question the logs answer on their own. "Whose agent, and on behalf of which user?" is not. That answer lives inside the credential the caller presented, in a shape only you know. Identity configuration is how you tell Elva where to find it.
Once configured, the client and user identifiers appear on every tool-call log entry and on every webhook delivery, so MCP traffic can be attributed the same way the rest of your platform is.
Two identifiers, declared separately
Each MCP server configures two sources independently, because they answer different questions and are rarely found in the same place.
Client ID
The calling application. Which of your customers, partners, or internal services is behind this connection.
User ID
The person the call is for, when there is one. Often absent, for reasons worth understanding before you rely on it.
Each can be drawn from one of several places:
oauth_client_id: the OAuth client_id the caller authenticated with. Client ID only.scope: a named capture group from a pattern you supply, matched against the OAuth scope string.token_claim: a claim you name, read from the caller's JWT.header: a request header you nominate.none: nothing is recorded.
Every source is declared, never guessed. Elva does not try to infer the shape of your scope strings or tokens. If no source is configured the identifier stays empty rather than being filled with something plausible but wrong, because an attribution you cannot trust is worse than none at all.
Why your user IDs may be empty
This is the one result that surprises people, and it is a property of OAuth rather than of Elva. Under the client_credentials grant there is no end user. The scope is fixed when the connection is established and sent unchanged on every later call, so anything embedded in it identifies a connection, not a person. A thousand employees behind one service account produce exactly one identifier.
Genuine per-user attribution therefore needs one of two things:
- One connection per user, so that the credential itself is the identity.
- A per-request header, where your client passes the acting user on each call and you point the User ID source at that header. This is why
headeris an available source rather than an afterthought.
Where to go next
On this page
- Identity & attribution