Identity bundles
An Identity bundle is a named credential set that AgentMux assigns to an agent instance at launch. The bundle decouples what an agent does (configured by the Memory bundle and the agent’s provider) from who it acts as (configured by Identity). The same Memory + provider can run as different identities — work, personal, demo — without restart.
What goes in an Identity
Section titled “What goes in an Identity”An Identity is a logical grouping of per-provider credentials:
| Provider class | Credential type | Examples |
|---|---|---|
github | Personal access token | repo scopes, gh CLI auth |
aws | Profile name (referenced from ~/.aws/) | dev, qa, prod |
anthropic | API key | Claude API access (fallback to OAuth) |
custom | Free-form key/value | Any provider-specific token |
The set of providers in a bundle is open-ended — AccountProvider is "github" | "aws" | "anthropic" | "custom" today, with custom covering anything that doesn’t fit a named slot.
OAuth credentials as bundle members
Section titled “OAuth credentials as bundle members”Identity bundles now carry OAuth credentials as first-class members, not just API keys. Each bundle’s Claude / Codex / Copilot OAuth login lives in its own auth-config directory, so two bundles for the same provider can hold genuinely distinct OAuth sessions (work account vs personal, etc.). The bundle stores a pointer to the directory plus a status field (valid / expired / needs_reauth / unknown) that surfaces in the bundle manager so credential health is visible without launching an agent.
The OAuth invariant: a successful OAuth flow always lands bound to a bundle. If you start an OAuth flow without one selected, the system creates a new bundle on the spot rather than letting the credential live “ambient” — that ambient path used to silently let two named identities share ~/.claude, with no actual isolation.
Migration is automatic: any pre-bundles OAuth login becomes a synthesized Default identity bundle pointing at the existing ~/.claude (or equivalent), no token movement required. The Default bundle behaves like any other — you can rename it, delete it, or swap an agent to a different bundle without losing the credential.
For the spec, see SPEC_OAUTH_IDENTITY_BUNDLES_2026_05_22.md in the main repo.
How Identity is reached
Section titled “How Identity is reached”Identity is not a widget-bar entry. Two paths reach it:
Per-agent (the original surface):
- Open an Agent pane (pinned in the widget bar).
- Click the cog (⚙) in the pane header.
- Switch to the Identity tab.
App-wide manager (hamburger menu):
- Click the hamburger (≡) at the top of the tab bar.
- Choose Identity & Memory.
- The bundle manager modal opens — browse and edit any bundle without first opening a specific agent.
The hamburger-menu path opens a singleton modal shared across the app: if it’s already open in another window, clicking the entry focuses that window instead of opening a duplicate. The per-agent cog path stays scoped to the current pane.
The view registration (view: "identity") and IdentityPaneViewModel exist for pane.open RPC and right-click menu paths, but the primary paths are the two above.
Launch flow
Section titled “Launch flow”The Launch Agent modal exposes a single Identity dropdown. The default selection is the singleton blank Identity (“no creds — use ambient environment”). Selecting a real Identity at launch:
- Resolves the bundle’s accounts.
- Computes the per-provider env vars (
GH_TOKEN,AWS_PROFILE, …) the agent’s CLI needs. - Spawns the agent process with those env vars set.
- Records the
identity_idforeign key on thedb_agent_instancesrow.
You can swap Identity on a running agent by reopening the Identity tab and picking a different bundle — the spawn-time env injection re-applies on next turn.
If the selected provider requires OAuth (or an API key) and isn’t authenticated yet, the modal’s Pre-Launch Auth panel appears inline and gates the Launch button. In the current release the OAuth result is session-scoped; persistent bundle storage that ties an OAuth login to a reusable Identity is Phase C and not yet shipped.
Persistence
Section titled “Persistence”Identity bundles live in two SQLite tables in the sidecar’s objects.db:
| Table | Owns |
|---|---|
db_identity_bundles | Bundle metadata: id, name, description, is_blank flag |
db_identity_bindings | Per-provider binding: (identity_id, provider) → account_id |
The actual credential records live in db_identity_accounts (the individual-credentials table). db_identity_bindings is a junction between Identity bundles and that table.
These tables are part of objects.db’s flat schema (run_object_schema). See SPEC_CONSOLIDATE_FORGE_IDENTITY_INTO_AGENT_2026_04_13.md for the canonical model.
What Identity is not
Section titled “What Identity is not”- Not a credential vault. AgentMux doesn’t encrypt or audit credential access at the OS level today. The bundle is a grouping convenience — the credentials still live wherever the provider’s CLI puts them.
- Not the same as a session. Identity is durable; the agent instance owns a foreign key to it. Sessions come and go; Identity survives.
- Not a top-level pane. No widget-bar entry. See Pane types for the full pane catalog.
See also
Section titled “See also”- Memory bundles — the other half of agent composition
- First Agent Setup — provider login flows
- Auth flows — per-provider auth-dir isolation
- Pane Types — where Identity bundles surface in the UI