What Conarium actually does, how it fails, and — just as important — what it does not protect against. Written for the engineer who has to put this in the path between an AI assistant and a real database.
Conarium is a self-hosted governance layer that sits between an AI assistant (Cursor, Copilot, Claude Code, Windsurf, or any MCP client) and your data. Every query the assistant issues passes through Conarium first. Sensitive values are masked before the model sees them, writes are refused, and every access is written to a tamper-evident, PII-safe audit log. It runs entirely inside your perimeter — the vendor never receives your data.
AI assistant ──MCP──▶ Conarium ──▶ your database / docs / APIs
│
├─ parse & analyse the SQL
├─ enforce read-only + allow/deny + row caps
├─ mask PII in the result before it returns
└─ append a hash-chained audit entry
▼
masked result ──▶ AI assistant real values ──▶ you
The assistant reasons on masked tokens it cannot de-anonymize; the operator sees the real values on the way back. The SQL gate accepts Postgres, Microsoft SQL Server, and Oracle. MySQL is not implemented. Oracle does not resolve synonyms or database links. Connectors cover Postgres, internal docs, OpenAPI specs, Jira and Slack, exposed to every assistant over MCP.
These are enforced in code, not policy prose:
SELECT/WITH queries pass. DROP, DELETE, UPDATE, INSERT, ALTER, CREATE, TRUNCATE are blocked — including when smuggled inside comments or stacked queries (SELECT 1; DROP …).PolicyError is thrown) — never passed through. Uncertainty resolves to refusal, not leakage.policy.scanCharCap (default 16 384) is replaced whole with [MASKED_PII], even when it contains no identifier.Policy is a small JSON document. Nothing is allowed unless you allow it; anything on a deny list is refused first.
{
"allowTables": ["public.customers", "public.orders"],
"denyTables": ["*.secrets", "*.admin_users"],
"maskColumns": ["*.email", "*.phone", "*.tax_id"],
"maxRows": 100,
"allowConnectors": ["postgres", "docs"]
}
A security tool that hides its limits isn't a security tool. Conarium is a governance layer in the AI data-access path — not a silver bullet.
These are design decisions, not gaps we forgot. A half-working detector is worse than none: it increments a count and still hands the value to the model.
maskColumns and conarium-suggest-policy (a name-based guess that does not write your config).P in position 1, 7-3-1 check digits. TD1/TD2 are not implemented.@. One decode pass; a lone 5@ store is left alone.--expect-count / --expect-last-hash, or an external OpenTimestamps anchor.What the scanner does catch, when the bytes are there: IBAN (mod-97), TCKN, cards (Luhn), TR phones (mobile / landline / 08xx / +90 / spaced), email, MRZ as above, and IP (IPv4/IPv6) only if policy.detectors.ip is true. Identity detectors (TCKN, card, IBAN, email) cannot be turned off — the schema rejects the key. A field longer than policy.scanCharCap (default 16 384) is replaced whole with [MASKED_PII]; it is never skipped.
Conarium runs as a single service inside your infrastructure (local or VPC). It's a standard MCP stdio server — your assistant launches it and speaks MCP over stdio. It needs no inbound port. The only outbound call is an npm version check at startup, disabled with CONARIUM_NO_UPDATE_CHECK=1.
npm i @conarium-ai/core npx conarium-init npx conarium-doctor --config ./conarium.config.json --no-net
init prints that doctor line itself. The package ships these commands: conarium, conarium-doctor, conarium-init, conarium-verify, conarium-countersign-verify, conarium-coverage, conarium-reconcile, conarium-stamp, conarium-anchor-upgrade, conarium-console, conarium-suggest-policy.
git clone https://github.com/dogrucanemek-alt/conarium.git cd conarium
docker build -t conarium . docker run --rm -i \ -v "$PWD/conarium.config.json:/app/conarium.config.json:ro" \ conarium --config /app/conarium.config.json
npm ci npm run build # tsc → dist/ node dist/index.js --config ./conarium.config.json
Register Conarium as an MCP server over stdio in your client (Cursor, Claude Code, Windsurf…):
{
"mcpServers": {
"conarium": {
"command": "node",
"args": ["/path/to/conarium/dist/index.js", "--config", "/path/to/conarium.config.json"]
}
}
}
From then on, every query the assistant issues passes through Conarium first. It sits in the query path, so plan for it as you would any component there. Its default is to fail closed: if it can't make a safe decision, the assistant gets a refusal — never raw data.
Source: github.com/dogrucanemek-alt/conarium — MIT-licensed. Read it, run it, fork it. Questions: e.dogru@conarium.dev.
Conarium is early. It is pre-1.0, built and run by a solo founder, with one production deployment so far (the author's own company ERP: 121,374 records, 121,366 identities masked, zero leaked to the model — the figure cannot be verified from outside). It has no third-party security certification (SOC 2 / ISO). Neither is planned. No independent penetration test — that one is on the roadmap. If you need a certified, multi-customer, enterprise-hardened vendor today, Conarium isn't there yet, and we'd rather tell you than pretend. What we offer right now is a genuinely self-hosted, inspectable governance layer and a direct line to the person who built it.
A fair concern for a solo-founder tool in your data path, and the answer is the license: Conarium is MIT-licensed. You can read the source, run it, fork it and maintain it yourself — forever, no permission needed. If the project stops tomorrow, you're not left with an orphaned black box; you keep a governance layer you fully control. That's the whole point of self-hosted + open-core: your risk isn't tied to our survival. Need a formal source-escrow arrangement on top of that for procurement? Just ask.