# Credentials And Local Storage The local Node runtime stores connections, OAuth client configuration, pending OAuth states, and recent run logs in SQLite. The Cloudflare Workers runtime stores the same runtime records in D1 and temporary transit files in R2. By default the database lives at: ```text ./data/connect.sqlite ``` Set `OOMOL_CONNECT_DATA_DIR` to use another directory. The Docker image defaults this to `/app/data`, which is intended to be mounted as a volume. - `no_auth` providers are available as virtual connections and do not store secrets. - `api_key` and `custom_credential` providers store their local secrets in SQLite. - `oauth2` providers use user-provided OAuth client configuration and a localhost callback URL. ## Encryption Set `OOMOL_CONNECT_ENCRYPTION_KEY` to encrypt stored credentials and OAuth client secrets: ```bash OOMOL_CONNECT_ENCRYPTION_KEY="replace-with-a-long-random-secret" npm run dev ``` The runtime uses AES-256-GCM for records that contain provider credentials or OAuth client configuration. The key is not stored by OpenConnector; if it is lost, encrypted records cannot be recovered. Without `OOMOL_CONNECT_ENCRYPTION_KEY`, the runtime stays usable for local development and prints a startup warning. In that mode, treat `connect.sqlite` as a sensitive local file. ## Credential Fields Credential fields are declared by each provider's catalog `auth` metadata. The runtime treats that metadata as the contract for local API requests: - `api_key` connections always require `values.apiKey`. - `api_key` connections may declare additional `extraFields`. - `custom_credential` connections require exactly the provider-declared `fields`. - `oauth2` client config may declare additional `clientConfigFields`. All submitted string values are trimmed. Empty strings are treated as missing. Unknown submitted fields are rejected instead of being silently stored, because credential forms, scripts, and provider definitions should fail fast when they drift. Inspect a provider before writing setup scripts: ```bash curl -s http://localhost:3000/api/providers/github ``` ## Connection Identity When a provider can cheaply validate credentials against a current-user or current-account endpoint, its validator stores a stable connection profile: - `accountId`: provider-side user, workspace, bot, account, or token identifier. - `displayName`: human-readable account label. - `grantedScopes`: provider-native scopes granted to the credential, when known. The runtime exposes this profile in `/api/connections`, MCP action discovery, action agent guides, and recent run logs. Agents should use it to understand which account an action will run as; raw provider tokens are never exposed. Check current connections: ```bash curl -s http://localhost:3000/api/connections ``` ## API Key Connections Create or replace the default API key connection: ```bash curl -s -X PUT http://localhost:3000/api/connections/github \ -H 'content-type: application/json' \ -d '{"authType":"api_key","values":{"apiKey":"github_pat_..."}}' ``` Create or replace a named API key connection: ```bash curl -s -X PUT http://localhost:3000/api/connections/github \ -H 'content-type: application/json' \ -d '{"authType":"api_key","connectionName":"work","values":{"apiKey":"github_pat_..."}}' ``` The accepted keys are `apiKey` plus the provider's `auth[].extraFields`. Execute an action with the default connection: ```bash curl -s -X POST http://localhost:3000/v1/actions/github.get_current_user \ -H 'content-type: application/json' \ -d '{"input":{}}' ``` ## Custom Credential Connections Create or replace the default custom credential connection: ```bash curl -s -X PUT http://localhost:3000/api/connections/example \ -H 'content-type: application/json' \ -d '{"authType":"custom_credential","values":{"host":"localhost","password":"..."}}' ``` The accepted keys come from the provider's `auth[].fields`. ## OAuth2 Connections OAuth2 providers require your own provider OAuth app. List OAuth-capable providers and copy the `expectedRedirectUri` for the service: ```bash curl -s http://localhost:3000/api/oauth/configs ``` Paste that exact callback URL into the provider OAuth app. With the default port, GitHub uses: ```text http://localhost:3000/oauth/callback ``` If the browser reaches the runtime through another origin, set `OOMOL_CONNECT_ORIGIN` before starting the runtime: ```bash OOMOL_CONNECT_ORIGIN="https://your-tunnel.example" npm run dev ``` Then use the new `expectedRedirectUri` returned by `/api/oauth/configs`. Store the local client configuration: ```bash curl -s -X PUT http://localhost:3000/api/oauth/configs/github \ -H 'content-type: application/json' \ -d '{"clientId":"...","clientSecret":"..."}' ``` Some providers declare additional OAuth client fields in `auth[].clientConfigFields`; send those as `extra`. Start authorization: ```bash curl -s -X POST http://localhost:3000/api/oauth/authorizations \ -H 'content-type: application/json' \ -d '{"service":"github"}' ``` Open the returned `authorizationUrl` in a browser. After the provider redirects to the local callback URL, the runtime stores the OAuth credential as the default connection. To store the OAuth credential as a named connection, include `connectionName` when starting authorization: ```bash curl -s -X POST http://localhost:3000/api/oauth/authorizations \ -H 'content-type: application/json' \ -d '{"service":"github","connectionName":"work"}' ``` Protect the local SQLite database like any other file containing API keys or OAuth tokens. ## Selecting A Connection For Execution The default connection is used when no alias is provided: ```bash curl -s -X POST http://localhost:3000/v1/actions/github.get_current_user \ -H 'content-type: application/json' \ -d '{"input":{}}' ``` If a named connection already exists, select it with `x-oo-connector-alias`: ```bash curl -s -X POST http://localhost:3000/v1/actions/github.get_current_user \ -H 'x-oo-connector-alias: work' \ -H 'content-type: application/json' \ -d '{"input":{}}' ``` The `alias` query parameter is also accepted: ```bash curl -s -X POST "http://localhost:3000/v1/actions/github.get_current_user?alias=work" \ -H 'content-type: application/json' \ -d '{"input":{}}' ``` ## Reset And Key Rotation Reset local runtime data: ```bash npm run runtime:data -- reset --yes ``` Rotate the local SQLite credential encryption key: ```bash OOMOL_CONNECT_ENCRYPTION_KEY="old-secret" \ OOMOL_CONNECT_NEW_ENCRYPTION_KEY="new-secret" \ npm run runtime:data -- rotate-key ``` Remove local SQLite credential encryption only when you intentionally want plaintext local storage: ```bash OOMOL_CONNECT_ENCRYPTION_KEY="old-secret" \ npm run runtime:data -- rotate-key --plain ``` `runtime:data` is for the local SQLite runtime only. For Cloudflare, back up and restore D1/R2 directly with Cloudflare tooling. ## OAuth Token Refresh OAuth access tokens are refreshed automatically when they are expired and the provider issued a refresh token. Refreshed credentials are written back to the local SQLite store, using encryption when `OOMOL_CONNECT_ENCRYPTION_KEY` is configured. If a token is expired and no refresh token is available, reconnect the provider from the local runtime. Providers such as Google may require authorization parameters that request offline access; provider definitions should include those parameters when refresh tokens are expected. ## Local API Access The server binds to `127.0.0.1` by default. Set `HOST=0.0.0.0` only when the runtime must be reachable from outside the local machine or container. Set an admin bearer token when the admin API or web console is reachable outside your own shell: ```bash OOMOL_CONNECT_ADMIN_TOKEN="replace-with-an-admin-token" npm run dev ``` Admin clients calling `/api`, `/docs`, or the web console should send: ```text Authorization: Bearer replace-with-an-admin-token ``` Create runtime tokens for `/v1` and `/mcp` callers from the web console Access tab or `POST /api/runtime-tokens`. The token is shown once when created; only a hash is stored in SQLite. Runtime clients should send `Authorization: Bearer oct_...`. `OOMOL_CONNECT_RUNTIME_TOKEN` is still accepted for bootstrap scripts and backward compatibility. The bundled web console receives a same-site local cookie from the runtime so it can keep working when API-token authentication is enabled. ## Action Policy Use `OOMOL_CONNECT_ALLOWED_ACTIONS` to expose only selected actions to HTTP and MCP execution: ```bash OOMOL_CONNECT_ALLOWED_ACTIONS="hackernews.*,github.get_current_user" npm run dev ``` Use `OOMOL_CONNECT_BLOCKED_ACTIONS` to deny specific actions even when a broader allowlist includes them: ```bash OOMOL_CONNECT_ALLOWED_ACTIONS="github.*" \ OOMOL_CONNECT_BLOCKED_ACTIONS="github.delete_repository" \ npm run dev ``` Provider proxy requests use separate service-level policy variables because `/v1/proxy/:service` can reach provider API endpoints beyond the curated action catalog. If any action policy is configured, proxy requests are denied by default unless the service is explicitly allowed: ```bash OOMOL_CONNECT_ALLOWED_ACTIONS="github.get_current_user" \ OOMOL_CONNECT_ALLOWED_PROXIES="github" \ npm run dev ``` Use `OOMOL_CONNECT_BLOCKED_PROXIES` to deny provider proxies even when `OOMOL_CONNECT_ALLOWED_PROXIES` contains `*`: ```bash OOMOL_CONNECT_ALLOWED_PROXIES="*" \ OOMOL_CONNECT_BLOCKED_PROXIES="github" \ npm run dev ``` Action policy entries are comma-separated action ids. A provider-wide wildcard such as `gmail.*` matches all actions for that provider. Proxy policy entries are comma-separated provider service names, or `*` for all provider proxies.