<< BACK

Enabling GuardDuty Runtime Monitoring, Inspector, and Macie

enabling AWS's three cornerstone active security services in one session — what each does, the exact commands, cost breakdown, and suppression rules to avoid alert fatigue.

DATE:
FEB.07.2026
READ:
14 MIN

AWS Security Hub tells you about configuration issues — resources that don’t meet compliance standards. But there are three other services that actively scan for threats, vulnerabilities, and data exposure: GuardDuty for threat detection, Inspector for vulnerability management, and Macie for sensitive data discovery. Together they transform your account from passively monitored to actively defended.

Despite being fundamental to any serious security posture, these services are often disabled on accounts that were set up before an organization adopted a formal security framework. Enabling all three took us under an hour, including verification. Total ongoing cost: approximately $47/month.


The security services ecosystem

The three services operate at different layers and feed into Security Hub:

  • GuardDuty analyzes VPC Flow Logs, DNS logs, CloudTrail events, and (with runtime monitoring) OS-level events inside containers. Detects threats in progress.
  • Inspector continuously scans ECR images, EC2 instances, and Lambda functions for known CVEs. Detects exploitable vulnerabilities.
  • Macie uses ML to discover PII, credentials, and sensitive data in S3 buckets. Detects data exposure.

All three findings flow into Security Hub, which provides a unified dashboard. EventBridge rules can route critical findings to PagerDuty, Slack, or auto-remediation Lambdas.


Amazon Inspector — vulnerability scanning

What it scans

  • ECR images — analyzes container images for known CVEs on every push and when new CVEs are published. Rescans existing images when new vulnerabilities are discovered.
  • EC2 instances — uses the SSM agent to inventory installed packages and check against vulnerability databases.
  • Lambda functions — analyzes deployment packages and layers for vulnerable dependencies.

Enabling Inspector

++
aws inspector2 enable 
  --resource-types EC2 ECR LAMBDA 
  --region us-east-1
++

Output:

++
{
    "accounts": [{
        "accountId": "ACCOUNT_ID",
        "resourceState": {
            "ec2": {"status": "ENABLING"},
            "ecr": {"status": "ENABLING"},
            "lambda": {"status": "ENABLING"}
        },
        "status": "ENABLING"
    }]
}
++

Verify after a few minutes:

++
aws inspector2 batch-get-account-status --region us-east-1
++

EC2 scanning requirements

Inspector uses the SSM agent for EC2 scanning. Verify SSM connectivity:

++
aws ssm describe-instance-information 
  --query 'InstanceInformationList[].{Id:InstanceId,Status:PingStatus}' 
  --output table
++

If instances aren’t appearing, check that:

  1. SSM agent is installed (included by default on Amazon Linux and Ubuntu AMIs)
  2. The instance IAM role includes AmazonSSMManagedInstanceCore
  3. The instance has network access to SSM endpoints (via NAT gateway or VPC endpoints)

Viewing ECR findings

++
aws inspector2 list-findings 
  --filter-criteria '{
    "ecrImageRepositoryName": [{
      "comparison": "EQUALS",
      "value": "my-app-backend"
    }]
  }' 
  --query 'findings[].{Title:title,Severity:severity.label}' 
  --output table
++

Cost

  • ECR: $0.09 per image initially scanned, $0.01 per rescan
  • EC2: $0.48 per instance per month
  • Lambda: $0.30 per function per month

For an environment with ~20 ECR images, 5 EC2 instances, and 10 Lambda functions: approximately $12-15/month.


Amazon Macie — S3 sensitive data discovery

What it finds

Macie uses ML and pattern matching to identify PII (names, addresses, SSNs, passport numbers), financial data (credit card numbers, bank accounts), credentials (AWS access keys, private keys, API tokens), and custom patterns you define.

Enabling Macie

++
aws macie2 enable-macie --region us-east-1

# Verify
aws macie2 get-macie-session --region us-east-1
++

Automated sensitive data discovery

After enabling, Macie starts sampling objects from each S3 bucket (not scanning everything — cost-optimized sampling):

++
aws macie2 get-automated-discovery-configuration --region us-east-1
++

For targeted full scans of specific buckets:

++
aws macie2 create-classification-job 
  --job-type ONE_TIME 
  --name "app-data-scan" 
  --s3-job-definition '{
    "bucketDefinitions": [{
      "accountId": "ACCOUNT_ID",
      "buckets": ["my-app-user-uploads"]
    }]
  }' 
  --region us-east-1
++

Cost and optimization

