Docs

Daita agents / guide

Secrets and Authentication

Configure model, PostgreSQL, and MCP credentials without persisting secret values in agent records.

#Secret References

Daita persists references rather than provider keys, PostgreSQL passwords, or MCP bearer tokens. Values are resolved lazily from the OS keychain, an explicit environment reference, or an injected SecretProvider at the integration boundary.

Never place a secret value in an agent name, source label, prompt, URL, command-line argument, committed file, or log.

#API Model Keys

The terminal model-onboarding flow stores an API key in the OS keychain and writes only its reference into the agent configuration.

Python callers can validate and persist a key through configure_model():

python
import os
from pathlib import Path
 
from daita import Agent, LocalWorkspace
 
workspace = LocalWorkspace(Path("/absolute/path/project"))
agent = await Agent.create("atlas", workspace=workspace)
try:
    await agent.configure_model(
        provider="anthropic",
        model="your-model-id",
        api_key=os.environ["ANTHROPIC_API_KEY"],
        context_window_tokens=200_000,
        max_output_tokens=8_192,
    )
finally:
    await agent.close()

Close and reopen the agent to admit the persisted route. An API key passed directly to create_llm_provider() is runtime-only.

#Subscription Authentication

Codex subscription onboarding performs a ChatGPT device-code sign-in inside Daita and stores Daita's OAuth credential in the OS keychain. The agent configuration retains only a reference.

The terminal is the recommended path. A Python application can drive the same public flow:

python
def show_verification(prompt) -> None:
    print(prompt.verification_url, prompt.user_code)
 
 
credential = await agent.authenticate_model_subscription(
    provider="codex",
    on_verification=show_verification,
)
 
await agent.configure_model(
    provider="codex",
    model="gpt-5.6-terra",
    subscription_credential=credential,
)

Treat the returned opaque credential as a secret and discard the caller's reference after configure_model() returns.

Claude Code and Grok Build subscription routes use their official clients' existing logins:

bash
claude auth login
grok login

Daita does not copy those client-owned credentials. It invokes the client in a constrained model-only mode and fails closed when required isolation controls are missing or incompatible.

#PostgreSQL Passwords

Use an environment or keychain reference:

python
from daita import PostgreSQLSource
from daita.security import SecretReference
 
source = PostgreSQLSource(
    host="db.example.com",
    database="analytics",
    username="daita_agent",
    credential=SecretReference.environment("DAITA_POSTGRES_PASSWORD"),
    schemas=("public", "reporting"),
)
registration = await agent.attach(source)

Environment names use uppercase letters, digits, and underscores. Applications that want Daita to own a keychain credential can call:

python
reference = await agent.store_postgresql_password(password)
 
# If attachment is abandoned, remove that Daita-owned entry explicitly.
await agent.delete_postgresql_password(reference)

Use a dedicated least-privileged database role. Prefer ssl_mode="verify-full" when trusted CA configuration is available. The role should remain read-only unless exact table and column update scopes are deliberately enabled.

#MCP Bearer Tokens

python
from daita import MCPAuthentication
from daita.security import SecretReference
 
authentication = MCPAuthentication.bearer(
    SecretReference.environment("REFERENCE_MCP_TOKEN")
)

The binding stores only the reference. Daita resolves it immediately before each network request and never persists the MCP session identifier.

#Cleanup

Detaching a source or deleting an agent removes Daita-owned keychain credentials. Revoking an MCP binding removes its authority but does not delete an externally managed environment secret. None of these operations changes database roles, source data, provider accounts, or official-client login state.