β οΈ Work in Progress / Experimental β Version Guard is under active development. APIs, configuration formats, and behavior may change without notice. Use at your own risk in production environments.
Version Guard is an open-source cloud infrastructure version monitoring system that continuously scans cloud resources (databases, caches, compute) to detect version drift and compliance issues.
Version Guard helps organizations maintain infrastructure security and compliance by:
- Proactive Detection: Identifying resources running deprecated or end-of-life (EOL) versions before they become security risks
- Multi-Cloud Support: Scanning resources across AWS, GCP, and Azure through unified inventory sources
- Cost Optimization: Preventing expensive extended support charges (6x base price for AWS Extended Support)
- Compliance Tracking: Providing Red/Yellow/Green classification for compliance dashboards
- Automation: Continuously monitoring infrastructure without manual intervention
Version Guard implements a two-stage detection pipeline:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STAGE 1: DETECT (Temporal Workflow) β
β β
β Fan-Out: Parallel Detection per Resource Type β
β βββββββββ βββββββββββ βββββββββ β
β βAurora β β EKS β β More β ... β
β βββββ¬ββββ ββββββ¬βββββ βββββ¬ββββ β
β βββββββββββββΌββββββββββββ β
β βΌ β
β Inventory (Wiz) + EOL Data + Classify β
β β β
βββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ
β STAGE 2: STORE β
β βΌ β
β Create Versioned JSON Snapshot β
β β β
β s3://bucket/snapshots/YYYY/MM/DD/{snapshot-id}.json β
β s3://bucket/snapshots/latest.json β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
π€ YOUR CUSTOM EMITTERS
(See "Extending Version Guard")
Key Components:
- Inventory Sources: Wiz saved reports for resource discovery (multi-cloud)
- EOL Data: endoflife.date API β no cloud provider credentials needed
- Classification: Red (EOL/deprecated), Yellow (extended support/approaching EOL), Green (current)
- S3 Snapshots: Versioned JSON storage for audit trail and downstream consumption
- HTTP Admin API: Trigger scans and query status
- β Multi-Cloud Inventory: Wiz integration for AWS, GCP, Azure resource discovery
- β Open EOL Data: All EOL data from endoflife.date β no cloud provider credentials needed
- β Parallel Detection: Temporal-based workflows for scalable scanning
- β Versioned Snapshots: S3 storage with full audit history
- β Local Development: Full docker-compose setup with MinIO (S3) and Temporal
- β Extensible Architecture: Plugin your own emitters for issue tracking, dashboards, notifications
Version Guard includes AI agent skills that automate common tasks. No manual configuration editing required β AI agents can autonomously add and manage resources.
Autonomously add new cloud resource types to Version Guard using any AI agent (Claude Code, Goose, Amp, etc.).
What it does:
- Queries endoflife.date API to validate EOL data coverage
- Auto-detects Wiz CSV schema from existing test fixtures
- Generates
pkg/config/defaults/resources.yamlentries with proper field mappings - Runs tests to verify configuration works
- Creates properly formatted git commits
Quick Start:
# With Claude Code (when in this repository)
claude "Use the add-version-guard-resource skill to add OpenSearch support"
# With Amp (when in this repository)
amp "Add OpenSearch to Version Guard"Time saved: ~30-60 minutes per resource type reduced to 2-3 minutes of autonomous execution.
π See SKILLS.md for comprehensive documentation, including:
- Installation for different AI platforms
- Detailed usage examples (OpenSearch, Aurora PostgreSQL, EKS)
- Troubleshooting guide
- Creating your own skills
Version Guard uses a config-driven approach - resources are defined in pkg/config/defaults/resources.yaml:
| Resource | Inventory | EOL Source | Status |
|---|---|---|---|
| EKS (Kubernetes) | Wiz | amazon-eks | β Production tested |
| ElastiCache (Redis/Valkey/Memcached) | Wiz | amazon-elasticache-redis, valkey | β Production tested |
| Aurora MySQL | Wiz | amazon-aurora-mysql | |
| Aurora PostgreSQL | Wiz | amazon-aurora-postgresql | π Config ready, needs Wiz report ID |
| OpenSearch | Wiz | amazon-opensearch, elasticsearch | β Production tested |
| RDS MySQL | β | amazon-rds-mysql | π Planned (add to config) |
| RDS PostgreSQL | β | amazon-rds-postgresql | π Planned (add to config) |
| Lambda | β | aws-lambda | π Planned (add to config) |
Adding a new resource type requires:
- A Wiz saved report for the resource type
- Adding ~15 lines to
pkg/config/defaults/resources.yaml - Adding the report ID to
WIZ_REPORT_IDSenvironment variable
No code changes needed for any resource whose inventory shape matches one of the existing patterns. If the resource needs version/engine reshaping (extracting a value from a JSON column, normalizing engine names, deriving the engine from the version, β¦) declare it via the YAML transforms DSL β see TRANSFORMS.md. See USAGE.md for the broader workflow.
- Go 1.24+
- Docker (for docker-compose local setup)
- Wiz API access (optional β falls back to mock data)
git clone https://github.com/block/Version-Guard.git
cd Version-Guard
# Build binaries
make build-all
# Verify build
./bin/version-guard --help
./bin/version-guard-cli --helpThe easiest way to run Version Guard locally. This starts Temporal, MinIO (S3-compatible storage), and the Version Guard server in one command:
# With mock inventory (no Wiz credentials needed)
docker compose up --build
# With real Wiz inventory
export WIZ_CLIENT_ID_SECRET="your-client-id"
export WIZ_CLIENT_SECRET_SECRET="your-client-secret"
export WIZ_REPORT_IDS='{
"aurora-mysql":"your-aurora-mysql-report-id",
"eks":"your-eks-report-id",
"elasticache-redis":"your-elasticache-report-id",
"elasticache-valkey":"your-elasticache-report-id",
"elasticache-memcached":"your-elasticache-report-id"
}'
docker compose up --buildServices started:
| Service | Purpose | Port |
|---|---|---|
temporal |
Workflow orchestration | 7233 (gRPC), 8233 (Web UI) |
minio |
S3-compatible snapshot storage | 9000 (API), 9001 (Console) |
endoflife |
Local EOL data override (nginx) | 8082 |
version-guard |
The server | 8081 (HTTP admin), 9090 (Temporal SDK metrics) |
The endoflife service serves patched EOL data for products with pending upstream PRs on endoflife.date, and proxies everything else to the live API. See deploy/endoflife-override/README.md for details on adding or updating overrides.
Once running, open the Temporal Web UI at http://localhost:8233 to trigger and monitor workflows.
Temporal SDK metrics are enabled by default and exposed at
http://localhost:9090/metrics. Set TEMPORAL_METRICS_ENABLED=false to disable
them, or set TEMPORAL_METRICS_LISTEN_ADDRESS to use a different address.
If you prefer running components individually:
- Start local Temporal server:
make temporal
# Opens Web UI at http://localhost:8233- Run Version Guard server (in a separate terminal):
# With mock inventory data (no Wiz credentials needed)
make dev
# Or with real Wiz inventory (requires credentials)
export WIZ_CLIENT_ID_SECRET="your-client-id"
export WIZ_CLIENT_SECRET_SECRET="your-client-secret"
export WIZ_REPORT_IDS='{"aurora-mysql":"report-id","eks":"report-id","elasticache-redis":"report-id","elasticache-valkey":"report-id","elasticache-memcached":"report-id"}'
make devVia the HTTP admin endpoint (recommended):
# Full fleet scan
curl -X POST http://localhost:8081/scan
# Targeted scan (specific resource types only)
curl -X POST http://localhost:8081/scan \
-H 'Content-Type: application/json' \
-d '{"resource_types":["aurora-mysql","eks"]}'Via the CLI:
# Full fleet scan
./bin/version-guard-cli scan start
# Targeted scan, wait for completion
./bin/version-guard-cli scan start \
--resource-type aurora-mysql --resource-type eks \
--waitVia Temporal directly:
# Temporal CLI (from inside the temporal container if using docker-compose)
docker compose exec temporal temporal workflow start \
--task-queue version-guard-detection \
--type OrchestratorWorkflow \
--input '{}' \
--address localhost:7233 \
--namespace version-guard-dev
# Or via the Temporal Web UI at http://localhost:8233 β Start WorkflowMonitor workflow execution:
# Watch Version Guard logs in real-time
docker compose logs --follow version-guard
# View Temporal Web UI for detailed workflow execution
# Open http://localhost:8233 β Workflows β Select your workflowExample successful workflow output:
Status: COMPLETED
Total Findings: 8,386 resources scanned
Compliance: 45.36%
Runtime: 29.35 seconds
Resource Breakdown:
- aurora: 4,257 findings
- eks: 155 findings (65 GREEN, 90 YELLOW)
- elasticache: 3,974 findings (3,739 GREEN, 138 YELLOW, 97 UNKNOWN)
Verify snapshot creation:
Snapshots are stored in MinIO (local S3) at s3://version-guard-snapshots/snapshots/YYYY/MM/DD/{workflow-id}.json:
# List snapshots (from logs)
docker compose logs version-guard | grep "Snapshot created"
# Access MinIO Console to browse snapshots
# Open http://localhost:9001 (default credentials: minioadmin/minioadmin)# Using the CLI
./bin/version-guard-cli service list
./bin/version-guard-cli finding list# Run all tests
make test
# Run specific package tests
go test ./pkg/workflow/detection -v
go test ./pkg/inventory/wiz -v
go test ./pkg/policy -v
# Run with coverage
make test-coverageVersion Guard is configured via environment variables or CLI flags:
| Variable | Description | Default |
|---|---|---|
TEMPORAL_ENDPOINT |
Temporal server address | localhost:7233 |
TEMPORAL_NAMESPACE |
Temporal namespace | version-guard-dev |
HTTP_PORT |
HTTP admin port (POST /scan) |
8081 |
S3_BUCKET |
S3 bucket for snapshots | version-guard-snapshots |
AWS_REGION |
AWS region (for S3 snapshots) | us-west-2 |
WIZ_CLIENT_ID_SECRET |
Wiz client ID (optional) | - |
WIZ_CLIENT_SECRET_SECRET |
Wiz client secret (optional) | - |
WIZ_REPORT_IDS |
JSON map of resource ID to Wiz report ID (optional) | - |
EOL_BASE_URL |
Custom endoflife.date API base URL (optional) | https://endoflife.date/api |
CONFIG_PATH |
Path to a custom resources config file (overrides the embedded default; empty = use embedded) | (empty) |
TAG_APP_KEYS |
Comma-separated AWS tag keys for app/service | app,application,service |
SCHEDULE_ENABLED |
Enable automatic scheduled scanning | false |
SCHEDULE_CRON |
Cron expression for scan schedule | 0 6 * * * (daily 06:00 UTC) |
SCHEDULE_ID |
Temporal schedule ID (stable across restarts) | version-guard-scan |
SCHEDULE_JITTER |
Random jitter to prevent thundering herd | 5m |
--verbose / -v |
Enable debug-level logging | false |
Custom Resource Catalog:
Version Guard ships with a canonical resources.yaml embedded into the binary at build time, so the default install scans the standard catalog with no extra files. Override it by writing your own YAML and pointing CONFIG_PATH at it β your file fully replaces the embedded default (no merge, no overlay), so you can change resource IDs, field mappings, EOL providers, or drop resources entirely without rebuilding:
# Use the embedded default (no CONFIG_PATH set)
./version-guard
# Ship a custom catalog
./version-guard --config-path /etc/version-guard/my-resources.yaml
# or
CONFIG_PATH=/etc/version-guard/my-resources.yaml ./version-guardUse pkg/config/defaults/resources.yaml as a starting template β copy it, edit, and bind-mount the file into your container. For per-resource version/engine reshaping (JSON extraction, prefix stripping, engine normalization, version-derived engine), see the dedicated TRANSFORMS.md β it covers the whole DSL, when to use each operation, and when not to use a transform at all.
Scheduled Scanning:
Version Guard can automatically run scans on a cron schedule using the Temporal Schedule API. Disabled by default β enable with SCHEDULE_ENABLED=true:
# Enable daily scans at 06:00 UTC (default)
export SCHEDULE_ENABLED=true
# Or customize the schedule
export SCHEDULE_ENABLED=true
export SCHEDULE_CRON="*/30 * * * *" # Every 30 minutes
export SCHEDULE_JITTER="2m"The schedule uses a create-or-update pattern β safe to restart the server without creating duplicate schedules. If the cron expression changes, the existing schedule is updated automatically.
# Verify the schedule
temporal schedule list --namespace version-guard-dev
temporal schedule describe --schedule-id version-guard-scan --namespace version-guard-devCustomizing AWS Tag Keys:
Version Guard extracts the service name from AWS resource tags. By default, it looks for tags like app, application, or service. You can customize these to match your organization's tagging conventions:
# Example: Your organization uses "team" for service attribution
export TAG_APP_KEYS="team,squad,application"The tag keys are tried in order β the first matching tag wins.
Wiz Report IDs:
Version Guard uses a single JSON map to configure all Wiz report IDs:
export WIZ_REPORT_IDS='{
"aurora-mysql": "your-aurora-mysql-report-id",
"eks": "your-eks-report-id",
"elasticache-redis": "your-elasticache-report-id",
"elasticache-valkey": "your-elasticache-report-id",
"elasticache-memcached": "your-elasticache-report-id"
}'The keys correspond to resource IDs in pkg/config/defaults/resources.yaml. This approach:
- β Scales to dozens of resources without env var sprawl
- β Single environment variable to manage
- β Easy to add new resources (just add to JSON map)
Logging:
Version Guard uses structured JSON logging via Go's log/slog package for production observability:
# Run with debug-level logging
./bin/version-guard --verbose
# Production mode (info-level logging only)
./bin/version-guardLogs are output in JSON format for easy parsing by log aggregation tools (Datadog, Splunk, CloudWatch Insights):
{
"time": "2024-01-15T10:30:45Z",
"level": "WARN",
"msg": "failed to detect drift for resource",
"resource_id": "arn:aws:rds:us-west-2:123456789012:cluster:my-db",
"error": "version not found in EOL database"
}Benefits:
- Machine-readable structured data with typed fields
- Context-aware logging with trace IDs
- Queryable logs (e.g., filter by
resource_idorerror) - Integrates seamlessly with observability platforms
See ./bin/version-guard --help for all options.
| Status | Criteria | Typical Action |
|---|---|---|
| π΄ RED | Past EOL, deprecated, extended support expired | Urgent upgrade required |
| π‘ YELLOW | In extended support (costly), approaching EOL (< 90 days) | Plan upgrade soon |
| π’ GREEN | In standard support, current version | Compliant |
| βͺ UNKNOWN | Version not found in EOL database | Investigate |
Version Guard provides interfaces for custom emitters so you can integrate with your own systems:
See pkg/emitters/emitters.go for interface definitions:
type IssueTrackerEmitter interface {
Emit(ctx context.Context, snapshotID string, findings []*types.Finding) (*IssueTrackerResult, error)
}
type DashboardEmitter interface {
Emit(ctx context.Context, snapshotID string, summary *types.SnapshotSummary) (*DashboardResult, error)
}Example implementations:
pkg/emitters/examples/logging_emitter.go- Logs findings to stdout (included)- Your custom emitter - Send findings to Jira, ServiceNow, Slack, PagerDuty, etc.
Snapshots are stored as JSON in S3:
s3://your-bucket/snapshots/YYYY/MM/DD/{snapshot-id}.json
s3://your-bucket/snapshots/latest.json
Snapshot Schema:
{
"snapshot_id": "scan-2026-04-09-123456",
"version": "v3",
"generated_at": "2026-04-09T12:34:56Z",
"findings_by_type": {
"aurora": [
{
"resource_id": "db-cluster-1",
"status": "red",
"message": "Running deprecated version 13.3 (EOL: 2025-03-01)"
}
]
},
"summary": {
"total_resources": 150,
"red_count": 12,
"yellow_count": 35,
"green_count": 103,
"compliance_percentage": 68.7
}
}Consume snapshots with:
- AWS Lambda triggered on S3 events
- Scheduled cron job reading
latest.json - Custom Temporal workflow (implement
Stage 3: ACT)
- ARCHITECTURE.md - Detailed system architecture
- CONTRIBUTING.md - How to contribute
- pkg/workflow/detection/ - Per-resource detection activities (inventory β EOL β classify) driven by
resources.yaml
Contributions are welcome! Please see CONTRIBUTING.md for:
- Code of conduct
- Development setup
- Testing guidelines
- Pull request process
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Bug reports: GitHub Issues
- Feature requests: GitHub Discussions
- Security issues: Please report privately via GitHub's security advisory form (do not open public issues)
Version Guard is maintained by the open-source community.
Special thanks to:
- Temporal for the workflow orchestration framework
- Wiz for multi-cloud security scanning
- endoflife.date for open EOL data
Note: Version Guard is designed as a collector/detector system. The emission of findings to issue trackers, dashboards, or notification systems is left to implementers. See "Extending Version Guard" above for integration patterns.