Macie pricing scales with data volume:

  • Automated discovery: first 150GB free/month, then $1.25/GB
  • Classification jobs: $1.00/GB scanned
  • Bucket monitoring: free for first 150 buckets, $0.10/bucket/month after

Set up a budget alert:

++
aws budgets create-budget 
  --account-id ACCOUNT_ID 
  --budget '{
    "BudgetName": "MacieMonthly",
    "BudgetLimit": {"Amount": "50", "Unit": "USD"},
    "TimeUnit": "MONTHLY",
    "BudgetType": "COST",
    "CostFilters": {"Service": ["Amazon Macie"]}
  }' 
  --notifications-with-subscribers '[{
    "Notification": {
      "NotificationType": "ACTUAL",
      "ComparisonOperator": "GREATER_THAN",
      "Threshold": 80
    },
    "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "team@example.com"}]
  }]'
++

GuardDuty runtime monitoring — threat detection inside containers

Standard GuardDuty vs runtime monitoring

Standard GuardDuty analyzes three data sources: VPC Flow Logs, DNS logs, and CloudTrail events. This detects network-level threats but can’t see what happens inside your containers.

Runtime monitoring adds OS-level events: process execution, network connections, file access, DNS resolution — all from inside running containers. This enables detection of threats invisible at the network layer:

  • Cryptomining processes inside compromised containers
  • Reverse shells opened by exploited application code
  • Credential theft via access to the metadata service
  • Lateral movement attempts from within a container

Enabling GuardDuty

If GuardDuty isn’t already enabled:

++
aws guardduty create-detector --enable --region us-east-1
++

Get the detector ID:

++
DETECTOR_ID=$(aws guardduty list-detectors 
  --query 'DetectorIds[0]' --output text --region us-east-1)
++

Enable runtime monitoring with agent management for all compute types:

++
aws guardduty update-detector 
  --detector-id "$DETECTOR_ID" 
  --features '[
    {
      "Name": "RUNTIME_MONITORING",
      "Status": "ENABLED",
      "AdditionalConfiguration": [
        {"Name": "EKS_ADDON_MANAGEMENT", "Status": "ENABLED"},
        {"Name": "ECS_FARGATE_AGENT_MANAGEMENT", "Status": "ENABLED"},
        {"Name": "EC2_AGENT_MANAGEMENT", "Status": "ENABLED"}
      ]
    }
  ]' 
  --region us-east-1
++

How ECS Fargate agent management works

With ECS_FARGATE_AGENT_MANAGEMENT enabled, GuardDuty automatically injects a sidecar container into your ECS task definitions at task launch time. The sidecar:

  • Uses ~50MB memory, negligible CPU
  • Is NOT injected into existing running tasks — only new tasks
  • Does NOT modify your task definition in the console or in CDK

Verify the sidecar is running:

++
aws ecs describe-tasks 
  --cluster my-cluster 
  --tasks $(aws ecs list-tasks --cluster my-cluster --query 'taskArns[0]' --output text) 
  --query 'tasks[0].containers[].name' 
  --output text
# Should include: aws-guardduty-agent
++

Runtime monitoring finding types

+--------------------+----------+--------------------+
| Finding Type       | Source   | What It Detects    |
+--------------------+----------+--------------------+
| Execution:Runtime/ | Runtime  | Unknown binary     |
| NewBinaryExecuted  |          | executed in        |
|                    |          | container          |
+--------------------+----------+--------------------+
| CryptoCurrency:Run | Runtime  | Crypto mining      |
| time/BitcoinTool.B |          | software running   |
+--------------------+----------+--------------------+
| Backdoor:Runtime/C | Runtime  | Communication with |
| &CActivity.B       |          | known C2 servers   |
+--------------------+----------+--------------------+
| PrivilegeEscalatio | Runtime  | Container escape   |
| n:Runtime/RuncCont |          | attempt            |
| ainerEscape        |          |                    |
+--------------------+----------+--------------------+
| UnauthorizedAccess | Standard | SSH brute force on |
| :EC2/SSHBruteForce |          | EC2                |
+--------------------+----------+--------------------+
| Recon:EC2/PortProb | Standard | Port scan from     |
| eUnprotectedPort   |          | internet           |
+--------------------+----------+--------------------+

Cost

Runtime monitoring pricing:

  • ECS Fargate: $1.50 per vCPU per month (first 500 vCPUs)
  • EC2: $0.36 per vCPU per month (first 500 vCPUs)

For an environment with ~10 Fargate vCPUs: approximately $15/month.


SSM automation CloudWatch logging

While enabling the three main services, also send SSM automation logs to CloudWatch (this closes an additional Security Hub finding):

