Skip to content

Getting Started

This guide covers three paths to get VibeWarden running. Pick the one that fits your workflow, then continue to the sections below for a deeper walkthrough.


Path 1 — Generate a prompt (easiest)

Go to vibewarden.dev/start and fill in two fields. The page generates a ready-to-paste prompt tailored to your app and stack.


Path 2 — Copy a prompt template

Paste one of these directly into Claude Code, Cursor, or your AI coding tool.

Existing app:

Add VibeWarden security sidecar to this project.

VibeWarden is open source (Apache 2.0).
  GitHub: https://github.com/vibewarden/vibewarden
  Docs:   https://vibewarden.dev/llms-full.txt

Install: curl -fsSL https://vibewarden.dev/install.sh | sh
  (downloads a single Go binary — review the script first if you prefer)

Setup:   vibew wrap --upstream 3000
Run:     vibew dev

New project:

Build [your app idea] with VibeWarden as the security sidecar.

VibeWarden is open source (Apache 2.0).
  GitHub: https://github.com/vibewarden/vibewarden
  Docs:   https://vibewarden.dev/llms-full.txt

Install: curl -fsSL https://vibewarden.dev/install.sh | sh
Setup:   mkdir myapp && cd myapp && vibew init
Run:     vibew dev

Path 3 — Manual setup

The rest of this guide is the manual walkthrough. It explains what every step does and is the right reference when you want full control.


Prerequisites

  • Docker Engine 27+ and Docker Compose v2+ installed and running.
  • Your app listening on a local port (e.g., 3000).

Multi-architecture support

VibeWarden Docker images are published as multi-arch manifests covering linux/amd64 and linux/arm64. Docker selects the correct image automatically — no extra flags needed on Apple Silicon (M1/M2/M3) or ARM64 servers such as AWS Graviton.


Which command do I need?

Scenario Command See
Adding the sidecar to an existing app vibew wrap --upstream <port> Step 2
Starting a brand-new project vibew init Step 2 alt
Adding a feature to an existing config vibew add <feature> after either of the above

The two setup commands are parallel paths. wrap adapts an existing source tree; init scaffolds a fresh project directory. Both end up in the same place: a vibewarden.yaml you can iterate on from Step 3.


Step 1 — Install the vibew wrapper

The vibew script is a thin shell wrapper that downloads the correct VibeWarden binary for your platform and delegates all commands to it. Commit it to your repo — it pins the version your team uses.

curl -fsSL https://vibewarden.dev/vibew > vibew && chmod +x vibew

Windows

Windows support is planned — see #667 (winget) and #668 (Scoop). VibeWarden currently builds for macOS and Linux only.

You can also install vibew globally:

sudo mv vibew /usr/local/bin/vibew

Step 2 — vibew wrap

Run vibew wrap inside your project directory. Pass --upstream with the port your app listens on. Add feature flags for the security plugins you want enabled.

./vibew wrap --upstream 3000 --auth --rate-limit

Common flags:

Flag Description
--upstream <port> Port your app listens on (default: auto-detected or 3000)
--auth Enable authentication (Ory Kratos)
--rate-limit Enable rate limiting
--tls --domain example.com Enable TLS (requires --domain)
--force Overwrite existing files

What wrap generates

vibewarden.yaml          # Main config — commit this
vibew                    # Wrapper script (macOS/Linux)
.vibewarden-version      # Pinned version
.dockerignore            # Prevents secrets and build artifacts from entering the image
AGENTS.md                # AI agent context (generic — Claude Code, Cursor, etc.)
AGENTS-VIBEWARDEN.md     # Tool-agnostic AI agent context (all agents)

AI agent context

vibew wrap generates context files for your AI coding assistant. When you ask Claude or Cursor to "add a login page," the AI knows to use Kratos flows instead of building auth from scratch. Regenerate after config changes with ./vibew context refresh.


Step 2 alt — vibew init (for a brand-new project)

Use vibew init when you are starting from an empty directory and want VibeWarden wired up before you write any app code. The typical flow:

mkdir myapp && cd myapp
vibew init
# ...your AI agent reads AGENTS-VIBEWARDEN.md and writes app code that
#    fits the pre-configured security layer.

Common flags:

Flag Description
--port <port> Port your app will listen on (default: 3000)
--name <name> Project name for Docker Compose and image tags (default: directory name)
--describe "<text>" One-line project description; written to PROJECT.md and injected into agent files
--version <vN.N.N> Pin a specific VibeWarden version in .vibewarden-version
--force Overwrite existing files

What init generates

./                                # current directory (you mkdir + cd first)
  vibewarden.yaml                 # Local dev config (TLS self-signed, port 8443)
  vibewarden.production.yaml      # Production overrides (letsencrypt, port 443)
  .vibewarden-version             # Pinned VibeWarden version
  Dockerfile                      # Placeholder with examples for common stacks
  .gitignore
  PROJECT.md                      # Project description (only when --describe is given)
  AGENTS.md                       # AI agent context (tool-agnostic)
  AGENTS-VIBEWARDEN.md            # VibeWarden-specific instructions for agents

Environment separation

vibewarden.yaml is your local dev config. vibewarden.production.yaml contains production overrides. vibew bundle deep-merges the production overrides automatically. Never put production-only settings in vibewarden.yaml.

init does not generate app source code. It sets up the sidecar and the agent context files so that your AI assistant can write the app code inside a project that already has TLS, rate limiting, and the security posture nailed down.

init vs. wrap

  • vibew init — empty directory, no app code yet.
  • vibew wrap — existing source tree. Leaves your code alone and adds only the sidecar config.

If you prefer a browser-driven flow, the prompt generator at vibewarden.dev/start produces a ready-to-paste prompt that uses vibew init under the hood.

