The machine-generated inventory of every resource an external entity can reach — IAM Access Analyzer's active ExternalAccess findings — read against the declared zone of trust, so the terms-and-conditions review has a list to work from rather than a memory
The API supplies the facts, but a human judgement against a documented baseline turns them into evidence.
Fetch
$ aws accessanalyzer list-analyzers --query 'analyzers[].{Name:name,Type:type,Status:status,Arn:arn,LastAnalyzedAt:lastResourceAnalyzedAt}'$ aws accessanalyzer list-findings-v2 --analyzer-arn <ANALYZER_ARN> --filter '{"status":{"eq":["ACTIVE"]},"findingType":{"eq":["ExternalAccess"]}}'$ aws organizations describe-organization --query 'Organization.{Id:Id,FeatureSet:FeatureSet,ManagementAccount:MasterAccountId}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name iam-external-access-analyzer-enabled --compliance-types NON_COMPLIANTExpected output
From list-analyzers, one row per analyzer with type ACCOUNT or ORGANIZATION for external access (the ACCOUNT_UNUSED_ACCESS, ORGANIZATION_UNUSED_ACCESS, ACCOUNT_INTERNAL_ACCESS and ORGANIZATION_INTERNAL_ACCESS types answer different questions and do not produce ExternalAccess findings) and status one of ACTIVE, CREATING, DISABLED, FAILED. From list-findings-v2, one finding per resource shared outside the zone of trust, each with resource, resourceType, resourceOwnerAccount, findingType, status, createdAt and analyzedAt. From describe-organization, the organization id, FeatureSet ALL or CONSOLIDATED_BILLING, and the management account id — the boundary an ORGANIZATION analyzer treats as internal. From the Config rule, an empty NON_COMPLIANT set means an external-access analyzer is enabled and ACTIVE in that Region.
Map — what it proves
- recipe1
- recipe— an authored recipe collects evidence for this control
- KSI only— a Key Security Indicator reaches it, but no recipe is authored yet
- orphan— no Key Security Indicator reaches it — a person writes it up instead
What else these families can fetch:AC 16/50 →
GovCloud
IAM Access Analyzer and Organizations operate in GovCloud (US); analyzer and resource ARNs use partition arn:aws-us-gov. The Config managed rule IAM_EXTERNAL_ACCESS_ANALYZER_ENABLED is NOT available in either GovCloud (US) Region — its published availability excludes GovCloud (US-East) and GovCloud (US-West) — so in GovCloud the fourth call has no rule to query and the analyzer's own status field from list-analyzers is the evidence that it is enabled.
Notes & assertions
AC-20 is a two-limb control and only one limb is in this output. The limb that is here: which external entities can reach organization-controlled information. Access Analyzer answers that by logic-based reasoning over resource-based policies, and every access by a principal INSIDE the zone of trust is trusted by definition, so a finding is exactly an access that crosses the boundary the organization declared. The limb that is not here: whether each of those crossings is covered by terms and conditions consistent with the trust relationship. That is an agreement — a contract, an interconnection security agreement, an authorization to connect — and no call returns it. Attach the agreement register and reconcile it finding by finding; the reconciliation, not the finding list, is the AC-20 artifact. The inventory also has a direction. Access Analyzer sees resources you share OUT. It does not see an external system your people use to process organization information — a SaaS tool reached from a workstation leaves no resource policy in your account and produces no finding. That half of AC-20 has to come from your own third-party register, and inventing a join between the two would make the coverage claim wider than the evidence. Three scope facts worth pinning down before the count is quoted. External-access analysis is REGIONAL: an analyzer evaluates only resources in the Region where it is enabled, so one analyzer per Region in use, or the inventory is silently partial. Fifteen resource types are analyzed for external access — S3 buckets and directory buckets, IAM roles, KMS keys, Lambda functions and layers, SQS queues, Secrets Manager secrets, SNS topics, EBS volume snapshots, RDS DB and DB cluster snapshots, ECR repositories, EFS file systems, DynamoDB streams and tables — and a resource type outside that list is not covered by the analyzer at all. And findings refresh within about 30 minutes of a policy change but can lag up to 24 hours when a change notification is missed, so a finding list is a recent state, not a live one.
References
- Using IAM Access Analyzer — zone of trust, ExternalAccess findings, the fifteen analyzed resource types, and the regional scope of external-access analysis https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html
- AWS CLI: accessanalyzer list-analyzers (type ACCOUNT | ORGANIZATION | *_UNUSED_ACCESS | *_INTERNAL_ACCESS; status ACTIVE | CREATING | DISABLED | FAILED) https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/list-analyzers.html
- AWS CLI: accessanalyzer list-findings-v2 (filterable on status and findingType; returns resource, resourceType, resourceOwnerAccount, analyzedAt) https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/list-findings-v2.html
- AWS Config managed rule: iam-external-access-analyzer-enabled (IAM_EXTERNAL_ACCESS_ANALYZER_ENABLED) — unavailable in both AWS GovCloud (US) Regions https://docs.aws.amazon.com/config/latest/developerguide/iam-external-access-analyzer-enabled.html
- AWS CLI: organizations describe-organization (Id, FeatureSet, management account; AvailablePolicyTypes is deprecated — use list-roots instead) https://docs.aws.amazon.com/cli/latest/reference/organizations/describe-organization.html
This AWS mapping is authored opinion (overlay v3.0.0), versioned separately from the dataset and written against ruleset 2026.07.14.01. The upstream FedRAMP dataset names none of these tools.
The Supply Chain Risk run (8)
- automatable
- partial — needs judgement
- narrative — no API proves this
Every authored recipe filed under SCR, in the order the plan works them. The mark says how much of the evidence the command produces on its own.
- partialThe machine-generated inventory of every resource an external entity can reach — IAM Access Analyzer's active ExternalAccess findings — read against the declared zone of trust, so the terms-and-conditions review has a list to work from rather than a memoryyou are herequarterlyexternal-access-inventory-and-trust-boundaryAWS IAM Access Analyzer · AWS Organizations · AWS Config
- partialThe advisories AWS itself has issued against this account — operational issues, scheduled changes and account notifications, each dated and scoped — together with the subscribers on the topic those alerts are published to and the confirmation state of each subscription, which is the difference between an address that was entered and an address that receivescontinuoussecurity-advisories-receipt-and-disseminationAWS Health · Amazon SNS
- partialWhether the tooling that examines acquired software is switched on and covering the estate, and what it found: Inspector's per-account enablement state for each scanned resource type, the registry-wide ECR scanning configuration (scan type and frequency, and the repository filters that decide which repositories it applies to), Inspector's own coverage statistics, and a CycloneDX 1.4 or SPDX 2.3 SBOM exported per monitored resource — the component-level inventory of what was actually acquired.continuousacquisition-scanning-and-sbom-inventoryAmazon Inspector · Amazon ECR
- partialWhether Dependabot alerting is configured in this organization and which repositories it actually reaches, together with the alerts themselves — each carrying the advisory that raised it, the package, ecosystem and manifest path it was found in, the reason a human gave for closing it, and, for a remediated one, the date it was fixed. The first half is the population; the second half is what was found in it, and the second half means nothing without the first.continuousdependency-vulnerability-monitoringGitHub Dependabot · GitHub code security configurations
- partialThe organization's webhook configuration — which endpoints are subscribed to the supply-chain alert event, whether each is switched on, and where it points — together with the platform's own record of what it actually delivered to them and with what response code. Configuration says a path exists; the delivery log says the path carried something.continuoussupply-chain-alert-notification-routingGitHub webhooks · GitHub Dependabot
- partialWhether static analysis is configured in this organization and which repositories it actually reaches; for each of those repositories, which query suite ran over which languages, whether the recurring schedule is still alive, when the analysis last ran and with how many rules in the run; and what the analysis found, split into what is still open and what a person closed by hand — each closure carrying who closed it, which of four fixed reasons they chose, and whatever they wrote down. The first two halves are the population and the proof that testing happened; the third is the half an assessment asks for, and read without the other two it cannot be told apart from the output of a scanner that never ran.continuousstatic-analysis-coverage-and-flaw-dispositionGitHub code scanning · GitHub CodeQL · GitHub code security configurations
- partialThe rules that made every change to the mainline arrive through a reviewed pull request, as a signed commit, onto a history that cannot be rewritten — together with the record of when those rules themselves last changed and who changed them, and the platform's own per-push record of any change that got past them.weeklydeveloper-change-control-and-integrityGitHub repository rulesets · GitHub pull requests
- partialThe exact component-and-version inventory the boundary's repositories build from — every package the dependency graph resolved, carrying the version string that is the only thing SA-22's question can be asked about — together with whether that graph is switched on across the boundary at all, and then the open advisories for which the ecosystem offers no patched version, which is the closest thing a pipeline emits to a component nobody maintains any more. The inventory is the load-bearing half and it is why this recipe exists separately from the vulnerability one: "is this component past end of support" is a question about a name and a version, and a check that cannot produce the version has not asked it.monthlyunsupported-component-inventory-and-lifecycle-reviewGitHub dependency graph · GitHub Dependabot · GitHub code security configurations