feat: choose the upstream credentials an assistant's turns use
Merged
DA
5d ago+10411+10411+01234567890123456789012345678901234567890123456789-1584-1584-0123456789012345678901234567890123456789
AIM-598 (1 of 2)
Stacked on #8042.
Summary
- Configurable execution profiles. Profiles already decide a turn's credential per assistant, root trigger and execution context, but only from an unambiguous server configuration. A server with several fitting credentials stayed a gap. Admins can now set a server's choice to an auth client, to no upstream authentication, or back to automatic.
executionprofiles.SetChoicewrites a new version that copies every other choice. Turns already running keep the version they bound, and the next turn binds the new one.Bindstill only fills servers that have no choice, so nothing changes silently.- Choices are validated with the shared
CheckConfiguredChoice. Userless profiles take shared credentials only (personal and EMA are refused). A server the assistant does not reach through a proxy is refused. - Changes require the profile's
expected_version, so a stale read is a conflict, never an overwrite. Each change is audited asassistant:update_execution_profile, with before and after choices, in the same transaction. - Choosing grants nothing: the typed resolver's live
mcp:authchecks still run on every request.
- API
assistants.listExecutionProfiles(assistant read): each trigger × context, with each server's choice and its source (admin,issuance,backfill, orautomaticfor the choice the next turn would make). Servers with no choice show their gap reason, and every server lists the options its context can choose.assistants.setExecutionProfileChoice(assistant write).
- Dashboard: assistant → Identity → Upstream credentials. One card per trigger and context, with a select per server. Gaps are explained, and the selects are read-only without assistant write.
- Platform MCP: new
choose_assistant_upstream_credential, next toselect_assistant_runtime. It previews withconfirmed:false, andconfirmed:trueneeds the exact trigger, context, server, choice andexpected_version. External audience only, org admin plus assistant:write, with bounded refusals. Managed assistants cannot change their own credentials. - Demo seed: the identity-bound assistant reaches Linear, and an admin-chosen version has its person-backed dashboard turns use the shared token. Postflight checks it.
- Next PR: personal connections for person-backed turns resolve as the authorizing user, and recovery links reach only that user.
Motivation
RFC section 7.8: assistant turns cannot see a consent picker, so ambiguous servers need an explicit, versioned choice that an admin can make and audit without changing turns that are already running.
Gutternote review steps
- Setup: the seeded demo data covers it.
- Sidebar → Assistants → Identity-bound assistant → the Identity tab.
- Under Upstream credentials, the dashboard trigger has two cards. When acting for a person shows Linear using Engineering automation token, the seeded admin choice. When acting for nobody shows Linear as Not chosen, with "No credential chosen yet. Choose one."
- Open the Linear select in the person-free card. It offers only Engineering automation token, because a personal account cannot serve a turn that acts for nobody. Choose it. A toast confirms the save, and the audit log shows "changed the upstream credentials of assistant".
- Switch it back to Automatic. The card returns to Not chosen.