{"id":50103613,"url":"https://github.com/limitcool/gatewarden","last_synced_at":"2026-05-23T09:02:45.409Z","repository":{"id":356064132,"uuid":"1230868124","full_name":"limitcool/gatewarden","owner":"limitcool","description":"  Open-source AI WAF for self-hosted apps, built for Caddy, trusted identity headers, deterministic enforcement, and   reviewable AI-assisted security operations.","archived":false,"fork":false,"pushed_at":"2026-05-06T12:34:23.000Z","size":550,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T14:08:52.712Z","etag":null,"topics":["access-control","ai","ai-security","ai-waf","application-security","caddy","caddy-server","forward-auth","homelab","nextjs","oidc","postgres","reverse-proxy","rust","security-gateway","sqlite","waf","web-application-firewall","zero-trust"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/limitcool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T11:57:17.000Z","updated_at":"2026-05-06T12:36:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/limitcool/gatewarden","commit_stats":null,"previous_names":["limitcool/gatewarden"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/limitcool/gatewarden","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/limitcool%2Fgatewarden","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/limitcool%2Fgatewarden/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/limitcool%2Fgatewarden/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/limitcool%2Fgatewarden/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/limitcool","download_url":"https://codeload.github.com/limitcool/gatewarden/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/limitcool%2Fgatewarden/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33389229,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access-control","ai","ai-security","ai-waf","application-security","caddy","caddy-server","forward-auth","homelab","nextjs","oidc","postgres","reverse-proxy","rust","security-gateway","sqlite","waf","web-application-firewall","zero-trust"],"created_at":"2026-05-23T09:02:44.605Z","updated_at":"2026-05-23T09:02:45.400Z","avatar_url":"https://github.com/limitcool.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gatewarden\n\n[English](README.md) | [简体中文](README.zh-CN.md)\n\n[![GitHub release](https://img.shields.io/github/v/release/limitcool/gatewarden)](https://github.com/limitcool/gatewarden/releases)\n[![Docker pulls](https://img.shields.io/badge/ghcr-gatewarden-black)](https://github.com/limitcool/gatewarden/pkgs/container/gatewarden)\n[![Crates.io](https://img.shields.io/crates/v/gwaf)](https://crates.io/crates/gwaf)\n[![License](https://img.shields.io/github/license/limitcool/gatewarden)](LICENSE)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/limitcool/gatewarden)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/gatewarden-mark.svg\" alt=\"Gatewarden logo\" width=\"92\" height=\"92\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Open-source AI WAF for self-hosted apps\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/dashboard-overview.png\" alt=\"Gatewarden dashboard overview\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n## Overview\n\nGatewarden is an open-source AI WAF for self-hosted apps.\n\nIt sits in front of your services, consumes trusted identity headers from your auth layer, applies deterministic enforcement, and uses AI in a reviewable advisory lane for rule suggestions, event analysis, and operator workflows.\n\n## What This AI WAF Does\n\n- Protects admin and login surfaces with deterministic checks\n- Acts as an AI-assisted WAF for self-hosted and internal applications\n- Works well with `Caddy forward_auth`\n- Reuses identity context from TinyAuth, oauth2-proxy, or other OIDC-aware front layers\n- Stores events, rules, approvals, and settings in SQLite or PostgreSQL\n- Exposes a web console for events, rules, approvals, settings, status codes, and latency\n- Keeps AI in an advisory role instead of letting it block requests directly\n\n## Why Gatewarden\n\nMost self-hosted teams already have:\n\n- a reverse proxy\n- an identity layer\n- a few fragile path rules\n- scattered logs\n\nGatewarden gives those teams one place to:\n\n- enforce basic security decisions\n- inspect what happened\n- review rule changes\n- add AI-assisted analysis without giving up deterministic control\n\n## Screenshots\n\n### Dashboard\n\n![Gatewarden Dashboard](docs/assets/dashboard-overview.png)\n\n### Events\n\n![Gatewarden Events](docs/assets/dashboard-events.png)\n\n### Rules\n\n![Gatewarden Rules](docs/assets/dashboard-rules.png)\n\n## Project Status\n\nGatewarden is early, but already usable as a local or single-node OSS AI WAF deployment.\n\nCurrent OSS scope:\n\n- Caddy-first integration\n- trusted-header identity mapping\n- basic login rate limiting\n- admin-path protection\n- AI-assisted rule suggestions and operator review flows\n- console pages for dashboard, events, rules, suggestions, approvals, and settings\n- structured observability for status codes and response time from Caddy access logs\n- SQLite for lightweight single-node setups and PostgreSQL for production-backed persistence\n\nNot finished yet:\n\n- full OIDC relying-party login for the console\n- multi-node sync\n- advanced enterprise audit and collaboration workflows\n- richer AI rule generation pipeline\n\n## Architecture\n\nMain directories:\n\n- `app/` - Rust HTTP service with `forward_auth`, console API, policy evaluation, and log ingest\n- `crates/` - shared core, gateway, policy, rate-limit, and Caddy integration crates\n- `web/` - Next.js admin console\n- `gatewarden.yaml` - runtime configuration\n\n## Quick Start\n\n### Docker Compose SOP\n\n1. Create a working directory and place these files inside it:\n\n- `docker-compose.yaml`\n- `gatewarden.yaml`\n\n2. Start Gatewarden:\n\n```bash\ndocker compose up -d\n```\n\n3. Open the web console in your browser:\n\n```text\nhttp://127.0.0.1:3000\n```\n\n4. Point Caddy `forward_auth` to:\n\n```text\nhttp://127.0.0.1:4000\n```\n\nPort roles:\n\n- `3000`: browser-facing web console\n- `4000`: Gatewarden API and `forward_auth` endpoint for Caddy\n\nDefault mounts:\n\n- `./gatewarden.yaml` -\u003e `/config/gatewarden.yaml`\n- `./docker-data` -\u003e `/opt/gatewarden/app/data`\n\nThe default compose setup:\n\n- pulls `ghcr.io/limitcool/gatewarden:latest`\n- uses SQLite inside `./docker-data`\n- does not require you to set `CONSOLE_API_BASE_URL`\n\nIt pulls the published image from:\n\n```text\nghcr.io/limitcool/gatewarden:latest\n```\n\n### 1. Start the backend\n\n```powershell\ncargo run -p gwaf\n```\n\nDefault address:\n\n```text\n127.0.0.1:4000\n```\n\n### 2. Start the web console\n\n```powershell\npnpm install\npnpm --dir web run dev\n```\n\nDefault address:\n\n```text\nhttp://127.0.0.1:3010\n```\n\nSQLite remains the default quick-start database:\n\n```yaml\ndatabase:\n  url: \"sqlite://app/data/ingress.db?mode=rwc\"\n```\n\nFor production or external persistence, use PostgreSQL:\n\n```yaml\ndatabase:\n  url: \"postgres://gatewarden:change-me@127.0.0.1:5432/gatewarden\"\n```\n\n### 3. Validate the project\n\n```powershell\ncargo check\ncargo test\npnpm --dir web run check\npnpm --dir web run build\n```\n\n## Caddy Integration\n\nGatewarden is designed to work behind a real auth layer as an AI-assisted WAF with deterministic enforcement.\n\nIf you already have OIDC:\n\n- keep your current OIDC provider or auth proxy\n- let that layer authenticate the user first\n- have it emit trusted headers such as `Remote-User`, `Remote-Email`, `Remote-Groups`, `X-Auth-Provider`, and `X-Authenticated`\n- point `gatewarden.yaml` `identity.trusted_headers.*` at those real header names\n\nGatewarden does not need to replace your existing OIDC flow for this model. It consumes trusted identity context after authentication.\n\nDeployment model:\n\n- browser -\u003e `http://127.0.0.1:3000`\n- Caddy `forward_auth` -\u003e `http://127.0.0.1:4000/api/forward-auth`\n- your upstream app stays behind Caddy as usual\n\nThis is why both `3000` and `4000` exist:\n\n- `3000` is the user-facing console\n- `4000` is the internal Gatewarden API surface that Caddy calls\n\nReusable `Caddyfile` snippet:\n\n```caddy\n(gatewarden_forward_auth) {\n\tforward_auth http://127.0.0.1:4000 {\n\t\turi /api/forward-auth\n\t\tcopy_headers Remote-User Remote-Email Remote-Groups X-Auth-Provider X-Authenticated X-Request-Id\n\t}\n}\n```\n\nStructured access log example for status code, host, request ID, user agent, and latency ingestion:\n\n```caddy\n{\n\tlog {\n\t\toutput file /var/log/caddy/access.jsonl\n\t\tformat json\n\t}\n}\n\napp.example.com {\n\tlog {\n\t\toutput file /var/log/caddy/access.jsonl\n\t\tformat json\n\t}\n\n\timport gatewarden_forward_auth\n\n\treverse_proxy http://127.0.0.1:8080 {\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t\theader_up X-Forwarded-Host {host}\n\t\theader_up X-Forwarded-Uri {uri}\n\t}\n}\n```\n\nThen enable log ingestion in `gatewarden.yaml` and point it at the same JSON log file path:\n\n```yaml\nobservability:\n  caddy_access_log:\n    enabled: true\n    path: \"app/data/caddy-access.jsonl\"\n    poll_interval_ms: 1000\n```\n\nMinimal usage example:\n\n```caddy\napp.example.com {\n\timport gatewarden_forward_auth\n\n\treverse_proxy http://127.0.0.1:8080 {\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t\theader_up X-Forwarded-Host {host}\n\t\theader_up X-Forwarded-Uri {uri}\n\t}\n}\n```\n\nExample with a dedicated auth host and two protected apps:\n\n```caddy\n(gatewarden_forward_auth) {\n\tforward_auth http://127.0.0.1:4000 {\n\t\turi /api/forward-auth\n\t\tcopy_headers Remote-User Remote-Email Remote-Groups X-Auth-Provider X-Authenticated X-Request-Id\n\t}\n}\n\nauth.example.com {\n\treverse_proxy http://127.0.0.1:9000\n}\n\napp.example.com {\n\timport gatewarden_forward_auth\n\n\treverse_proxy http://127.0.0.1:8080 {\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t\theader_up X-Forwarded-Host {host}\n\t\theader_up X-Forwarded-Uri {uri}\n\t}\n}\n\naccounts.example.com {\n\timport gatewarden_forward_auth\n\n\treverse_proxy http://127.0.0.1:8081 {\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t\theader_up X-Forwarded-Host {host}\n\t\theader_up X-Forwarded-Uri {uri}\n\t}\n}\n```\n\nTo expose status code and latency metrics, enable structured Caddy access logs and point Gatewarden at that file in `gatewarden.yaml`.\n\n## Configuration\n\nThe project uses a YAML runtime config:\n\n```text\ngatewarden.yaml\n```\n\nPort mapping before you edit the config:\n\n- browser console: `http://127.0.0.1:3000`\n- Gatewarden API and Caddy `forward_auth`: `http://127.0.0.1:4000`\n- `server.listen_addr` in `gatewarden.yaml` refers to the Gatewarden API listener on `4000`, not the browser console port\n- if you use the default Docker Compose setup, the console port is handled by the container image and compose file, not by `gatewarden.yaml`\n\nComplete example:\n\n```yaml\nserver:\n  listen_addr: \"127.0.0.1:4000\"\n\ndatabase:\n  url: \"sqlite://app/data/ingress.db?mode=rwc\"\n  # Production example:\n  # url: \"postgres://gatewarden:change-me@127.0.0.1:5432/gatewarden\"\n\nidentity:\n  mode: \"trusted_header\"\n  provider_hint: \"external-oidc\"\n  trusted_headers:\n    authenticated: \"X-Authenticated\"\n    subject: \"Remote-User\"\n    email: \"Remote-Email\"\n    groups: \"Remote-Groups\"\n    provider: \"X-Auth-Provider\"\n\nsecurity:\n  admin_shadow_prefixes:\n    - \"/admin\"\n  login_ip_limit:\n    rule_id: \"protect-login-ip\"\n    path_prefix: \"/api/login\"\n    rps: 5\n    burst: 10\n  login_user_limit:\n    rule_id: \"protect-login-user\"\n    path_prefix: \"/api/login\"\n    rps: 3\n    burst: 6\n  console_admin_groups:\n    - \"admin\"\n  protected_hosts:\n    - \"app.example.com\"\n    - \"accounts.example.com\"\n\nai:\n  enabled: false\n  provider: \"openai\"\n  model: \"gpt-4.1-mini\"\n  api_key_env: \"GATEWARDEN_AI_API_KEY\"\n  # Optional for OpenAI-compatible gateways:\n  # base_url: \"https://api.openai.com/v1\"\n  timeout_ms: 15000\n  system_prompt: \"You are Gatewarden, an AI security analyst. Produce concise, evidence-based, operator-reviewable guidance.\"\n\nobservability:\n  caddy_access_log:\n    enabled: true\n    path: \"app/data/caddy-access.jsonl\"\n    poll_interval_ms: 1000\n  geoip:\n    enabled: false\n    database_path: \"app/data/GeoLite2-City.mmdb\"\n```\n\nImportant sections:\n\n- `server.listen_addr`\n- `database.url`\n- `identity.trusted_headers.*`\n- `security.admin_shadow_prefixes`\n- `security.login_ip_limit.*`\n- `security.login_user_limit.*`\n- `security.console_admin_groups`\n- `ai.enabled`\n- `ai.provider`\n- `ai.model`\n- `ai.api_key_env`\n- `ai.base_url`\n- `ai.timeout_ms`\n- `observability.caddy_access_log.*`\n- `observability.geoip.*`\n\n## AI Configuration\n\nGatewarden now supports real model-backed advisory workflows for:\n\n- asynchronous AI rule suggestions\n- per-request AI explanation in the events view\n\nSupported provider values:\n\n- `openai`\n- `anthropic`\n- `gemini`\n- `groq`\n- `deepseek`\n- `xai`\n- `ollama`\n\nThe default path is:\n\n- `provider: \"openai\"`\n- `model: \"gpt-4.1-mini\"`\n- `api_key_env: \"GATEWARDEN_AI_API_KEY\"`\n\nTo use the official OpenAI API:\n\n```yaml\nai:\n  enabled: true\n  provider: \"openai\"\n  model: \"gpt-4.1-mini\"\n  api_key_env: \"GATEWARDEN_AI_API_KEY\"\n  base_url: \"https://api.openai.com/v1\"\n  timeout_ms: 15000\n```\n\nTo use an OpenAI-compatible gateway such as OpenRouter, a relay, or your own proxy:\n\n```yaml\nai:\n  enabled: true\n  provider: \"openai\"\n  model: \"gpt-4.1-mini\"\n  api_key_env: \"GATEWARDEN_AI_API_KEY\"\n  base_url: \"https://your-openai-compatible-endpoint/v1\"\n  timeout_ms: 15000\n```\n\nEnvironment example:\n\n```powershell\n$env:GATEWARDEN_AI_API_KEY=\"your-api-key\"\n```\n\nImportant boundary:\n\n- AI stays in the advisory lane\n- published enforcement still requires human approval\n- realtime blocking and rate limiting remain deterministic\n\n## AI WAF Model\n\nGatewarden follows a few explicit rules:\n\n- `Caddy-first`\n- `deterministic enforcement`\n- `trusted identity headers`\n- `AI advisory only`\n\nThat means:\n\n- identity should come from a trusted upstream auth layer\n- blocking and rate limiting remain deterministic and auditable\n- AI suggestions stay reviewable before becoming active policy\n\n## Open Source and Commercial\n\nThis repository is the OSS mainline.\n\n- License: `AGPL-3.0-only`\n- OSS repository: `gatewarden`\n- Commercial add-ons: private `gatewarden-enterprise`\n\nIf you need closed-source deployment, OEM/white-label rights, commercial support, or enterprise-only features, see [COMMERCIAL.md](COMMERCIAL.md).\n\n## Documentation\n\n- [README.zh-CN.md](README.zh-CN.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n- [SECURITY.md](SECURITY.md)\n- [COMMERCIAL.md](COMMERCIAL.md)\n\n## Branding Assets\n\nThe repository includes:\n\n- a reusable project mark for GitHub, docs, and product UI\n- an application icon for the web console\n- live screenshots from the current OSS dashboard\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flimitcool%2Fgatewarden","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flimitcool%2Fgatewarden","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flimitcool%2Fgatewarden/lists"}