Configuration Reference
All VibeWarden configuration lives in vibewarden.yaml at the root of your
project. Every field can also be set via an environment variable — the variable
name is the YAML key path uppercased and prefixed with VIBEWARDEN_, with dots
replaced by underscores. Example: server.port → VIBEWARDEN_SERVER_PORT.
Environment variable substitution in YAML values is supported using ${VAR}
syntax. This is recommended for secrets:
database:
external_url: "postgres://user:${DB_PASSWORD}@db.example.com:5432/vibewarden"
profile
Type: string
Default: dev
Accepted values: dev, tls, prod
Selects the deployment profile. Affects TLS settings, credential validation
strictness, and which generated files are produced.
server
Settings for the VibeWarden HTTP listener.
| Field |
Type |
Default |
Description |
server.host |
string |
127.0.0.1 |
Host/IP to bind to |
server.port |
int |
8443 |
Port to listen on |
server:
host: 0.0.0.0
port: 8443
upstream
Settings for the upstream application being protected.
| Field |
Type |
Default |
Description |
upstream.host |
string |
127.0.0.1 |
Upstream host |
upstream.port |
int |
3000 |
Upstream port |
upstream.health.enabled |
bool |
false |
Enable active upstream health checking |
upstream.health.path |
string |
/health |
HTTP path to probe |
upstream.health.interval |
duration |
10s |
Time between probes |
upstream.health.timeout |
duration |
5s |
Per-probe timeout |
upstream.health.unhealthy_threshold |
int |
3 |
Consecutive failures to mark unhealthy |
upstream.health.healthy_threshold |
int |
2 |
Consecutive successes to mark healthy |
upstream:
host: 127.0.0.1
port: 3000
health:
enabled: true
path: /health
interval: 10s
timeout: 5s
app
Controls how your application is included in the generated Docker Compose file.
When neither build nor image is set, no app service is rendered and
VibeWarden falls back to host.docker.internal.
| Field |
Type |
Default |
Description |
app.build |
string |
"" |
Docker build context path (e.g., .) — used in dev/tls profiles |
app.image |
string |
"" |
Docker image reference (e.g., ghcr.io/org/myapp:latest) — used in prod profile |
app:
build: . # dev workflow: build from source
# image: ghcr.io/org/myapp:latest # prod workflow: use pre-built image
tls
| Field |
Type |
Default |
Description |
tls.enabled |
bool |
true |
Enable TLS |
tls.domain |
string |
"" |
Domain for the TLS certificate. Required when provider is letsencrypt |
tls.provider |
string |
"" |
Certificate provider: letsencrypt, self-signed, or external |
tls.cert_path |
string |
"" |
Path to PEM certificate. Required when provider is external |
tls.key_path |
string |
"" |
Path to PEM private key. Required when provider is external |
tls.storage_path |
string |
"" |
Directory for ACME certificate storage. Applies to letsencrypt only |
tls:
enabled: true
provider: letsencrypt
domain: myapp.example.com
auth
auth (top-level)
| Field |
Type |
Default |
Description |
auth.enabled |
bool |
false |
Enable the authentication middleware |
auth.mode |
string |
none |
Auth strategy: none, kratos, jwt, or api-key |
auth.public_paths |
list |
[] |
Glob patterns that bypass auth. /_vibewarden/* is always public |
auth.session_cookie_name |
string |
ory_kratos_session |
Kratos session cookie name |
auth.login_url |
string |
/self-service/login/browser |
Redirect for unauthenticated users |
auth.on_kratos_unavailable |
string |
503 |
Behavior when Kratos is unreachable: 503 or allow_public |
auth.identity_schema |
string |
email_password |
Identity schema: email_password, email_only, username_password, social, or a file path |
auth.jwt
Used when auth.mode is jwt.
| Field |
Type |
Default |
Description |
auth.jwt.jwks_url |
string |
"" |
Direct JWKS endpoint URL. Takes precedence over issuer_url |
auth.jwt.issuer_url |
string |
"" |
OIDC issuer base URL for auto-discovery |
auth.jwt.issuer |
string |
"" |
Expected iss claim value. Required |
auth.jwt.audience |
string |
"" |
Expected aud claim value. Required |
auth.jwt.claims_to_headers |
map |
see below |
JWT claims injected as upstream request headers |
auth.jwt.allowed_algorithms |
list |
[RS256, ES256] |
Accepted signing algorithms. Never include none or HS256 in production |
auth.jwt.cache_ttl |
duration |
1h |
How long the JWKS is cached locally |
Default claims_to_headers:
claims_to_headers:
sub: X-User-Id
email: X-User-Email
email_verified: X-User-Verified
auth.api_key
Used when auth.mode is api-key.
| Field |
Type |
Default |
Description |
auth.api_key.header |
string |
X-API-Key |
Request header carrying the API key |
auth.api_key.keys |
list |
[] |
Static key entries (see below) |
auth.api_key.openbao_path |
string |
"" |
KV path in OpenBao where key hashes are stored |
auth.api_key.cache_ttl |
duration |
5m |
TTL for keys fetched from OpenBao |
auth.api_key.scope_rules |
list |
[] |
Ordered path+method authorization rules |
Each entry in keys:
| Field |
Type |
Description |
name |
string |
Human-readable label |
hash |
string |
Hex-encoded SHA-256 of the plaintext key |
scopes |
list |
Permission scopes granted to this key |
Each entry in scope_rules:
| Field |
Type |
Description |
path |
string |
Glob pattern matched against the request path |
methods |
list |
HTTP methods this rule applies to (empty = all methods) |
required_scopes |
list |
Scopes the key must possess |
auth.social_providers
List of OAuth2/OIDC social login providers (used with auth.mode: kratos).
| Field |
Type |
Description |
provider |
string |
Provider name: google, github, apple, facebook, microsoft, gitlab, discord, slack, spotify, oidc |
client_id |
string |
OAuth2 client ID |
client_secret |
string |
OAuth2 client secret |
scopes |
list |
OAuth2 scopes to request (optional; provider defaults apply) |
label |
string |
Custom login button label (optional) |
team_id |
string |
Apple Developer Team ID (Apple only) |
key_id |
string |
Apple private key ID (Apple only) |
id |
string |
Unique identifier for OIDC entries |
issuer_url |
string |
OIDC issuer URL (OIDC provider only) |
auth.ui
| Field |
Type |
Default |
Description |
auth.ui.mode |
string |
built-in |
built-in or custom |
auth.ui.app_name |
string |
"" |
Application name on built-in login pages |
auth.ui.logo_url |
string |
"" |
Logo URL for built-in pages |
auth.ui.primary_color |
string |
#7C3AED |
Accent color for built-in pages |
auth.ui.background_color |
string |
#1a1a2e |
Background color for built-in pages |
auth.ui.login_url |
string |
"" |
Custom login page URL (when mode: custom) |
auth.ui.registration_url |
string |
"" |
Custom registration page URL |
auth.ui.settings_url |
string |
"" |
Custom account settings page URL |
auth.ui.recovery_url |
string |
"" |
Custom account recovery page URL |
kratos
Used when auth.mode is kratos.
| Field |
Type |
Default |
Description |
kratos.public_url |
string |
http://127.0.0.1:4433 |
Kratos public API URL |
kratos.admin_url |
string |
http://127.0.0.1:4434 |
Kratos admin API URL |
kratos.dsn |
string |
"" |
Kratos database DSN (postgres URL) |
kratos.external |
bool |
false |
Connect to a user-managed Kratos instance instead of starting one |
kratos.smtp.host |
string |
localhost |
SMTP server host |
kratos.smtp.port |
int |
1025 |
SMTP server port |
kratos.smtp.from |
string |
no-reply@vibewarden.local |
Sender address for Kratos emails |
rate_limit
| Field |
Type |
Default |
Description |
rate_limit.enabled |
bool |
true |
Enable rate limiting |
rate_limit.store |
string |
memory |
Backing store: memory or redis |
rate_limit.trust_proxy_headers |
bool |
false |
Read X-Forwarded-For for client IP. Enable only behind a trusted proxy |
rate_limit.exempt_paths |
list |
[] |
Glob patterns that bypass rate limiting. /_vibewarden/* is always exempt |
rate_limit.per_ip and rate_limit.per_user
| Field |
Type |
Default (per_ip) |
Default (per_user) |
Description |
requests_per_second |
float |
10 |
100 |
Sustained token refill rate |
burst |
int |
20 |
200 |
Maximum tokens that can accumulate |
rate_limit.redis
Only read when store is redis.
| Field |
Type |
Default |
Description |
url |
string |
"" |
Redis URL (redis:// or rediss://). Takes precedence over all other fields |
address |
string |
localhost:6379 |
Redis address in host:port form |
password |
string |
"" |
Redis AUTH password |
db |
int |
0 |
Logical database index |
pool_size |
int |
0 (auto) |
Connection pool size (0 = auto based on CPU count) |
key_prefix |
string |
vibewarden |
Key namespace prefix |
fallback |
bool |
true |
Fail-open on Redis failure (true) or fail-closed (false) |
health_check_interval |
duration |
30s |
How often to probe Redis for recovery |
| Field |
Type |
Default |
Description |
security_headers.enabled |
bool |
true |
Enable security headers middleware |
security_headers.hsts_max_age |
int |
31536000 |
HSTS max-age in seconds (1 year) |
security_headers.hsts_include_subdomains |
bool |
true |
Add includeSubDomains to HSTS |
security_headers.hsts_preload |
bool |
false |
Add preload to HSTS |
security_headers.content_type_nosniff |
bool |
true |
Set X-Content-Type-Options: nosniff |
security_headers.frame_option |
string |
DENY |
X-Frame-Options: DENY, SAMEORIGIN, or "" to disable |
security_headers.content_security_policy |
string |
"" (disabled) |
Content-Security-Policy value — empty by default; set explicitly to opt in |
security_headers.referrer_policy |
string |
strict-origin-when-cross-origin |
Referrer-Policy value |
security_headers.permissions_policy |
string |
"" |
Permissions-Policy value |
security_headers.cross_origin_opener_policy |
string |
same-origin |
Cross-Origin-Opener-Policy value |
security_headers.cross_origin_resource_policy |
string |
same-origin |
Cross-Origin-Resource-Policy value |
security_headers.permitted_cross_domain_policies |
string |
none |
X-Permitted-Cross-Domain-Policies value |
security_headers.suppress_via_header |
bool |
true |
Remove Via header from proxied responses |
cors
| Field |
Type |
Default |
Description |
cors.enabled |
bool |
false |
Enable CORS plugin |
cors.allowed_origins |
list |
[] |
Permitted origins. Use ["*"] for development only |
cors.allowed_methods |
list |
[GET, POST, PUT, DELETE, OPTIONS] |
Permitted HTTP methods |
cors.allowed_headers |
list |
[Content-Type, Authorization] |
Permitted request headers |
cors.exposed_headers |
list |
[] |
Response headers exposed via Access-Control-Expose-Headers |
cors.allow_credentials |
bool |
false |
Set Access-Control-Allow-Credentials: true. Must not be combined with allowed_origins: ["*"] |
cors.max_age |
int |
0 |
Preflight cache duration in seconds. 0 omits the header |
waf
VibeWarden's built-in Web Application Firewall inspects every inbound request
for common attack patterns in-process, with no external dependencies.
waf (top-level)
| Field |
Type |
Default |
Description |
waf.enabled |
bool |
false |
Enable the WAF middleware |
waf.mode |
string |
block |
Detection mode: block (reject with 400) or detect (pass through and log) |
waf.rules
Per-rule toggles. All rules are enabled by default when waf.enabled is true.
Set a rule to false to disable that check while keeping all others active.
| Field |
Type |
Default |
Description |
waf.rules.sqli |
bool |
true |
Detect SQL injection patterns in query strings and request bodies |
waf.rules.xss |
bool |
true |
Detect cross-site scripting payloads |
waf.rules.path_traversal |
bool |
true |
Detect directory traversal sequences (e.g. ../../etc/passwd) |
waf.rules.command_injection |
bool |
true |
Detect shell command-injection metacharacters |
waf.content_type_validation
| Field |
Type |
Default |
Description |
waf.content_type_validation.enabled |
bool |
false |
Enable Content-Type validation on body-bearing requests |
waf.content_type_validation.allowed |
list |
[application/json, application/x-www-form-urlencoded, multipart/form-data] |
Permitted media types. Requests with other types receive 415 Unsupported Media Type |
waf:
enabled: true
mode: block
rules:
sqli: true
xss: true
path_traversal: true
command_injection: true
content_type_validation:
enabled: true
allowed:
- application/json
- application/x-www-form-urlencoded
- multipart/form-data
body_size
| Field |
Type |
Default |
Description |
body_size.max |
string |
"" |
Global maximum body size (e.g., 1MB, 512KB). Empty means no limit |
body_size.overrides |
list |
[] |
Per-path overrides |
Each entry in body_size.overrides:
| Field |
Type |
Description |
path |
string |
URL path prefix to match |
max |
string |
Maximum body size for this path |
body_size:
max: 1MB
overrides:
- path: /api/upload
max: 50MB
ip_filter
| Field |
Type |
Default |
Description |
ip_filter.enabled |
bool |
false |
Enable IP filter plugin |
ip_filter.mode |
string |
blocklist |
allowlist or blocklist |
ip_filter.addresses |
list |
[] |
IP addresses or CIDR ranges |
ip_filter.trust_proxy_headers |
bool |
false |
Read X-Forwarded-For for client IP |
ip_filter:
enabled: true
mode: allowlist
addresses:
- 10.0.0.0/8
- 192.168.1.100
resilience
| Field |
Type |
Default |
Description |
resilience.timeout |
duration |
30s |
Upstream response timeout. 0 disables the timeout |
resilience.circuit_breaker
| Field |
Type |
Default |
Description |
resilience.circuit_breaker.enabled |
bool |
false |
Enable circuit breaker |
resilience.circuit_breaker.threshold |
int |
5 |
Consecutive failures to trip the circuit |
resilience.circuit_breaker.timeout |
duration |
60s |
How long the circuit stays open before probing |
resilience.retry
| Field |
Type |
Default |
Description |
resilience.retry.enabled |
bool |
false |
Enable retry with exponential backoff |
resilience.retry.max_attempts |
int |
3 |
Total attempts including the initial request |
resilience.retry.backoff |
duration |
100ms |
Wait before the first retry |
resilience.retry.max_backoff |
duration |
10s |
Upper bound on computed backoff |
resilience.retry.retry_on |
list |
[502, 503, 504] |
HTTP status codes that trigger a retry |
telemetry
| Field |
Type |
Default |
Description |
telemetry.enabled |
bool |
true |
Master switch for all telemetry |
telemetry.path_patterns |
list |
[] |
URL path normalization patterns using :param syntax |
telemetry.prometheus.enabled |
bool |
true |
Enable Prometheus pull-based exporter at /_vibewarden/metrics |
telemetry.otlp.enabled |
bool |
false |
Enable OTLP push-based exporter |
telemetry.otlp.endpoint |
string |
"" |
OTLP HTTP endpoint URL. Required when otlp.enabled is true |
telemetry.otlp.headers |
map |
{} |
HTTP headers for OTLP authentication |
telemetry.otlp.interval |
duration |
30s |
Export interval |
telemetry.otlp.protocol |
string |
http |
Transport protocol. Only http is supported |
telemetry.logs.otlp |
bool |
false |
Export structured events via OTLP. Requires otlp.endpoint |
telemetry.traces.enabled |
bool |
false |
Enable distributed tracing. Requires otlp.enabled |
Legacy metrics: section
The metrics: config block is deprecated. Settings are automatically migrated
to telemetry: at startup with a deprecation warning. Migrate before the next
major version.
observability
Controls generation of the optional local observability stack (Grafana, Prometheus,
Loki, Promtail).
| Field |
Type |
Default |
Description |
observability.enabled |
bool |
false |
Generate the observability stack |
observability.grafana_port |
int |
3001 |
Host port for Grafana |
observability.prometheus_port |
int |
9090 |
Host port for Prometheus |
observability.loki_port |
int |
3100 |
Host port for Loki |
observability.retention_days |
int |
7 |
Log retention period in Loki |
database
| Field |
Type |
Default |
Description |
database.external_url |
string |
"" |
Full postgres:// connection URL. When set, the local Postgres container is omitted from the generated Compose file |
database.tls_mode |
string |
require |
PostgreSQL SSL mode: disable, require, verify-ca, verify-full |
database.pool.max_conns |
int |
10 |
Maximum open connections |
database.pool.min_conns |
int |
2 |
Minimum idle connections |
database.connect_timeout |
duration |
10s |
Connection establishment timeout |
egress
Configuration for the egress proxy plugin. See the Egress Proxy guide
for a full feature walkthrough.
egress (top-level)
| Field |
Type |
Default |
Description |
egress.enabled |
bool |
false |
Enable the egress proxy plugin |
egress.listen |
string |
127.0.0.1:8081 |
TCP address the egress proxy binds to |
egress.default_policy |
string |
deny |
Disposition for requests that match no route: deny or allow |
egress.allow_insecure |
bool |
false |
Permit plain HTTP egress requests globally. Per-route allow_insecure overrides this |
egress.default_timeout |
duration |
30s |
Request timeout applied when a route does not specify its own |
egress.default_body_size_limit |
string |
"" |
Global maximum request body size (e.g. 10MB). Empty means no limit |
egress.default_response_size_limit |
string |
"" |
Global maximum response body size (e.g. 50MB). Empty means no limit |
egress.dns
DNS-level SSRF protection settings.
| Field |
Type |
Default |
Description |
egress.dns.block_private |
bool |
true |
Block requests to RFC 1918 private, loopback, and reserved IP ranges |
egress.dns.allowed_private |
list |
[] |
CIDR ranges exempt from block_private. Example: ["10.0.0.0/8"] |
egress.routes
Ordered list of egress route definitions. Routes are evaluated in declaration
order; the first matching route wins.
| Field |
Type |
Default |
Description |
name |
string |
— |
Unique human-readable identifier for this route. Required |
pattern |
string |
— |
URL glob matched against outbound request URLs (must start with http:// or https://). Required |
methods |
list |
[] |
HTTP methods this route applies to. Empty means all methods |
timeout |
duration |
"" |
Per-route request timeout. Empty uses egress.default_timeout |
secret |
string |
"" |
OpenBao KV path of the secret to fetch and inject |
secret_header |
string |
"" |
Request header to inject the secret value into (e.g. Authorization) |
secret_format |
string |
"" |
Value template — {value} is replaced with the resolved secret (e.g. Bearer {value}) |
rate_limit |
string |
"" |
Rate limit expression (e.g. 100/s, 500/m). Empty means no per-route limit |
body_size_limit |
string |
"" |
Maximum request body size. Empty uses egress.default_body_size_limit |
response_size_limit |
string |
"" |
Maximum response body size. Empty uses egress.default_response_size_limit |
allow_insecure |
bool |
false |
Permit plain HTTP for this route, overriding the global setting |
egress.routes[].circuit_breaker
| Field |
Type |
Description |
threshold |
int |
Consecutive failures to trip the circuit. Must be > 0 |
reset_after |
duration |
How long the circuit stays open before allowing a probe request |
egress.routes[].retries
| Field |
Type |
Default |
Description |
max |
int |
— |
Maximum retry attempts (not counting the initial request). Must be >= 1 |
methods |
list |
[GET, HEAD, PUT, DELETE] |
HTTP methods eligible for retry. Empty uses the default idempotent set |
backoff |
string |
exponential |
Backoff strategy: exponential or fixed |
egress.routes[].mtls
| Field |
Type |
Description |
cert_path |
string |
Filesystem path to the PEM-encoded client certificate |
key_path |
string |
Filesystem path to the PEM-encoded private key |
ca_path |
string |
Filesystem path to a PEM-encoded CA bundle used to verify the server's certificate (optional; uses system roots when empty) |
egress.routes[].validate_response
| Field |
Type |
Description |
status_codes |
list |
Allowed HTTP status code expressions (e.g. ["2xx", "301"]). Empty means no validation |
content_types |
list |
Allowed MIME type prefixes (e.g. ["application/json"]). Empty means no validation |
egress.routes[].cache
| Field |
Type |
Description |
enabled |
bool |
Activate in-memory response caching for this route |
ttl |
duration |
Cache entry lifetime. Zero means never expire (not recommended) |
max_size |
int |
Maximum cached response body size in bytes. Zero means no per-entry limit |
egress.routes[].sanitize
| Field |
Type |
Description |
headers |
list |
Header names whose values are replaced with [REDACTED] in log events (forwarded request is unchanged) |
query_params |
list |
Query parameter names stripped from the URL before forwarding |
body_fields |
list |
JSON field names replaced with [REDACTED] in the request body before forwarding. Only applied when Content-Type is application/json |
| Field |
Type |
Description |
inject |
map |
Static headers added to (or overwriting) the outbound request |
strip_request |
list |
Request header names removed before forwarding upstream |
strip_response |
list |
Response header names removed from the upstream response before returning to the app. Server and X-Powered-By are always stripped |
egress:
enabled: true
listen: "127.0.0.1:8081"
default_policy: deny
default_timeout: "30s"
dns:
block_private: true
routes:
- name: stripe-api
pattern: "https://api.stripe.com/**"
methods: ["POST"]
timeout: "10s"
secret: app/stripe
secret_header: Authorization
secret_format: "Bearer {value}"
rate_limit: "100/s"
circuit_breaker:
threshold: 5
reset_after: "30s"
retries:
max: 3
backoff: exponential
secrets
| Field |
Type |
Default |
Description |
secrets.enabled |
bool |
false |
Enable secrets management plugin |
secrets.provider |
string |
openbao |
Secret store backend |
secrets.cache_ttl |
duration |
5m |
How long fetched secrets are cached in memory |
secrets.openbao
| Field |
Type |
Default |
Description |
secrets.openbao.address |
string |
"" |
OpenBao server URL (e.g., http://openbao:8200) |
secrets.openbao.mount_path |
string |
secret |
KV v2 mount path |
secrets.openbao.auth.method |
string |
"" |
Auth method: token or approle |
secrets.openbao.auth.token |
string |
"" |
Static token (used when method: token) |
secrets.openbao.auth.role_id |
string |
"" |
AppRole role_id (used when method: approle) |
secrets.openbao.auth.secret_id |
string |
"" |
AppRole secret_id (used when method: approle) |
secrets.inject
| Field |
Type |
Description |
secrets.inject.headers |
list |
Secrets injected as HTTP request headers |
secrets.inject.env_file |
string |
Path to write a .env file with secret values |
secrets.inject.env |
list |
Secrets written to the env file |
Each entry in secrets.inject.headers:
| Field |
Type |
Description |
secret_path |
string |
KV path of the secret |
secret_key |
string |
Key within the secret map |
header |
string |
HTTP header name |
secrets.dynamic
| Field |
Type |
Default |
Description |
secrets.dynamic.postgres.enabled |
bool |
false |
Enable dynamic Postgres credential generation |
secrets.dynamic.postgres.roles |
list |
[] |
OpenBao database roles to request credentials for |
Each entry in roles:
| Field |
Type |
Description |
name |
string |
OpenBao database role name |
env_var_user |
string |
Env var to write the generated username into |
env_var_password |
string |
Env var to write the generated password into |
secrets.health
| Field |
Type |
Default |
Description |
secrets.health.check_interval |
duration |
6h |
How often to run secret health checks |
secrets.health.max_static_age |
duration |
2160h |
Maximum acceptable age of a static secret (90 days) |
secrets.health.weak_patterns |
list |
[] |
Substrings that indicate a weak or default secret |
webhooks
| Field |
Type |
Description |
webhooks.endpoints |
list |
Webhook endpoints to deliver audit events to |
Each entry in webhooks.endpoints:
| Field |
Type |
Default |
Description |
url |
string |
— |
HTTP(S) endpoint to POST events to. Required |
events |
list |
— |
Event types to deliver. Use ["*"] to subscribe to all |
format |
string |
raw |
Payload format: raw, slack, or discord |
timeout_seconds |
int |
10 |
Per-request HTTP timeout in seconds |
audit
| Field |
Type |
Default |
Description |
audit.enabled |
bool |
true |
Enable the audit log sink |
audit.output |
string |
stdout |
Write destination: stdout or a file path |
log
| Field |
Type |
Default |
Description |
log.level |
string |
info |
Log level: debug, info, warn, error |
log.format |
string |
json |
Log format: json or text |
admin
| Field |
Type |
Default |
Description |
admin.enabled |
bool |
false |
Enable the admin API at /_vibewarden/admin/* |
admin.token |
string |
"" |
Bearer token for admin API authentication |
overrides
Escape hatches for advanced users. All fields are optional.
| Field |
Type |
Description |
overrides.kratos_config |
string |
Path to a custom kratos.yml file. When set, VibeWarden uses it instead of generating one |
overrides.compose_file |
string |
Path to a custom docker-compose.yml file |
overrides.identity_schema |
string |
Path to a custom Kratos identity schema JSON file |
Full example vibewarden.yaml
profile: dev
server:
host: 0.0.0.0
port: 8443
tls:
enabled: true
provider: self-signed
upstream:
host: 127.0.0.1
port: 3000
auth:
enabled: true
mode: jwt
jwt:
jwks_url: "https://dev-abc123.us.auth0.com/.well-known/jwks.json"
issuer: "https://dev-abc123.us.auth0.com/"
audience: "https://api.your-app.com"
claims_to_headers:
sub: X-User-Id
email: X-User-Email
email_verified: X-User-Verified
public_paths:
- /health
- /static/*
rate_limit:
enabled: true
store: memory
per_ip:
requests_per_second: 10
burst: 20
per_user:
requests_per_second: 100
burst: 200
security_headers:
enabled: true
hsts_max_age: 31536000
content_security_policy: ""
telemetry:
enabled: true
prometheus:
enabled: true
path_patterns:
- "/api/v1/users/:id"
- "/api/v1/orders/:order_id"
log:
level: info
format: json