Quick Start
This walkthrough takes you from a fresh install to seeing real evaluation findings.
1. Build Stave
git clone https://github.com/sufield/stave.git
cd stave
make build
2. Run Against Example Observations
Stave ships with example observations and controls in the testdata/ directory. Evaluate a scenario where an S3 bucket has been public for 10 days against a 7-day (168h) threshold:
./stave apply \
--controls testdata/e2e/e2e-01-violation/controls \
--observations testdata/e2e/e2e-01-violation/observations \
--max-unsafe 168h \
--now 2026-01-11T00:00:00Z
Output (abbreviated — input_hashes truncated for readability):
{
"schema_version": "out.v0.1",
"kind": "ASSESSMENT",
"run": {
"tool_version": "dev",
"now": "2026-01-11T00:00:00Z",
"sla_threshold": "168h0m0s",
"snapshots": 3,
"input_hashes": {
"files": { "2026-01-01T00:00:00Z.json": "26770e3c...", "...": "..." },
"overall": "8761e974..."
}
},
"summary": {
"resources_evaluated": 2,
"attack_surface": 1,
"violations": 1
},
"findings": [
{
"control_id": "CTL.EXP.DURATION.001",
"control_name": "Unsafe Exposure Duration Bound",
"control_description": "A resource must not remain unsafe beyond the configured time window.",
"resource_id": "res:aws:s3:bucket:public-bucket",
"resource_type": "storage_bucket",
"resource_vendor": "aws",
"source": {"file": "infra/main.tf", "line": 42},
"evidence": {
"first_unsafe_at": "2026-01-01T00:00:00Z",
"last_seen_unsafe_at": "2026-01-11T00:00:00Z",
"unsafe_duration_hours": 240,
"threshold_hours": 168,
"matched_properties": [{"path": "public", "value": true}],
"why_now": "Resource has been unsafe for 240 hours (threshold: 168 hours). Unsafe since 2026-01-01T00:00:00Z."
},
"mitigation": {
"description": "Control violation detected.",
"action": "Review the unsafe configuration and remediate."
}
}
]
}
Stave exits with code 3 because it found a violation: the bucket public-bucket has been publicly accessible for 240 hours, exceeding the 168-hour threshold.
3. Validate Inputs First
Before evaluation, check that your inputs are well-formed:
./stave validate \
--controls testdata/e2e/e2e-01-violation/controls \
--observations testdata/e2e/e2e-01-violation/observations
4. Diagnose Unexpected Results
If results don't match expectations, use diagnose:
./stave diagnose \
--controls testdata/e2e/e2e-01-violation/controls \
--observations testdata/e2e/e2e-01-violation/observations \
--now 2026-01-11T00:00:00Z
5. Use S3 Controls with Real Configurations
For evaluating real S3 configurations, point Stave at the S3 control pack:
./stave apply \
--controls controls/s3 \
--observations ./your-observations \
--max-unsafe 7d
Selection note:
stave controls list --built-inshows the full embedded catalog.stave packs list/stave packs show s3show curated starter policy packs.- Packs are intentionally smaller than the full catalog.
Next Steps
- Recipes cookbook — Reusable multi-command workflows (CI fix-loops, Terraform ingestion, jq filtering)
- Docker Demo — See 7 real-world S3 misconfiguration scenarios without any setup
- Core Concepts: Controls — Understand the control model
- Create Observation Snapshots — Get your AWS data into Stave's format
- Controls Reference — Browse all 43 controls