PolicyGuard is a security policy engine for Infrastructure as Code (IaC) that helps identify security issues and compliance violations in Terraform and OpenTofu configurations. It uses Open Policy Agent (OPA) to evaluate resources against customizable security policies.
- Terraform Support: Parse both Terraform and OpenTofu configuration files
- Module Support: Analyze resources within Terraform modules
- Variable Interpolation: Handle variable references and interpolation in Terraform files
- Policy Severity Customization: Adjust severity levels to match organizational priorities
- Policy Evaluation: Evaluate resources against security policies using OPA
- Multiple Output Formats: Human-readable, JSON, JUnit, and SARIF formats
- Customizable Policies: Write your own policies in Rego
- CI/CD Integration: Exit codes and formats suitable for automation
- Real-time Feedback: Get immediate feedback on security violations
- Remediation Suggestions: Actionable fixes for security issues
- Installation
- Quick Start
- Usage
- Commands
- Security Policies
- Configuration
- CI/CD Integration
- Development
- Contributing
# Clone the repository
git clone https://github.com/ToluGIT/policyguard.git
cd policyguard
# Build the binary
go build -o policyguard ./cmd/policyguard
# Install to system path (optional)
sudo mv policyguard /usr/local/bin/
go install github.com/ToluGIT/policyguard/cmd/[email protected]
- Go 1.21 or later
- Terraform or OpenTofu configuration files to scan
- Scan a Terraform file:
policyguard scan main.tf
- Scan an OpenTofu file:
policyguard scan main.tf/tf
- Scan a directory supports .tf:
policyguard scan ./infrastructure
- Get JSON output:
policyguard scan main.tf --format json
- Fail on violations (for CI/CD):
policyguard scan main.tf --fail-on-error
PolicyGuard automatically analyzes resources defined in Terraform modules. When you scan a directory containing modules, the parser will:
- Identify module declarations in your Terraform files
- Resolve local modules (using the
source
attribute) - Parse the module contents and extract resources
- Include those resources in the security analysis
Module resources are properly attributed with their module path in violation reports, making it easy to identify which module contains a security issue.
PolicyGuard handles Terraform variable references and interpolation in your code:
- Direct references:
var.bucket_name
- String interpolation:
"${var.environment}-bucket"
- Conditional expressions:
var.enable_encryption ? "AES256" : null
- Binary operations:
var.retention_days + 7
When analyzing your code, the parser extracts variable definitions and attempts to resolve them to evaluate the actual values that would be used in your infrastructure.
# Scan Terraform files
policyguard scan vpc.tf
# Scan OpenTofu files
policyguard scan vpc.tf
# Scan multiple files .tf
policyguard scan *.tf
# Scan a directory recursively (finds all .tf, .tf.json)
policyguard scan ./infrastructure
# Scan a project with Terraform modules
policyguard scan ./project-with-modules
# Use custom policies
policyguard scan main.tf --policy ./custom-policies
# Output to file
policyguard scan main.tf --output report.txt
PolicyGuard supports multiple output formats:
- human (default): Human-readable format with colors
- json: Machine-readable JSON format
- junit: JUnit XML format for CI systems
- sarif: SARIF format for GitHub/GitLab integration
# JSON output
policyguard scan main.tf --format json
# JUnit for CI
policyguard scan main.tf --format junit --output results.xml
# SARIF for GitHub
policyguard scan main.tf --format sarif --output results.sarif
policyguard scan [path] [flags]
Flags:
--policy, -p
: Path to policy files (default:policies/
)--format, -f
: Output format (human, json, junit, sarif)--output, -o
: Output file (default: stdout)--fail-on-error
: Exit with non-zero code on violations--severity-config
: Path to custom policy severity configuration file
Examples:
# Scan with custom policies
policyguard scan main.tf --policy ./security-policies
# Generate JSON report
policyguard scan ./infra --format json --output report.json
# CI/CD mode
policyguard scan . --fail-on-error
# Use custom severity configuration
policyguard scan main.tf --severity-config custom-severity.json
policyguard validate [path] [flags]
Flags:
--verbose, -v
: Show detailed validation output
Examples:
# Validate all policies
policyguard validate policies/
# Validate specific policy
policyguard validate policies/aws/s3_encryption.rego
policyguard policy list [flags]
Flags:
--policy, -p
: Path to policy files--format, -f
: Output format (human, json)
Examples:
# List all policies
policyguard policy list
# List in JSON format
policyguard policy list --format json
policyguard policy show [policy-id] [flags]
Flags:
--policy, -p
: Path to policy files--format, -f
: Output format (human, json, raw)
Examples:
# Show policy details
policyguard policy show s3_bucket_encryption
# Show raw policy content
policyguard policy show ec2_instance_security --format raw
PolicyGuard includes built-in security policies for AWS resources:
- s3_bucket_encryption: Ensure S3 buckets have encryption enabled
- s3_bucket_public_access: Prevent public access to S3 buckets
- s3_bucket_logging: Ensure S3 access logging is enabled
- ec2_instance_security: Comprehensive EC2 security checks
- No public IP addresses
- Encrypted EBS volumes
- IMDSv2 enforcement
- Secure security groups
- Prevent unrestricted inbound access
- No SSH open to the world
- No unrestricted outbound access
- sns_encryption: Ensure SNS topics are encrypted
- sns_fifo_settings: Verify FIFO topic configurations
- sns_delivery_protocols: Check allowed delivery protocols
- sns_access_policy: Validate access control and permissions
- sqs_encryption: Ensure SQS queues have encryption enabled
- sqs_dead_letter: Verify dead letter queue configurations
- sqs_retention_period: Check message retention settings
- sqs_access_policy: Validate queue access control
- dynamodb_encryption: Ensure tables are encrypted
- dynamodb_recovery: Verify point-in-time recovery is enabled
- dynamodb_ttl: Check time-to-live configurations
- dynamodb_autoscaling: Validate capacity mode and scaling settings
- dynamodb_monitoring: Ensure monitoring and alerting are configured
You can write custom policies in Rego. Create a .rego
file in your policies directory:
package policyguard
import future.keywords.contains
import future.keywords.if
# Ensure RDS instances have encryption enabled
deny[violation] {
resource := input.resource
resource.type == "aws_db_instance"
not resource.attributes.storage_encrypted
violation := {
"id": sprintf("rds-no-encryption-%s", [resource.name]),
"policy_id": "rds_encryption",
"severity": "high",
"message": sprintf("RDS instance '%s' does not have encryption enabled", [resource.name]),
"details": "RDS instances should have encryption enabled for data at rest",
"remediation": "Set storage_encrypted = true"
}
}
PolicyGuard can be configured using:
- Command-line flags (highest priority)
- Environment variables
- Configuration file (
.policyguard.yaml
)
# .policyguard.yaml
policy_path: ./policies
output_format: human
fail_on_error: false
verbose: false
export POLICYGUARD_POLICY_PATH=./custom-policies
export POLICYGUARD_OUTPUT_FORMAT=json
export POLICYGUARD_FAIL_ON_ERROR=true
You can customize the severity levels of policy violations using a JSON configuration file. This allows you to align security policies with your organization's priorities and risk tolerance.
# Scan with custom severity configuration
policyguard scan main.tf --severity-config severity-config.json
The severity configuration file uses this format:
{
"description": "Production environment severity configuration",
"default_severity": "medium",
"severities": {
"s3_bucket_encryption": "critical",
"s3_bucket_logging": "low",
"dynamodb_encryption": "high",
"sns_encryption": "high"
}
}
Valid severity levels:
critical
: Highest severity requiring immediate attentionhigh
: High-priority security concernsmedium
: Moderate security issues (default)low
: Low-risk security concernsinfo
: Informational findings
For more details, see Policy Severity Configuration.
name: Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Install PolicyGuard
run: go install github.com/ToluGIT/policyguard/cmd/[email protected]
- name: Run Security Scan
run: policyguard scan . --fail-on-error --format sarif --output results.sarif
- name: Upload SARIF results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif
security-scan:
stage: test
script:
- go install github.com/ToluGIT/policyguard/cmd/[email protected]
- policyguard scan . --fail-on-error --format junit --output report.xml
artifacts:
reports:
junit: report.xml
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: policyguard
name: PolicyGuard Security Scan
entry: policyguard scan
language: system
files: '\.tf$'
pass_filenames: true
# Clone the repository
git clone https://github.com/ToluGIT/policyguard.git
cd policyguard
# Install dependencies
go mod download
# Run tests
make test
# Run integration tests
make integration-test
# Build binary
make build
# Install locally
make install
# Unit tests
make test
# Integration tests
make integration-test
# All tests
make test-all
# Test coverage
make coverage
- Create a new
.rego
file inpolicies/[provider]/
- Follow the policy structure:
package policyguard deny[violation] { # Policy logic here violation := { "id": "unique-id", "policy_id": "policy_name", "severity": "high|medium|low", "message": "Description", "details": "Detailed explanation", "remediation": "How to fix" } }
- Add tests for your policy
- Run
policyguard validate
to ensure syntax is correct
Contributions are supported! (especially adding more rules for other CSPs) Please see Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
- Open Policy Agent for the policy engine
- HashiCorp HCL for Terraform parsing
- Cobra for CLI framework