Skip to main content
Coral is designed as a local data-access layer for a trusted user and the agents or scripts that user chooses to run. It does not send your source configuration, usage history, or query results to a Coral-hosted service. Source credentials are used locally and sent to the upstream providers you configure when a query requires them.

Intended threat model

This release is intended for single-user local use:
  • You install and run the coral binary on your own macOS, Linux, or x86_64 Windows machine.
  • You choose which source specs to install, which credentials to provide, and which MCP clients or scripts may call Coral.
  • Coral stores configuration under the local Coral config directory, which defaults to the platform config directory and can be changed with CORAL_CONFIG_DIR. Source secrets default to OS credential storage when the local keychain is usable, with plaintext file storage available as fallback.
  • CLI and MCP queries run through the same local runtime. The internal gRPC server binds to loopback, and the MCP server uses stdio transport.
Coral can also be run as a server that several people sign in to. That is a different trust boundary, described under Shared deployments below. Coral reduces data exposure by keeping execution local and by exposing a narrow MCP surface: sql, add_function, search, list_catalog, describe, list_columns, optional feedback, coral://guide, and coral://tables. MCP tool and resource metadata can include installed source/schema names so clients can route source-specific requests to Coral during discovery. Secret values are not returned through coral.inputs; secret rows show only whether a value is configured.

What Coral protects against

Coral’s current protections are aimed at accidental exposure within that local trust boundary:
  • Source secrets are stored separately from non-secret source variables and are never written into config.toml.
  • By default, sources use the operating-system credential store when Coral can successfully write, read, and delete a probe item. On macOS this uses Keychain; on Windows, Credential Manager; on Linux, Secret Service.
  • If keychain probing fails in auto mode, Coral stores source secrets in plaintext local files and reports the route as file (plaintext) in source output.
  • State files written by Coral use private file permissions on Unix systems. On Windows, Coral stores local state under %APPDATA%\withcoral\coral\config by default and relies on the user’s Windows profile ACLs as the local trust boundary.
  • SQL execution is configured as read-only: DDL, DML, and multiple statements are disabled.
  • Source and workspace names are validated before they are used in local state paths.
  • MCP clients can query installed sources, but they do not receive raw stored secret values through the discovery tables or resources.

Shared deployments

When Coral runs with login enabled, the machine belongs to an operator rather than to each user, and what a signed-in person may reach is decided by workspace membership instead of by control of the host account. The properties that matter for a threat model:
  • Signing in grants no access by itself. A verified login refreshes a row in the user directory. It creates no workspace and joins none, and no membership is derived from upstream group claims, email domains, or roles.
  • Access is per workspace, at two levels. Members read a workspace’s contents: SQL, catalog, search, and the table functions already installed. Owners additionally configure sources, read traces, change the function set, run search maintenance, manage membership, and delete the workspace.
  • Source configuration is owner-only, reads included, because source responses carry configuration and credential metadata. There is no redacted member-visible source view.
  • Tokens minted for the MCP surface authenticate an agent, and agent credentials are refused every owner-level operation regardless of the role the person behind them holds. An owner’s MCP client can query the workspace; it cannot install a function, configure a source, read traces, or change membership.
  • A workspace the caller may not reach is reported as absent, not forbidden, so the workspace namespace does not become an oracle for names. A workspace with no owner is concealed the same way, from its remaining members included.
  • There is no superuser. The built-in local principal is refused outright where login is enabled, so host-global settings such as runtime feature flags are exposed to nobody there.
  • Revocation binds at different points on different surfaces. On the gRPC API, membership is authorized per request, so a change lands on that caller’s next request. An authenticated MCP session is admitted once, at its handshake: a caller whose membership was removed cannot open a new session, but the session they already hold is not terminated, and its one-hour timeout is an idle timer rather than a maximum lifetime. What that session can still do is bounded by the gRPC surface behind it, which refuses its workspace-scoped calls. Restart the MCP listener to end sessions already open.
  • Recovering a workspace with no reachable owner requires possession of the state database. The repository recovery tool authenticates nobody: treat filesystem access to the state directory, or the Postgres connection URL, as equivalent to ownership of every workspace on that deployment.
Shared server access control covers all of this in operational detail, including recovery.

Secret storage configuration

Coral reads the credential storage preference from config.toml:
Supported values:
Changing the global preference does not rewrite existing credentials. To update those, remove and re-add the source you want to update.

What you still need to trust

Coral is not a sandbox for untrusted agents, source specs, or credentials. If you give an unsandboxed agent permission to run as your user, that agent may already be able to read local files your OS account can read, such as shell config, project files, or SSH configuration. Coral adds access to the sources you configure; it does not make an otherwise untrusted local agent safe.
  • A connected MCP client can ask Coral to query any source you have installed.
  • A connected MCP client can install or replace persistent function artifacts in the selected workspace through add_function. On a deployment with login enabled this call is refused instead: MCP tokens authenticate an agent, and agents cannot change the function set.
  • A source token can access whatever the upstream provider allows for that token, so prefer read-only and least-privilege credentials.
  • A custom source spec can direct Coral to make HTTP requests or read local file locations declared by that spec. Only install source specs you trust.
  • Anyone who can control your user account should be treated as able to use the configured sources. If a source uses file-backed secret storage, anyone who can read your local Coral config directory should also be treated as able to read its stored source secrets.
  • Coral does not attempt to protect against a compromised machine, compromised MCP client, malicious shell environment, or malicious upstream API response.

Practical guidance

  • Scope provider tokens to the minimum data your workflow needs.
  • Put Coral’s config directory on a local disk protected by your operating system account controls.
  • Use coral source list or coral source info <NAME> to inspect whether a source uses keychain or file (plaintext) secret storage.
  • Review custom source specs before installing them, especially base_url, auth, and file location fields.
  • Configure coral mcp-stdio only in MCP clients you are comfortable allowing to query your installed sources.
Report suspected vulnerabilities privately through the project’s security policy.