IAM Setup
InfraWatch needs an IAM user and role to access AWS services. This page explains how to set them up with least-privilege permissions.
How It Works
InfraWatch uses a two-layer IAM model:
- IAM User (
POWER_AWS_ACCESS_KEY_ID) — has permission to callsts:AssumeRoleon the base role. This is the only permission this user needs. - IAM Role (
BASE_ROLE_ARN) — has read-only access to AWS services. The backend assumes this role and applies a restrictive session policy per request, scoped to only the services the user was approved for.
Step 1 — Create the IAM User
Create an IAM user with programmatic access (access key + secret key). This user only needs one permission:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789012:role/InfraWatchRole"
}
]
}
Set the access key and secret in your .env or Helm values as POWER_AWS_ACCESS_KEY_ID and POWER_AWS_SECRET_ACCESS_KEY.
Step 2 — Create the IAM Role
Create an IAM role (e.g., InfraWatchRole) that the IAM user can assume. The trust policy should allow the user's account:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/infrawatch-power-user"
},
"Action": "sts:AssumeRole"
}
]
}
Set this role's ARN as BASE_ROLE_ARN in your configuration.
Step 3 — Attach Permissions to the Role
The base role needs read-only access to the AWS services InfraWatch monitors. Attach a policy with the following actions:
| Service | Required IAM Actions |
|---|---|
| EC2 | ec2:Describe* |
| EKS | eks:List*, eks:Describe* |
| Databases | rds:Describe*, rds:List*, docdb:Describe*, docdb:List* |
| ElastiCache | elasticache:Describe*, elasticache:List* |
| OpenSearch | es:List*, es:Describe*, es:ESHttpGet |
| MQ | mq:List*, mq:Describe* |
| SES | ses:*, sesv2:* |
| Secrets Manager | secretsmanager:Get*, secretsmanager:List*, secretsmanager:Describe* |
| IAM | iam:Get*, iam:List*, iam:GenerateCredentialReport |
| Cost Explorer | ce:Get*, ce:List*, ce:Describe* |
| Load Balancers | elasticloadbalancing:Describe* |
| CloudWatch | cloudwatch:Get*, cloudwatch:List* |
| AWS Health | health:Describe* |
Full IAM Policy
Here's a complete policy you can attach to the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2",
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*"
},
{
"Sid": "EKS",
"Effect": "Allow",
"Action": ["eks:List*", "eks:Describe*"],
"Resource": "*"
},
{
"Sid": "Databases",
"Effect": "Allow",
"Action": [
"rds:Describe*", "rds:List*",
"docdb:Describe*", "docdb:List*"
],
"Resource": "*"
},
{
"Sid": "ElastiCache",
"Effect": "Allow",
"Action": ["elasticache:Describe*", "elasticache:List*"],
"Resource": "*"
},
{
"Sid": "OpenSearch",
"Effect": "Allow",
"Action": ["es:List*", "es:Describe*", "es:ESHttpGet"],
"Resource": "*"
},
{
"Sid": "MQ",
"Effect": "Allow",
"Action": ["mq:List*", "mq:Describe*"],
"Resource": "*"
},
{
"Sid": "SES",
"Effect": "Allow",
"Action": ["ses:*", "sesv2:*"],
"Resource": "*"
},
{
"Sid": "SecretsManager",
"Effect": "Allow",
"Action": [
"secretsmanager:Get*",
"secretsmanager:List*",
"secretsmanager:Describe*"
],
"Resource": "*"
},
{
"Sid": "IAM",
"Effect": "Allow",
"Action": [
"iam:Get*", "iam:List*",
"iam:GenerateCredentialReport"
],
"Resource": "*"
},
{
"Sid": "CostExplorer",
"Effect": "Allow",
"Action": ["ce:Get*", "ce:List*", "ce:Describe*"],
"Resource": "*"
},
{
"Sid": "LoadBalancers",
"Effect": "Allow",
"Action": "elasticloadbalancing:Describe*",
"Resource": "*"
},
{
"Sid": "CloudWatch",
"Effect": "Allow",
"Action": ["cloudwatch:Get*", "cloudwatch:List*"],
"Resource": "*"
},
{
"Sid": "Health",
"Effect": "Allow",
"Action": "health:Describe*",
"Resource": "*"
}
]
}
Session Policies
When a user's access request is approved, InfraWatch calls sts:AssumeRole with a session policy that limits the temporary credentials to only the approved services. For example, if a user is approved for EC2 and RDS, the session policy only includes ec2:Describe*, rds:Describe*, rds:List*, and cloudwatch:*.
This means:
- The base role defines the maximum possible permissions
- Each session is scoped to the minimum required permissions
- Credentials auto-expire after the approved duration (up to 12 hours)
- No manual credential cleanup needed
AWS Health API
The AWS Health API (health:Describe*) requires a Business or Enterprise support plan. If your account doesn't have one, the collector handles the SubscriptionRequiredException gracefully — health events simply won't appear in the alerts panel.