++
aws ssm update-service-setting 
  --setting-id "arn:aws:ssm:us-east-1:ACCOUNT_ID:servicesetting/ssm/automation/customer-script-log-destination" 
  --setting-value "CloudWatch" 
  --region us-east-1

# Verify
aws ssm get-service-setting 
  --setting-id "arn:aws:ssm:us-east-1:ACCOUNT_ID:servicesetting/ssm/automation/customer-script-log-destination" 
  --query 'ServiceSetting.SettingValue' 
  --output text
# Expected: CloudWatch
++

Suppression rules to avoid alert fatigue

After enabling these services, expect a flood of expected findings. Set up suppression rules before your security team gets overwhelmed.

Security Hub: suppress Inspector findings with no available fix

++
aws securityhub create-automation-rule 
  --rule-name "suppress-inspector-no-fix" 
  --rule-order 1 
  --description "Suppress Inspector findings where no fix is available" 
  --criteria '{
    "ProductName": [{"Value": "Inspector", "Comparison": "EQUALS"}],
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}],
    "NoteText": [{"Value": "No fix available", "Comparison": "CONTAINS"}]
  }' 
  --actions '[{
    "Type": "FINDING_FIELDS_UPDATE",
    "FindingFieldsUpdate": {
      "Workflow": {"Status": "SUPPRESSED"},
      "Note": {"Text": "Auto-suppressed: no fix available", "UpdatedBy": "automation"}
    }
  }]'
++

GuardDuty: suppress known traffic patterns

++
aws guardduty create-filter 
  --detector-id "$DETECTOR_ID" 
  --name "expected-vpn-traffic" 
  --action ARCHIVE 
  --finding-criteria '{
    "Criterion": {
      "service.action.networkConnectionAction.remoteIpDetails.ipAddressV4": {
        "Eq": ["203.0.113.50"]
      }
    }
  }' 
  --region us-east-1
++

Macie: allow list for test data

++
aws macie2 create-allow-list 
  --name "test-data-patterns" 
  --criteria '{"regex": "TEST-SSN-[0-9]{3}-[0-9]{2}-[0-9]{4}"}' 
  --description "Exclude test SSN patterns"
++

Verification checklist

++
#!/bin/bash
REGION="us-east-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

echo "=== Inspector Status ==="
aws inspector2 batch-get-account-status 
  --query 'accounts[0].resourceState' --output json --region "$REGION"

echo "=== Macie Status ==="
aws macie2 get-macie-session 
  --query '{Status:status}' --output json --region "$REGION"

echo "=== GuardDuty Runtime Monitoring ==="
DETECTOR_ID=$(aws guardduty list-detectors 
  --query 'DetectorIds[0]' --output text --region "$REGION")
aws guardduty get-detector 
  --detector-id "$DETECTOR_ID" 
  --query 'Features[?Name==`RUNTIME_MONITORING`]' --output json

echo "=== SSM Automation Logging ==="
aws ssm get-service-setting 
  --setting-id "arn:aws:ssm:${REGION}:${ACCOUNT_ID}:servicesetting/ssm/automation/customer-script-log-destination" 
  --query 'ServiceSetting.SettingValue' --output text
++

Total cost summary

+--------------------+--------------------+-------------------+
| Service            | What's billed      | Estimated monthly |
+--------------------+--------------------+-------------------+
| GuardDuty Standard | VPC Flow Logs,     | $12               |
|                    | CloudTrail, DNS    |                   |
|                    | events             |                   |
+--------------------+--------------------+-------------------+
| GuardDuty Runtime  | Per vCPU on        | $15               |
| Monitoring         | monitored compute  |                   |
+--------------------+--------------------+-------------------+
| Inspector          | Per ECR image, EC2 | $12               |
|                    | instance, Lambda   |                   |
|                    | function           |                   |
+--------------------+--------------------+-------------------+
| Macie (automated   | Per GB sampled     | $5                |
| discovery)         | (first 150GB free) |                   |
+--------------------+--------------------+-------------------+
| Security Hub       | Per finding per    | $3                |
|                    | month              |                   |
+--------------------+--------------------+-------------------+
| Total              |                    | ~$47/month        |
+--------------------+--------------------+-------------------+

For the visibility gained — active threats, exploitable vulnerabilities, and sensitive data exposure — $47/month is an exceptional security investment. A single undetected data breach would cost orders of magnitude more.

The most important takeaway: these services are not enterprise-only features. They are baseline security controls that every AWS account should have enabled from day one. If your account doesn’t have them, enable them today. It takes one session.