After vibew init, continue from Step 3 below.


Step 3 — Build and start

There are two development modes. Choose based on where you are in your workflow.


Mode 1 — First run (just works)

The generated Dockerfile is a multi-stage build. It compiles your app inside Docker, so you do not need any language toolchain installed locally. Run:

./vibew dev

This command:

  1. Runs vibew generate to produce .vibewarden/generated/docker-compose.yml from your vibewarden.yaml.
  2. Runs docker build (multi-stage: compiles your app inside the container).
  3. Starts the full stack with docker compose up.

Your app is protected at https://localhost:8443. Nothing else is required for the first run.

If your app image hasn't been built yet

vibew dev checks for the app Docker image before starting. If the image is missing you'll see an error like:

app image "myapp:latest" not found in the local Docker daemon.
Build the image first, then run `vibew dev` again.

Build steps:
  1. Build your application binary / artifact.
  2. Run `vibew build` to build the Docker image.

Run vibew build first, then retry vibew dev. If something else is wrong, vibew doctor gives a full diagnostic:

vibew doctor       # human-readable
vibew doctor --json  # machine-readable (for AI agents)

Mode 2 — Iterative development (faster rebuilds)

The multi-stage Docker build recompiles from source every time, which can take 30–60 seconds. For fast iteration, build locally with your language tool and then package the resulting artifact into a thin Docker image. This build takes only a few seconds.

Step 3a — Build the app artifact locally

go build -o bin/myapp ./cmd/myapp
./gradlew build
npm run build

Step 3b — Package into a thin Docker image

./vibew build

This runs docker build using the thin-image stage in your Dockerfile (the commented-out section at the bottom). It copies the pre-built artifact instead of recompiling, so the image builds in seconds. You can also run docker build -t myapp . directly if you prefer.

Step 3c — Start or restart the stack

On first start:

./vibew dev

After subsequent code changes — restart containers without a full docker compose recreate:

./vibew restart

When to use which mode

Situation Command
First run, no local toolchain needed vibew dev
Code change, want fast feedback build locally, then vibew build + vibew restart
Added a new service or changed vibewarden.yaml vibew dev (full recreate)

Trust the self-signed certificate

On first run, VibeWarden generates a self-signed CA certificate so your browser can open https://localhost:8443 without TLS errors. Export and trust it with:

./vibew cert export > vibewarden-ca.pem

Then import vibewarden-ca.pem into your browser's or OS's trusted certificate store (or pass --cacert vibewarden-ca.pem to curl).


What just happened

The stack

vibew dev starts several containers:

Container Purpose
vibewarden The security sidecar — Caddy embedding all middleware
kratos Identity server (only when auth.mode: kratos)
kratos-db Postgres for Kratos (only when auth.mode: kratos and no external DB)
openbao Secrets manager (only when secrets.enabled: true)

Your app runs outside Docker and is reached from the container network via host.docker.internal. Alternatively, set app.build or app.image in vibewarden.yaml to include your app in the Compose stack.

The middleware chain

Every inbound request passes through this ordered chain before reaching your app:

Request
 IP filter (if enabled)
 Rate limiter — per-IP token bucket
 Body size limit
 WAF — SQLi / XSS / path traversal detection (enabled by default in `detect` mode)
 Authentication — JWT / Kratos / API key
 Rate limiter — per-user token bucket
 Secret injection into request headers
 Upstream (your app)
 Security headers added to response
 Audit log event emitted
Response

Generated files

Runtime files land under .vibewarden/generated/ (add this to .gitignore):

.vibewarden/generated/
  docker-compose.yml           # Full stack
  kratos/kratos.yml            # Ory Kratos config
  kratos/identity.schema.json  # Identity schema
  observability/               # Grafana/Prometheus/Loki (when enabled)

Do not edit generated files. Re-run vibew generate after changing vibewarden.yaml.


Next steps

Enable authentication

The default JWT mode works with any OIDC provider. Edit vibewarden.yaml:

auth:
  mode: jwt
  jwt:
    jwks_url: "https://your-provider/.well-known/jwks.json"
    issuer:   "https://your-provider/"
    audience: "your-api-identifier"
  public_paths:
    - /static/*
    - /health

See the Identity Providers guide for step-by-step examples with Auth0, Keycloak, Firebase, Cognito, Okta, Supabase, and Kratos.

Add observability

./vibew add metrics
./vibew build
./vibew dev

Open Grafana at http://localhost:3001 to see request rate, latency percentiles, rate limit hits, and auth decisions in real time.

Generate a dev JWT

Use vibew token to mint a signed JWT for local testing without an external OIDC provider:

curl https://localhost:8443/api/me \
  --cacert vibewarden-ca.pem \
  -H "Authorization: Bearer $(./vibew token --json)"

See the Observability guide for details.

Enable TLS for production

./vibew add tls --domain myapp.example.com

This sets tls.provider: letsencrypt and tls.domain in vibewarden.yaml and writes the domain to vibewarden.production.yaml. When you run vibew bundle, the production overrides (letsencrypt, port 443) are merged automatically.

See the Production Deployment guide for the full production checklist.

Validate your config

./vibew validate

Reports all validation errors in vibewarden.yaml before you start the stack.


Troubleshooting

Port already in use

VibeWarden defaults to port 8443. Change it in vibewarden.yaml:

server:
  port: 9443

App not reachable

If your app does not run inside Docker, verify it is listening on 0.0.0.0 (not 127.0.0.1), or override the upstream host:

upstream:
  host: host.docker.internal
  port: 3000

Containers not starting

# Check container health
./vibew status

# Show detailed logs for all containers
./vibew logs

# Diagnose common issues automatically
./vibew doctor