Security

Copair is a local agent. It runs on your machine, reads your files directly, and spawns subprocesses in your terminal. There is no Copair server, no code upload, and no telemetry. The security model is designed around that reality: your approval is the enforcement point, and secrets never leave your machine in readable form.

Approval gate

Every tool call — file writes, edits, shell commands, git operations — is held at an approval gate before execution. In the default ask mode you see the tool name and its full input, then approve or deny.

Permission modes (permissions.mode in config):

ModeBehavior
askPrompt before every tool call (default)
auto-approveApprove automatically — use only in trusted, sandboxed environments
denyReject all tool calls; agent can only read and plan

Allow-list (permissions.allow_tools in config): specific tools can be pre-approved so they never prompt:

permissions:
  mode: ask
  allow_tools:
    - read
    - glob
    - grep

Session-level "always allow" is path-specific for write, edit, read, glob, and grep. Selecting "always" on a write to src/auth.ts approves future writes to that file only — not every write the agent performs. New-file creation always re-prompts even when the file's directory matches an existing allow-list entry. See Permissions & Approval for the full tiered-read behavior.

File system access

Copair enforces a project boundary: the directory where you run copair is the root. By default the agent cannot read or write files outside this root.

Blocked by default (built-in deny list):

  • ~/.ssh/ — SSH private keys
  • ~/.aws/ — AWS credentials
  • ~/.gnupg/ — GPG keys
  • ~/.config/ — application credentials
  • ~/.netrc, ~/.npmrc, ~/.pypirc — package registry tokens
  • /etc/ — system configuration
  • **/.env, **/.env.* (outside project root)

Expanding access (permissions.allow_paths): grant the agent access to specific paths outside the project root:

permissions:
  allow_paths:
    - ~/shared-libs
    - /data/datasets

Overriding the deny list (permissions.deny_paths): replace the built-in list entirely. When non-empty this list is used instead of the defaults:

permissions:
  deny_paths:
    - ~/.ssh
    - ~/.aws

Cross-repository bash detection

The bash tool accepts arbitrary shell commands, so the project boundary cannot be enforced by path-checking the tool input. Instead, Copair scans every bash command for path tokens that escape the project root — relative paths starting with ../, absolute paths outside the root, and ~/ home references — and escalates them to a forced approval prompt with a red warning, regardless of the configured permission mode or any matching bash allow-list entry.

  Cross-repository access
 bash: cat ../../other-repo/.env

 [y]es  [n]o

The detection is code-level — a model cannot phrase its way around it by quoting paths differently or piping commands. Workflow YAML files that include shell steps go through the same approval gate before each step executes.

The same tier rules apply to bash as to native file tools: paths inside the project root are allowed without a prompt, sensitive files (.env*, *.pem, id_rsa, etc.) always prompt, and cross-repo paths always prompt.

Secrets handling

API keys and tokens are interpolated from environment variables at config load time — they are never stored in config files. When Copair writes session files, logs, or returns tool output to the model, all text passes through a redaction filter that replaces known secret patterns with [REDACTED:<label>].

Patterns redacted automatically:

  • Anthropic API keys (sk-ant-…)
  • OpenAI API keys (sk-…)
  • GitHub tokens (ghp_…, github_pat_…)
  • AWS access keys (AKIA…)
  • Linear tokens (lin_api_…)
  • Bearer tokens

Redaction runs on: tool output before it is sent to the model, session JSONL entries, and the audit log.

Prompt injection hardening

Copair wraps all file content and tool results in labelled XML context blocks before including them in the model prompt. An anti-injection preamble at the top of the system prompt instructs the model to treat these blocks as data, not instructions.

This limits — but does not eliminate — the risk from adversarial content in files the agent reads. Treat the approval gate as the primary defence: if a tool call looks unexpected, deny it.

MCP server security

When you configure MCP servers, Copair applies several mitigations:

  • Env isolation: MCP subprocesses receive a minimal environment (PATH, HOME, TMPDIR, LANG) by default. No API keys or credentials from the parent shell are forwarded unless you set inherit_env: true on a specific server.
  • Startup validation: Copair checks that each configured command exists (which / existsSync) before starting. Invalid servers are skipped with a warning — startup continues rather than crashing.
  • Config warnings: If you configure an MCP server with an env key matching a known secret pattern (_KEY, _SECRET, _TOKEN, _PASSWORD), Copair logs a warning at startup.
mcp_servers:
  my-tool:
    command: my-mcp-server
    args: []
    env:
      TOOL_CONFIG: /path/to/config   # fine
      # OPENAI_API_KEY: ...          # would trigger a warning
    inherit_env: false               # default — do not forward parent env

Config reference

KeyTypeDefaultDescription
security.path_validationstrict | warnstrictHow to handle out-of-boundary path access: strict blocks and returns an error; warn logs and allows
security.redact_high_entropybooleanfalseAlso redact strings that look like secrets by entropy heuristic, even if they don't match a known pattern
network.web_search_timeout_msnumber15000Timeout in ms for web search tool requests
network.provider_timeout_msnumber120000Timeout in ms for LLM provider API calls
permissions.allow_pathsstring[][]Paths outside the project root the agent may access
permissions.deny_pathsstring[][]Override the built-in credential deny list. When non-empty, replaces it entirely

Reporting vulnerabilities

Please report security issues via GitHub Security Advisories. Do not open a public issue for security vulnerabilities.

Last updated May 12, 2026