feat: choose the shared credential an agent key uses per server

Merged
DA
3d ago
+4875-146

AIM-596 (5 of 5)

Stacked on #8039.

Summary

  • keys.create takes auth_client_choices for agent keys: one {mcp_server_id, auth_client_id?} per server.
    • Each must be a shared credential (service account or static credential) the server offers enabled, or no-auth on a server that needs none.
    • Pass-through credentials are refused and not listed: the agent gateway does not forward the caller's headers to its servers, so the key could not authenticate there.
    • Personal and identity-provider clients are refused: an agent reaches a person's connection only while acting for them.
    • Choices are recorded in the key's creation transaction under a new api_key credential kind keyed by the key's row id. Ordinary keys refuse choices.
  • keys.rotate copies the rotated key's choices to its replacement.
  • Serving (only where upstream_auth_enforced is on):
    • On a direct server the key has a choice for, the key goes through the typed resolver with that choice: the mandatory mcp:auth check, client headers, and service-account tokens. This includes private servers without a sign-in issuer, where the key is resolved after it authenticates.
    • On the agent gateway, members the key has a choice for are served the same way (memberChoices.onlyChosen).
    • Servers the key has no choice for keep today's path, so existing keys and their attachments are unaffected.
  • ResolveAuthClientAccessTokens: a self-owned (service-account) registration is resolved without attachments for any caller, since its token belongs to nobody. People's connections still go through attachments.
  • authClients.listMcpServerChoices: a server's enabled shared credentials (names and types only), for callers who can connect to the server. Legacy keys are refused.
  • Dashboard: both ways of issuing an agent key (the agent setup wizard and Issue a key in an agent's Credentials section) show "Choose which credential this key uses" under each selected remote or tunneled server that offers several shared credentials. Continuing or issuing is blocked, naming the servers, until each is chosen; the offered credentials are read again at issue.
  • Platform MCP / Admin MCP: no change. Neither creates API keys.

Motivation

RFC section 7.7: agent key creation is the interactive moment that establishes a key's choices, so later key use needs no browser consent, and several ready shared credentials need an explicit choice rather than a silent default.

Gutternote review steps

  1. Setup: in a remote server's Settings → Authentication, add two shared static credentials. Turn on upstream_auth_enforced for the organization to see the chosen one served.
  2. Sidebar → Identity → Agents → an agent → Credentials → New key (/<org>/projects/<project>/identities/agent:<id>/credentials?credential=new).
  3. On the servers step, tick that server. A select reading "Choose which credential this key uses" appears under it.
  4. Continue without choosing. It stops with "Choose which credential the key uses on ." Choose one of the two and issue the key.