Skip to main content
Version: 1.7.0

Quickstart

Run the DVARA AI governance platform locally with a single docker compose up, create your first workspace and API key in the DVARA Flightdeck, and make a governed, OpenAI-compatible chat completion — end to end in under five minutes. Policy, PII scanning, budget enforcement, and the audit trail kick in on the very first request.

This page uses the ready-made quick-start stack from the dvara-examples repository. For every other deployment topology (multi-provider, Ollama, full MCP), see Docker Compose Setup.

No license needed — and nothing is held back

The quick-start stack runs with no license key, in the Development posture. That is not a trial or a reduced tier: you get the full policy engine, the complete PII pipeline, guardrails, the signed tamper-evident audit chain, real cost calculation and budgets, SSO and every routing strategy.

A license adds the MCP and A2A planes, production rights and support — see Container images & license posture. To get a 30-day trial license:

  1. Book a demobook a slot (also reachable from the navbar). Share your name, work email, company, team size, and a use case — explicitly mention you need a trial license for a self-hosted install. The team emails a 30-day trial envelope back, typically the same business day.
  2. Email support — if the web form is blocked (corporate proxy, SSO, air-gapped), email support@dvarahq.com with the same details. A human replies with a 30-day trial envelope the same business day.

For applying the key across all planes, renewal, and what happens at expiry, see Get and apply a license.

Try it in 60 seconds (no API key, no license)

Want the fastest possible taste before the full setup below? This self-contained stack runs the gateway with the built-in mock provider — so it needs no provider API key, no license and no cloning. Copy one file into an empty directory and run a single command.

Evaluation only

This minimal stack skips the production secrets (encryption password, actuator keys, audit HMAC) and leaves the data plane keyless (require-api-key defaults to false) so you can curl it directly. It's a first taste on your laptop — the full quickstart below adds a real provider, workspace-scoped API keys, the DVARA Flightdeck, and the secrets you'd set for anything past evaluation.

Create docker-compose.yml:

services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: dvara
POSTGRES_USER: dvara
POSTGRES_PASSWORD: dvara
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dvara"]
interval: 3s
timeout: 3s
retries: 20

gateway:
image: ghcr.io/dvarahq/dvara-gateway:1.7.0 # public image, no login needed
platform: linux/amd64
depends_on:
postgres:
condition: service_healthy
environment:
DVARA_LICENSE_KEY: "" # blank => Development posture (everything but MCP/A2A)
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/dvara
SPRING_DATASOURCE_USERNAME: dvara
SPRING_DATASOURCE_PASSWORD: dvara
MOCK_PROVIDER_ENABLED: "true" # built-in mock provider — no real key needed
ports:
- "8080:8080"

Start it and wait ~15 seconds for the gateway to report ready:

docker compose up -d
# wait until readiness returns 200 (the gateway boots in ~15s)
until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/actuator/health/readiness)" = "200" ]; do sleep 2; done

Make your first governed request — keyless, against the mock provider:

curl -s http://localhost:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"mock/gpt-4","messages":[{"role":"user","content":"hello dvara"}]}'
{"id":"mock-8d3af69d...","object":"chat.completion","model":"mock/gpt-4",
"choices":[{"index":0,"message":{"role":"assistant","content":"This is a mock response"},"finish_reason":"stop"}],
"usage":{"prompt_tokens":6,"completion_tokens":5,"total_tokens":11}}

That request went through the full governance pipeline — a GATEWAY_RESPONSE event was already recorded on the signed audit chain for it (visible in docker compose logs gateway). DVARA is governing the call, not just proxying it.

See governance actually block a request

DVARA scans every prompt for PII and, by default, logs what it finds. Turn that into a hard block by adding one line to the gateway service's environment: block and recreating it:

DVARA_LLM_GATEWAY_PII_DEFAULT_ACTION: "BLOCK" # detect PII and refuse the request
docker compose up -d gateway # recreate the gateway with the new policy
until [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/actuator/health/readiness)" = "200" ]; do sleep 2; done

Now send a prompt that contains a Social Security number. Governance, not the provider, stops it:

curl -s -w '\nHTTP %{http_code}\n' http://localhost:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"mock/gpt-4","messages":[{"role":"user","content":"my SSN is 123-45-6789"}]}'
{"error":{"message":"Request blocked: PII detected (SSN)",
"type":"pii_violation","code":"pii_detected","trace_id":"83e006f5..."}}
HTTP 400

The plain hello request still returns 200 — only the one carrying PII is refused, and it never reached the provider.

