AWS Integration Setup
This guide walks through connecting an AWS account to ThreatWeaver's Cloud Security module. By the end of this guide, ThreatWeaver will be discovering and assessing your AWS resources on a recurring scan schedule.
Approximately 20 minutes for the first account. Subsequent accounts (if using CloudFormation StackSets) take about 5 minutes each after the initial template is ready.
Prerequisitesβ
Before starting, make sure you have:
- AWS: IAM permissions to create roles and attach managed policies. At minimum:
iam:CreateRole,iam:AttachRolePolicy,sts:AssumeRole - ThreatWeaver: Admin or Security Admin role in your ThreatWeaver tenant
- License: The
cloud_securitymodule must be active in your ThreatWeaver tenant license
To verify your ThreatWeaver license, navigate to Admin β License and confirm cloud_security is listed as an active module.
Security Modelβ
ThreatWeaver accesses your AWS account using IAM Role assumption with External ID β not long-lived IAM access keys. This is the recommended approach for third-party AWS integrations because:
- The IAM role can be revoked instantly by deleting the trust relationship
- The External ID prevents confused deputy attacks (another party cannot trick ThreatWeaver into assuming your role)
- Temporary credentials (valid 1 hour) are automatically refreshed β there are no long-lived secrets to rotate manually
The role ThreatWeaver assumes has no write permissions. It cannot create, modify, or delete any AWS resource.
Step 1: Retrieve Your Connector Configuration from ThreatWeaverβ
Before creating anything in AWS, get the ThreatWeaver-specific values you need for the trust policy.
- Open ThreatWeaver and navigate to Cloud Security β Settings
- Click Add Connector β AWS
- Note down two values (do not close this screen):
- ThreatWeaver AWS Account ID β the account ID of ThreatWeaver's scanning infrastructure
- External ID β a UUID unique to your ThreatWeaver tenant
These values are unique to your ThreatWeaver instance. Keep this browser tab open while you work in the AWS console.
Step 2: Create the IAM Roleβ
Option A: AWS Console (Recommended for Single Accounts)β
-
Open the AWS IAM Console β Roles β Create role
-
Trusted entity type: Select "AWS account"
-
Under "An AWS account", select "Another AWS account" and enter the ThreatWeaver AWS Account ID from Step 1
-
Check "Require external ID" and enter the External ID from Step 1
-
Click Next
-
On the Add permissions screen, search for and attach both policies:
SecurityAudit(AWS managed)ReadOnlyAccess(AWS managed)
-
Click Next
-
Role name:
ThreatWeaverScanner
Description:Read-only role for ThreatWeaver cloud security posture scanning -
Click Create role
-
Open the newly created role and copy the Role ARN. It will look like:
arn:aws:iam::123456789012:role/ThreatWeaverScanner
Option B: AWS CLIβ
If you prefer the CLI, use the following commands. Replace placeholder values with your own:
# Create the trust policy document
cat > /tmp/tw-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::THREATWEAVER_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR_EXTERNAL_ID_FROM_THREATWEAVER"
}
}
}
]
}
EOF
# Create the IAM role
aws iam create-role \
--role-name ThreatWeaverScanner \
--assume-role-policy-document file:///tmp/tw-trust-policy.json \
--description "Read-only role for ThreatWeaver cloud security posture scanning"
# Attach the required managed policies
aws iam attach-role-policy \
--role-name ThreatWeaverScanner \
--policy-arn arn:aws:iam::aws:policy/SecurityAudit
aws iam attach-role-policy \
--role-name ThreatWeaverScanner \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# Retrieve the role ARN
aws iam get-role --role-name ThreatWeaverScanner --query 'Role.Arn' --output text
Option C: CloudFormation (For Organizations with Multiple Accounts)β
For AWS Organizations with multiple member accounts, use CloudFormation StackSets to deploy the role to all accounts simultaneously.
Create a CloudFormation template:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'ThreatWeaver read-only scanning role'
Parameters:
ThreatWeaverAccountId:
Type: String
Description: ThreatWeaver AWS Account ID
ExternalId:
Type: String
Description: ThreatWeaver External ID for your tenant
Resources:
ThreatWeaverRole:
Type: AWS::IAM::Role
Properties:
RoleName: ThreatWeaverScanner
Description: Read-only role for ThreatWeaver cloud security posture scanning
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${ThreatWeaverAccountId}:root'
Action: sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: !Ref ExternalId
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
- arn:aws:iam::aws:policy/ReadOnlyAccess
Outputs:
RoleArn:
Description: ARN of the ThreatWeaver scanning role
Value: !GetAtt ThreatWeaverRole.Arn
Deploy as a StackSet targeting your organization's management account and all desired member accounts.
Step 3: Understand What Gets Scannedβ
The two managed policies cover these AWS services:
| Service | What ThreatWeaver Reads |
|---|---|
| IAM | Users, groups, roles, policies, access keys, MFA devices, password policy, account summary |
| S3 | Buckets, bucket policies, ACLs, block public access settings, encryption, logging, versioning, lifecycle |
| EC2 | Instances, security groups, EBS volumes, VPCs, subnets, NACLs, route tables, internet gateways |
| RDS | DB instances, parameter groups, subnet groups, snapshots (public/private status) |
| Lambda | Functions, function policies, environment variable names (not values) |
| CloudTrail | Trails, trail status, event selectors |
| CloudWatch | Metric filters, alarms, log groups |
| KMS | Keys, key metadata, key policies, key rotation status |
| Config | Configuration recorders, delivery channels, config rules |
| SNS | Topics and subscriptions |
| SQS | Queues and queue policies |
| EKS | Clusters, node groups |
| ECS | Clusters, tasks, services |
ThreatWeaver reads resource configurations, not the data stored in those resources. It calls s3:ListBuckets and s3:GetBucketPolicy but never s3:GetObject. It describes EC2 instances but does not connect to them. Your customer data is never accessed.
Step 4: Configure the Connector in ThreatWeaverβ
Return to ThreatWeaver where you left the connector setup screen open.
-
Fill in the connector form:
Field Value Connector Name A human-readable label (e.g., "AWS Production", "AWS Dev") Role ARN The ARN from Step 2 (e.g., arn:aws:iam::123456789012:role/ThreatWeaverScanner)External ID Pre-filled β do not change Regions Select all regions where you have resources. For full coverage, select all. For targeted scanning, select specific regions. Scan Schedule Every 4 hours (recommended for production). Every hour for highly dynamic environments. Every 24 hours for stable/dev accounts. -
Click Test Connection
ThreatWeaver will call sts:AssumeRole with the External ID, then call iam:GetAccountSummary to verify the credentials work. You will see either a green "Connection successful" message or an error with details.
- If the test passes, click Save Connector
Step 5: Run the First Scanβ
After saving the connector, click Scan Now to trigger an immediate discovery pass rather than waiting for the first scheduled cycle.
A large AWS account (hundreds of EC2 instances, many IAM roles, multiple regions) can take 10-30 minutes for the initial scan. You can monitor progress in the connector's Scan History tab.
Once the scan completes:
- Cloud Resources will populate in
/cloud/posture - Findings will appear in
/cloud/findings - Compliance benchmark scores will update at
/cloud/compliance
What Data Gets Synced and How Oftenβ
| Data Type | Sync Frequency | Notes |
|---|---|---|
| IAM users, roles, policies | Every scan cycle | Complete enumeration each cycle |
| S3 buckets and policies | Every scan cycle | Full bucket list + policy for each |
| EC2 instances and security groups | Every scan cycle | All instances across selected regions |
| RDS instances | Every scan cycle | Config only, no DB connections |
| VPC resources | Every scan cycle | VPCs, subnets, NACLs, route tables |
| CloudTrail trails | Every scan cycle | Status, configuration, S3 destination |
| CloudWatch alarms and metric filters | Every scan cycle | Alarm state, filter patterns |
| KMS key metadata | Every scan cycle | Key metadata and rotation status |
| ECS/EKS containers | Every scan cycle | Running task/pod inventory |
Historical findings are retained indefinitely. Resources that no longer exist (deleted EC2 instance, removed S3 bucket) are marked as Decommissioned in the inventory after two consecutive scans confirm they are gone.
Multi-Account Setupβ
If you have an AWS Organization, repeat the IAM role creation in each member account. The role name and External ID should be identical across all accounts β only the account ID in the ARN will differ.
Then in ThreatWeaver, create one connector per account:
AWS Production (account 111111111111) β arn:aws:iam::111111111111:role/ThreatWeaverScanner
AWS Staging (account 222222222222) β arn:aws:iam::222222222222:role/ThreatWeaverScanner
AWS Dev (account 333333333333) β arn:aws:iam::333333333333:role/ThreatWeaverScanner
Each connector has its own scan schedule, region selection, and finding set. The Cloud Security dashboard aggregates findings across all connectors with a provider filter to drill into specific accounts.
Use the CloudFormation template from Step 2 Option C as a StackSet targeting your AWS Organization. This deploys the IAM role to all current and future member accounts automatically. You still need to register each account's ARN in ThreatWeaver manually (or via the ThreatWeaver API).
Troubleshootingβ
"Access Denied" on Test Connectionβ
Symptom: The test connection returns AccessDenied: User: arn:aws:sts::... is not authorized to assume role...
Causes and fixes:
-
Wrong Account ID in trust policy β Verify the ThreatWeaver scanning account ID in the trust policy matches exactly what ThreatWeaver showed you. A single digit difference will cause this error.
aws iam get-role --role-name ThreatWeaverScanner \
--query 'Role.AssumeRolePolicyDocument' -
External ID mismatch β The External ID in the trust policy must exactly match what ThreatWeaver sends. Check for leading/trailing spaces or character encoding issues.
-
Role ARN typo β Verify the ARN in ThreatWeaver matches the actual role ARN. Account IDs are 12 digits; ARNs are case-insensitive for service names but the account ID and role name must match exactly.
"Partial Scan β Some Regions Missing"β
Symptom: Findings appear for some regions but not others. The scan log shows errors for specific regions.
Causes and fixes:
-
Region not enabled β Some AWS regions require opt-in before use (e.g.,
ap-southeast-3,eu-south-1). ThreatWeaver can only scan regions that are enabled in your account. Check Account Settings β Regions in the AWS console. -
Regional API throttling β The first scan of a large account in a region may hit API rate limits. ThreatWeaver uses exponential backoff, but very high-volume accounts may see partial results on the first scan. Subsequent scans usually complete fully.
-
Region not selected in connector β Verify that all desired regions are checked in the connector's region selector.
"Rate Limit Exceeded" During Scanβ
Symptom: Scan log shows ThrottlingException or RequestLimitExceeded for specific API calls.
Cause: ThreatWeaver calls many AWS APIs in parallel across regions. For accounts with limited AWS API quotas, or during times of high legitimate API activity, scans may encounter throttling.
Fix:
- Reduce scan frequency β switch from hourly to every 4 hours to reduce API call volume
- Request a quota increase for specific APIs in the AWS Service Quotas console (most relevant:
DescribeInstances,ListBuckets,ListRoles) - Schedule scans during off-peak hours using the custom cron schedule option
"Findings Disappeared After a Scan"β
Symptom: Findings that were previously visible are now gone, even though the underlying misconfiguration still exists.
Cause: Usually this means the resource was renamed or recreated in AWS, generating a new resource ID. ThreatWeaver tracks resources by their cloud-native ID (ARN, instance ID, etc.). A new resource ID creates a new inventory entry and new findings.
Fix: This is expected behavior. Search for findings by resource type rather than by the old resource name to find the new entry.
"Connector Shows 'Disconnected' Status"β
Symptom: A previously working connector shows a red Disconnected status.
Cause: The IAM role's trust policy was modified, the role was deleted, or the External ID was changed.
Fix:
- Click Test Connection to see the specific error
- If the role was deleted, recreate it following Step 2
- If the trust policy was modified, re-add the correct ThreatWeaver principal and External ID
- If your ThreatWeaver instance was migrated (new deployment with new account ID), update the trust policy with the new account ID
"No Findings Despite Known Misconfigurations"β
Symptom: You know you have public S3 buckets or open security groups, but the Findings page shows nothing.
Causes and fixes:
-
First scan not yet completed β Wait for the initial scan to finish. Check the scan status in the connector's Scan History tab.
-
Regions not covered β The resource may be in a region that is not selected in the connector configuration. Add the missing region and trigger a new scan.
-
Resource is in a different account β Verify the resource is in the AWS account associated with the connector ARN.
-
Policy gap β Some resources require specific API calls that might not be covered by the two managed policies. Check the scan log for
AccessDeniederrors that name specific API calls. If you see them, you may need to add a supplementary inline policy to theThreatWeaverScannerrole for those specific actions.
Connector Permissions Referenceβ
The following table maps ThreatWeaver scan checks to the specific IAM permissions required. Both SecurityAudit and ReadOnlyAccess together cover all of these.
| Check | Required IAM Action |
|---|---|
| IAM password policy | iam:GetAccountPasswordPolicy |
| IAM users and MFA | iam:ListUsers, iam:ListMFADevices, iam:ListVirtualMFADevices |
| IAM access keys | iam:ListAccessKeys, iam:GetAccessKeyLastUsed |
| IAM roles and policies | iam:ListRoles, iam:ListAttachedRolePolicies, iam:GetRolePolicy |
| S3 bucket inventory | s3:ListAllMyBuckets, s3:GetBucketLocation |
| S3 bucket config | s3:GetBucketPublicAccessBlock, s3:GetBucketPolicy, s3:GetBucketAcl, s3:GetBucketEncryption, s3:GetBucketLogging, s3:GetBucketVersioning |
| EC2 instances | ec2:DescribeInstances |
| Security groups | ec2:DescribeSecurityGroups |
| VPC and flow logs | ec2:DescribeVpcs, ec2:DescribeFlowLogs |
| EBS volumes | ec2:DescribeVolumes |
| RDS instances | rds:DescribeDBInstances |
| CloudTrail | cloudtrail:DescribeTrails, cloudtrail:GetTrailStatus, cloudtrail:GetEventSelectors |
| CloudWatch | cloudwatch:DescribeAlarms, logs:DescribeMetricFilters |
| KMS keys | kms:ListKeys, kms:GetKeyRotationStatus, kms:DescribeKey, kms:GetKeyPolicy |
| AWS Config | config:DescribeConfigurationRecorders, config:DescribeDeliveryChannels |
| EKS clusters | eks:ListClusters, eks:DescribeCluster |
| ECS tasks | ecs:ListClusters, ecs:ListTasks, ecs:DescribeTasks |
Removing an AWS Connectorβ
To disconnect ThreatWeaver from your AWS account:
- In ThreatWeaver β Cloud Security β Settings, click the connector you want to remove
- Click Delete Connector and confirm
- In the AWS IAM console, delete the
ThreatWeaverScannerrole (or detach its policies to disable it)
Deleting the connector in ThreatWeaver stops future scans. Historical findings and the resource inventory are retained in ThreatWeaver for audit purposes. If you want to delete the historical data as well, contact your ThreatWeaver admin β there is no bulk-delete UI for connector history.
Related Pagesβ
- Cloud Security Overview β Full module overview, finding categories, and severity model
- Identity Security β Identity risk and attack path analysis
- WeaverScore β How cloud findings influence the overall risk score