Checkov is Bridgecrew's open-source static analysis tool for Infrastructure as Code. It scans Terraform, CloudFormation, Azure ARM templates, Kubernetes manifests, Helm charts, Dockerfiles, and Secrets Manager configurations against hundreds of built-in security policies mapped to CIS Benchmarks, SOC 2, PCI DSS, and HIPAA. Checkov's role in modern DevSecOps pipelines makes it a critical tool both for proactive misconfiguration detection and for authorized security assessment — understanding what Checkov checks, how suppression works, and where its blind spots lie.
Checkov is a Python-based static analysis tool with no agent or server required for basic operation. It reads IaC files, parses them into an internal resource graph, and evaluates each resource against a library of check functions. Checks are grouped by framework (terraform, cloudformation, kubernetes, dockerfile, etc.) and provider (aws, azure, gcp). Checkov integrates with Bridgecrew cloud for results aggregation, historical trending, and additional SaaS-only policies.
| Framework | File Types | Check Count (approx.) |
|---|---|---|
| Terraform (HCL) | .tf, .tfvars | 1000+ checks across AWS, Azure, GCP, OCI, K8s |
| Terraform Plan | tfplan.json | Same as HCL, but on rendered plan output |
| CloudFormation | .yaml, .json, .template | 300+ checks for AWS resources |
| Kubernetes | .yaml, .json manifests | 100+ checks for Pod, Deployment, NetworkPolicy |
| Helm | Chart.yaml, values.yaml | Rendered manifests evaluated as Kubernetes |
| Dockerfile | Dockerfile | 50+ checks for image security |
| Azure ARM | azuredeploy.json | 200+ checks for Azure resources |
| GitHub Actions | .github/workflows/*.yml | 30+ checks for workflow security |
| Ansible | *.yml playbooks | 40+ checks |
| Secrets | All files | Secret detection patterns across all frameworks |
Checkov's Terraform support is its most comprehensive. It parses HCL files, resolves variable references where possible, and evaluates resource blocks against provider-specific policies. Running Checkov against Terraform code before terraform apply catches misconfigurations that would otherwise land in production infrastructure.
# Install Checkov
pip install checkov
# Basic scan of a Terraform directory
checkov -d /path/to/terraform/
# Scan a specific file
checkov -f main.tf
# Output formats
checkov -d . --output cli # human-readable (default)
checkov -d . --output json # machine-readable JSON
checkov -d . --output junitxml # CI/CD JUnit format
checkov -d . --output sarif # GitHub Advanced Security SARIF
# Scan Terraform plan output (most accurate — catches dynamic values)
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
checkov --file tfplan.json --framework terraform_plan
# Filter by severity
checkov -d . --check-level HIGH # only HIGH and CRITICAL
# Show only failed checks with remediation
checkov -d . --compact --quiet
# List all available Terraform checks
checkov --list --framework terraform | head -50
# Scan and report by compliance framework
checkov -d . --framework terraform --compliance cis_aws_1.3.0
checkov -d . --framework terraform --compliance pci_dss_v3.2.1
# Run and parse results for critical findings
checkov -d /path/to/terraform/ --output json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
results = data.get('results', {})
failed = results.get('failed_checks', [])
# Focus on security-impactful checks
high_value = [
'CKV_AWS_18', # S3 bucket logging
'CKV_AWS_19', # S3 encryption at rest
'CKV_AWS_20', # S3 public access
'CKV_AWS_57', # S3 ACL public-read
'CKV_AWS_58', # EKS secrets encryption
'CKV_AWS_79', # EC2 IMDSv2 required
'CKV_AWS_8', # EC2 detailed monitoring
'CKV_AWS_135', # EBS encryption
'CKV_AWS_23', # RDS encryption
'CKV_AWS_17', # RDS storage encrypted
'CKV2_AWS_5', # Security group not attached to resource
'CKV_AWS_25', # SG open to world on admin ports
]
print(f'Total failures: {len(failed)}')
print()
for check in failed:
check_id = check.get('check_id')
check_name = check.get('check_type', {})
resource = check.get('resource')
file_path = check.get('file_path')
file_line = check.get('file_line_range', [0,0])
if check_id in high_value:
print(f'[HIGH-VALUE] {check_id}: {check.get(\"check_id\")}')
print(f' Resource: {resource}')
print(f' File: {file_path}:{file_line[0]}-{file_line[1]}')
print()
"
# Key Terraform misconfigurations Checkov detects:
# AWS:
# - S3 buckets without server-side encryption (CKV_AWS_19)
# - S3 buckets with public access enabled (CKV_AWS_20, CKV_AWS_57)
# - Security groups open to 0.0.0.0/0 on SSH (22), RDP (3389), MySQL (3306)
# - RDS instances without encryption at rest
# - Lambda functions with overly permissive IAM roles
# - EC2 metadata service v1 enabled (SSRF-to-IMDS attacks)
# - KMS key rotation disabled
# - CloudTrail logging not enabled
# - S3 bucket logging not enabled
# Azure:
# - Storage accounts with public blob access
# - Key Vault without soft delete
# - SQL Server without TDE
# - Virtual network without NSG
# GCP:
# - Cloud Storage buckets with uniform bucket-level access disabled
# - GKE node pools with legacy metadata endpoints
# - Compute instances with public IP addresses
# Static HCL scanning misses dynamically computed values
# Terraform plan scanning resolves variables and module outputs
# Example: static scan misses this because cidr_block is a variable
resource "aws_security_group_rule" "ssh" {
cidr_blocks = [var.allowed_cidr] # Could be 0.0.0.0/0 at runtime
from_port = 22
to_port = 22
protocol = "tcp"
type = "ingress"
}
# Plan scan WILL catch this if var.allowed_cidr = "0.0.0.0/0"
terraform init
terraform plan -var="allowed_cidr=0.0.0.0/0" -out=tfplan
terraform show -json tfplan > tfplan.json
checkov -f tfplan.json --framework terraform_plan
# Checkov now sees the resolved value and can flag the open security group rule
# Multi-environment scanning: catch environment-specific misconfigs
for ENV in dev staging production; do
echo "=== Scanning $ENV ==="
terraform plan -var-file=environments/$ENV.tfvars -out=tfplan.$ENV
terraform show -json tfplan.$ENV > tfplan.$ENV.json
checkov -f tfplan.$ENV.json --framework terraform_plan --output cli 2>&1 | \
grep -E "^(Passed|Failed)" | head -5
done
Checkov's CloudFormation checks cover IAM policies, S3 configurations, RDS encryption, EC2 instance settings, and VPC network controls. CloudFormation scanning is particularly valuable because CF templates often manage cross-account resources with complex IAM policies that static inspection struggles to fully evaluate.
# Scan a CloudFormation template
checkov -f template.yaml --framework cloudformation
# Scan a directory of CloudFormation templates
checkov -d /path/to/cfn/ --framework cloudformation
# Critical CloudFormation checks
# CKV_AWS_2: API Gateway: Access logging enabled
# CKV_AWS_25: Security group: SSH open to world
# CKV_AWS_30: IAM: Password policy minimum length 14
# CKV_AWS_36: CloudTrail: Log file validation enabled
# CKV_AWS_40: IAM: Access key rotation
# CKV_AWS_41: IAM: No root access key
# CKV_AWS_67: CloudFormation: Stack notifications
# CKV_AWS_86: Cognito: Advanced security mode enabled
# CKV_AWS_111: IAM policy: Wildcard resource with write actions
# Parse JSON output for IAM wildcard policy violations
checkov -f template.yaml --output json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
for check in data.get('results', {}).get('failed_checks', []):
if 'IAM' in check.get('check_id', '') or 'iam' in check.get('check_id','').lower():
print(f\"{check['check_id']}: {check.get('resource')}\")
print(f\" {check.get('check_type','')}\")
# Code block shows the failing configuration
for line in check.get('code_block', []):
if line[1].strip():
print(f\" {line[0]}: {line[1].rstrip()}\")
print()
"
# Compare results against manual IAM policy review
# Checkov CKV_AWS_111: IAM wildcard — but doesn't understand full policy semantics
# An overly permissive policy that Checkov misses:
# {"Effect": "Allow", "Action": "s3:*", "Resource": "arn:aws:s3:::bucket-name/*"}
# CKV_AWS_111 checks for "Resource: *" — a scoped wildcard action may pass Checkov
# but still grants excessive permissions
Checkov's Kubernetes checks evaluate Pod security configurations, network policies, RBAC resources, and container-level security settings. Many of these checks map directly to CIS Kubernetes Benchmark controls and are complementary to runtime security tools like Falco.
# Scan a directory of Kubernetes manifests
checkov -d /path/to/k8s/ --framework kubernetes
# Scan rendered Helm chart output
helm template myapp ./charts/myapp | checkov -f - --framework kubernetes
# Scan live cluster via kubectl (render manifests from running state)
kubectl get all -A -o yaml | checkov -f - --framework kubernetes
# Key Kubernetes checks:
# CKV_K8S_1: Containers run as root
# CKV_K8S_6: Capabilities not dropped
# CKV_K8S_8: Liveness probe defined
# CKV_K8S_10: Resource limits defined
# CKV_K8S_15: Image pull policy set to Always
# CKV_K8S_16: Container does not run in privileged mode
# CKV_K8S_17: HostPID not used
# CKV_K8S_18: HostIPC not used
# CKV_K8S_19: HostNetwork not used
# CKV_K8S_20: Containers share the host process ID namespace
# CKV_K8S_25: Secrets not in environment variables (use secretRef instead)
# CKV_K8S_28: AppArmor profile configured
# CKV_K8S_30: ServiceAccount automountServiceAccountToken: false
# CKV_K8S_36: Seccomp profile configured
# CKV_K8S_37: Minimize admission of containers with NET_RAW capability
# Typical insecure Kubernetes deployment (multiple Checkov failures):
cat << 'EOF' | checkov -f - --framework kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: insecure-app
spec:
template:
spec:
hostNetwork: true # CKV_K8S_19: FAIL
hostPID: true # CKV_K8S_17: FAIL
containers:
- name: app
image: myapp:latest # CKV_K8S_15: FAIL (no digest pin)
securityContext:
privileged: true # CKV_K8S_16: FAIL
runAsUser: 0 # CKV_K8S_6: FAIL
env:
- name: DB_PASSWORD
value: "hardcoded123" # Secret detection: FAIL
# No resource limits CKV_K8S_10: FAIL
# No liveness probe CKV_K8S_8: FAIL
EOF
# Secure equivalent that passes Checkov:
cat << 'EOF'
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp@sha256:abcdef...
imagePullPolicy: Always
securityContext:
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "100m"
livenessProbe:
httpGet:
path: /health
port: 8080
envFrom:
- secretRef:
name: app-secrets # Use secretRef, not env value
EOF
Checkov provides three suppression mechanisms: inline code comments (checkov:skip), the .checkov.yaml configuration file, and the Bridgecrew platform suppression UI. Each mechanism can be misused to suppress legitimate security findings. Auditing suppressions is essential for any Checkov security assessment.
# Find all inline Checkov suppressions in Terraform files
grep -rn "checkov:skip" --include="*.tf" /path/to/terraform/
# Format: #checkov:skip=CKV_AWS_20:Reason for skipping
# Example of a problematic suppression (no reason or too broad):
resource "aws_s3_bucket" "data" {
bucket = "company-data"
#checkov:skip=CKV_AWS_20:legacy configuration # Skips public access check!
#checkov:skip=CKV_AWS_57:JIRA-1234 # Skips ACL check!
}
# Kubernetes inline suppression
# In a YAML file:
# checkov.io/skip1: "CKV_K8S_16=privileged required for legacy app"
# Find all inline suppressions across all IaC files
grep -rn "checkov:skip\|checkov.io/skip" \
--include="*.tf" --include="*.yaml" --include="*.yml" \
/path/to/iac/ | sort
# .checkov.yaml global configuration — most dangerous suppression vector
cat .checkov.yaml 2>/dev/null
# skip-check:
# - CKV_AWS_20 # Globally skips public S3 access check
# - CKV_K8S_16 # Globally skips privileged container check
# A .checkov.yaml at the repo root suppresses checks for ALL files
# Scan WITH all suppressions disabled to find hidden findings
# Override: run without --skip-check and without reading .checkov.yaml
checkov -d . --skip-path .checkov.yaml # ignore the config file
checkov -d . --check CKV_AWS_20,CKV_AWS_57,CKV_K8S_16,CKV_K8S_17 # force specific checks
# Count suppressed checks to identify over-suppression
checkov -d . --output json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
skipped = data.get('results', {}).get('skipped_checks', [])
print(f'Skipped checks: {len(skipped)}')
by_check = {}
for s in skipped:
cid = s.get('check_id', 'unknown')
by_check[cid] = by_check.get(cid, 0) + 1
print('Most suppressed checks:')
for k, v in sorted(by_check.items(), key=lambda x: -x[1])[:10]:
print(f' {k}: {v} instances')
"
Checkov's built-in checks cover general cloud security best practices but cannot enforce organization-specific policies — required tags, approved AMI lists, specific naming conventions, or proprietary compliance requirements. Custom policies fill these gaps. Understanding what Checkov cannot check helps direct manual review efforts.
# Custom Python policy: check that all S3 buckets have required tags
# Save as: custom_checks/CKV_CUSTOM_1.py
from checkov.common.models.enums import CheckCategories, CheckResult
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
REQUIRED_TAGS = {"Environment", "Owner", "CostCenter", "DataClassification"}
class S3RequiredTags(BaseResourceCheck):
def __init__(self):
name = "Ensure S3 buckets have required organizational tags"
id = "CKV_CUSTOM_1"
supported_resources = ["aws_s3_bucket"]
categories = [CheckCategories.GENERAL_SECURITY]
super().__init__(name=name, id=id, categories=categories,
supported_resources=supported_resources)
def scan_resource_conf(self, conf):
tags = conf.get("tags", [{}])[0]
if not isinstance(tags, dict):
return CheckResult.FAILED
missing = REQUIRED_TAGS - set(tags.keys())
if missing:
self.details.append(f"Missing required tags: {missing}")
return CheckResult.FAILED
return CheckResult.PASSED
scanner = S3RequiredTags()
# Run with custom check directory
checkov -d /path/to/terraform/ --external-checks-dir ./custom_checks/
# Custom policy for Rego (OPA-based) — Kubernetes
# Save as: custom_policies/k8s_no_latest_tag.yaml
metadata:
name: "K8S_CUSTOM_1"
category: "SUPPLY_CHAIN"
severity: "HIGH"
type: "resource_policy"
resource_types:
- "Deployment"
- "Pod"
- "StatefulSet"
guidelines: "Image tags must not use 'latest'"
definition:
and:
- cond_type: "filter"
resource_types: ["Deployment"]
attribute: "spec.template.spec.containers.[].image"
operator: "not_contains"
value: ":latest"
# Areas where Checkov's static analysis cannot provide coverage:
# 1. Runtime behavior — a "properly configured" resource can still be exploited
# A correctly tagged, encrypted S3 bucket may still have a permissive bucket policy
# that Checkov doesn't flag if the resource itself looks compliant
# 2. Cross-resource relationships
# Checkov checks individual resources, not their interactions
# Example: an overly permissive IAM policy attached to a role attached to a Lambda
# may span multiple resources and require manual correlation
# 3. Variable resolution gaps
# HCL scanning cannot always resolve all variable values
# checkov -d . --var-file=production.tfvars helps but doesn't cover all cases
# 4. Terraform modules
# Module calls are evaluated, but deeply nested modules may not fully resolve
# Use terraform plan scanning (--framework terraform_plan) for accuracy
# 5. Dynamic policy generation
# IAM policies generated by aws_iam_policy_document with for_each loops
# may not be fully evaluated
# 6. Application-level misconfigurations
# Checkov does not know what your application does with the infrastructure
# A correctly hardened RDS instance can still have weak application-level passwords
# Complement Checkov with:
# - tfsec: additional Terraform checks
# - kube-bench: CIS benchmark runtime check for Kubernetes
# - kube-hunter: active Kubernetes cluster penetration testing
# - Prowler: AWS-native configuration assessment
# - ScoutSuite: multi-cloud security auditing
Checkov's secrets scanner (--framework secrets) detects hardcoded credentials in IaC files using pattern matching and entropy analysis. This runs separately from the misconfiguration checks and covers Terraform, CloudFormation, Kubernetes manifests, and other files in the repository.
# Enable secrets scanning (separate from misconfiguration scanning)
checkov -d . --framework secrets
# Combine misconfiguration and secrets scanning
checkov -d . --framework terraform,secrets
# Example of secrets Checkov detects in Terraform:
resource "aws_db_instance" "database" {
# Checkov SECRET_1: hardcoded password
password = "SuperSecret123!" # FAIL: hardcoded DB password
}
resource "kubernetes_secret" "api_keys" {
data = {
# Checkov SECRET_7: AWS access key pattern
AWS_ACCESS_KEY_ID = "AKIAIOSFODNN7EXAMPLE" # FAIL
AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" # FAIL
}
}
# View all detected secrets
checkov -d . --framework secrets --output json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
for result in data.get('results', {}).get('failed_checks', []):
print(f\"[{result.get('check_id')}] {result.get('check_type', {})}\")
print(f\" File: {result.get('file_path')}:{result.get('file_line_range')}\")
# Note: Checkov masks the actual secret value in output
for line in (result.get('code_block') or [])[:3]:
print(f\" {line[0]}: {line[1].rstrip()}\")
print()
"
# Secrets Checkov detects:
# - AWS access key IDs (AKIA...) and secret access keys
# - GitHub personal access tokens (ghp_...)
# - Slack tokens (xoxb-, xoxp-, xoxa-)
# - Google API keys (AIza...)
# - SSH private keys (-----BEGIN ... PRIVATE KEY-----)
# - Generic high-entropy strings in password/secret/key variable names
# - Database connection strings with embedded credentials
# - Azure storage connection strings
Checkov is typically integrated into CI/CD pipelines to enforce IaC quality gates before infrastructure changes are applied. The security of this integration — exit code handling, threshold configuration, and the conditions under which scans can be bypassed — directly determines whether the gate actually prevents insecure infrastructure from being deployed.
# GitHub Actions Checkov integration (secure pattern)
cat << 'EOF' > .github/workflows/checkov.yml
name: Checkov IaC Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Checkov
uses: bridgecrewio/checkov-action@v12
with:
directory: terraform/
framework: terraform
check: "HIGH,CRITICAL" # Only fail on HIGH/CRITICAL
soft_fail: false # Fail the build on findings (DO NOT set true)
output_format: sarif
output_file_path: checkov.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: checkov.sarif
if: always() # Upload even if scan fails
EOF
# Security audit of existing Checkov CI/CD integration
# Red flags to look for:
# 1. soft_fail: true — scan never fails the pipeline regardless of findings
grep -rn "soft.fail.*true\|soft_fail.*true" .github/workflows/ .gitlab-ci.yml 2>/dev/null
# 2. --check-level LOW — only flags low-severity issues (most pass)
grep -rn "\-\-check-level LOW\|\-\-severity LOW" .github/workflows/ 2>/dev/null
# 3. --skip-check with broad check IDs
grep -rn "\-\-skip-check" .github/workflows/ .gitlab-ci.yml Jenkinsfile 2>/dev/null | \
awk -F'skip-check' '{print $2}' | tr ',' '\n' | wc -l
# Many skipped checks = weakened gate
# 4. continue-on-error: true
grep -A2 -B2 "checkov" .github/workflows/*.yml 2>/dev/null | grep "continue-on-error"
# 5. Exit code override
grep -rn "checkov.*||.*true\|checkov.*; true\|; exit 0" .github/workflows/ 2>/dev/null
# Baseline threshold — track violations over time
# A properly configured gate should:
# - Block on NEW violations (not pre-existing suppressed ones)
# - Use --baseline to capture existing state and only fail on regressions
checkov -d . --create-baseline # Create baseline.json of current state
checkov -d . --baseline baseline.json # Only fail on NEW checks not in baseline
When Checkov is used with the Bridgecrew SaaS platform, a Bridgecrew API token is required to upload scan results, access SaaS-only policies, and view historical trends. This token is equivalent to a user credential with full access to the organization's IaC security posture — all scan results, suppression configurations, and repository integrations.
# Bridgecrew API token (BC_API_KEY) locations
# Common locations where this key is stored:
# 1. CI/CD environment variables
grep -rn "BC_API_KEY\|BRIDGECREW_API_KEY\|bc_api_key" \
.github/workflows/ .gitlab-ci.yml Jenkinsfile 2>/dev/null
# 2. Developer dotfiles and local configurations
cat ~/.checkov.yml 2>/dev/null | grep -i "api.key\|api_key\|token"
env | grep -i "BC_API_KEY\|BRIDGECREW"
# 3. Docker or CI secrets files
find . -name ".env" -o -name ".env.local" | xargs grep -l "BC_API_KEY" 2>/dev/null
# Checkov configuration file may contain the key
cat .checkov.yaml 2>/dev/null | grep -i "api.key"
# Validate a Bridgecrew API key
BC_API_KEY="bc_api_key_here"
curl -s "https://www.bridgecrew.cloud/api/v1/user/profile" \
-H "Authorization: $BC_API_KEY" | python3 -m json.tool
# Returns: user profile, organization, email
# Enumerate organization's suppression rules via Bridgecrew API
curl -s "https://www.bridgecrew.cloud/api/v1/suppressions" \
-H "Authorization: $BC_API_KEY" | python3 -m json.tool
# Returns: all organization-wide suppressions (checks suppressed for all repos)
# List all repositories connected to Bridgecrew
curl -s "https://www.bridgecrew.cloud/api/v1/repositories" \
-H "Authorization: $BC_API_KEY" | python3 -m json.tool
# Access historical scan results revealing infrastructure inventory
curl -s "https://www.bridgecrew.cloud/api/v1/resources?resourceType=aws_s3_bucket" \
-H "Authorization: $BC_API_KEY" | python3 -m json.tool
# Returns all S3 buckets tracked across all repos — full infrastructure inventory
# Modify suppression rules (requires write access)
curl -s -X POST "https://www.bridgecrew.cloud/api/v1/suppressions" \
-H "Authorization: $BC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"policyId": "CKV_AWS_20",
"suppressionType": "Policy",
"comment": "Authorized suppression for testing",
"accountIds": []
}'
# This globally suppresses a check across ALL repositories for the organization
| Control | Action | Priority |
|---|---|---|
| Run plan-based scanning | Use terraform plan → show -json → checkov --framework terraform_plan for dynamic value resolution, not just static HCL scanning | Critical |
| Enforce non-zero exit code | Set soft_fail: false in CI/CD; never use continue-on-error: true on Checkov steps | Critical |
| Audit suppression inventory | Grep codebase for all checkov:skip annotations quarterly; require business justification and expiry date for each suppression | High |
| Restrict .checkov.yaml scope | Never place global skip-check entries without per-file overrides; review .checkov.yaml in code review | High |
| Protect Bridgecrew API key | Store as a CI/CD secret; rotate quarterly; audit access to the Bridgecrew console | High |
| Enable secrets scanning | Add --framework secrets alongside misconfiguration scanning in all CI/CD pipelines | High |
| Scan all IaC frameworks | Don't limit to terraform; scan cloudformation, kubernetes, helm, ansible, and dockerfile too | High |
| Use baseline tracking | Create a baseline.json to track pre-existing issues; fail only on new violations to avoid alert fatigue | Medium |
| Write custom policies | Extend Checkov with organization-specific checks: required tags, approved AMIs, naming conventions, encryption key policies | Medium |
| Combine with complementary tools | Use tfsec + Checkov for Terraform; kube-bench + Checkov for Kubernetes; neither alone covers everything | Medium |
Checkov ensures your infrastructure is provisioned securely. Ironimo tests whether your deployed applications are actually secure at runtime — finding injection vulnerabilities, authentication bypasses, and broken access controls that IaC scanning cannot detect.
Start free scan