That is the point: the gateway governs your model calls out of the box, with no license. Detection is real (checksum-validated, not a keyword list), and BLOCK is one of three actions — LOG and REDACT are the others, the last replacing the value with a reversible token. Tear this down with docker compose down -v, then continue below for the full setup with real providers, workspace-scoped keys, and the DVARA Flightdeck.

Prerequisites

  • Docker 20.10 or later with Compose v2 (docker compose, not the legacy docker-compose).
  • No license key for this quickstart. (A license adds the MCP and A2A planes — optional, see the note above.)
  • At least one provider API key. The quick-start stack is wired for OpenAI only (OPENAI_API_KEY=sk-...). To use more providers out of the box, jump to the multi-provider stack. To run with no external provider at all, see the Ollama stack for local models.
  • Free TCP ports 8080 (gateway data plane), 8090 (DVARA Flightdeck), and 5432 (PostgreSQL). If any of these are taken, edit the ports: mappings in docker-compose.yml before starting the stack.

Step 1: Clone the examples and pick a stack

git clone https://github.com/dvarahq/dvara-examples.git
cd dvara-examples/docker-compose/quick-start

The quick-start/ stack runs three services:

  • PostgreSQL (port 5432) — config, audit, and workspace store for the governance platform. Requires PostgreSQL 14 or later; the example stack pins postgres:16-alpine.
  • DVARA LLM Gateway (port 8080) — the governed data plane that serves OpenAI-compatible API calls.
  • DVARA Flightdeck (port 8090) — the Console and Portal for managing policies, workspaces, budgets, and the audit trail.

Step 2: Configure your keys

cp .env.example .env

Open .env in your editor. The committed .env.example lists every variable the quick-start stack expects:

# .env — quick-start stack (no license needed)

# Optional — set only to activate the MCP and A2A planes:
# DVARA_LICENSE_KEY=DVARA-...<your-license-envelope>

# secrets — generate each: `openssl rand -base64 32`
# (the audit HMAC secret is optional since 1.7.0 — see the note below)
DVARA_ENCRYPTION_MASTER_PASSWORD=<openssl-rand-output>
DVARA_ACTUATOR_API_KEY=<openssl-rand-output>
DVARA_ACTUATOR_METRICS_API_KEY=<different-openssl-rand-output>
DVARA_AUDIT_HMAC_SECRET=<openssl-rand-output>

OPENAI_API_KEY=sk-<your-openai-key>
DB_PASSWORD=dvara
  • DVARA_LICENSE_KEYoptional. Leave it out and the install runs in the Development posture with every feature except the MCP and A2A planes. Set it to activate those two planes; no image change is needed.
  • DVARA_ENCRYPTION_MASTER_PASSWORD — Encrypts the provider API keys that DVARA stores. Save this value somewhere safe — losing it permanently locks you out of every stored credential.
  • DVARA_ACTUATOR_API_KEY — Bearer required by the Flightdeck License/Status page and any other authenticated actuator path (except /actuator/prometheus).
  • DVARA_ACTUATOR_METRICS_API_KEY — separate Bearer required only by /actuator/prometheus. Must differ from DVARA_ACTUATOR_API_KEY (principle of least privilege).
  • DVARA_AUDIT_HMAC_SECRET — HMAC-SHA256 key for the tamper-evident audit chain. Optional since 1.7.0: leave it out and this stack, which has a database, generates a secret on first boot and persists it — so the chain is signed from the first request with no setup step to forget. Set it when you want to hold the key material yourself, and set it on both halves when a data-plane pod ships audit to Flightdeck. The one value that is refused on a production-class profile is the default-dev-secret-change-in-production placeholder, which is published in our repository and therefore forgeable.
  • OPENAI_API_KEY — your OpenAI API key. For other providers, see the multi-provider/ stack.
  • DB_PASSWORD — PostgreSQL password. Leave as dvara for local evaluation; change it for any other environment.

To reject keyless data-plane requests with HTTP 401, also uncomment DVARA_LLM_GATEWAY_REQUIRE_API_KEY=true in .env. The default false lets unauthenticated requests through (anonymous, no workspace attribution) — convenient for the first smoke test in Step 4, but unsafe for any deployment past evaluation.

Two layers of keys
  • Provider key (sk-...) — used by the gateway to call OpenAI. Never given to client code.
  • DVARA key (gw_...) — used by your application to call the gateway. Created in Step 5.

Step 3: Start the stack

docker compose up -d
Already ran this stack before? Pull first.

The quick-start uses pull_policy: missing, so docker compose up reuses any cached image instead of fetching the newest published one. To refresh to the latest release, pull first:

