Skip to main content

inject_identity_env

Function inject_identity_env 

Source
pub fn inject_identity_env(
    mstore: Arc<Store>,
    id_store: Arc<Store>,
    identity_store: Arc<Store>,
    block_id: &str,
    env_vars: &mut HashMap<String, String>,
) -> Result<(), SpawnGateError>
Expand description

Inject identity-derived env vars into the spawn map for a block.

Synchronous, broker-less entry point — in production only the durable-jekt sign-in recheck (server/jekt_held.rs) calls it. The CLI-spawn paths use inject_identity_env_async instead (via build_persistent_spawn_env in server/agent_handlers/input.rs). Resolution flow:

  1. Look up the active AgentInstance for this block. If none exists, the caller didn’t go through the launch modal — return immediately, no injection (unless the block names a deleted agent: that is refused with SpawnGateError::AgentDeleted, #3577).
  2. Read its identity_id. Empty / “blank” no longer short-circuits to ambient creds (see #2463 — this used to bypass the layer-3 gate entirely, so whether a spawn required a bound account depended on whether a stray ambient credential happened to exist on the test machine). It now falls through to the same steps below, which gate purely on the agent definition’s own provider — identical to how a non-empty-but-unresolvable identity_id (e.g. a legacy sentinel) already behaved.
  3. Read the db_agent_identity_links rows for the instance’s definition.
  4. For each binding: fetch the account, resolve its SecretRef, look up the provider’s env-var matrix, write each var into env_vars.
    • Api-key-class per-binding failures are logged and skipped — other bindings still inject (historical behavior).
    • Oauth-class failures (account row missing, lookup error, non-OAuthConfigDir secret_ref) are always BLOCKING: the function returns SpawnGateError before the CLI process is created. use_ambient_login no longer exempts an agent and is not read here (the opt-out was retired, see m0017_ambient_login_grandfather.rs).
  5. If the agent definition’s own provider is oauth-class and no binding for it exists at all (fresh/never-bound or post-delete-cascade), the same gate applies — implicit ambient fallback is how the delete-doesn’t-deauthenticate gap happened (spec §2.2 edge case).

Layer 3 of SPEC_ACCOUNT_DELETE_DEAUTH_LAYERS_2_4_2026_07_14.md. Before it, this function was intentionally infallible (“the spawn never aborts because a secret didn’t resolve”) — that is still true for api-key-class bindings, but oauth-class resolution failures now fail the spawn by default so account deletion is honest at the next spawn.