Security and data handling

Obsidian is built to run inside your environment and keep source, secrets, and findings under your control. This page describes where data lives, what is stored, and the trust boundaries between components.

Deployment and data residency

Obsidian is self-hosted. The control-plane API and all persistent state live in a single SQLite database that you host; the dashboard talks only to that API. Nothing is sent to a managed Obsidian service — there isn’t one.

What happens to your source code

A scanner node clones a repository into an ephemeral, job-scoped workspace, runs the detectors, uploads normalized findings, and discards the workspace. The control plane stores findings, evidence coordinates (file and line), and metadata — not raw repository source. The API hands runners job-scoped clone credentials, so a node only ever has access to the repository it is currently scanning.

Authentication and access

  • Users sign in with email and password; passwords are hashed with bcrypt, and sessions are cookie-based.
  • Access is role-based: Admin, Security, Auditor, and Viewer.
  • Browser mutations flow through session-authenticated proxy routes — there is no shared admin API key.

Secret handling

  • Fine-grained GitHub PATs are encrypted at rest with CRYPTO_DISCOVERY_SECRET_KEY (a base64-encoded 32-byte key). Stored payloads carry a key version; there is no automatic key rotation, so rotating the key means re-encrypting stored secrets.
  • GitHub App integration uses short-lived installation tokens rather than stored long-lived credentials.
  • Secret plaintext is never returned to the browser after submission.

Audit trail

Sensitive reads and mutations are recorded as audit events — among them node creation and credential issue/revoke, GitHub connection and public-repository changes, issue handoffs, assistant chat calls, and audit-snapshot creation. The Auditor role exists for review-only access.

AI and agent boundaries

The optional AI assistant and the MCP server are read-only and operate over the same source-backed knowledge layer. Neither returns raw repository source, secret values, clone credentials, or generated patches.

  • The AI assistant is off by default (OPENAI_ASSISTANT_ENABLED=false). When enabled, the API calls OpenAI server-side over the knowledge layer — findings and summaries, not raw code — and every call is session-authenticated and audited.
  • The MCP server is read-only across stdio and HTTP. Remote HTTP requires a bearer token, is organization-scoped, binds to loopback by default, and fails closed when no scope is set. See Connect a coding agent.

External connections and air-gap

In normal operation Obsidian reaches out only to GitHub (to clone repositories) and, if you enable the assistant, to OpenAI. For an air-gapped or no-egress deployment: keep the assistant disabled, scan local folders with the CLI, or point GitHub onboarding at GitHub Enterprise Server via CRYPTO_DISCOVERY_GITHUB_API_BASE_URL. With those choices the platform runs without external calls.

Every configuration variable referenced here is documented in Configuration.