Deployment model
Datris is fully self-hosted. It runs as a set of containers on infrastructure you operate — on-prem, in your cloud account, or on a laptop. There is no managed service, no hosted control plane, no support tunnel, and no subprocessor: no customer data reaches Datris.ai the company.Trust boundaries
Where data can go
Your data goes only where you send it. Besides the destinations your pipelines write to, data leaves the perimeter only to the AI provider you choose for each AI slot, to the agents you connect, and, if you turn them on, to web search and a GitHub repository for scripts. The chat assistants need a cloud AI provider, while code generation and embeddings can run on local models. Data Flows lists, for row values, schemas, credentials, provider keys, logs and scripts, every place each can go and the setting that changes it.Identity and authorization
- Humans log in to the UI with a username and password (BCrypt, cost 12). The first boot creates an
adminaccount with a random bootstrap password, printed once to the server log (docker compose logs datris | grep "Bootstrap login"); change it at first login. Sessions are opaque random tokens in anHttpOnly,SameSite=Strictcookie with an 8-hour TTL. Three roles — admin, editor, viewer. WithOIDC_ENABLED=true, people can instead sign in with SSO through your identity provider (OpenID Connect authorization code flow with PKCE; ID tokens checked for signature, issuer, audience, expiry and nonce, RS256/ES256 only); they become ordinary Datris users with one of the three roles, and the built-inadminaccount can never be reached through SSO. See User Authentication and Single sign-on (OIDC). - Programmatic clients — the CLI, MCP agents, scripts — each hold their own labeled API key, sent as
x-api-keyand validated against Vault. Every key carries an explicit list of capabilities (resource:action[:scope]); a call outside that list returns 403, and the MCP tool catalog an agent sees is filtered to match. Templates (read-only,rag-builder,reporting,ops) cover the common shapes. Keys are stored hashed, shown once, and revocable individually. See API Keys. - Tap scripts never receive a platform key. Each run gets a short-lived, read-only token for the platform API that the tap wrapper attaches automatically.
DATRIS_GOVERNED=1; an existing install adds USE_USER_AUTH=true, USE_API_KEYS=true, USE_AUDIT_LOG=true and USE_AGENT_POLICY=true to .env (see Switch on the governance controls). The governance.controls doctor check names any of the four that is off.
Credentials
- HashiCorp Vault holds every secret — source and destination credentials, AI provider keys, the platform’s own service passwords. The platform never persists a secret to disk outside Vault, and API responses mask sensitive fields.
- Agents never hold a key. An agent references a secret by name (
create_tap_secret,list_tap_secrets,get_tap_secret_fieldsreturns key names only). The value is delivered to the tap at run time as environment variables inside the runner and to the destination writer inside the server. It never appears in an agent’s config, prompt, or tool result. - Agents can only touch their own secrets. Secrets created through MCP are tagged as tap secrets; an agent cannot modify or delete a secret a person created in the UI.
- Secrets are masked in logs. Tap stderr is scrubbed before it is logged.
Agent governance
- Agent Policy decides, per action, whether an agent runs it unattended, waits for a person to approve it, or is refused. It is enforced by the platform on every client — the in-platform Assistant, Claude, Cursor, the CLI, any script — and an agent cannot edit the policy or decide an approval, whatever its key holds. An approval executes exactly what was proposed; if the resource changed in between, it is refused as stale. See Agent Policy.
- Audit log (with the audit log on,
USE_AUDIT_LOG=true) records every platform write, best effort by default and without loss in strict mode — create, change, run, delete, login, key rotation, denied request — attributed to a login, an API key, or the Assistant acting on a user’s behalf. Agents can attach a one-linereasonto any change and it is stored with the entry. Entries are queryable in the UI and over REST, exportable as CSV, and mirrored line-by-line to the server log (JSON under theproductionprofile) so an existing log pipeline or SIEM receives the trail with no extra integration. See Audit Log. - Provenance, with stamping on for a pipeline, stamps every landed row (XML sources excepted; a run that cannot be stamped fails in strict mode) with the run, config version, tap run, script commit, and declared source;
get_provenanceresolves a stamp back to its origin, and vector-search results carry the same fields per chunk so a RAG answer can cite where its context came from. See Provenance, Lineage & Discovery. - Versioning. Every pipeline and tap definition change is snapshotted; restores are append-only. Tap scripts can be stored in a git repository you own. See Tap GitHub Storage.
- Recovery agent actions pass through the same policy gate; under
proposemode everything it wants to do queues for approval. See Incidents.
Isolation of agent-written code
Taps are Python that agents (or people) write and Datris runs. On Docker Compose the isolated runner is on by default: tap code executes in a separatedatris-tap-runner container that holds no platform credentials and sits on a network with no route to the config store, the object store, or Vault. It can reach its data source, install the packages it declares into a throwaway environment, call back into the Datris API with its per-run read-only token, and return records. The server refuses to start with isolation on and a missing or default runner token. See Tap Execution & Isolation.
Transport and storage
- TLS terminates at a reverse proxy you place in front of the server (nginx, Caddy, Traefik). Do not expose port 8080 directly. Container-to-container traffic inside the Compose network is plaintext; the host network is the trust boundary.
- External databases. With
DATRIS_ENV=productionthe server refuses to start if a JDBC URL points at an external Postgres host withoutsslmode=requireor stricter. - At rest. Datris does not enforce encryption at rest on Postgres, MongoDB, MinIO, or Kafka; enable it per store for production.
- Multi-tenancy, when enabled, isolates tenants at the database level — separate Postgres databases and separate object-store buckets.
Air-gapped operation
Every store Datris depends on is bundled or pointable at one you already run. For the AI features, local models through Ollama cover code generation and the one-shot helpers (profiling, fix suggestions, tap diagnosis), and the bundledbge-m3 embedding server covers embeddings. The chat assistants (the Assistant, Search chat, Catalog chat, the Configuration assistant, Ops chat and the recovery agent) need one of the supported cloud providers today, so an air-gapped deployment runs without them. See No cloud exit. The bundled embedding model downloads once on first start; pre-pull the images and the model on a connected machine and move them across. Add DATRIS_UPDATE_CHECK=0 to .env so datris doctor does not try to reach datris.ai (without a route out the attempt only times out after 3 s and is reported as skipped).
No telemetry
The platform sends no usage data, crash reports, or license checks. There is no beacon in the server, the UI, the MCP server, or the installer, and no install id or other identifier is created. Verify it yourself:docs.datris.ai) are shown to you, never fetched.
Datris uses the update check to count the versions in use by distinct source address. Nothing is stored on your machine. The documentation site you are reading measures page views; the platform does not.
Vulnerability handling
Private reporting, response targets, advisories, SBOMs, and dependency scanning are on Vulnerability Disclosure.What Datris does not do
Stated so you can plan around it rather than discover it:- No built-in MFA. MFA comes from your identity provider through OIDC single sign-on (
OIDC_ENABLED=true, see Single sign-on (OIDC)): people who sign in with SSO get whatever MFA, password rules and lockout the provider enforces. Local accounts, including theadminrecovery account, still have a minimum password length only and no complexity rules or lockout. - No SAML, and no group-to-role mapping from the identity provider yet: an SSO user’s role is set on the Users screen (or
OIDC_DEFAULT_ROLEfor new people). - No built-in rate limiting or WAF — put one in front of production deployments.
- No enforced encryption at rest — enable it per store.
- CORS allowed origins default to
*for development — setcors.allowedOriginsto your real origins in production. - No SOC 2 report. In a self-hosted deployment no customer data reaches Datris.ai, so most trust-services criteria fall on your environment; the controls that do apply to the vendor — secure development and vulnerability handling — are described above.
Operator checklist for production
- Run Vault in non-dev mode with sealed root tokens.
- Put a TLS-terminating reverse proxy in front of the server; do not expose 8080.
- Switch on the governance controls:
DATRIS_GOVERNED=1on a new install, orUSE_USER_AUTH=trueandUSE_API_KEYS=true(with the agent policy and audit log in step 5) in.env; change the admin bootstrap password immediately; issue one scoped key per agent. - Turn on SSO (
OIDC_ENABLED=truewith your identity provider’s issuer and client) so people sign in with their company account and its MFA; keep theadminpassword for recovery. See Single sign-on (OIDC). - Turn on
USE_AGENT_POLICY=trueand start from Use recommended; turn onUSE_AUDIT_LOG=trueand ship the log line to your aggregator.datris doctorshowsgovernance.controlsas ok once all four are on. - Keep the isolated tap runner on (the Compose default).
- Set
DATRIS_ENV=production,sslmode=requireon external Postgres, andcors.allowedOrigins. - Enable encryption at rest on the stores; rotate API keys periodically.
- Run the doctor self-check before every upgrade.
DATRIS_GOVERNED=1, SSO, the agent policy and the audit log), so that permission and policy problems show up in QA before a catalog reaches production. See Dev, QA and production.