/workspace/config/security, or in your config.json (inference and CORS controls under the client block; dashboard credentials under governance.auth_config). The rest live in the reverse proxy in front of Vikat.
0. Read the startup security report
You do not have to audit this from memory. On every start, Vikat inspects its own resolved configuration — afterconfig.json, the configuration store and the built-in defaults have been
merged — and reports each permissive setting that is actually in effect. Each one is written as a
WARN log line and repeated in a console banner, naming the setting, what it exposes, and the exact
configuration that closes it:
governance.auth_config.is_enabled, client.enforce_auth_on_inference, the field
encryption key, client.disable_content_logging and client.allowed_origins. A gateway with all
five closed prints nothing, so the report is also the quickest confirmation that your hardening
took effect. There is no flag to suppress it — the way to silence the warning is to fix the setting.
These defaults are permissive and they have not changed. Turning one on in a release would stop
existing deployments answering, so Vikat reports the exposure rather than changing behaviour under
you. Nothing in this report alters how the gateway runs.
1. Use a strong dashboard password
The dashboard can be protected with Password protect the dashboard on the Security Settings page (an admin username + password). Anyone who reaches the dashboard URL without credentials can read configuration, virtual keys, and logs, so this is the first thing to turn on for a public host.Password policy is enforced starting OSS v1.6.0 and Enterprise v1.5.0. On these versions Vikat validates the password both in the UI and on the server before saving, and rejects weak values with HTTP 400. On earlier versions there was no strength check at all. If you are running an older build, choose a strong password manually (and upgrade as soon as you can).
- At least 12 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
2. Enforce authentication on inference
By default, inference endpoints (/v1/chat/completions, /v1/embeddings, /v1/images/generations, and related endpoints) accept anonymous requests. On a public host that means anyone who finds the URL can spend against your provider keys.
Turn on the Enable Auth on Inference toggle on the Security Settings page (labeled Enforce Virtual Keys on Inference in OSS). This requires every inference call to present a valid credential, such as a Virtual Key, API key, or user token, which Vikat resolves to scoped upstream provider keys. Your raw provider keys never leave the gateway.
This is the main setting. The older fields
enforce_governance_header and enforce_scim_auth are deprecated. Don’t use them in new deployments. Changing this setting requires a Vikat restart in Enterprise.3. Review the rest of the Security Settings page
The Security Settings page (/workspace/config/security) exposes several more controls worth checking before going public:
x-vikat-eh-* header allowlist (header_filter_config). See Tighten both header allowlists for details.
4. Terminate TLS and serve from a reverse proxy
Never expose Vikat’s HTTP port directly to the internet. Put a reverse proxy (NGINX, an Ingress controller, or a cloud load balancer) in front of it to terminate TLS, so all traffic, including dashboard logins, virtual keys, and prompts, is encrypted in transit. See the Nginx reverse proxy guide for streaming-safe proxy settings, and bind Vikat itself to an internal interface so it is only reachable through the proxy.5. Send security headers from the reverse proxy
Add hardening response headers at the proxy layer to defend the dashboard against clickjacking, MIME sniffing, and protocol downgrade. Vikat is served behind the proxy, so this is the right place to set them once for every response.- NGINX
- Kubernetes (NGINX Ingress)
Use the
always flag (NGINX) so headers are sent even on error responses. Only enable HSTS once you are confident HTTPS will stay on. Browsers cache it for the full max-age.6. Restrict network exposure
Network-level controls limit the impact of a misconfiguration:- Don’t publish the raw container port. Expose only the reverse proxy; keep Vikat on an internal network or
localhostupstream. - Firewall / security groups. Allow inbound traffic only on
443(and80for the ACME/HTTP-to-HTTPS redirect). Block everything else. - Restrict the admin surface. If only your team needs the dashboard, put it behind a VPN, an IP allowlist, or an identity-aware proxy rather than the open internet.
- Run as non-root. The official
vikat/vikat-gatewayimage already runs as an unprivileged user. Keep it that way and avoid mounting host paths writable.
Hardening checklist
1
Startup security report is silent
Restart the gateway and check the logs: no
security posture: lines means nothing on this list is still open.2
Strong dashboard password (or SSO)
12+ chars with mixed case, number, and symbol. Upgrade to OSS v1.6.0 / Enterprise v1.5.0+ so the policy is enforced.
3
Auth enforced on inference
enforce_auth_on_inference: true: no anonymous path to a model.4
Direct API keys disabled
allow_direct_keys: false unless you have a specific reason.5
CORS locked to your origins
Explicit
allowed_origins, never * in production.6
TLS terminated at a reverse proxy
No raw HTTP port exposed to the internet.
7
Security headers set at the proxy
HSTS, frame-ancestors / X-Frame-Options, nosniff, Referrer-Policy.
8
Budgets and rate limits configured
Per-virtual-key limits before the first real request.
9
Network exposure minimized
Firewall to 443, admin surface behind VPN/allowlist where possible.
Related guides
- Nginx reverse proxy
- Enterprise security hardening
- Virtual keys
- Budgets and limits
- Security at Vikat: how Vikat itself is built and scanned

