Skip to content

feat(cli): add infraspec check command for pre-apply security checks#213

Open
robmorgan wants to merge 2 commits into
mainfrom
feat/gatekeeper-mvp
Open

feat(cli): add infraspec check command for pre-apply security checks#213
robmorgan wants to merge 2 commits into
mainfrom
feat/gatekeeper-mvp

Conversation

@robmorgan

@robmorgan robmorgan commented Feb 5, 2026

Copy link
Copy Markdown
Owner

Summary

This PR adds InfraSpec Gatekeeper - a pre-apply guardrail that performs static analysis on Terraform configurations to catch security misconfigurations before terraform apply.

Features

  • New CLI command: infraspec check [path...] [flags]
  • HCL rule format following the terraform test pattern with .spec.hcl files
  • 10 operators: exists, not_exists, equals, not_equals, contains, not_contains, matches, greater_than, less_than, one_of
  • Logical combinators: all, any, not for complex conditions
  • HCL parser using hashicorp/hcl/v2 with variable resolution (defaults + tfvars)
  • 13 built-in security rules covering S3, Security Groups, VPC, and IAM
  • Two output formats: Styled text (with lipgloss) and JSON for CI
  • Message templating: {{.resource_name}}, {{.resource_type}}, {{.file}}, {{.line}}
  • Auto-discovery: .infraspec.hcl config files and *.spec.hcl rule files

File Discovery Pattern

my-terraform-repo/
├── .infraspec.hcl          # Repo-wide config and rules (auto-discovered)
├── modules/
│   └── s3/
│       ├── main.tf
│       └── main.spec.hcl   # Module-specific rules

HCL Rule Example

rule "S3_001" {
  name          = "S3 bucket must have encryption"
  severity      = "error"
  resource_type = "aws_s3_bucket"
  
  condition {
    check {
      attribute = "server_side_encryption_configuration"
      operator  = "exists"
    }
  }
  
  message     = "S3 bucket '{{.resource_name}}' does not have encryption"
  remediation = "Add server_side_encryption_configuration block"
  tags        = ["security", "s3", "encryption"]
}

Config File Example

# .infraspec.hcl
config {
  min_severity = "warning"  # Minimum severity to report
  format       = "text"     # Output format (text, json)
  strict       = false      # Treat unknowns as violations
  no_builtin   = false      # Disable built-in rules
}

Built-in Rules

Rule Description Severity
S3_001 S3 bucket must have encryption error
S3_002 S3 bucket should have versioning warning
S3_003 S3 bucket should block public access error
S3_004 S3 bucket should have logging warning
SG_001 No SSH from 0.0.0.0/0 error
SG_002 No RDP from 0.0.0.0/0 error
SG_003 No unrestricted ingress error
SG_004 Egress should be restricted warning
VPC_001 VPC should have flow logs warning
VPC_002 Default SG should restrict all traffic warning
IAM_001 IAM role should not have inline policy warning
IAM_002 IAM policy should not use wildcard actions error
IAM_003 IAM policy should not use wildcard resources warning

Usage Examples

# Check Terraform files
infraspec check ./terraform

# JSON output for CI
infraspec check ./terraform --format json

# List all rules
infraspec check --list-rules

# Use custom rules
infraspec check ./terraform --rules my-rules.hcl

# Exclude specific rules
infraspec check ./terraform --exclude S3_004,VPC_001

# Only run specific rules
infraspec check ./terraform --include S3_001,S3_002,SG_001

Exit Codes

  • 0 - All checks passed
  • 1 - One or more violations found
  • 2 - Parse or configuration error

Test plan

  • Unit tests for HCL rule loader (pkg/gatekeeper/rules/hcl_loader_test.go)
  • Unit tests for config loader (pkg/gatekeeper/config/config_test.go)
  • Unit tests for HCL parser (pkg/gatekeeper/parser/parser_test.go)
  • Unit tests for rule engine (pkg/gatekeeper/engine/engine_test.go)
  • Unit tests for built-in rules (pkg/gatekeeper/rules/builtin/builtin_test.go)
  • Example Terraform configs (good and bad) in examples/gatekeeper/
  • All existing tests still pass

🤖 Generated with Claude Code

Add InfraSpec Gatekeeper - a static analysis tool for Terraform configurations
that catches security misconfigurations before `terraform apply`.

Features:
- New `infraspec check` CLI command with comprehensive flags
- YAML-based rule schema with 10 operators (exists, equals, contains, matches, etc.)
- Logical combinators (all, any, not) for complex conditions
- HCL parser using hashicorp/hcl/v2 with variable resolution
- 13 built-in security rules for S3, Security Groups, VPC, and IAM
- Text output with lipgloss styling and JSON output for CI
- Message templating with {{.resource_name}}, {{.file}}, etc.

Built-in rules:
- S3_001-S3_004: Encryption, versioning, public access, logging
- SG_001-SG_004: SSH/RDP from 0.0.0.0/0, unrestricted ingress/egress
- VPC_001-VPC_002: Flow logs, default security group
- IAM_001-IAM_003: Inline policies, wildcard actions/resources

Exit codes: 0 (pass), 1 (violations), 2 (error)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
infraspec Ready Ready Preview, Comment Feb 5, 2026 6:44am

Convert InfraSpec Gatekeeper to use HCL for rules instead of YAML,
following the `terraform test` pattern with `.tftest.hcl` files.

Key changes:
- Add HCL rule parser using hashicorp/hcl/v2
- Support `.infraspec.hcl` config files (auto-discovered in repo root)
- Support `*.spec.hcl` rule files alongside Terraform code
- Convert all 13 built-in rules from YAML to HCL format
- Add config options: min_severity, format, strict, no_builtin
- Implement rule override semantics (later sources override earlier)
- Maintain backwards compatibility with YAML via extension detection

New file discovery pattern:
- `.infraspec.hcl` found by walking up directory tree
- `*.spec.hcl` files discovered alongside `.tf` files

HCL rule schema supports:
- `rule` blocks with labels for IDs
- `condition` blocks with `check`, `all`, `any`, `not` combinators
- Go template syntax for message interpolation ({{.resource_name}})

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 365 days.

@github-actions github-actions Bot added the stale label Mar 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant