If you believe you have found a security vulnerability in this project, please report it responsibly:
-
Do not open a public issue. Instead, send an email to security@elvatis.com with:
- A clear description of the vulnerability
- Steps to reproduce
- Expected and actual behavior
- Any PoC code or attachments (zip) if safe to share
-
We will acknowledge receipt within 48 hours and provide a timeline for fixes.
-
Do not publicly disclose the issue until we have had a reasonable time to address it.
We appreciate responsible disclosure.
Only the latest release is supported. This project is not published to npm;
releases are Git tags with a matching GitHub Release, so "latest" means the
highest version tag on main.
| Version | Supported |
|---|---|
| 0.9.x | yes |
| older | no |
Report against the latest release. A fix ships in the next release rather than as a patch to an older tag.
This is a public repository and the bridge talks to several paid AI APIs, so a single committed key is a live credential leak.
- Credentials saved through Conduit are written to an authenticated encrypted vault.
config.jsonstores only opaquevault:v1:references. The vault master key is protected with current-user DPAPI on Windows or Secret Service on Linux. A headless Linux host without Secret Service must inject an explicit 32-byte key throughCONDUIT_VAULT_KEY(or the configured environment-variable name); Conduit does not fall back to plaintext storage. - Real environment variables are suitable for ephemeral provider credentials and
managed secret injection. A
.envfile is plaintext even when it is gitignored; restrict its filesystem permissions and prefer the encrypted vault or a platform secret manager for retained credentials. .env.exampledocuments the supported variables and must contain placeholders only, never a working key.- Never paste a key into a README, an issue, a test fixture or a config file.
npm run scan:secretsscans the tracked tree for credential-shaped strings, andnpm run scan:secrets:historyalso scans every blob in git history. The same scanner runs in CI (.github/workflows/secret-scan.yml) on every push and pull request, so a leak fails the build instead of shipping.
If a key does reach a public commit, treat it as compromised: rotate it at the provider first, then clean up the repository. Rotation is the fix; deleting the commit is not, because the value is already public.
Retained sessions, memories, agent profiles, and provider-neutral state use the same purpose-separated authenticated encryption before file, SQLite, or Prisma storage. Authentication failures stop the load; corrupted ciphertext is never treated as plaintext. Retention is opt-in, bounded by size and optional expiry, and supports explicit export and deletion. Backups remain encrypted.
Bind the bridge to loopback unless remote access is intentional. A non-loopback
bind requires bearer-token authentication. State-changing HTTP requests reject
foreign and opaque (Origin: null) browser origins, request bodies are limited to
1 MiB, and dashboard responses deny framing and MIME sniffing. WebSocket clients
must authenticate with the bearer header or the conduit-token.<token>
subprotocol; tokens in WebSocket query strings are not accepted because URLs are
commonly retained in logs and history.
Agent policies accept only known tool names. Windows command arguments containing
quotes or control characters are rejected before a .cmd or .bat shim is
invoked. Every fallback provider is checked against its own agent policy.
Each CLI provider can select an absolute executable path. Relative or unusable
overrides fail closed instead of silently selecting another PATH entry, and read-only
diagnostics report the resolved path and CLI version. Codex runs with
--ignore-user-config: its login remains available, while user MCP servers, hooks,
feature flags, and permission settings cannot replace the model, effort, and sandbox
policy supplied by the bridge. Each provider subprocess receives only its own API-key
environment variables; other providers' credentials are omitted, and version
diagnostics receive no provider credentials.
Pipeline working directories are resolved through symlinks and Windows junctions and must remain inside the selected repository or a registered workspace. Repository pipeline allowlists, agent overrides, mandatory approval gates, and per-run cost limits are enforced by the server.
A working directory is a scope check, not an operating-system sandbox. Native CLI
agents can still have the permissions of the user running the bridge. Use a
container, virtual machine, or restricted operating-system account when executing
untrusted prompts or tools. The community write demo therefore requires the
explicit --allow-write-demo option.
Live pipeline details contain the prompt and provider output so an approval can resume in the same process. Durable pipeline history stores summary metadata only; it omits prompts, templates, and model output. A running or paused pipeline found after restart is marked interrupted and must be started again.
Usage and cost values are conservative local estimates, not provider invoices. The budget ledger reserves estimated capacity before each provider call, counts fallback attempts, and validates persisted values before using them for a hard stop. Keep the runtime directory private even though its files are created with owner-only permissions where the platform supports them.
Optional platform operators use high-entropy bearer tokens whose configuration keeps
only salted SHA-256 verifiers. Comparisons use constant-time primitives. Roles are
viewer, operator, reviewer, and admin; each configured identity also has an explicit
workspace allowlist. Routes must derive the audit identity from the authenticated
token and check both capability and workspace, never accept an operator name or user
scope from a request body. The existing bridge bearer maps to local-admin, and an
auth-disabled loopback request keeps that compatibility identity.
Retrieved memory is untrusted reference data. Only approved, unexpired memory in the authenticated user, workspace, agent, provider, or profile scope may enter a prompt. Cross-provider replay requires explicit selection and redaction. Raw client-supplied skill instructions must not be promoted into a system prompt; routes resolve approved stored skill IDs or restrict raw instructions to an administrator.