docker compose pull # fetch the pinned :1.7.0 images from GHCR
docker compose up -d # restart with the refreshed images

First-time evaluators with no local cache skip this — the initial up pulls the most recent image automatically.

Apple Silicon / arm64 hosts

DVARA images are published linux/amd64 only. Docker Desktop on Apple Silicon pulls and runs them under Rosetta automatically — you may see a one-line The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) warning at boot, but everything works and you can ignore it. The data-plane performance overhead is negligible for evaluation workloads.

If you're running docker run directly (not docker compose), add --platform linux/amd64 to silence the warning. On non-Desktop Docker (e.g. plain Docker Engine on a Linux/arm64 host), --platform linux/amd64 is required, not optional.

The three containers (postgres, dvara-gateway, dvara-flightdeck) come up in order — PostgreSQL first (healthcheck-gated), then the gateway, then the DVARA Flightdeck. Total time on a warm Docker cache is ~30 seconds; the first run is slower because images pull from GitHub Container Registry.

Check everything is running:

docker compose ps

Expected output — all three services should report running with healthy status:

NAME STATUS PORTS
quick-start-dvara-gateway-1 Up 45 seconds (healthy) 0.0.0.0:8080->8080/tcp
quick-start-dvara-flightdeck-1 Up 30 seconds (healthy) 0.0.0.0:8090->8090/tcp
quick-start-postgres-1 Up 50 seconds (healthy) 0.0.0.0:5432->5432/tcp

Check the gateway is alive:

curl -s http://localhost:8080/actuator/health | python3 -m json.tool

For the rich gateway status (license, region, version, providers, routes, warnings), call /actuator/gateway-status with the operator's DVARA_ACTUATOR_API_KEY Bearer — or just open the DVARA Flightdeck's License page, which renders the same data through the browser session.

# The key was generated for you in .env during Step 1. Source it once:
source .env

curl -s http://localhost:8080/actuator/gateway-status \
-H "Authorization: Bearer $DVARA_ACTUATOR_API_KEY" \
| python3 -m json.tool

List the models the gateway currently exposes — this hits OpenAI live and returns each model with its capability flags:

curl -s http://localhost:8080/v1/models | python3 -m json.tool

For interactive prompt testing, use the Playground in the DVARA Flightdeck at http://localhost:8090/playground (requires admin login). The playground can be disabled in production with DVARA_FLIGHTDECK_PLAYGROUND_ENABLED=false.

Step 4: Make your first request

With the gateway running, make an OpenAI-compatible chat completion directly against port 8080:

curl -s -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "What is the capital of France?"}
]
}' | python3 -m json.tool

You should see a standard OpenAI chat completion response:

{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "gpt-4o",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The capital of France is Paris."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 14,
"completion_tokens": 8,
"total_tokens": 22
}
}

If the request fails

The two most common first-run errors, and what each means:

{
"error": {
"message": "No provider configured for model: gpt-4o. Set OPENAI_API_KEY to register the provider.",
"type": "invalid_request_error",
"code": "no_provider",
"trace_id": "84423bed556c4a71a9d73758e8881d08"
}
}

The gateway does not see an OpenAI provider registered. The error message tells you exactly which environment variable to set. Stop the stack (docker compose down), re-check the value in .env, and bring it back up — environment variables are read at container start, so editing .env while the stack is running does nothing.

{
"error": {
"message": "OpenAI API error 401 (invalid API key - check your provider credentials)",
"type": "provider_error",
"code": "provider_error",
"trace_id": "a6783439db1f46a6bfed511a0011e955"
}
}

The key is configured but OpenAI rejected it. Verify the key works outside DVARA with curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY".

Step 5: Create a workspace and your first API key

The request above went through the gateway without an API key. This bypasses all workspace-scoped enforcement (rate limits, budgets, policies, PII detection, cost attribution) and should only be used for initial smoke testing. Real applications authenticate with a DVARA API key that identifies a workspace — that is how all governance features work.

Production deployments

Set DVARA_LLM_GATEWAY_REQUIRE_API_KEY=true to reject keyless requests with 401. Without this, requests bypass all workspace-scoped governance.

Open the DVARA Flightdeck at http://localhost:8090. On first visit you will be redirected to /setup to create the initial owner account (first name, email, and a password of at least eight characters). Submitting it takes you to /login — creating the account does not sign you in, so log in with the credentials you just chose.

First-run /setup form for creating the initial owner accountFirst-run /setup form for creating the initial owner account
Figure 1. First-run /setup form for the initial owner

