Skip to main content

Overview

ZapStack requires read-only access to your AWS resources to identify optimization opportunities. We follow the principle of least privilege, requesting only the permissions necessary for our checks.

Permission Categories

Resource Discovery

Permissions to list and describe resources:
ec2:Describe*
rds:Describe*
dynamodb:Describe*
dynamodb:List*
lambda:List*
lambda:Get*
s3:ListAllMyBuckets
s3:GetBucketLocation
elasticloadbalancing:Describe*

CloudWatch Metrics

Permissions to read utilization metrics:
cloudwatch:GetMetricData
cloudwatch:GetMetricStatistics
cloudwatch:ListMetrics

Cost & Usage

Permissions to estimate savings:
ce:GetCostAndUsage
pricing:GetProducts

Full Policy Document

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EC2ReadOnly",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:DescribeVolumes",
        "ec2:DescribeSnapshots",
        "ec2:DescribeAddresses",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeNetworkInterfaces",
        "ec2:DescribeRegions"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RDSReadOnly",
      "Effect": "Allow",
      "Action": [
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        "rds:DescribeReservedDBInstances"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DynamoDBReadOnly",
      "Effect": "Allow",
      "Action": [
        "dynamodb:DescribeTable",
        "dynamodb:ListTables"
      ],
      "Resource": "*"
    },
    {
      "Sid": "LambdaReadOnly",
      "Effect": "Allow",
      "Action": [
        "lambda:ListFunctions",
        "lambda:GetFunction",
        "lambda:GetFunctionConfiguration"
      ],
      "Resource": "*"
    },
    {
      "Sid": "S3ReadOnly",
      "Effect": "Allow",
      "Action": [
        "s3:ListAllMyBuckets",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ELBReadOnly",
      "Effect": "Allow",
      "Action": [
        "elasticloadbalancing:DescribeLoadBalancers",
        "elasticloadbalancing:DescribeTargetGroups",
        "elasticloadbalancing:DescribeTargetHealth"
      ],
      "Resource": "*"
    },
    {
      "Sid": "CloudWatchReadOnly",
      "Effect": "Allow",
      "Action": [
        "cloudwatch:GetMetricData",
        "cloudwatch:GetMetricStatistics",
        "cloudwatch:ListMetrics"
      ],
      "Resource": "*"
    },
    {
      "Sid": "CostExplorerReadOnly",
      "Effect": "Allow",
      "Action": [
        "ce:GetCostAndUsage"
      ],
      "Resource": "*"
    },
    {
      "Sid": "PricingReadOnly",
      "Effect": "Allow",
      "Action": [
        "pricing:GetProducts"
      ],
      "Resource": "*"
    }
  ]
}

Trust Policy

The IAM role trust policy should allow ZapStack to assume the role:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ZAPSTACK_ACCOUNT_ID:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "YOUR_EXTERNAL_ID"
        }
      }
    }
  ]
}

Security Considerations

What We Can Access

  • Resource metadata (IDs, configurations, tags)
  • CloudWatch metrics (CPU, memory, network utilization)
  • Cost and usage data

What We Cannot Access

  • Data stored in S3 buckets
  • Database contents
  • Secrets or credentials
  • Application logs

External ID

We use an external ID in the trust policy to prevent the confused deputy problem. Your external ID is unique to your organization and shown in your dashboard.

Revoking Access

To revoke ZapStack’s access:
  1. Delete the CloudFormation stack, or
  2. Delete the IAM role directly
Access is revoked immediately upon role deletion.