Skip to main content

Module inject

Module inject 

Source
Expand description

The credential-injection entry points and the layer-3 spawn gate.

Split out of the single ~2193-line resolver.rs (pure relocation, no behavior change): inject_identity_env / inject_identity_env_async (thin public wrappers), IdentityBinding + resolve_bindings_for_instance (direct-link lookup), and inject_identity_env_with_broker — the security-critical credential-injection gate. Every test that exercises inject_identity_env_with_broker moved here WITH it, as one atomic unit, per the module split’s constraint that this function and its tests must never be separated.

Before touching gate_oauth_failure / inject_identity_env_with_broker: see the warning doc comment directly above inject_identity_env_with_broker below.

Structs§

IdentityBinding 🔒
Resolved (provider, account) pair ready for env injection.

Functions§

agent_has_identity_binding
Whether an agent has any identity binding — its own links, or its template’s when it has none — checked without the binding resolver’s “no links” warning. For callers that ask on every sweep (memory), so an unlinked agent costs a lookup, not a log line.
block_agent_id 🔒
The agent a block names (agentId, or legacy agent:id), if any.
bound_oauth_config_dir 🔒
inject_identity_env
Inject identity-derived env vars into the spawn map for a block.
inject_identity_env_async
The optional broker lets the OAuth-class branch publish identityaccounts:changed on a status change discovered by the expiry probe. None skips the publish; the agentinput turn (server/agent_handlers/input.rs) and agent.send (app_api/agent_io.rs) pass Some(broker.clone()) through build_persistent_spawn_env so any live account list flips its status badge without a reload. Per spec §4.4.
inject_identity_env_with_broker
Before touching gate_oauth_failure / inject_identity_env_with_broker: this module is where SPEC_PROVIDER_ISOLATION_2026_06_20.md’s INV-A (“never the user’s global ~/.<P> dir”) is enforced — or, once already, silently stopped being enforced. Read docs/retro/retro-auth-isolation-invariant-silently-orphaned-2026-07-14.md first. Short version: an unbound oauth-class provider used to auto-route to an AgentMux-owned isolated dir (no user action, no global exposure); a 2026-07-08 refactor orphaned that path without meaning to, and it was never restored. Today’s gate always blocks an unbound oauth-class provider; the per-agent “true ambient” opt-out (use_ambient_login) is no longer read.
resolve_account
Resolve an account by id, checking id_store first — the authoritative, per-account-isolatable primary, which is what preserves the disposable-test-account isolation guarantee — and falling back to identity_store’s read-through mirror (IDENTITY_STORE_SCHEMA_VERSION v2, docs/specs/SPEC_IDENTITY_STORE_SPLIT_2026_08_17.md §3.1) only when the primary lookup misses. Returns the account alongside WHICH store it came from, so a caller that later writes a status update (the OAuth expiry probe below) writes it back to the SAME store instead of always assuming id_store — writing to the wrong store would silently create a second, never-read copy.
resolve_account_for_spawn
SPAWN-PATH account lookup — current channel’s id_store only, never the global mirror.
resolve_bindings_for_instance 🔒
resolve_bound_claude_config_dir_for_agent
resolve_bound_oauth_config_dir for a Claude agent row by its id, with no block — memory resolution’s question (#3603): where does this agent’s Claude run, so where are its memories (projects/<cwd>/memory, a Claude layout). None for any other provider, and for an account bound to the ambient ~/.claude — the spawn refuses that dir, and memory writes must never land in the user’s own Claude projects.
resolve_bound_oauth_config_dir
Read-only lookup of a block’s identity-bound OAuth config dir — the same directory inject_identity_env_with_broker’s OAuth branch would inject, without any of that function’s side effects (no token-expiry probe, no account-status upsert, no identityaccounts:changed publish, no SpawnGateError on failure). For a background caller that only needs to know WHERE to look (e.g. subagent_watcher deciding which directory to watch at agent registration, not spawn) rather than what to inject.
template_parent_id_if_seeded 🔒
Resolve the identity bindings for an instance from the direct agent↔account links only.