WAF++ PASS – API server for persisting and querying scan results
Project description
wafpass-server
REST API for persisting and querying WAF++ PASS scan results. Part of the WAF++ framework monorepo.
| Component | Role |
|---|---|
pass/ · wafpass-core |
Compliance engine, CLI, IaC parsers ← produces results |
wafpass-server/ · this package |
FastAPI + PostgreSQL · stores results, exposes APIs |
wafpass-dashboard/ · React SPA |
Consumes this API · visualises compliance posture |
Quick start
Docker Compose (recommended)
From the repo root:
cp .env.example .env # fill in passwords
docker compose up --build
- API:
http://localhost:8000 - Swagger UI:
http://localhost:8000/api/docs - Dashboard:
http://localhost:3000
Local development
# Prerequisites: PostgreSQL running locally
pip install -e ".[dev]"
# Apply database migrations
alembic upgrade head
# Start server with auto-reload
uvicorn wafpass_server.main:app --reload --port 8000
Environment variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
— | PostgreSQL URL, e.g. postgresql+asyncpg://user:pass@host/db |
WAFPASS_ENV |
local |
Environment tag (local, staging, production) |
CORS_ORIGINS |
http://localhost:3000 |
Comma-separated allowed CORS origins |
WAFPASS_CONTROLS_DIR |
controls |
Path to WAF++ control YAML files (used by Sandbox endpoint) |
API reference
Health
| Method | Path | Description |
|---|---|---|
GET |
/health |
Liveness check → {"status": "ok"} |
Runs
Ingest and retrieve compliance scan results produced by wafpass check --output json.
| Method | Path | Description |
|---|---|---|
POST |
/runs |
Ingest a wafpass-result.json payload |
GET |
/runs |
List runs (limit, offset, project) |
GET |
/runs/{id} |
Full run with findings, controls metadata, secret findings |
GET |
/runs/{id}/controls |
Controls metadata for a run |
GET |
/runs/{id}/findings |
Filtered findings (severity, pillar, status) |
Push a result from CI:
wafpass check ./infra --output json | \
curl -s -X POST http://localhost:8000/runs \
-H "Content-Type: application/json" \
-d @-
Set metadata before posting:
import json, httpx
result = json.loads(open("wafpass-result.json").read())
result.update({"project": "my-infra", "branch": "main", "git_sha": "abc1234"})
httpx.post("http://localhost:8000/runs", json=result)
Controls catalogue
Browse and manage WAF++ controls independently of scan runs.
| Method | Path | Description |
|---|---|---|
POST |
/controls |
Upsert a control (returns {data, meta} envelope) |
GET |
/controls |
List controls (pillar, severity, page, per_page) |
GET |
/controls/{id} |
Get a single control |
DELETE |
/controls/{id} |
Delete a control |
Waivers
Team-shared waiver records. Suppresses a control from failing in the dashboard, shared across all team members.
| Method | Path | Description |
|---|---|---|
GET |
/waivers |
List waivers (project filter — returns global + project-specific) |
PUT |
/waivers/{id} |
Upsert a waiver (idempotent — create or update by control ID) |
DELETE |
/waivers/{id} |
Delete a waiver |
{
"reason": "Covered by external quarterly IAM review — SEC-1234",
"owner": "platform-team",
"expires": "2026-09-30",
"project": ""
}
Risk acceptances
Formally accepted residual risks with approver sign-off, RFC, and traceability links.
| Method | Path | Description |
|---|---|---|
GET |
/risks |
List risk acceptances |
PUT |
/risks/{id} |
Upsert a risk acceptance |
DELETE |
/risks/{id} |
Delete a risk acceptance |
{
"reason": "Legacy system — migration planned Q3 2026",
"approver": "Jane Smith",
"owner": "platform-team",
"rfc": "RFC-0042",
"jira_link": "https://jira.example.com/browse/SEC-100",
"risk_level": "high",
"residual_risk": "medium",
"expires": "2026-09-30",
"accepted_at": "2026-01-15T09:00:00Z",
"project": ""
}
Architect Sandbox
Run the real WAF++ engine against arbitrary HCL snippets in-process. Requires wafpass-core and a populated WAFPASS_CONTROLS_DIR.
| Method | Path | Description |
|---|---|---|
POST |
/sandbox |
Evaluate HCL against all loaded controls |
GET |
/sandbox/status |
Check engine availability |
# Check if engine is ready
curl http://localhost:8000/sandbox/status
# Run HCL snippet
curl -X POST http://localhost:8000/sandbox \
-H "Content-Type: application/json" \
-d '{"hcl": "resource \"aws_s3_bucket\" \"b\" {}", "iac": "terraform"}'
Without wafpass-core, the server starts normally and all other endpoints remain available. Sandbox returns 503 with a descriptive message.
Database migrations
Migrations use Alembic.
alembic upgrade head # apply all migrations
alembic downgrade -1 # roll back one step
alembic revision --autogenerate -m "my change" # generate migration after editing models.py
alembic current # show applied revision
Migration history:
| Revision | Change |
|---|---|
0001_create_runs |
Initial runs table |
0002_add_run_metadata |
path, controls_loaded, controls_run, regions, source_paths |
0003_add_controls_meta |
controls_meta JSONB |
0004_add_plan_changes |
plan_changes JSONB |
0005_add_controls |
controls catalogue table |
0006_add_secret_findings |
secret_findings JSONB |
0007_add_waivers_risks |
waivers and risk_acceptances tables |
Docker
The build context is the monorepo root because the Dockerfile copies pass/ first to install wafpass-core:
# From repo root
docker build -t wafpass-server -f wafpass-server/Dockerfile .
docker run \
-e DATABASE_URL=postgresql+asyncpg://wafpass:wafpass@host.docker.internal/wafpass \
-e CORS_ORIGINS=http://localhost:3000 \
-e WAFPASS_CONTROLS_DIR=/app/controls \
-p 8000:8000 \
wafpass-server
The entrypoint (entrypoint.sh) runs alembic upgrade head automatically before starting uvicorn — no manual migration step needed in production.
Custom controls directory:
# docker-compose.yml — wafpass-server service
volumes:
- ./my-controls:/app/controls:ro
environment:
WAFPASS_CONTROLS_DIR: /app/controls
Interactive docs
| URL | Description |
|---|---|
http://localhost:8000/api/docs |
Swagger UI — try requests in browser |
http://localhost:8000/api/redoc |
ReDoc — read-only reference |
Development
pip install -e ".[dev]"
pytest
See TECH.md for architecture details, database schema, and contribution guidance.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wafpass_server-0.4.0.tar.gz.
File metadata
- Download URL: wafpass_server-0.4.0.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dddd556d911bddd08d3a1b044f36d0090de8632484d83c51d78d70156a2d1320
|
|
| MD5 |
31968be6ae75218fc18f5353e3a2c06c
|
|
| BLAKE2b-256 |
4a0d45c404fd9a508a9083482dd5e496e29654382e60142aff975a77b8f541c3
|
Provenance
The following attestation bundles were made for wafpass_server-0.4.0.tar.gz:
Publisher:
release.yml on WAF2p/wafpass-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wafpass_server-0.4.0.tar.gz -
Subject digest:
dddd556d911bddd08d3a1b044f36d0090de8632484d83c51d78d70156a2d1320 - Sigstore transparency entry: 1254717382
- Sigstore integration time:
-
Permalink:
WAF2p/wafpass-server@be3d0e3dde341b9236ada0ef223ebc5208e11361 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/WAF2p
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@be3d0e3dde341b9236ada0ef223ebc5208e11361 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wafpass_server-0.4.0-py3-none-any.whl.
File metadata
- Download URL: wafpass_server-0.4.0-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e07e1a6424afc5bfb0bb3bbb298985ae5f4ebd2786af489d67e4af39956804b4
|
|
| MD5 |
43b111b79f26fc650f1570f9f3a2172a
|
|
| BLAKE2b-256 |
1e4c995e1c62c08ec3004859c01f9a393ad71b50279d618a9b19cfc045933b9f
|
Provenance
The following attestation bundles were made for wafpass_server-0.4.0-py3-none-any.whl:
Publisher:
release.yml on WAF2p/wafpass-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wafpass_server-0.4.0-py3-none-any.whl -
Subject digest:
e07e1a6424afc5bfb0bb3bbb298985ae5f4ebd2786af489d67e4af39956804b4 - Sigstore transparency entry: 1254717426
- Sigstore integration time:
-
Permalink:
WAF2p/wafpass-server@be3d0e3dde341b9236ada0ef223ebc5208e11361 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/WAF2p
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@be3d0e3dde341b9236ada0ef223ebc5208e11361 -
Trigger Event:
push
-
Statement type: