Skip to content

feat: choose the upstream credentials an assistant's turns use - #8043

Merged
danielkov merged 147 commits into
mainfrom
daniel/aim-598-feat-assistant-profile-choices
Oct 30, 2026
Merged

danielkov merged 147 commits into
mainfrom
daniel/aim-598-feat-assistant-profile-choices

Conversation

@danielkov

@danielkov danielkov commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

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.SetChoice writes a new version that copies every other choice. Turns already running keep the version they bound, and the next turn binds the new one. Bind still 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 as assistant:update_execution_profile, with before and after choices, in the same transaction.
    • Choosing grants nothing: the typed resolver's live mcp:auth checks still run on every request.
  • API
    • assistants.listExecutionProfiles (assistant read): each trigger × context, with each server's choice and its source (admin, issuance, backfill, or automatic for 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 to select_assistant_runtime. It previews with confirmed:false, and confirmed:true needs the exact trigger, context, server, choice and expected_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

  1. Setup: the seeded demo data covers it.
  2. Sidebar → Assistants → Identity-bound assistant → the Identity tab.
  3. 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."
  4. 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".
  5. Switch it back to Automatic. The card returns to Not chosen.

Administrators can create remote_session, service_account, static_credential
and pass_through auth clients, offer an existing client on another server, and
replace an administrator-created client's headers. The typed resolver treats
administrator-created clients and associations as authoritative instead of
checking them against the server settings that backfilled copies mirror.
Server settings add a credential another server already offers or create a
new one, and a credential's sheet edits and rotates its headers. The static
Authorization identity choice is renamed to a shared credential. Agent pages
edit credential blocks for managers and connection owners.
…o daniel/aim-596-feat-dashboard-auth-client-setup
Where typed auth client resolution is enforced, consent offers each server's
permitted auth clients, preselects the remembered choice or the fixed order,
and records the picked client and its own registration on the new
credential. Gateways offer the choice per member and capture tools through it.
A member added after a credential was issued gets no-auth or its single
ready permitted client recorded atomically the first time it is used, where
typed auth client resolution is enforced. Otherwise it stays unavailable
until the person reconnects to choose.
Agent key creation records an auth client choice per server under a new
api_key credential kind, rotation copies it, and under enforcement the key
is served through those choices on direct servers and agent gateway members.
The key wizard asks for a credential on servers offering several.
…wser

Token requests name a per-server choice with upstream_auth_client; issuance
profiles let an admin choose for an OAuth client or workload subject; with
neither, the only ready credential is used, else selection_required.
Admins pick, per trigger and execution context, the credential each MCP server
is served with. A change is a new profile version, so running turns keep
theirs. Listed and changed through the API, the assistant's Identity tab and
a Platform MCP tool; audited.
@danielkov
danielkov requested review from a team as code owners October 24, 2026 16:44
@changeset-bot

changeset-bot Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b594a47

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
server Minor
dashboard Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@linear-code

linear-code Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

AIM-598

@danielkov

Copy link
Copy Markdown
Contributor Author

Demo

Assistant upstream credentials before a choice

  1. The identity-bound assistant's person-backed turns use the seeded admin choice on Linear; its person-free turns have no choice yet.

@danielkov

Copy link
Copy Markdown
Contributor Author

Assistant upstream credentials after choosing the shared token

  1. After choosing the shared token for person-free turns (the only option offered there), the gap is gone.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 58 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread server/design/assistants/design.go Resolved

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Bind a registration's issuer to the client's project, refuse empty header
entries, keep stored secrets across '_'/'-' spellings, report members'
choice among several credentials in get_my_mcp_connection_status, map the
post-offer read failure, and cover admin clients and cross-server offers.
…o daniel/aim-596-feat-dashboard-auth-client-setup
…aniel/aim-596-feat-consent-auth-client-picker
Let an agent approval proceed when only the person lacks access, offer
connect and reconnect for identity-provider clients, record no client for a
no-auth server, and let a later no-auth approval clear the remembered client.
… daniel/aim-597-mig-issuance-selection-profiles
…niel/aim-597-feat-headless-auth-client-choices
…daniel/aim-598-feat-assistant-profile-choices
@blacksmith-sh

blacksmith-sh Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
github.com/speakeasy-api/gram/server/internal/platformmcp/setupcorpus/
TestPinnedCorpusIsWithinItsRevalidationWindow
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Drops the "New:" prefix, names the reuse option "Existing credential" and
leaves it out when no other server has a credential to share. The upstream
sign-in row now says what probing a remote upstream found.
…aniel/aim-596-feat-consent-auth-client-picker
…niel/aim-596-feat-gateway-new-member-choices
…niel/aim-596-feat-agent-key-auth-client-choices
… daniel/aim-597-mig-issuance-selection-profiles
…niel/aim-597-feat-headless-auth-client-choices
…daniel/aim-598-feat-assistant-profile-choices
…suance-selection-profiles

Regenerate the issuance selection profiles migration on top of main (SQL unchanged).
…choices

# Conflicts:
#	server/internal/demoseed/queries/04_servers.sql
#	server/internal/demoseed/repo/09_postflight_identity.sql.go
#	server/internal/platformmcp/queries.sql
Base automatically changed from daniel/aim-597-feat-headless-auth-client-choices to main October 30, 2026 09:22
# Conflicts:
#	server/internal/demoseed/queries/04_servers.sql
# Conflicts:
#	seed/demo/PAGES.md
#	server/internal/demoseed/queries/04_servers.sql
#	server/internal/demoseed/queries/09_postflight_identity.sql
#	server/internal/demoseed/seed_04_servers.go
#	server/internal/demoseed/seed_09_postflight_identity.go

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 58 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

@danielkov
danielkov added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit 9146e3f Oct 30, 2026
49 checks passed
@danielkov
danielkov deleted the daniel/aim-598-feat-assistant-profile-choices branch October 30, 2026 10:23
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants