PromptShield

Environment Variables

Every environment variable across the gateway, detection engine, and dashboard, with cross-service connection notes.

This page covers all environment variables across all three PromptShield services.

Shared secrets

These values must be identical on both sides of a connection.

SecretSet on (service A)Must match (service B)
Engine API keyPROMPTSHIELD_API_KEY (engine)ENGINE_API_KEY (dashboard) and PROMPTSHIELD_ENGINE_API_KEY (gateway)
Gateway admin tokenPROMPTSHIELD_ADMIN_TOKEN (gateway)GATEWAY_ADMIN_TOKEN (dashboard)
Audit ingest secretAUDIT_INGEST_SECRET (dashboard)AUDIT_INGEST_SECRET (gateway direct push)

The engine API key has three different variable names — one per service — because each service owns its own namespace. They must all carry the same value.


Gateway

Core

VariableDefaultDescription
PROMPTSHIELD_PORT8080Port the gateway listens on
PROMPTSHIELD_PROVIDERgeminiUpstream provider: gemini | openai | anthropic | openai-compatible | selfhosted
PROMPTSHIELD_PROVIDERSComma-separated list for multi-provider routing, e.g. anthropic,openai,gemini. First entry is the fallback.
PROMPTSHIELD_UPSTREAM_URLprovider defaultOverride the upstream base URL (single-provider mode only)
PROMPTSHIELD_CHAT_ROUTE/v1/chat/completionsInbound route path
PROMPTSHIELD_POLICY_PATHconfig/policy.yamlPath to the policy YAML file
PROMPTSHIELD_ALLOW_DEFAULT_POLICYfalseAllow startup with a default allow-all policy when the policy file is missing. Unsafe in production.

Detection engine

