Skip to main content

Credential storage

GAIA never writes tokens or API keys to plaintext files. All secrets live exclusively in your OS credential store: Each connector occupies a dedicated keyring slot keyed by gaia.connections:<connector-id>:<secret-name>. MCP server tokens use $keyring:<slot> references in ~/.gaia/mcp_servers.json — the JSON file itself contains no actual secrets. OAuth refresh tokens and MCP server API keys are AES-256 encrypted by the OS keyring at rest and decrypted in memory only when a tool call needs them.

Per-agent grant + activation model

Connecting a service does not give every agent access to it. Access is gated at up to three levels depending on connector type:
  1. Connection — you store a credential once in the keyring (OAuth refresh token or PAT).
  2. Grant — you explicitly allow a specific agent to use that credential for a specific scope. Gates credential access (get_access_token). Applies to every connector type.
  3. Activation — you explicitly enable a specific agent to see an MCP server’s tools in its system prompt. Gates MCP tool visibility. Defaults to OFF — least-privilege opt-in. Applies to mcp_server connectors only.
OAuth connectors (e.g. Google) reach the provider through native Python @tool functions that call get_credential_sync directly — there is no MCP tool surface for activations to gate. Per-agent control for OAuth is handled entirely by the per-scope grant toggles. Calling activate() / deactivate() for an OAuth connector raises ConfigurationError; the HTTP route returns 400 Bad Request; the CLI exits with code 3. An agent that calls get_credential_sync("google", agent_id=..., required_scopes=["gmail.readonly"]) without a matching grant receives AuthRequiredError(reason=AGENT_NOT_GRANTED) and cannot proceed. No token is ever returned to an ungranted agent. Without an activation, an MCP connector’s tools never enter the agent’s tool list — they don’t bloat the system prompt, and the agent cannot select them even if it has a grant. Grants are stored in ~/.gaia/connectors/grants.json and activations in ~/.gaia/connectors/activations.json — both flat files that are not secret stores. They contain agent IDs and scope/boolean values, never credentials. When a grant is requested during OAuth connect, GAIA records only the intersection of the agent’s requested scopes and the scopes the token endpoint actually grants.

Revocation

You can revoke access at any level:

Threat model

See also