Once you are signed in:

  1. WorkspacesCreate Workspace. Give it a name like My Team and leave the defaults. Submit.
Create Workspace form — name, status, region defaultsCreate Workspace form — name, status, region defaults
Figure 2. Create Workspace form — name + status + region; defaults are fine for the quickstart
Workspaces list after creating a workspaceWorkspaces list after creating a workspace
Figure 3. Workspaces list — your new workspace appears here
  1. Click into the new workspace → API KeysCreate Key. Give it a name like quickstart-key and submit.
Create-key modal in the workspace API keys pageCreate-key modal in the workspace API keys page
Figure 4. Create-key modal — name and scope the new key
  1. Copy the generated gw_... key from the confirmation screen — it is shown exactly once and never stored in plaintext. If you close the modal without copying, create another key.
Plaintext key reveal — the gw_... value is shown exactly oncePlaintext key reveal — the gw_... value is shown exactly once
Figure 5. Plaintext reveal — copy now; the key is never stored in plaintext

Now repeat the chat completion call with the DVARA key attached:

curl -s -X POST http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer gw_<your-workspace-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Hello from my first workspace"}
]
}' | python3 -m json.tool

Go back to the DVARA Flightdeck and open Dashboard — you should see the request appear in the live metrics panel within a few seconds. Open Audit and you will see a GATEWAY_RESPONSE audit event tagged with your workspace ID and API key fingerprint. Open Token Usage to see the tokens and cost broken down per workspace.

Flightdeck Dashboard live metrics after the first governed requestFlightdeck Dashboard live metrics after the first governed request
Figure 6. Dashboard — your first request appears in the live metrics within seconds

Using the OpenAI SDK

DVARA is fully OpenAI-compatible — point any OpenAI SDK at http://localhost:8080/v1 and pass the DVARA key as api_key. The gateway handles everything else (workspace routing, rate limiting, audit, cost tracking, guardrails). To call Anthropic, Gemini, Bedrock, or any other DVARA-supported provider through the same OpenAI SDK, only the model field changes.

Copy-paste examples for every supported SDK and framework live in SDK & Framework Integrations:

  • Python — OpenAI Python, Anthropic SDK via DVARA, AWS Bedrock, Google GenAI, LiteLLM, LangChain
  • JavaScript / TypeScript — OpenAI JavaScript, Anthropic JS, Vercel AI SDK
  • Java — OpenAI Java SDK, Spring AI, LangChain4j

Stop the stack

docker compose down # stop containers, keep the postgres volume
docker compose down -v # stop and also delete the postgres volume

Use down while you are iterating — it preserves your workspaces, API keys, audit trail, and configuration across restarts. Use down -v only when you want to reset the environment completely.

Troubleshooting

STARTUP FAILED: PostgreSQL is required

If the gateway crashes on startup with this banner, the SPRING_DATASOURCE_* environment variables are missing. DVARA requires PostgreSQL — there is no in-memory fallback.

========================================
STARTUP FAILED: PostgreSQL is required
========================================
spring.datasource.url is not configured.
DVARA requires PostgreSQL — there is no
in-memory fallback.
========================================

Every stack in dvara-examples already wires PostgreSQL correctly. If you see this error, make sure you ran docker compose up -d from inside docker-compose/quick-start/ (or one of the other stack directories) — not from a custom file that stripped out the database service.

STARTUP FAILED: invalid license key

A missing DVARA_LICENSE_KEY does not crash anything — the install boots in the Development posture. This banner means the key is present but invalid: an empty string, a line break pasted into the middle, or a tampered envelope. Both the gateway and the DVARA Flightdeck validate the token at startup, so both must see the same value.

Fix:

  1. Re-copy the license token from the trial email — one continuous string, no whitespace.
  2. Put it in .env as DVARA_LICENSE_KEY=DVARA-... (the license is a DVARA--prefixed Ed25519-signed envelope, not a JWT).
  3. docker compose down && docker compose up -d.

Environment values are read at container start; editing .env while the stack is running has no effect until you restart.

Next steps

  • Docker Compose Setup — all four stacks (quick-start, multi-provider, ollama, full) and how to enable OIDC, SAML, or built-in auth
  • Provider Setup — configure OpenAI, Anthropic, Gemini, Bedrock, Azure OpenAI, Mistral, Cohere, Groq, Qwen, DeepSeek, Moonshot, ChatGLM, Grok, and Ollama in detail
  • Configuration Reference — every environment variable the gateway and DVARA Flightdeck understand
  • API — interactive OpenAPI reference for every /v1/* endpoint, with a configurable Try it panel