AWS
The AWS connector reads one AWS account and files three snapshot evidence items. It signs in with an IAM user’s access key. We recommend that the key only assumes a read-only role (see section 1); the key can also read the account itself, as before. For several accounts, add one integration per account.
| Collector | Cadence | What it shows | Suggested controls |
|---|---|---|---|
IAM credentials (iam-credentials) |
monthly | Every IAM user from the credential report: console password, password last used, MFA, each active access key’s last rotation and last use; the root account’s MFA and access keys. Flags: No MFA (console password without MFA), Key over 90 days (active key last rotated more than 90 days ago), Unused 90 days (password or active key not used for 90 days, or never used since being created or rotated more than 90 days ago), Root without MFA, Root keys present. | PCI DSS 8.2.6, 8.3.9, 8.4.2; SOC 2 CC6.1 |
Logging (logging) |
quarterly | CloudTrail trails in the regions read (shadow trails included, each trail once): multi-region, log file validation, logging now, which management events the trail records (all, reads only, writes only, none; from its event selectors), latest delivery, S3 bucket. A trail that records no management events does not count as logging and is flagged. Flag: No multi-region trail logging. Also lists each region’s coverage: all management events, partial (the logging trails there record only reads or only writes: they still log, but half the API activity is not recorded), unknown (only trails whose event selectors this account cannot read), none, or denied (AWS refused CloudTrail there). A logging multi-region trail covers every region; any other trail covers its home region. | PCI DSS 10.2.1, 10.3.4; SOC 2 CC7.2 |
Security findings (security-findings) |
monthly | Open findings at or above the configured severity, per region, with their age, read from the new Security Hub (GetFindingsV2, OCSF) or Security Hub CSPM (GetFindings, ASFF); the evidence names the API each region was read with. A region where Security Hub is not enabled is listed as “not enabled” and named in the description; when it is not enabled in any region read, the run fails instead of filing “0 findings”. Findings whose severity is Unknown or Other (new Security Hub only) are always listed, labelled UNKNOWN or OTHER, whatever the lowest severity, so nothing is hidden. With cross-region aggregation a finding comes back from more than one region: each is listed once, by its ID, in its own region. |
PCI DSS 6.3.1, 11.3.1; SOC 2 CC7.1 |
Proofroom keeps only what the summaries need: no finding descriptions, remediation text or resource details, and no credentials beyond the integration’s own key (sealed at rest, redacted from every log and error). A role’s temporary credentials live only in memory for the run, and are redacted too.
1. Recommended: a read-only role and a user that can only assume it
The role holds the read permissions; the IAM user’s access key can do nothing else than assume it. A leaked key is then useless without the role’s external ID, and you can revoke access by editing the role’s trust policy.
-
IAM console → Users → Create user, for example
proofroom-audit. Do not give it console access. Note its ARN (arn:aws:iam::<account>:user/proofroom-audit). -
IAM console → Roles → Create role → Custom trust policy. Pick a long random external ID (for example from a password generator; letters, digits and
_+=,.@:/-) and paste, with your values:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<account>:user/proofroom-audit" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "<your external ID>" } } } ] } -
Attach the AWS managed policy SecurityAudit to the role, name it (for example
ProofroomAudit) and create it. Keep the default maximum session duration (1 hour) or longer: Proofroom asks for 1-hour sessions. -
Give the user one inline policy that allows only assuming the role and reading its own access keys (the second statement lets Proofroom track the key’s age; it is optional):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<account>:role/ProofroomAudit" }, { "Effect": "Allow", "Action": "iam:ListAccessKeys", "Resource": "arn:aws:iam::*:user/${aws:username}" } ] } -
Open the user → Security credentials → Create access key → “Application running outside AWS”. Copy the access key ID and secret access key at once.
The role may sit in another account than the user (a cross-account role): put the user’s ARN in that role’s trust
policy and the role’s ARN in the user’s policy. Then the role cannot read the user’s access keys, so keep the
iam:ListAccessKeys statement on the user if you want the key’s age tracked.
Without a role. Attach SecurityAudit to the user itself instead (steps 1 and 5) and leave the role fields blank. Existing integrations keep working this way.
Tighter alternative to SecurityAudit. If you prefer a policy that allows only the calls Proofroom makes, attach this
to the role (or to the user, without a role) instead of SecurityAudit. STS GetCallerIdentity needs no permission.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ProofroomEvidence",
"Effect": "Allow",
"Action": [
"iam:GenerateCredentialReport",
"iam:GetCredentialReport",
"iam:GetAccountSummary",
"iam:ListAccessKeys",
"ec2:DescribeRegions",
"cloudtrail:DescribeTrails",
"cloudtrail:GetTrailStatus",
"cloudtrail:GetEventSelectors",
"securityhub:GetFindings",
"securityhub:DescribeSecurityHubV2"
],
"Resource": "*"
}
]
}
securityhub:GetFindings covers both GetFindings (Security Hub CSPM) and GetFindingsV2 (Security Hub).
2. Create the integration
Integrations → Catalogue → AWS → Connect:
- Access key ID and secret access key of the user above.
- Role ARN (recommended) and external ID: the role from section 1. Leave both blank to read with the key itself.
- Regions, one per line (for example
eu-west-2), or blank. Blank: Proofroom reads every region enabled in the account (EC2DescribeRegions; opt-in regions you have not enabled are skipped). Listed: only those regions are read. They are checked against the account’s regions: a listed region the account has not enabled is skipped and named in the evidence; a name that is not an AWS region fails the run. - Lowest severity of Security Hub findings to list (default
HIGH). - Findings API (default
auto):autoasks each region whether the new Security Hub is enabled and reads it there, and reads Security Hub CSPM elsewhere;v2reads only the new Security Hub;cspmreads only Security Hub CSPM.
Test connection names the account and who it ran as (“as role ProofroomAudit” or “as user proofroom-audit”),
checks that IAM is readable and lists the regions it will read. If it says STS refused AssumeRole, check the role’s
trust policy, the external ID and the user’s policy. If it says IAM refused GetAccountSummary, SecurityAudit is not
attached to the role (or user).
3. Outbound access
The server needs HTTPS (443) to iam.amazonaws.com, and for each region read sts.<region>.amazonaws.com (the first
listed region, or us-east-1), ec2.<region>.amazonaws.com (the same region), cloudtrail.<region>.amazonaws.com and
securityhub.<region>.amazonaws.com.
Access key expiry
AWS access keys never expire. Proofroom reads when the key was created (ListAccessKeys for the key’s own user) and
shows it on the integration page as due for rotation a year later, labelled Access key …<last 4 characters of the key ID>. With a role, the user’s access key is still the credential tracked: Proofroom reads it with the key itself (the
optional iam:ListAccessKeys statement above) or, when that is refused, with the role (same account only). When
neither may read it, or the key belongs to the root user, the page shows a note instead.
Rotate the key under your usual policy: create a second key, update the integration, then deactivate and delete the old one. The IAM credentials evidence also flags keys over 90 days old, including Proofroom’s own.
Notes
- The credential report is generated by AWS at most every four hours; the summary shows when it was generated.
- The report covers each user’s first two access keys, which is all IAM allows.
- Security Hub and Security Hub CSPM. The new Security Hub (generally available since December 2025) keeps its
findings in OCSF and is read with
GetFindingsV2; the older service, now called Security Hub CSPM, is read withGetFindings. Open means: Security Hub CSPM record stateACTIVEwith workflow statusNEWorNOTIFIED; Security Hub status New, In Progress, Unknown or Other (Suppressed, Resolved and Archived are left out). Security Hub’s Fatal severity is listed as CRITICAL. - In
automode, if the key may not callsecurityhub:DescribeSecurityHubV2, Proofroom cannot tell whether the new Security Hub is enabled; it reads Security Hub CSPM in that region and says so in the evidence. - Security Hub CSPM answers HTTP 401 (
InvalidAccessException) both when it is not enabled in a region and when the key lackssecurityhub:GetFindings; the two cannot be told apart. The summary lists such a region as “Security Hub: not enabled in this region, or the key lacks securityhub:GetFindings” and the run still succeeds, as long as at least one region read answers; if none does, the run fails. - A region AWS refuses. When CloudTrail or Security Hub answers access denied in one region (HTTP 403, or 400
AccessDeniedException— for example a service control policy that denies a region), that region is listed as “denied” in the evidence and the description, and the other regions are still read. The run fails only when every region read is refused. - Organisation trails. A member account may be refused
GetEventSelectorson an organisation trail owned by the management account. The trail is still listed (and counts as logging when it is logging), with the note “event selectors not readable from this account” and its management events shown as unknown. Read the logging evidence from the management account to see them. - If EC2 refuses
DescribeRegionsand regions are listed, Proofroom reads them unchecked and says so; with no regions listed, the run fails namingec2:DescribeRegions. SecurityAudit includes it. - AWS throttling (HTTP 400 with
Throttling,ThrottlingExceptionorRequestLimitExceeded, or 429TooManyRequestsException) is a rate limit: Proofroom backs off and retries up to three times. If it persists, the run fails and is retried automatically an hour later, then 6 and 24 hours later.
Not yet confirmed on a live account (UNVERIFIED)
DescribeSecurityHubV2answering 404 (ResourceNotFoundException) in a region where the new Security Hub is not enabled. The API reference lists the 404 but does not tie it to “not enabled”.- The OCSF field names Proofroom reads from
GetFindingsV2results (finding_info.uid,finding_info.title,finding_info.first_seen_time_dt,severity_id,status_id,cloud.region,resources[].type/uid,metadata.product.name) and the names of theseverity_idandstatus_idvalues, which come from the OCSF schema. - Reading a shadow trail’s event selectors: Proofroom calls
GetEventSelectorsin the trail’s home region. - How a member account is refused
GetEventSelectorson an organisation trail (Proofroom treats HTTP 403, or 400 with an access-denied message, as refused), and how an SCP region denial is answered by CloudTrail and Security Hub. GetFindingsV2accepting aseverity_idfilter ofEq 0/Eq 99alongsideGtein oneORcomposite filter.