VariableDefaultDescription
PROMPTSHIELD_ENGINE_URLnoneDetection engine URL (e.g. http://localhost:4321). none = gateway mode, no scanning.
PROMPTSHIELD_ENGINE_API_KEYBearer token sent to the engine. Must match PROMPTSHIELD_API_KEY in the engine. Required when PROMPTSHIELD_ALLOW_UNAUTH=false on the engine (the default).

API keys

VariableDescription
PROMPTSHIELD_UPSTREAM_API_KEYGlobal key fallback (single-provider mode)
GEMINI_API_KEYGemini API key
OPENAI_API_KEYOpenAI API key
ANTHROPIC_API_KEYAnthropic API key
SELFHOSTED_API_KEYOptional key for self-hosted endpoints

Multiple keys are supported via comma-separated values — the gateway rotates through them in round-robin order.

Model selection

No default model. Set one via env var or pass model in every request.

VariableDescription
PROMPTSHIELD_MODELGlobal override — takes priority over all per-provider model vars
PROMPTSHIELD_GEMINI_MODELModel for gemini
PROMPTSHIELD_OPENAI_MODELModel for openai
PROMPTSHIELD_ANTHROPIC_MODELModel for anthropic
PROMPTSHIELD_SELFHOSTED_MODELModel for selfhosted
PROMPTSHIELD_OPENAI_COMPATIBLE_MODELModel for openai-compatible

Multi-provider routing

VariableDescription
PROMPTSHIELD_MODEL_ROUTESCustom model-to-provider routing, e.g. llama3=selfhosted,mistral=openai-compatible
PROMPTSHIELD_GEMINI_UPSTREAM_URLOverride Gemini base URL
PROMPTSHIELD_OPENAI_UPSTREAM_URLOverride OpenAI base URL
PROMPTSHIELD_ANTHROPIC_UPSTREAM_URLOverride Anthropic base URL
PROMPTSHIELD_SELFHOSTED_UPSTREAM_URLSelf-hosted endpoint URL
PROMPTSHIELD_OPENAI_COMPATIBLE_UPSTREAM_URLOpenAI-compatible endpoint URL

Admin API

VariableDefaultDescription
PROMPTSHIELD_ADMIN_TOKENAuthenticates /admin/config and /admin/policy requests. Must match GATEWAY_ADMIN_TOKEN in the dashboard. Use a strong random value in production.

Audit log (standalone mode)

VariableDefaultDescription
PROMPTSHIELD_AUDIT_URLDashboard server URL for direct audit push, e.g. http://localhost:3000. Leave unset when using docker-compose (log-fwd handles audit forwarding).
AUDIT_INGEST_SECRETShared secret for the audit ingest endpoint. Required when PROMPTSHIELD_AUDIT_URL is set. Must match AUDIT_INGEST_SECRET in the dashboard.

Security and metrics

VariableDefaultDescription
PROMPTSHIELD_EXPOSE_METRICS_ON_MAIN_PORTfalseExpose unauthenticated /metrics on the public listener. Unsafe. Prefer PROMPTSHIELD_METRICS_ADDR.
PROMPTSHIELD_METRICS_ADDRInternal-only bind address for /metrics, e.g. 127.0.0.1:9090
PROMPTSHIELD_TRUST_GATEWAY_CIDRSComma-separated CIDRs of trusted upstream forwarders (e.g. a reverse proxy in front of the gateway) whose X-Real-IP header is honored. Loopback is always trusted. Example: 10.0.0.0/8,192.168.0.0/16.

TLS

Set both or neither. Setting one without the other is a startup error.

VariableDescription
PROMPTSHIELD_TLS_CERTPath to TLS certificate (PEM)
PROMPTSHIELD_TLS_KEYPath to TLS private key (PEM)

Detection engine

VariableDefaultDescription
PROMPTSHIELD_ENGINE_PORT4321Port the engine listens on
PROMPTSHIELD_ENGINE_HOST0.0.0.0Host the engine binds to
PROMPTSHIELD_LOG_LEVELINFOLog level: DEBUG | INFO | WARNING | ERROR
PROMPTSHIELD_API_KEYBearer token clients must send. Must match ENGINE_API_KEY (dashboard) and PROMPTSHIELD_ENGINE_API_KEY (gateway). Leave empty only when PROMPTSHIELD_ALLOW_UNAUTH=true.
PROMPTSHIELD_ALLOW_UNAUTHfalseAllow unauthenticated requests. Only for local development.

Dashboard

Dashboard server (apps/server)

VariableDefaultRequiredDescription
DATABASE_URLYesPostgreSQL connection string
BETTER_AUTH_SECRETYesAuth signing secret (min 32 chars)
BETTER_AUTH_URLhttp://localhost:3000YesPublic URL of the auth server
CORS_ORIGINhttp://localhost:8000YesAllowed CORS origin (the web app URL)
ENGINE_URLhttp://localhost:4321NoDetection engine base URL
ENGINE_API_KEYNo*Bearer token for engine requests. *Required when PROMPTSHIELD_ALLOW_UNAUTH=false on the engine (the default). Must match PROMPTSHIELD_API_KEY in the engine.
GATEWAY_URLhttp://localhost:8080NoGateway base URL for health checks and admin calls
GATEWAY_ADMIN_TOKENNoToken for gateway admin API calls. Must match PROMPTSHIELD_ADMIN_TOKEN on the gateway.
GATEWAY_CONFIG_SOURCElocal_envNolocal_env reads from GATEWAY_ENV_PATH; gateway_api calls the gateway admin API
GATEWAY_CONFIG_ENDPOINT/admin/configNoGateway admin config endpoint path
POLICY_SOURCElocal_fileNolocal_file reads/writes POLICY_FILE_PATH; gateway_api uses the gateway admin API
GATEWAY_POLICY_ENDPOINT/admin/policyNoGateway admin policy endpoint path
POLICY_FILE_PATH../../config/policy.yamlNoPath to policy YAML (when POLICY_SOURCE=local_file)
POLICY_ALLOWED_DIRSNoComma-separated absolute paths allowed for policy file operations
GATEWAY_ENV_PATH../../config/gateway.envNoPath to gateway env file (when GATEWAY_CONFIG_SOURCE=local_env)
AUDIT_INGEST_SECRETYesShared secret validating audit ingest requests from log-fwd or gateway direct push
CONFIG_ADMIN_EMAILSNoComma-separated emails allowed to call config-mutating endpoints

Web app (apps/web)

VariableDefaultDescription
VITE_SERVER_URLhttp://localhost:3000Dashboard server URL (browser-side). Must be reachable from the user's browser.

Audit log forwarding (log-fwd sidecar)

VariableDefaultDescription
AUDIT_SERVER_URLhttp://localhost:3000Dashboard URL the log-fwd sidecar POSTs audit lines to
AUDIT_INGEST_SECRETShared secret (must match the dashboard server's AUDIT_INGEST_SECRET)
GATEWAY_LOG_SOURCEfileLog source: docker tails container logs, file tails a log file, stdin reads stdin
GATEWAY_CONTAINER_NAMEpromptshield-gatewayDocker container to tail when GATEWAY_LOG_SOURCE=docker
GATEWAY_LOG_FILE../../gateway-logs/promptshield.logLog file to tail when GATEWAY_LOG_SOURCE=file

Docker Compose injected variables

When running with docker-compose, the following variables are set automatically and do not need to be in .env.local:

VariableInjected valueNotes
DATABASE_URLBuilt from POSTGRES_PASSWORDInjected into the server service
BETTER_AUTH_URLhttp://localhost:3000Injected into the server service
CORS_ORIGINhttp://localhost:8000Injected into the server service
ENGINE_URLhttp://promptshield-engine:4321Container-network address
ENGINE_API_KEY${ENGINE_API_KEY:?set in .env.local}Required. Compose fails fast if missing. Must match engine PROMPTSHIELD_API_KEY.
GATEWAY_URLhttp://promptshield-gateway:8080Container-network address
VITE_SERVER_URLhttp://localhost:3000Browser-facing; stays as localhost
AUDIT_SERVER_URLhttp://ps-server:3000Docker-network dashboard address for the log-fwd sidecar
GATEWAY_LOG_SOURCEdockerDocker mode tails the gateway container logs
GATEWAY_LOG_FILE/gateway-logs/promptshield.logFile path used when GATEWAY_LOG_SOURCE=file inside the sidecar

Common misconfigurations

Dashboard cannot reach the detection engine (401)

Symptom: /internal/engine/health returns 401 or "Engine unreachable".

Cause: ENGINE_API_KEY is not set in the dashboard server environment. The engine defaults to PROMPTSHIELD_ALLOW_UNAUTH=false.

Fix: Add ENGINE_API_KEY=<value> to promptshield/.env.local. The value must equal PROMPTSHIELD_API_KEY on the engine. In docker-compose, the value is injected automatically from .env.local.


Gateway cannot reach the detection engine (401)

Symptom: Requests pass through unscanned; gateway logs show engine 401.

Cause: PROMPTSHIELD_ENGINE_API_KEY is missing from the gateway environment.

Fix: Add PROMPTSHIELD_ENGINE_API_KEY=<value> to promptshield-gateway/.env. Value must equal PROMPTSHIELD_API_KEY on the engine.


Dashboard admin calls to gateway fail (403)

Symptom: Policy or config saves from the dashboard return 403.

Cause: GATEWAY_ADMIN_TOKEN (dashboard) does not match PROMPTSHIELD_ADMIN_TOKEN (gateway).

Fix: Ensure both carry the same value. For docker-compose dev, set GATEWAY_ADMIN_TOKEN=dev-gateway-admin-token in promptshield/.env.local and PROMPTSHIELD_ADMIN_TOKEN=dev-gateway-admin-token in promptshield-gateway/.env.local.


Audit logs not appearing in the dashboard

Symptom: Dashboard shows no audit events despite traffic flowing through the gateway.

Cause: The audit path is broken, or AUDIT_INGEST_SECRET doesn't match on both sides.

Docker Compose fix: Confirm the log-fwd service is running (docker compose --profile logs up). Check that AUDIT_INGEST_SECRET in promptshield/.env.local matches the value passed to the log-fwd container (both default to dev-ingest-secret).

Standalone fix: Set PROMPTSHIELD_AUDIT_URL=http://localhost:3000 and AUDIT_INGEST_SECRET=<value> in promptshield-gateway/.env. The secret must match AUDIT_INGEST_SECRET in the dashboard.

On this page