AWS Inspector: Automated Vulnerability Assessment for EC2 and Containers (2026)
AWS Inspector v2 delivers continuous, agent-less vulnerability scanning across EC2 instances, Amazon ECR container images, and Lambda functions — giving security teams a real-time, prioritized view of software vulnerabilities without the overhead of managing scan schedules or agents.
Table of Contents
- Inspector v2 Overview: What Changed from v1
- What Inspector Scans: EC2, ECR, and Lambda
- Enabling Inspector Across Your AWS Organization
- Understanding Findings: CVE IDs, CVSS, and Inspector Scores
- Filtering and Suppressing Findings
- Integrating with Security Hub and EventBridge
- AWS CLI Commands for Inspector
- Python boto3: Findings Export and Jira Integration
- ECR Container Scanning: On-Push vs Continuous
- Lambda Code Scanning: Detecting Vulnerable Dependencies
- Cost Model and Optimization
1. Inspector v2 Overview: What Changed from v1
AWS Inspector was originally launched in 2015 as a rules-based assessment service. It required you to install the Amazon Inspector agent on every EC2 instance, manually define assessment targets and templates, and trigger assessment runs on a schedule. While functional, the operational overhead was significant — keeping agents updated, managing target configurations, and correlating results from hundreds of instances demanded continuous effort from security and operations teams.
AWS Inspector v2, launched in November 2021 and substantially enhanced through 2024–2026, is a fundamentally different product. The most important change is that it is entirely agent-less for EC2. Instead of deploying and maintaining the Inspector agent, Inspector v2 uses the AWS Systems Manager (SSM) agent, which is already present on most modern EC2 instances. For instances without SSM, AWS also introduced hybrid scanning using EC2 metadata and package inventory collected via EC2 native APIs. This means you can enable vulnerability scanning for thousands of instances without touching a single instance configuration.
The second major change is continuous scanning. Inspector v1 ran point-in-time assessments — you scheduled a run, waited for results, reviewed them, and repeated. Inspector v2 scans continuously. When a new CVE is published to the National Vulnerability Database (NVD), Inspector automatically re-evaluates all your resources against the new vulnerability data, even if no packages have changed. This means you learn about newly published vulnerabilities in your environment within hours, not days or weeks.
Inspector v2 also expanded its scope significantly. The original Inspector only covered EC2 instances. Version 2 adds native scanning for Amazon ECR container images and AWS Lambda functions, making it a unified vulnerability management platform across your compute footprint. Finally, Inspector v2 integrates natively with AWS Security Hub and AWS Organizations, enabling centralized findings management at enterprise scale.
- Agent-less EC2 scanning via SSM (no manual agent lifecycle)
- Continuous scanning triggered by new CVE publications
- EC2 + ECR + Lambda coverage under one service
- Native Security Hub integration with normalized findings format
- AWS Organizations multi-account support with delegated administrator
- Risk-based Inspector Score combining CVSS + environmental context
2. What Inspector Scans: EC2, ECR, and Lambda
Understanding exactly what Inspector v2 examines is essential for setting expectations about coverage and gap analysis.
EC2 Instance Scanning
For EC2 instances, Inspector v2 performs two distinct scan types. The first is package vulnerability scanning. Inspector collects the complete software inventory from the instance — every OS package, its version, and the package manager that installed it (apt, yum, rpm, dpkg). It then correlates this inventory against its vulnerability intelligence database, which aggregates CVE data from NVD, vendor security bulletins (Red Hat, Ubuntu, Amazon Linux, Debian, SUSE), and Inspector's own threat intelligence feeds. Supported operating systems include Amazon Linux 1 and 2 and 2023, Ubuntu 16.04–24.04, Red Hat Enterprise Linux 6–9, CentOS 7–8, Debian 8–12, and Windows Server 2012–2022.
The second EC2 scan type is network reachability scanning. Inspector analyzes your VPC configuration, security groups, network ACLs, and route tables to identify EC2 instances with network paths open to the internet. This does not require SSM and works purely through AWS configuration analysis. It flags conditions like instances with open ports (22, 3389, database ports) reachable from 0.0.0.0/0 via internet gateway or load balancer.
ECR Container Image Scanning
Inspector v2 scans container images stored in Amazon ECR for OS-level package vulnerabilities (same CVE database as EC2) plus programming language package vulnerabilities. This covers Python packages (pip/requirements.txt), Node.js packages (package.json/node_modules), Java packages (Maven/Gradle JARs via manifest), Ruby gems, and .NET NuGet packages embedded in the image layers. Inspector identifies vulnerabilities in these application-level dependencies even when they are not installed via the OS package manager.
Lambda Function Scanning
For Lambda functions, Inspector scans the deployment package for vulnerable library dependencies — the same language-package vulnerability detection applied to containers, but targeting your Lambda ZIP or container image packages. Inspector checks Python, Node.js, Java, and Ruby packages declared in your function's dependencies. It also performs Lambda code scanning to detect security issues in the function code itself, including hardcoded credentials, insecure cryptography usage, and code injection vulnerabilities, using static analysis rules.
3. Enabling Inspector Across Your AWS Organization
For organizations managing multiple AWS accounts, the recommended approach is to enable Inspector through AWS Organizations with a designated delegated administrator account. This pattern lets you turn on Inspector in all member accounts from a single place and view aggregated findings in one pane of glass.
The process starts in your AWS Organizations management account. You designate a security or audit account as the Inspector delegated administrator. From that account, you can enable Inspector for all existing member accounts and configure auto-enable settings so that any new accounts joining the organization get Inspector turned on automatically.
Here is the sequence of AWS CLI commands to set this up:
# Step 1: From the management account, designate the delegated admin
# Replace 111122223333 with your security account ID
aws inspector2 enable-delegated-admin-account \
--delegated-admin-account-id 111122223333 \
--region us-east-1
# Step 2: From the delegated admin account, enable Inspector
# for the entire organization with all scan types
aws inspector2 enable \
--resource-types EC2 ECR LAMBDA LAMBDA_CODE \
--region us-east-1
# Step 3: Configure auto-enable for new accounts
aws inspector2 update-organization-configuration \
--auto-enable ec2=true,ecr=true,lambda=true,lambdaCode=true \
--region us-east-1
# Step 4: Verify the organization configuration
aws inspector2 describe-organization-configuration \
--region us-east-1
The update-organization-configuration call sets the policy for future accounts. For accounts already in the organization that are not yet enrolled, use associate-member to add them individually, or use the Inspector console to bulk-enable across all accounts at once. Once enabled, Inspector begins scanning immediately — EC2 instances are typically scanned within 15 minutes of enrollment if the SSM agent is running and the instance has a compatible OS.
For EC2 scanning prerequisites, verify that the SSM agent is installed and running on your instances (it is pre-installed on Amazon Linux 2/2023, Ubuntu 20.04+, and Windows AMIs from AWS). The instance role must include the AmazonSSMManagedInstanceCore managed policy. Inspector will report instances as "SCAN ELIGIBLE" or "NO INVENTORY" in the console — the latter indicates SSM connectivity issues. See the EC2 Complete Guide for instance role and SSM setup details.
aws inspector2 enable --resource-types EC2 ECR LAMBDA LAMBDA_CODE in each account individually. Inspector is a regional service — you must enable it in each region where you have resources to scan.
4. Understanding Findings: CVE IDs, CVSS Scores, and Inspector Score Calculation
Every vulnerability identified by Inspector generates a finding — a structured record containing all the information needed to understand, prioritize, and remediate the issue. Understanding the anatomy of a finding is critical for effective triage.
Finding Components
Each finding includes a CVE ID (e.g., CVE-2024-3094, the XZ Utils backdoor) from the NVD, along with the affected package name, installed version, and the fixed version that resolves the vulnerability. The finding also records the resource type (EC2_INSTANCE, ECR_CONTAINER_IMAGE, or AWS_LAMBDA_FUNCTION), the resource identifier (instance ID, image digest, or function ARN), and the AWS account and region.
CVSS Score vs Inspector Score
Inspector findings include both the CVSS score (Common Vulnerability Scoring System, typically CVSS v3.1) and the Inspector score. These are different and serve different purposes. The CVSS score is the industry-standard severity rating assigned to the CVE itself — it represents the theoretical worst-case impact of the vulnerability in isolation, ranging from 0 to 10. A CVSS 9.8 critical vulnerability is critical in every environment, regardless of context.
The Inspector score is Amazon's enhanced risk score that adjusts the CVSS score based on environmental context specific to your AWS environment. Inspector raises the effective score when the vulnerable resource is reachable from the internet (network reachability finding overlaps with the CVE), has a high exploitation probability based on Amazon's threat intelligence, or is running in a privileged configuration. Conversely, the score may be effectively lower if the vulnerable component is not reachable or the specific vulnerable code path is not invoked. This contextual scoring helps you focus remediation on vulnerabilities that pose real risk in your environment rather than theoretical risk in isolation.
Inspector score ranges map to severity labels as follows: Critical (9.0–10.0), High (7.0–8.9), Medium (4.0–6.9), Low (1.0–3.9), and Informational (0.0–0.9).
Finding Status
Findings have a status of ACTIVE, SUPPRESSED, or CLOSED. A finding moves to CLOSED automatically when Inspector detects that the vulnerable package has been updated or removed from the resource — another benefit of continuous scanning. You do not need to manually close findings after patching; Inspector detects the remediation and closes the finding within the next scan cycle.
5. Filtering and Suppressing Findings
In a large AWS environment, Inspector can generate tens of thousands of findings. Effective filtering and suppression rules are essential for keeping noise manageable and ensuring that your team focuses on actionable issues.
Filter Rules
Inspector v2 supports saved filter rules that let you create named filters based on criteria such as finding severity, CVE ID, resource tags, resource type, AWS account, and finding status. Filters are useful for creating custom views — for example, a filter showing only Critical and High severity EC2 findings in your production account.
Suppression Rules
Suppression rules are more powerful: they permanently move matching findings to SUPPRESSED status, removing them from your active findings count. Use suppression rules for false positives, accepted risks (documented in your risk register), or findings in non-production environments that you are tracking separately.
Here is an example suppression rule JSON that suppresses all findings on resources tagged as dev/test environments for a specific CVE that you have assessed as not exploitable in your architecture:
{
"name": "suppress-dev-cve-2024-1234",
"description": "Suppress CVE-2024-1234 on dev/test instances - assessed non-exploitable",
"filterCriteria": {
"cveId": [
{
"comparison": "EQUALS",
"value": "CVE-2024-1234"
}
],
"resourceTags": [
{
"comparison": "EQUALS",
"key": "Environment",
"value": "dev"
}
]
},
"action": "SUPPRESS",
"reason": "CVE-2024-1234 requires local access to exploit. Dev instances are not internet-accessible and are isolated from production data. Risk accepted per security review 2026-05-15."
}
To create this suppression rule via the CLI:
# Create a suppression rule from a JSON file
aws inspector2 create-filter \
--name "suppress-dev-cve-2024-1234" \
--description "Suppress CVE-2024-1234 on dev/test instances" \
--filter-criteria file://suppression-rule.json \
--action SUPPRESS \
--reason "Local-access-only CVE, dev instances isolated. Risk accepted 2026-05-15." \
--region us-east-1
# List all existing filter rules
aws inspector2 list-filters \
--action SUPPRESS \
--region us-east-1
# Update an existing filter rule
aws inspector2 update-filter \
--filter-arn arn:aws:inspector2:us-east-1:111122223333:owner/111122223333/filter/EXAMPLE12345 \
--description "Updated: also covers test environment" \
--region us-east-1
Best practice: document every suppression rule with a reason and a review date. Suppression rules should be treated like security exceptions — they expire and need periodic review to ensure the accepted risk is still valid. Tag your suppression rules with an expiry date in the name or description, and review them quarterly. See AWS Security Best Practices for a framework on managing security exceptions.
6. Integrating Inspector with Security Hub and EventBridge
Inspector findings are most powerful when integrated into your broader security operations workflow. AWS provides two native integration paths: Security Hub for aggregation and normalization, and EventBridge for event-driven automation.
Security Hub Integration
When both Inspector v2 and Security Hub are enabled in the same account and region, Inspector automatically sends all findings to Security Hub in the AWS Security Finding Format (ASFF). This normalized format lets Security Hub aggregate findings from Inspector alongside findings from GuardDuty, AWS Config, Macie, WAF and Shield, and dozens of third-party tools in a single view. You can create Security Hub insights (saved queries) to track metrics like "count of critical Inspector findings per account" or "mean time to close high-severity EC2 findings."
To enable the integration from the Inspector side:
# Inspector-to-Security Hub integration is automatic when both services are enabled.
# Verify the integration status:
aws securityhub describe-products \
--product-arn arn:aws:securityhub:us-east-1::product/aws/inspector \
--region us-east-1
# Check that Inspector findings are flowing to Security Hub
aws securityhub get-findings \
--filters '{"ProductName":[{"Value":"Inspector","Comparison":"EQUALS"}],"RecordState":[{"Value":"ACTIVE","Comparison":"EQUALS"}]}' \
--max-results 5 \
--region us-east-1
EventBridge Integration for Automated Remediation
Inspector publishes findings to Amazon EventBridge as events with source aws.inspector2 and detail type Inspector2 Finding. You can create EventBridge rules to trigger automated responses to findings — for example, automatically quarantining an EC2 instance with a critical vulnerability by modifying its security group, creating a Jira or ServiceNow ticket, or sending a Slack alert to the security team.
Example EventBridge rule pattern targeting critical Inspector findings on EC2:
{
"source": ["aws.inspector2"],
"detail-type": ["Inspector2 Finding"],
"detail": {
"severity": ["CRITICAL"],
"status": ["ACTIVE"],
"resources": {
"type": ["AWS_EC2_INSTANCE"]
}
}
}
Attach this rule to a Lambda function that parses the event, extracts the instance ID and CVE details, creates a ticket in your issue tracker, and optionally modifies the instance security group to restrict outbound internet access until patching is confirmed. For high-traffic remediation pipelines, consider routing through an SQS queue to buffer and throttle Lambda invocations. See CloudWatch Monitoring for monitoring your remediation pipeline's performance.
7. AWS CLI Commands for Inspector
The AWS CLI provides full access to Inspector v2 functionality. Here are the most commonly used commands for day-to-day operations.
# Check Inspector status across all resource types in the current account/region
aws inspector2 describe-organization-configuration --region us-east-1
# Get account-level Inspector status and scan counts
aws inspector2 get-member \
--account-id 111122223333 \
--region us-east-1
# List all active CRITICAL findings across all resource types
aws inspector2 list-findings \
--filter-criteria '{
"findingStatus": [{"comparison":"EQUALS","value":"ACTIVE"}],
"severity": [{"comparison":"EQUALS","value":"CRITICAL"}]
}' \
--sort-criteria '{"field":"INSPECTOR_SCORE","sortOrder":"DESC"}' \
--max-results 50 \
--region us-east-1
# Get full details of a specific finding by ARN
aws inspector2 batch-get-finding-details \
--finding-arns arn:aws:inspector2:us-east-1:111122223333:finding/EXAMPLE \
--region us-east-1
# List findings for a specific EC2 instance
aws inspector2 list-findings \
--filter-criteria '{
"resourceId": [{"comparison":"EQUALS","value":"i-0abcd1234ef567890"}],
"findingStatus": [{"comparison":"EQUALS","value":"ACTIVE"}]
}' \
--region us-east-1
# Get aggregated findings statistics by severity
aws inspector2 get-findings-statistics \
--finding-statistic-types FINDING_BY_SEVERITY \
--region us-east-1
# List all resources being scanned by Inspector
aws inspector2 list-coverage \
--filter-criteria '{
"scanStatusCode": [{"comparison":"EQUALS","value":"ACTIVE"}]
}' \
--region us-east-1
# Check which EC2 instances are NOT covered (missing SSM agent or incompatible OS)
aws inspector2 list-coverage-statistics \
--filter-criteria '{
"resourceType": [{"comparison":"EQUALS","value":"AWS_EC2_INSTANCE"}],
"scanStatusCode": [{"comparison":"EQUALS","value":"INACTIVE"}]
}' \
--group-by RESOURCE \
--region us-east-1
# Export findings to S3 (for SIEM ingestion or offline analysis)
aws inspector2 create-findings-report \
--report-format CSV \
--s3-destination '{"bucketName":"my-security-reports","keyPrefix":"inspector/","kmsKeyArn":"arn:aws:kms:us-east-1:111122223333:key/EXAMPLE"}' \
--filter-criteria '{"findingStatus":[{"comparison":"EQUALS","value":"ACTIVE"}]}' \
--region us-east-1
The list-findings command supports pagination via --next-token. For large environments, use the create-findings-report approach to export all findings to S3 as CSV or JSON for bulk processing, rather than paginating through the API. Reports are delivered asynchronously — poll get-findings-report-status to check when the export is complete.
--output table with list-findings for a quick human-readable summary in the terminal. For scripting and automation, use --output json and pipe through jq to extract specific fields.
8. Python boto3: Findings Export and Jira Ticket Creation
For teams building custom security workflows, the boto3 SDK provides programmatic access to all Inspector v2 APIs. The following example demonstrates a complete pattern: fetching active high/critical findings, deduplicating by CVE, and creating Jira tickets for each unique vulnerability that affects production resources.
import boto3
import json
from collections import defaultdict
from datetime import datetime
import requests
from requests.auth import HTTPBasicAuth
# Configuration
JIRA_BASE_URL = "https://your-org.atlassian.net"
JIRA_PROJECT_KEY = "SEC"
JIRA_EMAIL = "security-bot@your-org.com"
JIRA_API_TOKEN = "your-jira-api-token" # Use Secrets Manager in production
AWS_REGION = "us-east-1"
def get_inspector_findings(severity_filter=None, resource_tag_filter=None):
"""Fetch active Inspector findings with optional filters."""
client = boto3.client("inspector2", region_name=AWS_REGION)
filter_criteria = {
"findingStatus": [{"comparison": "EQUALS", "value": "ACTIVE"}]
}
if severity_filter:
filter_criteria["severity"] = [
{"comparison": "EQUALS", "value": sev}
for sev in severity_filter
]
if resource_tag_filter:
filter_criteria["resourceTags"] = [
{"comparison": "EQUALS", "key": k, "value": v}
for k, v in resource_tag_filter.items()
]
findings = []
paginator = client.get_paginator("list_findings")
page_iterator = paginator.paginate(
filterCriteria=filter_criteria,
sortCriteria={"field": "INSPECTOR_SCORE", "sortOrder": "DESC"}
)
for page in page_iterator:
findings.extend(page.get("findings", []))
return findings
def group_findings_by_cve(findings):
"""Group findings by CVE ID to deduplicate across resources."""
cve_groups = defaultdict(list)
for finding in findings:
vuln = finding.get("packageVulnerabilityDetails", {})
cve_id = vuln.get("vulnerabilityId", "UNKNOWN")
cve_groups[cve_id].append({
"finding_arn": finding["findingArn"],
"severity": finding["severity"],
"inspector_score": finding.get("inspectorScore", 0),
"resource_type": finding["resources"][0]["type"],
"resource_id": finding["resources"][0]["id"],
"cvss_score": vuln.get("cvss", [{}])[0].get("baseScore", 0),
"description": finding.get("description", ""),
"remediation": finding.get("remediation", {}).get(
"recommendation", {}).get("text", "Update to fixed version"),
"affected_packages": [
f"{pkg['name']} {pkg['installedVersion']} -> {pkg.get('fixedInVersion', 'no fix')}"
for pkg in vuln.get("vulnerablePackages", [])
]
})
return cve_groups
def create_jira_ticket(cve_id, affected_resources):
"""Create a Jira security ticket for a CVE affecting multiple resources."""
max_score = max(r["inspector_score"] for r in affected_resources)
severity = affected_resources[0]["severity"]
description = affected_resources[0]["description"]
remediation = affected_resources[0]["remediation"]
resource_table = "\n".join([
f"| {r['resource_type']} | {r['resource_id']} | {r['inspector_score']:.1f} | {', '.join(r['affected_packages'][:2])} |"
for r in affected_resources[:10] # cap at 10 resources per ticket
])
jira_description = f"""
*CVE ID:* {cve_id}
*Severity:* {severity}
*Max Inspector Score:* {max_score:.1f}
*Affected Resource Count:* {len(affected_resources)}
*Description:*
{description}
*Remediation:*
{remediation}
*Affected Resources (top 10):*
|| Resource Type || Resource ID || Inspector Score || Affected Packages ||
{resource_table}
*Detected by:* AWS Inspector v2
*Detection Date:* {datetime.utcnow().strftime('%Y-%m-%d')}
*Inspector Finding ARN:* {affected_resources[0]['finding_arn']}
"""
payload = {
"fields": {
"project": {"key": JIRA_PROJECT_KEY},
"summary": f"[AWS Inspector] {severity} - {cve_id} affects {len(affected_resources)} resources",
"description": jira_description,
"issuetype": {"name": "Security Vulnerability"},
"priority": {"name": "Critical" if severity == "CRITICAL" else "High"},
"labels": ["aws-inspector", "vulnerability", cve_id.lower()]
}
}
response = requests.post(
f"{JIRA_BASE_URL}/rest/api/2/issue",
json=payload,
auth=HTTPBasicAuth(JIRA_EMAIL, JIRA_API_TOKEN),
headers={"Content-Type": "application/json"}
)
response.raise_for_status()
return response.json()["key"]
def main():
print("Fetching Inspector findings for production resources...")
findings = get_inspector_findings(
severity_filter=["CRITICAL", "HIGH"],
resource_tag_filter={"Environment": "production"}
)
print(f"Found {len(findings)} active HIGH/CRITICAL findings")
cve_groups = group_findings_by_cve(findings)
print(f"Unique CVEs: {len(cve_groups)}")
created_tickets = []
for cve_id, resources in cve_groups.items():
if len(resources) > 0:
ticket_key = create_jira_ticket(cve_id, resources)
created_tickets.append({"cve": cve_id, "ticket": ticket_key, "count": len(resources)})
print(f" Created {ticket_key} for {cve_id} ({len(resources)} resources)")
print(f"\nCreated {len(created_tickets)} Jira tickets")
return created_tickets
if __name__ == "__main__":
main()
In production, replace the hardcoded Jira API token with a call to AWS Secrets Manager (boto3.client("secretsmanager").get_secret_value(...)). Run this script as a Lambda function triggered by an EventBridge schedule (daily or on new critical findings) rather than running it manually. See AWS Lambda and Serverless for packaging Python dependencies and deploying this as a Lambda function. For the IAM permissions, see AWS IAM Roles and Policies — the Lambda execution role needs inspector2:ListFindings, inspector2:BatchGetFindingDetails, and appropriate Secrets Manager read access.
9. ECR Container Scanning: On-Push vs Continuous Scanning
Amazon ECR supports two scanning modes, and understanding the difference is important for choosing the right approach for your container security posture.
Basic Scanning (On-Push)
ECR Basic Scanning is built into ECR itself (not Inspector) and uses the open-source Clair vulnerability database. It scans images when they are pushed to the repository and does not re-scan images when new CVEs are published. Basic scanning is free but limited: it only covers OS packages, uses a less comprehensive CVE database than Inspector, and provides no contextual risk scoring. It is suitable for low-sensitivity environments or as a lightweight first gate in a CI/CD pipeline.
Enhanced Scanning (Inspector v2 Continuous)
ECR Enhanced Scanning is powered by AWS Inspector v2. When enabled, it scans images on push AND continuously re-evaluates all images in the repository as new CVEs are published. It covers OS packages plus language-level packages (Python, Node, Java, Ruby, .NET) and produces full Inspector findings with CVE IDs, CVSS scores, and Inspector scores. Findings appear in both the ECR console and the Inspector console.
To enable enhanced scanning on an ECR repository via CLI:
# Enable enhanced scanning on a specific repository
aws ecr put-image-scanning-configuration \
--repository-name my-app \
--image-scanning-configuration scanOnPush=true \
--region us-east-1
# Set enhanced scanning as the default for the entire registry
aws ecr put-registry-scanning-configuration \
--scan-type ENHANCED \
--rules '[{"repositoryFilters":[{"filter":"*","filterType":"WILDCARD"}],"scanFrequency":"CONTINUOUS_SCAN"}]' \
--region us-east-1
# Get scan findings for a specific image (by digest)
aws ecr describe-image-scan-findings \
--repository-name my-app \
--image-id imageDigest=sha256:abc123def456... \
--region us-east-1
# Alternatively, use Inspector directly for ECR findings
aws inspector2 list-findings \
--filter-criteria '{
"resourceType": [{"comparison":"EQUALS","value":"AWS_ECR_CONTAINER_IMAGE"}],
"ecrImageRepositoryName": [{"comparison":"EQUALS","value":"my-app"}],
"severity": [{"comparison":"EQUALS","value":"CRITICAL"}],
"findingStatus": [{"comparison":"EQUALS","value":"ACTIVE"}]
}' \
--region us-east-1
A best practice is to gate deployments on Inspector findings. In your CI/CD pipeline (CodePipeline, GitHub Actions, or Jenkins), after pushing an image to ECR, poll the Inspector findings API for the image digest and fail the pipeline if any CRITICAL findings exist. This prevents vulnerable images from reaching production. Use a threshold you are comfortable with — many teams allow HIGH severity with a 30-day remediation SLA but block on CRITICAL. See Amazon ECR Guide for detailed repository lifecycle and scanning configuration.
SCAN_ON_PUSH scans only when a new image version is pushed. CONTINUOUS_SCAN additionally re-scans existing images when new CVEs are published (recommended for production repositories). MANUAL requires explicit scan triggers. Use CONTINUOUS_SCAN for production registries and at minimum SCAN_ON_PUSH for all other registries.
10. Lambda Code Scanning: Detecting Vulnerable Dependencies
Lambda scanning is one of the newer Inspector v2 capabilities, particularly valuable as serverless architectures proliferate and the attack surface of Lambda functions is often underestimated. Inspector provides two Lambda scan types: package vulnerability scanning (standard) and Lambda code scanning (advanced).
Lambda Package Vulnerability Scanning
Standard Lambda scanning analyzes the function's deployment package (ZIP file or container image) for known vulnerable dependencies. Inspector extracts the package manifest (requirements.txt, package.json, pom.xml, Gemfile.lock) from the deployment package and identifies installed library versions that have known CVEs. This works for Python, Node.js, Java, and Ruby runtimes. Inspector scans Lambda functions at deployment time and continuously re-scans when new CVEs are published against libraries your function uses.
A common finding pattern: a Node.js Lambda function using an old version of the axios HTTP library with a SSRF or prototype pollution CVE. Inspector surfaces this with the CVE ID, the installed version, the fixed version, and a direct link to the NVD advisory. Remediation is straightforward — update the dependency in package.json, run npm install, and redeploy.
Lambda Code Scanning
Lambda code scanning uses static analysis to detect security weaknesses in the function source code itself, not just its dependencies. It identifies issues such as:
- Hardcoded AWS credentials, API keys, or passwords in function code
- Use of deprecated or insecure cryptographic functions (MD5, SHA-1 for security purposes)
- Potential SQL injection vulnerabilities when functions construct database queries
- Insecure deserialization patterns
- Overly permissive CORS configurations returned by the function
- Use of
eval()with untrusted input (Node.js)
To verify Lambda scanning is enabled and check coverage:
# Check Lambda scanning coverage
aws inspector2 list-coverage \
--filter-criteria '{
"resourceType": [{"comparison":"EQUALS","value":"AWS_LAMBDA_FUNCTION"}]
}' \
--region us-east-1
# Get Lambda-specific findings
aws inspector2 list-findings \
--filter-criteria '{
"resourceType": [{"comparison":"EQUALS","value":"AWS_LAMBDA_FUNCTION"}],
"findingType": [{"comparison":"EQUALS","value":"CODE_VULNERABILITY"}],
"findingStatus": [{"comparison":"EQUALS","value":"ACTIVE"}]
}' \
--region us-east-1
# Check which Lambda functions are not covered
aws inspector2 list-coverage-statistics \
--filter-criteria '{
"resourceType": [{"comparison":"EQUALS","value":"AWS_LAMBDA_FUNCTION"}],
"lambdaScanMode": [{"comparison":"NOT_EQUALS","value":"CODE"}]
}' \
--group-by SCAN_STATUS_CODE \
--region us-east-1
Lambda code scanning requires that Inspector has access to the function's source code. For ZIP deployments, Inspector reads the ZIP artifact from the Lambda service. For container-based Lambda functions, code scanning is not supported — only package vulnerability scanning applies. Lambda scanning is regional and covers functions in the regions where you have enabled Inspector. See AWS Lambda Serverless Guide for Lambda deployment best practices that integrate with Inspector scanning workflows.
CODE_VULNERABILITY rather than PACKAGE_VULNERABILITY. Filter criteria must specify the correct finding type when querying code findings vs dependency findings. Both types appear in the Inspector console under the Lambda findings view.
11. Cost Model and Optimization
AWS Inspector v2 pricing is usage-based with no upfront commitment. Understanding the cost model helps you optimize coverage without overspending, particularly in large organizations with hundreds of accounts and thousands of resources.
EC2 Instance Scanning Costs
EC2 scanning is charged per instance-month based on the number of instances scanned. As of mid-2026, pricing tiers are approximately: $1.51 per instance-month for the first 500 instances, $1.21 per instance-month from 501 to 5,000 instances, and $0.91 per instance-month above 5,000 instances. These prices are per active scanning month — Inspector only charges for instances that are actively scanned (i.e., have SSM connectivity and a compatible OS). Stopped instances are not scanned and not charged after 24 hours of being stopped.
ECR Container Image Scanning Costs
ECR enhanced scanning is charged per container image scanned. Each unique image digest is charged once when first scanned. Re-scans triggered by new CVE publications (continuous scanning) do not incur additional per-scan charges — you pay for the image once, and continuous scanning is included in that price. The price is approximately $0.09 per container image scanned. Images that are deleted from ECR are no longer scanned and no longer charged.
Lambda Scanning Costs
Lambda package vulnerability scanning is charged per Lambda function scanned per month (approximately $0.30 per function-month). Lambda code scanning, being more compute-intensive (static analysis), is charged separately at approximately $0.50 per function-month. Functions that are deleted or that Inspector cannot scan (e.g., unsupported runtime) are not charged.
Cost Optimization Strategies
Several strategies can help control Inspector costs without meaningfully reducing security coverage:
- Use resource tags to scope coverage: If you have non-production environments with very short-lived instances (e.g., ephemeral CI/CD build agents running for minutes), consider whether continuous Inspector scanning adds value versus the cost. Use the Inspector console to review coverage by account and resource type.
- Aggregate via Organizations: Inspector pricing tiers apply at the organization level when using a delegated administrator, not per account. An organization with 2,000 instances spread across 20 accounts gets the 501–5,000 tier pricing rather than first-500 pricing per account.
- ECR lifecycle policies: Implement ECR lifecycle policies to delete old image versions. Inspector stops charging for deleted images, and you reduce storage costs simultaneously. See Amazon ECR Guide for lifecycle policy configuration.
- Stop unused Lambda functions: Lambda functions in the INACTIVE state (not invoked for 14+ days and with provisioned concurrency at zero) are still scanned if enrolled. Review and delete Lambda functions that are no longer needed.
Inspector costs should be evaluated against the cost of a security incident resulting from an unpatched vulnerability. For most organizations, the risk reduction value far outweighs the scanning cost, particularly for production workloads handling sensitive data. For a comprehensive security posture that complements Inspector's vulnerability scanning, integrate with GuardDuty for threat detection and Security Hub for compliance monitoring. Together, these three services form the foundation of AWS-native security operations.
Read Next
AWS GuardDuty: Intelligent Threat Detection
Learn how GuardDuty uses ML to detect threats across CloudTrail, VPC Flow Logs, and DNS — the perfect complement to Inspector's vulnerability scanning.
AWS Security Best Practices (2026)
Comprehensive security best practices covering IAM least privilege, encryption, network security, and incident response for AWS environments.