Embed the DVARA LLM Gateway in Spring Boot
Use the Gateway starter when your Spring Boot application should serve DVARA's OpenAI-compatible LLM API. Unlike the engine-only starter, it places policy, PII, guardrails, rate limits, routing, and audit on supported Gateway request paths.
/v1 routesDo not add it to an application that already defines the same /v1 endpoints. Spring will report conflicting mappings at startup. Move your existing endpoints, or run DVARA as a separate process instead.
What do you need?
- Java 25
- Spring Boot 4.1
- Maven 3.9 or the Maven wrapper
- DVARA Open Source 1.8
This starter is part of DVARA Open Source. It does not turn the host into the Enterprise platform and does not add Flightdeck, persistent Enterprise evidence, managed classifiers, reversible tokenization, MCP, or A2A.
The source currently builds as 1.8.0-SNAPSHOT. Build and install the Open Source repository locally for this prerelease example. Replace the version with 1.8.0 only after the final artifact resolves from Maven Central.
Add the Gateway starter
Install the current Open Source snapshot locally:
./mvnw install -DskipTests
Add the Gateway starter to a Spring Boot 4.1 application:
<properties>
<java.version>25</java.version>
<dvara.version>1.8.0-SNAPSHOT</dvara.version>
</properties>
<dependencies>
<dependency>
<groupId>com.dvarahq</groupId>
<artifactId>dvara-spring-boot-starter-gateway</artifactId>
<version>${dvara.version}</version>
</dependency>
</dependencies>
Keep your application's normal entry point:
package com.acme.ai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AiApplication {
public static void main(String[] args) {
SpringApplication.run(AiApplication.class, args);
}
}
No DVARA component scan or configuration import is required.
Configure a safe local test
Use the built-in Mock provider so the first request does not leave your machine. PII scanning is enabled by default, but its default action is LOG; this example explicitly changes it to BLOCK so you can verify enforcement.
dvara:
audit:
file:
path: ./var/audit.jsonl
hmac-secret: ${DVARA_AUDIT_HMAC_SECRET}
llm-gateway:
pii:
default-action: BLOCK
providers:
mock:
enabled: true
latency-ms: 0
response: "Hello from embedded DVARA"
Generate a private audit key and start your application:
export DVARA_AUDIT_HMAC_SECRET="$(openssl rand -base64 32)"
./mvnw spring-boot:run
API-key enforcement is off by default in Open Source. This local example therefore omits Authorization; enable API-key enforcement before putting the application on a shared network.
Make a governed model call
curl -s http://localhost:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "mock/gpt",
"messages": [
{"role": "user", "content": "Hello"}
]
}'
The host application serves the response through DVARA:
{
"id": "mock-088a5c1ba8c14ab0bad32b4afef861b0",
"object": "chat.completion",
"created": 1789277403,
"model": "mock/gpt",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello from embedded DVARA"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 5,
"completion_tokens": 6,
"total_tokens": 11
}
}
The ID and creation time differ on every request. Token counts depend on the request and provider.
Verify that governance blocks before the provider
Send a synthetic SSN:
curl -s -w '\nHTTP %{http_code}\n' \
http://localhost:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "mock/gpt",
"messages": [
{"role": "user", "content": "The test SSN is 123-45-6789."}
]
}'
DVARA refuses the request before provider dispatch:
{
"error": {
"message": "Request blocked: PII detected (SSN)",
"type": "pii_violation",
"code": "pii_detected",
"trace_id": "63b52f85bf604dc3867f99cc48dd2832"
}
}
HTTP 400
Confirm the decision was written to the local tamper-evident audit file:
jq 'select(.eventType == "PII_DETECTED") |
{eventType, source: .payload.source,
count: .payload.entity_count, types: .payload.entity_types}' \
var/audit.jsonl
{
"eventType": "PII_DETECTED",
"source": "request",
"count": 1,
"types": "SSN"
}
If the audit file is absent, check that its directory is writable and that both audit settings resolved. DVARA refuses startup when a file path is set without a real HMAC secret.
Which routes does the starter govern?
The starter exposes DVARA's implemented /v1 APIs, but those operations do not all use one identical pipeline. Chat Completions carries the complete request and response governance path shown above. Models, Embeddings, Files, and Batch have operation-specific behavior and persistence limits.
Review the LLM Gateway endpoint matrix before promising that a control applies to another operation. In particular, an Open Source host tracks Batch jobs in memory, so a restart loses local tracking.
When should you run a separate Gateway?
Embed the Gateway only when your application's lifecycle, route ownership, scaling, and failure boundary should also be the Gateway's. Run the standalone Open Source distribution when you want an independent process, or deploy the Enterprise platform when you need Flightdeck and Enterprise governance services.