Cloud Storage
Amazon Web Services
API integration
Ship Cloud Storage features without building the integration. Full Amazon Web Services API access via Proxy, normalized data through Unified APIs, and 120+ MCP-ready tools for AI agents — all extensible to your exact use case.
Talk to usUse Cases
Why integrate with Amazon Web Services
Common scenarios for SaaS companies building Amazon Web Services integrations for their customers.
Power a CSPM product with AWS configuration data
SaaS companies building Cloud Security Posture Management tools can ingest S3 bucket encryption, public access block, IAM policies, Security Hub findings, and Config rule evaluations to score customer environments against CIS and PCI-DSS without writing per-service AWS SDK code.
Offer CIEM and identity hygiene insights
Identity security products can map the full IAM graph — users, roles, groups, access keys, MFA devices, and SSO identities — to surface stale credentials, over-privileged principals, and shadow admin paths across every account in a customer's AWS Organization.
Centralize threat and vulnerability findings in a SIEM or ticketing workflow
Security operations platforms can sweep GuardDuty, Inspector2, Security Hub, and Access Analyzer findings across every region and member account, then normalize them into unified Threat and Vulnerability Findings schemas for triage in Jira, ServiceNow, or an in-app dashboard.
Build a cloud asset inventory and network topology map
DSPM, CMDB, and network visualization tools can enumerate VPCs, subnets, transit gateways, route tables, security groups, RDS instances, EC2 volumes, Lambda functions, EKS clusters, and S3 buckets to render a live topology of a customer's AWS footprint.
Enable multi-account enterprise onboarding
Platforms serving enterprises can use AWS Organizations data to auto-discover every account and OU under a management account, so customers onboard their entire cloud estate in one connection instead of linking accounts one by one.
What You Can Build
Ship these features with Truto + Amazon Web Services
Concrete product features your team can ship faster by leveraging Truto’s Amazon Web Services integration instead of building from scratch.
Stale credential detector
Generate IAM credential reports and correlate access key last-used timestamps to flag long-lived keys and dormant admin users across every linked AWS account.
S3 public exposure scanner
Evaluate bucket policies, ACLs, public access block settings, encryption, and ownership controls to produce a single effective-exposure verdict for every S3 bucket a customer owns.
Cross-region threat feed
Iterate EC2 regions and pull GuardDuty, Inspector2, and Security Hub findings into a normalized Threat Findings stream that updates on a schedule or via Truto webhooks.
Snapshot leak monitor
Inspect RDS snapshot, DB cluster snapshot, and EBS snapshot attributes to detect snapshots shared with external AWS account IDs or made public.
Transit Gateway blast-radius visualizer
Pull TGW attachments, route tables, associations, and propagations to render lateral-movement paths and highlight flat-mesh routing between VPCs and accounts.
Organization-wide compliance dashboard
Use AWS Organizations to enumerate accounts and OUs, then aggregate Config rule compliance and Security Hub standards results into a single posture score per account, OU, or framework.
SuperAI
Amazon Web Services AI agent tools
Comprehensive AI agent toolset with fine-grained control. Integrates with MCP clients like Cursor and Claude, or frameworks like LangChain.
list_all_amazon_web_services_organizations_accounts
Every account in the organization, in one global sweep — never fan out per region. Account.Paths materialises grouping_path at zero extra cost, so the recursive ListParents climb is only a fallback. Map state from Account.State, not Account.Status, which retires 2026-09-09 and has no CLOSED value. JoinedTimestamp is the org-join date, not the creation date. An empty page is not a terminator: loop until NextToken is null. A standalone account returns AWSOrganizationsNotInUseException (400).
list_all_amazon_web_services_organizations_roots
The organization root. Exactly one call ever — the quota 'Roots in an organization: 1' is not adjustable, and the throttle is 1 req/s. Root has no Path field (only OUs do), so synthesize o-
list_all_amazon_web_services_organizations_ous
Organizational units under one parent, walked breadth-first. Nesting is capped at 5 levels and is not adjustable, so recursion is bounded and needs no cycle guard. Preferred over ListChildren because it returns {Arn, Id, Name, Path} inline and avoids a DescribeOrganizationalUnit per OU at a 2 req/s throttle. No created_at exists on OrganizationalUnit either.
list_all_amazon_web_services_organizations_parents
The direct parent (an OU or the root) of one account or OU, given as child_id. Every account or OU has exactly one parent, so this always returns a single-element list -- chain calls (feeding the returned Id back in as the next child_id) to walk up to the root instead of expecting a full ancestor chain in one call. Requires the caller to already know a starting child_id (from organizations-accounts or organizations-ous); there is no reverse lookup by name.
list_all_amazon_web_services_organizations_accounts_for_parent
Accounts directly under one root or OU, given as parent_id -- the org-tree-scoped counterpart to organizations-accounts (which lists every account in the org in one global sweep). Returns only direct children: accounts nested under a child OU of this parent are not included and need a separate call per child OU. Same Account shape as organizations-accounts, including the State vs deprecated Status distinction.
list_all_amazon_web_services_organizations_policies
Service control policies. Filter is required and single-valued, so RCPs are a second call with Filter=RESOURCE_CONTROL_POLICY. Management account or delegated administrator only. Filter out the AWS-managed p-FullAWSAccess or target counts are dominated by noise.
get_single_amazon_web_services_organizations_policy_by_id
One SCP with its document. Policy.Content is plain JSON and must NOT be URL-decoded — the opposite of IAM's GetPolicyVersion. Applying the IAM decode here mangles the policy.
list_all_amazon_web_services_organizations_policy_targets
Where one SCP is directly attached. Returns direct attachments only; inheritance must be computed from the OU tree because DescribeEffectivePolicy explicitly excludes SCPs — its PolicyType enum has no SERVICE_CONTROL_POLICY entry.
list_all_amazon_web_services_iam_account_authorization_details
The primary IAM collector. One paginated sweep returns every user, group, role and policy with GroupList, AttachedManagedPolicies, inline policy documents, Tags and PermissionsBoundary — replacing four of the eight per-user calls. It does NOT cover access keys, MFA devices or login profiles. IAM policy documents here are URL-encoded (RFC 3986): decode only if the string contains %7B, never if it starts with {.
list_all_amazon_web_services_iam_users
IAM users. Returns UserId, UserName, Arn, Path, CreateDate and PasswordLastUsed only — no Tags, no PermissionsBoundary. IAM users have no email and no display name anywhere in the API. PasswordLastUsed is console sign-in only, records at most one sign-in per 5-minute window, began 2014-10-20, and has a documented gap from 2018-05-03 22:50 PDT to 2018-05-23 14:08 PDT. A key-only user reports no_information forever — that is not 'never signed in'.
list_all_amazon_web_services_iam_roles
IAM roles. ListRoles DOES return AssumeRolePolicyDocument — the omission list names only PermissionsBoundary, RoleLastUsed and Tags — so GetRole is needed only for last_used_at, boundary and tags. Roles have no long-term credentials and no API lists any, so has_static_keys is structurally false and key_count structurally 0.
list_all_amazon_web_services_iam_policies
Managed policies. Scope=Local means customer-managed (is_custom). The response already carries DefaultVersionId, so GetPolicy can be skipped and GetPolicyVersion called directly. AttachmentCount (grants) and PermissionsBoundaryUsageCount (restricts) are separate numbers — summing them destroys a security-relevant distinction.
get_single_amazon_web_services_iam_account_password_policy_by_id
The account password policy. A 404 NoSuchEntity here means no policy is configured, so AWS defaults apply — a WEAKER posture. Render it as 'not configured', never as 'unknown', and never as a pass. IAM has no lockout threshold and no breached-password list at all.
create_a_amazon_web_services_iam_generate_credential_report
Starts the credential report job. WARNING: iam:GenerateCredentialReport is access level Write in the Service Authorization Reference, so it will not appear in a policy built by filtering for read access. Without it GetCredentialReport returns 410. Enabling this is a deliberate decision, not a default.
get_single_amazon_web_services_iam_credential_report_by_id
The credential report: base64 CSV with sentinels N/A, no_information, not_supported and uppercase TRUE/FALSE. Returns 410 if nobody generated one. It caps at the first two access keys per user and omits service-specific credentials entirely, so it is not the source of truth for static_credentials.
list_all_amazon_web_services_iam_access_keys
Access keys for one user, max 2. Access keys never expire — expires_at is structurally null, not unknown. last_used_at needs a separate GetAccessKeyLastUsed call per key; access keys are the only credential type that has last-used data at all.
list_all_amazon_web_services_iam_mfa_devices
MFA devices for one user. The response carries NO device type — type must be inferred from the SerialNumber shape, and FIDO/passkey vs TOTP is not cleanly distinguishable. Mark any mfa_methods value as derived.
get_single_amazon_web_services_iam_login_profile_by_id
Console password metadata for one user. A 404 NoSuchEntity is the ANSWER, not an error: it means has_console_access is false. Surfacing it as an integration error turns every programmatic-only user into noise.
list_all_amazon_web_services_iam_oidc_providers
OIDC identity providers in the account. Returns ARNs only — the issuer URL and audience list need GetOpenIDConnectProvider per ARN. Not paginated.
get_single_amazon_web_services_iam_oidc_provider_by_id
One OIDC provider. Url is stored WITHOUT the https:// scheme while trust-policy condition keys use the bare host — normalise both sides before joining. ClientIDList is the registered audience and can disagree with the :aud condition key; the trust policy is what actually gates the assume. A role trusting this provider with no :sub condition can be assumed by any subject from the issuer — model 'no sub condition' as its own state, never as an empty list.
list_all_amazon_web_services_iam_saml_providers
SAML identity providers in the account. Returns ARNs, ValidUntil and CreateDate. Not paginated. A federated trust to one of these is an external-trust edge on any role whose trust policy names it under Principal.Federated.
list_all_amazon_web_services_securityhub_findings
Lists ASFF findings via AWS Security Hub GetFindings (POST /findings). No required params beyond region/account_id; optional truto_time_filter narrows results server-side. Paginated (limit, next_cursor; AWS MaxResults capped at 100). A 404 here (or the underlying InvalidAccessException, originally HTTP 401) means Security Hub is not enabled for this account/region — that is normal DATA, not an integration failure. Check ListFindingAggregators first: if cross-region aggregation is on, calling the aggregation region returns everything and fanning out duplicates it all. Compliance.Status has only PASSED|WARNING|FAILED|NOT_AVAILABLE — there is NO NOT_APPLICABLE, and NOT_AVAILABLE conflates 'not applicable' with 'could not check'. Findings whose Config evaluation returned NOT_APPLICABLE are auto-archived after 3 days, so RecordState must explicitly include ARCHIVED (this method's fixed Filters already does) or they vanish; archived findings are permanently deleted after 30 days. Findings over 240 KB have Resource.Details silently stripped.
list_all_amazon_web_services_securityhub_enabled_standards
Lists standards enabled in this region/account via AWS Security Hub GetEnabledStandards (POST /standards/get). No required params beyond region/account_id. Paginated (limit, next_cursor; AWS MaxResults capped at 100). A 404 (or the underlying InvalidAccessException, originally HTTP 401) means Security Hub is not enabled here — that is normal DATA, not an integration failure. enabled_standards is a Security Hub-only concept — the other seven AWS security services have no notion of a compliance standard, and their feature toggles must not be forced into this field. standardVersion is not a field: the version is embedded in the StandardsArn (.../cis-aws-foundations-benchmark/v/1.2.0) and must be string-parsed.
get_single_amazon_web_services_securityhub_hub_by_id
Reports whether Security Hub is enabled in this region/account and which finding mapping applies, via AWS Security Hub DescribeHub (GET /accounts). No required params beyond region/account_id. A 404 here (or the underlying InvalidAccessException, originally HTTP 401) is DATA — Security Hub is simply not enabled here — not an integration failure. ControlFindingGenerator branches the whole finding mapping: SECURITY_CONTROL uses Compliance.SecurityControlId and Compliance.AssociatedStandards; STANDARD_CONTROL has those absent and needs ProductFields.StandardsArn or StandardsGuideArn and ProductFields.ControlId or RuleId. SubscribedAt is enablement time, not an evaluation time — it must not be mapped to last_evaluated_at.
list_all_amazon_web_services_securityhub_security_controls
Fetches control metadata via AWS Security Hub BatchGetSecurityControls (POST /securityControls/batchGet), fetched once per collection and cached — never per finding. Required: security_control_ids, one control id like 'IAM.1' (AWS's own API accepts 1-25 ids as an array). Known limitation, verified live: this proxy method currently interpolates security_control_ids as a literal string into the request body, so AWS rejects every input — a single id, a comma-separated list, or a JSON array string — with 400 InvalidInputException ('Expected an array, value was ...'). Calls to this method fail regardless of input until the config is fixed to parse the value into a JSON array. A 404 (or InvalidAccessException) instead means Security Hub itself is not enabled. This is the only source of SeverityRating, the control's inherent risk; a finding's own Severity.Label is INFORMATIONAL on every PASSED finding because it describes the outcome, not the control.
list_all_amazon_web_services_guardduty_detectors
Detector ids in this region via AWS GuardDuty ListDetectors — one detector per region per account. Returns ids only, not detector objects; hydrate each id with guardduty-detector get. No required params beyond region/account_id. Live-verified: swept 14 regions on the sandbox account and every region returned an empty list (GuardDuty is not enabled anywhere on this account) — the call itself succeeds (200, empty array), so treat an empty result as "GuardDuty not enabled here", not a failure. GuardDuty is regional: sweep every region you care about rather than assuming one region's presence or absence tells you about another.
list_all_amazon_web_services_guardduty_list_findings
Finding ids, max 50 per page, via AWS GuardDuty ListFindings. Requires detector_id from guardduty-detectors. Returns ids ONLY — GetFindings (guardduty-get-findings) is mandatory to hydrate them. ListFindings defaults to returning archived and unarchived findings mixed together; decide explicitly via truto_time_filter rather than inheriting the default. The optional `truto_time_filter` query param is a JSON-encoded object merged directly into the request body ($truto_merge, confirmed by tracing @truto/replace-placeholders to produce a clean merge) — pass the whole body fragment AWS expects at the root, i.e. {"findingCriteria": {"criterion": {...}}}. CRITICAL, live-verified against the sandbox account (with a syntactically-valid but not-owned detector id, so the request reaches AWS's body parser before failing on detectorId ownership): field names must be lowerCamelCase exactly as GuardDuty's JSON REST API defines them (findingCriteria, criterion, gte/eq/...) — {"findingCriteria":{"criterion":{"severity":{"gte":7}}}} and {"findingCriteria":{"criterion":{"type":{"eq":[...]}}}} both parsed correctly and reached the expected detectorId error; PascalCase (FindingCriteria/Criterion/MaxResults) is silently rejected by AWS with the generic "JSON could not be processed" instead. No live detector was found on the sandbox account (see guardduty-detectors) to confirm a real non-empty ListFindings call end-to-end with actual results.
get_single_amazon_web_services_guardduty_get_finding_by_id
Hydrates a batch of up to 50 finding ids via AWS GuardDuty GetFindings. Requires detector_id (from guardduty-detectors) and finding_ids (from guardduty-list-findings). CONFIG BUG, confirmed by tracing the placeholder resolver (@truto/replace-placeholders): the request body template is `{"findingIds": ["{{query.finding_ids}}"]}`. A single `finding_ids` query value resolves correctly to `["abc123"]`, but passing `finding_ids` more than once (the normal way to send several ids) resolves to a lodash.toString array-join, producing `["abc123,def456"]` — one comma-joined string inside a single array slot, not one array element per id — which GuardDuty will not accept as multiple ids. Until that config is fixed, call this method once per finding id rather than batching. severity is a Double with no severityLabel field anywhere — emit the raw number and mark any band as derived. There is no state field; the closest is service.archived, and service itself is optional. title is optional — fall back to type. resource has no single path: resource.resourceType discriminates about 20 mutually exclusive sub-objects, some of them arrays.
get_single_amazon_web_services_guardduty_detector_by_id
One detector's configuration via AWS GuardDuty GetDetector. Requires the detector id (path `id`) from guardduty-detectors — GetDetector rejects an id from a different account/region with "detectorId is not owned by the current account", so do not reuse an id across regions. status is the enablement signal. updatedAt is a configuration-change timestamp, NOT an evaluation timestamp — mapping it into last_evaluated_at would be a lie to the consumer. Live-verified error paths only (no live detector found in the sandbox account, see guardduty-detectors); the response shape below is from the AWS API reference, not a live response.
list_all_amazon_web_services_inspector_2_account_status
Inspector v2 enablement per account via AWS Inspector2 BatchGetAccountStatus. The caller-controlled query param `truto_inspector_accounts` (JSON-encoded {"accountIds":[...]}) is OPTIONAL — live-verified: omitting it entirely still returns the calling account's own status (AWS defaults accountIds to the caller's account when empty). Live-verified live on the sandbox account (471112750856) across 14 regions: Inspector2 is DISABLED account-wide in every region tried, for every resource type (ec2, ecr, lambda, lambdaCode, codeRepository). state.status is the top-level enablement signal; resourceState breaks it down per scan type, each with its own status (and, only on error, errorCode/errorMessage). There is NO timestamp anywhere in this response, so last_evaluated_at is unreadable for Inspector — record it as such rather than substituting a config timestamp.
list_all_amazon_web_services_inspector_2_coverage_statistics
Scan coverage counts per resource type via AWS Inspector2 ListCoverageStatistics, grouped by RESOURCE_TYPE (the config's body is static: groupBy=RESOURCE_TYPE, not caller-controlled). No required params beyond region/account_id. Live-verified: this operation is real and works — called live on the sandbox account across regions and got 200 with an empty array each time (Inspector2 is disabled account-wide, so there is nothing to have coverage over; an empty result here is DATA, not a failure). Counts reflect only resource types Inspector2 actually scans (EC2, ECR, Lambda, Lambda code, code repositories) — a resource type with zero enabled scanning simply has no entry, it is not reported as a zero count.
list_all_amazon_web_services_inspector_2_findings
Vulnerability findings via AWS Inspector2 ListFindings. The caller-controlled query param `truto_time_filter` (JSON-encoded object merged into the request body — see the guardduty-list-findings gotcha on the same $truto_merge mechanism) is OPTIONAL; omitting it lists all findings with no filter. No required params beyond region/account_id. Live-verified: this operation is real and works — called live on the sandbox account across regions and got 200 with an empty array each time (Inspector2 is disabled account-wide, so there are no findings; an empty result here is DATA, not a failure). Not paginated by this Truto method beyond following nextToken automatically; severity/status here follow Inspector2's own model (COMPLETE/ACTIVE lifecycle, CRITICAL/HIGH/MEDIUM/LOW/INFORMATIONAL/UNTRIAGED severity) which is unrelated to GuardDuty's raw numeric severity.
list_all_amazon_web_services_config_recorders
Calls AWS Config DescribeConfigurationRecorders to list configuration recorders in this region. No required params beyond region/account_id. NOT paginated. NoSuchConfigurationRecorderException is DATA — AWS Config is off — not a failure. AWS now allows only one recorder per account/region, so this list has at most one item.
list_all_amazon_web_services_config_recorder_status
Calls AWS Config DescribeConfigurationRecorderStatus for whether the recorder is actually recording. No required params beyond region/account_id. NOT paginated. lastStatusChangeTime is the only real timestamp in this response - there is no configSnapshotDeliveryInfo or delivery-channel data here (that belongs to the separate, legacy DeliveryChannelStatus API, which this resource does not call); do not expect those fields. name and arn can both be absent for a service-linked recorder, which instead carries servicePrincipal.
list_all_amazon_web_services_config_aggregate_compliance
Calls AWS Config DescribeAggregateComplianceByConfigRules. Requires aggregator_name (AWS's ConfigurationAggregatorName) - omit it and AWS Config rejects the literal, unresolved placeholder text as the aggregator name with a ValidationException, not the normal NoSuchConfigurationAggregatorException, which is confusing to debug. Per-(rule, account, region) compliance across the whole organization in one paged call, with no AssumeRole per account - Limit up to 1000, cursor-paginated. Counts arrive as {CappedCount, CapExceeded}, not an integer: when CapExceeded is true the count is a CEILING, and mapping it as exact publishes wrong numbers on exactly the largest rules. INSUFFICIENT_DATA is returned but cannot be used as a filter value, and the aggregate variant accepts only COMPLIANT and NON_COMPLIANT as filters despite the enum listing four.
list_all_amazon_web_services_config_rule_evaluation_status
Calls AWS Config DescribeConfigRuleEvaluationStatus. No required params beyond region/account_id. Cursor-paginated, Limit up to 50 rules per page. The ONLY source of real Config timestamps for a rule. DescribeComplianceByConfigRule carries no timestamp at all, so pairing this call in is mandatory - substituting our own fetch time would be exactly the staleness lie this model exists to prevent. Use LastSuccessfulEvaluationTime (evaluation), not LastSuccessfulInvocationTime (invocation). Excludes AWS Config Custom Lambda rules from status reporting entirely - only Managed rules and Custom Policy rules appear here.
list_all_amazon_web_services_accessanalyzer_analyzers
IAM Access Analyzer analyzers. status == ACTIVE is the enablement signal, and this is one of only two of the eight security services with a genuine last_evaluated_at: lastResourceAnalyzedAt.
get_single_amazon_web_services_macie_session_by_id
Reports whether Macie is enabled via AWS Macie GetMacieSession (GET /macie). No required params beyond region/account_id. Verified live across 11 regions: when Macie is not enabled, AWS returns HTTP 403 with body {"message": "Macie is not enabled"} — treat that as absence-of-data, not an integration failure. status PAUSED means enabled-but-suspended, not disabled — do not treat PAUSED as 'not enabled' (per AWS docs; not independently verified live since Macie is not enabled anywhere in this sandbox account).
list_all_amazon_web_services_identitystore_users
Identity Center users. ListUsers returns complete User objects — UserId, UserName, DisplayName, Emails, UserStatus and CreatedAt — so DescribeUser adds nothing for bulk sync. MFA registration state is NOT AVAILABLE through any public API (the console uses an undocumented sso-directory operation with no published wire contract). last_sign_in_at is NOT AVAILABLE either — only CloudTrail UserAuthentication events carry it. has_static_credentials and has_console_access are IAM-only concepts here.
list_all_amazon_web_services_sso_instances
Identity Center instances — the bootstrap for IdentityStoreId, InstanceArn, PrimaryRegion and Regions. Capped at 10 instances; do not blindly take [0]. Calling in the WRONG region returns an empty list, not an error, which is indistinguishable from 'the customer does not use Identity Center' — sweep candidate regions rather than trusting one empty result. Note the host is sso.
list_all_amazon_web_services_s_3_buckets
All buckets. Pagination is MANDATORY, not an optimisation: unpaginated requests are rejected outright for accounts with a bucket quota above 10,000, and BucketRegion is only returned on paginated requests — without it every bucket needs an extra GetBucketLocation. BucketArn is now returned; use it as provider_ref rather than constructing arn:aws:s3:::
list_all_amazon_web_services_s_3_bucket_public_access_block
Bucket-level Block Public Access. NoSuchPublicAccessBlockConfiguration (404) means not configured — all four flags false — and must not be read as blocked. BlockPublicAcls and BlockPublicPolicy are WRITE-TIME GUARDS ONLY: AWS states enabling them does not affect existing policies or ACLs. Only IgnorePublicAcls and RestrictPublicBuckets change effective read access, so computing exposure from the two Block flags produces false clean results. Effective BPA is the account setting OR the bucket setting, per flag. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_policy_status
Whether the bucket policy grants public access. This is the ONLY policy-derived signal available cross-account: GetBucketPolicy returns 405 Method Not Allowed for a caller outside the bucket owner's account regardless of IAM. Errors 404 NoSuchBucketPolicy when there is no bucket policy at all — the same error code GetBucketPolicy throws, NOT an empty document (live-verified; corrects an earlier claim here). Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_policy
The bucket policy document. NoSuchBucketPolicy (404) means no policy, not a failure. Cross-account this returns 405 Method Not Allowed regardless of IAM — map 405 to permission_denied, never to 'no policy'. The document is plain JSON, NOT URL-encoded. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_acl
Bucket ACL grants. Public means a Grantee.URI of http://acs.amazonaws.com/groups/global/AllUsers or .../global/AuthenticatedUsers. .../s3/LogDelivery is benign — do not flag it. AuthenticatedUsers is not anonymous (requests must be signed) but means any AWS account on earth, so keep it distinguishable rather than folding it into anonymous access. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_encryption
Default encryption. Since January 2023 SSE-S3 is applied to every bucket by default, so 'no default encryption' is an obsolete control and this rarely 404s — the real control is SSEAlgorithm == AES256, i.e. not a customer-managed key. SSEAlgorithm has FOUR values: AES256, aws:kms, aws:kms:dsse, aws:fsx. KMSMasterKeyID may be a key id, an ARN or an ALIAS — store the raw string with a discriminator. The docs are internally inconsistent (KMSMasterKeyID vs KMSKeyID); parse both. ServerSideEncryptionConfigurationNotFoundError has no documented Errors section, so treat an unrecognised 404 as not_collected, never as a pass. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_versioning
Versioning state. Returns an EMPTY document with no Status element at all when versioning was never enabled — absent is not the same as Suspended. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_object_lock
Object Lock. Returns only ObjectLockEnabled (single valid value Enabled) and an optional default rule. retention_locked is NOT a real S3 field: the closest honest mapping is Mode == COMPLIANCE, which is a default for FUTURE objects and says nothing about what is in the bucket now. Legal holds and per-object retention are per object version and would need unbounded per-object calls. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_lifecycle
Lifecycle rules. NoSuchLifecycleConfiguration (404) means no rules, not a failure. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_logging
Server access logging. Returns an EMPTY document with no LoggingEnabled element when logging is off, rather than erroring. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_replication
Replication rules and destination buckets. ReplicationConfigurationNotFoundError has no documented Errors section, so an unrecognised 404 must degrade to not_collected, never to a pass. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_tagging
Bucket tags. The not-configured error code is NoSuchTagSet — singular, NOT NoSuchTagSetError — and means no tags, not a failure. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_s_3_bucket_ownership_controls
Object ownership / ACL posture. OwnershipControlsNotFoundError has no documented Errors section, so an unrecognised 404 must degrade to not_collected, never to a pass. Never map a 403 AccessDenied this way — 'not configured' and 'cannot see' are opposite security conclusions. The collector must be region-sharded: a per-bucket GET sent to the wrong region returns 301, 307, 400 or AuthorizationHeaderMalformed.
list_all_amazon_web_services_rds_db_instances
DB instances ONLY — clusters never appear here. DBClusterIdentifier is populated iff the instance belongs to a cluster: emit one row per cluster and one per standalone instance, never both. For Aurora the security posture lives on the CLUSTER (StorageEncrypted, KmsKeyId, BackupRetentionPeriod, DeletionProtection, EnabledCloudwatchLogsExports), so reading them off the instance reports the wrong object. Neptune and DocumentDB come back here too — filter by Engine. Shape asymmetries vs DBCluster: DBSubnetGroup and Endpoint are objects here but bare strings there, and the status field is DBInstanceStatus, not Status. TagList is inline, so ListTagsForResource is redundant.
list_all_amazon_web_services_rds_db_clusters
DB clusters ONLY — Aurora and non-Aurora Multi-AZ. Instances never appear here. high_availability_mode cannot be a boolean: DBInstance.MultiAZ (one hidden standby), DBCluster.MultiAZ (members span AZs) and non-Aurora Multi-AZ clusters (two readable standbys) are three different failure domains. ReadReplicaDBClusterIdentifiers explicitly excludes cross-Region Aurora read replicas, so cross-region replicas are invisible from the source.
list_all_amazon_web_services_rds_global_clusters
Aurora Global Databases only — the one API that returns cross-Region membership directly. Each GlobalClusterMember carries DBClusterArn, whose region segment is the residency answer, plus IsWriter and Readers, covering the writer and every secondary. It does not replace per-region enumeration: a cross-Region replica made with CreateDBCluster and ReplicationSourceIdentifier has no GlobalClusterIdentifier and never appears here, and neither do instance-level cross-Region replicas. Treat it as a cross-check on top of enumeration, not the source of truth.
list_all_amazon_web_services_rds_db_snapshots
INSTANCE snapshots only — Aurora/cluster snapshots never appear here, so calling only this against an Aurora-heavy customer returns empty and would wrongly conclude they have no backups. The encryption field is Encrypted (contrast DBClusterSnapshot's StorageEncrypted). The RDS default is the mirror image of EC2's and is already correct: IncludeShared and IncludePublic both default false — leave them off, or you pull in other people's public snapshots. Automated snapshots cannot be shared at all, so skip the attribute call and set shared_with_accounts [] and is_public false by construction. Do not map location from SourceRegion — it means 'created in OR copied from'; parse the ARN instead.
list_all_amazon_web_services_rds_db_cluster_snapshots
CLUSTER snapshots only. The encryption field is StorageEncrypted, NOT Encrypted — one shared mapper reads undefined here and reports every Aurora snapshot as unencrypted, a false-negative security finding at scale. DBClusterSnapshot also has no SourceRegion and no scalar AvailabilityZone. Neither RDS snapshot type carries an owner field: parse source_account_ref from the ARN.
list_all_amazon_web_services_rds_snapshot_attributes
Sharing ACL for one manual instance snapshot. Skip entirely when SnapshotType is automated — automated snapshots cannot be shared, which removes over 90% of the per-item RDS calls. A manual snapshot can be shared with at most 20 accounts, and an encrypted snapshot cannot be made public, so encrypted && is_public is an impossible state worth asserting on.
list_all_amazon_web_services_rds_cluster_snapshot_attributes
Sharing ACL for one manual cluster snapshot. Same automated-snapshot skip applies.
list_all_amazon_web_services_rds_db_parameters
Instance parameter group values — the only path to min_tls_version, via a per-engine adapter. Three traps: this returns the GROUP's value, not the running instance's, so check ParameterApplyStatus == in-sync or a static parameter may claim TLS is enforced while the database still accepts plaintext; a parameter never set has NO ParameterValue element at all, so absent is not off and the engine default must be resolved; and enforcing TLS is not the same as setting a version floor. Use the parameter-name filter — it collapses 4-10 paginated calls per group to 1.
list_all_amazon_web_services_rds_db_cluster_parameters
Cluster parameter group values. Aurora MySQL exposes tls_version as a comma-separated ALLOW-LIST to parse, not a floor, and has a second invisible audit path (server_audit_logs_upload) that never appears in EnabledCloudwatchLogsExports.
list_all_amazon_web_services_rds_subnet_groups
DB subnet groups, for placing databases into the network graph. Note PubliclyAccessible true does not mean reachable and false does not mean safe — real exposure also needs route tables.
list_all_amazon_web_services_ec_2_regions
Calls EC2 DescribeRegions to list AWS regions visible to the calling account. Not paginated — no cursor exists for this call. Filter to optInStatus in {opt-in-not-required, opted-in}; calling EC2 or other services in a not-opted-in region fails. Describes only the connection's own account (contrast with an Organizations-wide region enumeration). Never hardcode a region list — call this instead. All EC2 Describe* actions must be granted on Resource: "*"; this integration cannot be IAM-scoped to a subset of VPCs.
list_all_amazon_web_services_ec_2_vpcs
Calls EC2 DescribeVpcs to list VPCs in the given region. Account-and-region-wide, cursor-paginated (NextToken, up to 1000 per page). Check blockPublicAccessStates: VPC Block Public Access can override an internet gateway route, so a subnet with an igw- route may still be unreachable. All EC2 Describe* actions must be granted on Resource: "*"; this integration cannot be IAM-scoped to a subset of VPCs.
list_all_amazon_web_services_ec_2_subnets
Calls EC2 DescribeSubnets to list subnets in the given region. Cursor-paginated (NextToken, up to 1000 per page). Each subnet carries its vpcId and availabilityZone; join to ec2-vpcs for the parent VPC. All EC2 Describe* actions must be granted on Resource: "*"; this integration cannot be IAM-scoped to a subset of VPCs.
list_all_amazon_web_services_ec_2_flow_logs
Calls EC2 DescribeFlowLogs to list VPC Flow Logs in the given region, one flat list keyed only by resourceId. Cursor-paginated (NextToken, up to 1000/page). Flow logs attach at VPC, SUBNET or ENI level, so checking resourceId == subnetId alone gives false negatives for the common "one flow log on the VPC" setup. Gate on flowLogStatus == ACTIVE AND deliverLogsStatus == SUCCESS — delivery can fail silently. Flow logs never capture DNS, IMDS, DHCP, ARP or Windows activation traffic. EC2 Describe* actions require Resource: "*"; cannot be IAM-scoped per VPC.
list_all_amazon_web_services_ec_2_route_tables
Calls EC2 DescribeRouteTables to list route tables in the given region. Cursor-paginated (NextToken; MaxResults capped at 100 here, not 1000). A subnet not explicitly associated is IMPLICITLY tied to the VPC main table, and AWS omits the subnet id for implicit associations — joining only on association.subnetId marks every default-configured subnet as having no route; fall back to the main table (association.main == true). Distinguish igw- (internet), nat- (outbound only) and eigw- (IPv6 outbound only) gateway ids in routeSet. EC2 Describe* actions require Resource: "*"; cannot be IAM-scoped per VPC.
list_all_amazon_web_services_ec_2_network_acls
Calls EC2 DescribeNetworkAcls to list network ACLs in the given region. Cursor-paginated (NextToken, up to 1000 per page). A genuinely different primitive from security groups: stateless, allow AND deny, ORDERED by a real ruleNumber, subnet-attached via associationSet. entrySet.protocol is a String holding a NUMBER ("-1", "6", "17"), never a protocol name, and NACL entries have no description field at all. All EC2 Describe* actions must be granted on Resource: "*"; this integration cannot be IAM-scoped to a subset of VPCs.
list_all_amazon_web_services_ec_2_network_interfaces
Calls EC2 DescribeNetworkInterfaces to list elastic network interfaces (ENIs) in the given region. Cursor-paginated (NextToken, up to 1000 per page). This is the ONLY path from security groups to subnets — SecurityGroup carries no list of attached interfaces and the relationship does not exist in AWS's model. Join groups.item.groupId -> subnetId, and be honest that this is "groups observed in use right now", not configuration: an autoscaling event changes it. All EC2 Describe* actions must be granted on Resource: "*"; this integration cannot be IAM-scoped to a subset of VPCs.
list_all_amazon_web_services_ec_2_security_groups
Calls EC2 DescribeSecurityGroups to list security groups in the given region. Cursor-paginated (NextToken, up to 1000/page). Stateful, ALLOW-ONLY, unordered, ENI-attached. Rules nested in ipPermissions/ipPermissionsEgress have no action, priority, enabled or logging_enabled fields — those don't exist in this model (contrast ec2-network-acls). ipProtocol "-1" means all protocols AND all ports — never default to 0-65535; for icmp, fromPort/toPort are TYPE and CODE, not ports. EC2 Describe* actions require Resource: "*"; cannot be IAM-scoped per VPC.
list_all_amazon_web_services_ec_2_security_group_rules
Calls EC2 DescribeSecurityGroupRules to list individual security-group rules in the given region — the only source of a real per-rule description and a stable securityGroupRuleId (ec2-security-groups only nests rules inline, unaddressable). Cursor-paginated (NextToken, up to 1000/page). Prefix-list rules (no referencedGroupInfo, no cidrIpv4/cidrIpv6) carry no CIDRs directly — resolve via ec2-prefix-lists / GetManagedPrefixListEntries using prefixListId. EC2 Describe* actions require Resource: "*"; cannot be IAM-scoped per VPC.
list_all_amazon_web_services_ec_2_prefix_lists
Calls EC2 DescribeManagedPrefixLists to list managed prefix lists (both AWS-owned, e.g. com.amazonaws.
list_all_amazon_web_services_ec_2_prefix_list_entries
CIDR (or ARN) entries behind one managed prefix list, via GetManagedPrefixListEntries. Requires prefix_list_id — get one from ec2-prefix-lists. Store the list's version alongside entries; a later diff can't distinguish our change from Amazon's without it. Paginated via NextToken/MaxResults. All EC2 Describe*/Get* actions must be granted on Resource: "*" — AWS does not support resource-level permissions here.
list_all_amazon_web_services_ec_2_vpc_peering
VPC peering connections via DescribeVpcPeeringConnections. Transitive peering does not exist in AWS — an active peering only makes routing possible, it does not create it, so cross-check ec2-route-tables for routes targeting the peering id. Dedup on vpcPeeringConnectionId: an inter-region peering appears identically from both regions/accounts. Paginated via NextToken/MaxResults. All EC2 Describe* actions require Resource: "*" — no resource-level IAM scoping.
list_all_amazon_web_services_ec_2_transit_gateways
Transit gateways via DescribeTransitGateways. The single highest-signal TGW finding lives here: options.defaultRouteTableAssociation/defaultRouteTablePropagation = "enable" is the flat-mesh default where every attached VPC can reach every other VPC. Regional resource — call once per region. Paginated via NextToken/MaxResults. All EC2 Describe* actions require Resource: "*".
list_all_amazon_web_services_ec_2_tgw_attachments
Attachments to transit gateways (VPCs, VPNs, Direct Connect gateways, peering) via DescribeTransitGatewayAttachments. association.transitGatewayRouteTableId is the ONLY route-table link on this object — propagation is not present here, so two look-alike attachments can have very different blast radii. Paginated via NextToken/MaxResults. All EC2 Describe* actions require Resource: "*".
list_all_amazon_web_services_ec_2_tgw_route_tables
Transit gateway route tables via DescribeTransitGatewayRouteTables — the anchor id for ec2-tgw-associations and ec2-tgw-propagations, which together determine actual reachability. Paginated via NextToken/MaxResults. All EC2 Describe* actions require Resource: "*".
list_all_amazon_web_services_ec_2_tgw_associations
Attachments ASSOCIATED with one TGW route table, via GetTransitGatewayRouteTableAssociations. Half the reachability rule: A reaches B iff B's attachment is in propagations[associations-inverse(A)]. Requires transit_gateway_route_table_id — get one from ec2-tgw-route-tables. Paginated via NextToken/MaxResults. All EC2 Describe*/Get* actions require Resource: "*".
list_all_amazon_web_services_ec_2_tgw_propagations
Attachments that PROPAGATE routes into one TGW route table, via GetTransitGatewayRouteTablePropagations. The other half of the reachability rule — without it, transit is unknowable from the attachment alone. Requires transit_gateway_route_table_id — get one from ec2-tgw-route-tables. Paginated via NextToken/MaxResults. All EC2 Describe*/Get* actions require Resource: "*".
list_all_amazon_web_services_ec_2_snapshots
EBS snapshots via DescribeSnapshots, scoped Owner.1=self — a correctness requirement, not an optimization: without it AWS returns every public snapshot in existence, paginating effectively forever. The status field (not "state") and tagSet (not "Tags") use non-standard names. No sharing field here — use ec2-snapshot-attribute for that — and no region field; the request region is the snapshot's region. AMIs are excluded (their snapshots already appear here). Paginated via NextToken/MaxResults. All EC2 Describe* actions require Resource: "*".
list_all_amazon_web_services_ec_2_snapshot_attribute
The sharing ACL for ONE EBS snapshot, via DescribeSnapshotAttribute (Attribute=createVolumePermission) — the only source of shared_with_accounts/is_public, and the most expensive call in this group: no batch form, one call per snapshot per region. The snapshot id is a PATH argument (call as ec2-snapshot-attribute
list_all_amazon_web_services_ec_2_snapshot_bpa_state
Account+region setting for EBS snapshot Block Public Access, via GetSnapshotBlockPublicAccessState — one call per region, not global. Unlike other "list" methods here, this returns a SINGLE state value, not an array of items. This changes how is_public must be read: under block-all-sharing, already-public snapshots are treated as private and aren't actually exposed, so reporting one as public is a false positive. Report both the per-snapshot ACL (ec2-snapshot-attribute) and this regional posture together. All EC2 Describe*/Get* actions require Resource: "*".
list_all_amazon_web_services_kms_keys
Key ids only — {KeyArn, KeyId} and NO metadata at all, so budget 4 calls per key. Pagination is a third dialect: Limit / Marker / NextMarker / Truncated, neither EC2's nor the JSON services' NextToken. This also returns AWS-managed aws/* service keys with no server-side filter, and in a mature account they vastly outnumber customer keys — the DescribeKey cost is paid on every one before KeyManager == CUSTOMER can discard it.
get_single_amazon_web_services_kms_key_by_id
Key metadata. Origin has FOUR values, not three: AWS_KMS, EXTERNAL (BYOK), AWS_CLOUDHSM and EXTERNAL_KEY_STORE (XKS). Do not read the deprecated CustomerMasterKeySpec — its documented value list is stale. Carry MultiRegion / MultiRegionConfiguration or the same logical key is reported as N unrelated keys. Call this FIRST and skip GetKeyRotationStatus for anything that is not a symmetric ENCRYPT_DECRYPT key. Works cross-account.
get_single_amazon_web_services_kms_key_rotation_by_id
Rotation state. All three fields are real — KeyRotationEnabled, RotationPeriodInDays (range 90-2560, default 365) and NextRotationDate — but they are NULL, not false, for asymmetric, HMAC and custom-key-store keys, where rotation is not applicable and false would read as a misconfiguration. AWS-managed keys always rotate and it cannot be changed. Rotation is a shared property of multi-region keys, configured only on the primary. Works cross-account.
get_single_amazon_web_services_kms_key_policy_by_id
The key policy, as a raw JSON string. Skip ListKeyPolicies entirely — the only valid policy name is 'default'. This does NOT work cross-account, so policy_grants_anyone is unobtainable unless we assume a role into that account. No API answers 'is this key public': naive Principal "*" matching produces FALSE POSITIVES on every normal key, because the standard idiom pairs Principal "*" with a kms:CallerAccount condition. Check for the ABSENCE of a scoping condition (kms:CallerAccount, aws:PrincipalOrgID, aws:PrincipalAccount, kms:ViaService). Grants are a second independent authorization path this does not show. Most KMS reads are also governed by the per-key policy, not just our IAM policy, so partial coverage must surface as permission_denied per key with a count, never as a failed run.
list_all_amazon_web_services_kms_aliases
Key aliases. Call this ONCE PER REGION, never per key — that is one of the three mitigations that keeps a 500-key, 20-region scan from costing 10,000 requests.
list_all_amazon_web_services_cloudtrail_trails
Lists CloudTrail trails visible in this account/region via AWS CloudTrail DescribeTrails. No required params beyond region/account_id. NOT paginated. `enabled` is NOT in this response — a trail can exist, be multi-region, KMS-encrypted and validated while being completely stopped, and this looks identical either way. includeShadowTrails defaults to true, so a naive multi-region sweep returns one multi-region trail once per region: dedup on TrailARN and treat the record where HomeRegion equals the region called as authoritative. Do NOT set includeShadowTrails false to avoid that — in a member account of an organization trail it returns nothing at all and we would wrongly report the account as unaudited. An absent KmsKeyId means SSE-S3, NOT unencrypted.
get_single_amazon_web_services_cloudtrail_trail_status_by_id
Calls AWS CloudTrail GetTrailStatus for one trail; pass the trail name or ARN as the id (from cloudtrail-trails), plus region/account_id. The ONLY source of whether a trail is actually logging: IsLogging. One extra call per trail per region, not optional. NOT paginated. IsLogging true is still not proof logs arrive — cross-check LatestDeliveryError and LatestDeliveryTime, since a trail writing to a deleted bucket reports true with a stale timestamp.
get_single_amazon_web_services_cloudtrail_event_selector_by_id
Calls AWS CloudTrail GetEventSelectors for one trail; pass the trail name or ARN as the id (from cloudtrail-trails), plus region/account_id. Data-event coverage for one trail. Classic and advanced event selectors are MUTUALLY EXCLUSIVE, so two parsers are needed. Classic is clean: three resource types (AWS::S3::Object, AWS::Lambda::Function, AWS::DynamoDB::Table) with explicit ARN lists. Advanced is a boolean predicate language (Equals/NotEquals/StartsWith/NotStartsWith/EndsWith/NotEndsWith) that no API evaluates for us, where negation can carve arbitrary holes out of a broad match and far more than three resource types are supported — an allowlist of three silently under-reports. Best-effort inference; say so. ExcludeManagementEventSources can carve out kms.amazonaws.com or rdsdata.amazonaws.com, so management coverage is not complete even when IncludeManagementEvents is true.
list_all_amazon_web_services_logs_log_groups
Calls AWS CloudWatch Logs DescribeLogGroups. No required params beyond region/account_id. limit is 1-50 (small — expect heavy paging) and Truto's pagination cursor for this method EXPIRES AFTER 24 HOURS, so cursors must not be persisted. Do NOT set log_group_name_pattern: when it is set the response contains only arn, creationTime and logGroupName, silently dropping retentionInDays and kmsKeyId, the two fields we need. An absent retentionInDays means NEVER EXPIRE, not zero. An absent kmsKeyId means AWS-owned SSE, not unencrypted. deletionProtectionEnabled protects the group from deletion, not the retention period — anyone with logs:PutRetentionPolicy can still shorten retention to 1 day. logGroupClass DELIVERY keeps events one day only regardless of retentionInDays.
list_all_amazon_web_services_ec_2_instances
EC2 instances, flattened to one row per instance -- DescribeInstances nests instances under reservations, but response_path unwraps reservationSet.item.instancesSet.item so each item here already IS an instance. Region-scoped XML Query API (call once per region); paginates via NextToken, up to 1000/page. XML->JSON: every scalar leaf comes back as {_text: value}, and a nested list (tagSet, groupSet, blockDeviceMapping...) collapses to a bare object instead of a one-item array when there's exactly one entry -- normalize before iterating. Fixture account returned zero instances in every region tested; schema below is derived from the AWS API reference, not a live sample.
list_all_amazon_web_services_ec_2_volumes
EBS volumes. DescribeVolumes XML Query API, region-scoped; paginates via NextToken, up to 500/page. The state field is called status (creating|available|in-use|deleting|deleted|error), not state; tags are under tagSet.item, not Tags. Every scalar leaf is wrapped as {_text: value} by XML->JSON conversion, and attachmentSet.item collapses to a bare object (not a one-element array) when the volume has exactly one attachment -- normalize before iterating. Fixture account returned zero volumes in every region tested; schema below is derived from the AWS API reference, not a live sample.
list_all_amazon_web_services_elbv_2_load_balancers
ALB/NLB/Gateway load balancers. DescribeLoadBalancers -- a different AWS service (elasticloadbalancing) and a different XML array convention than the ec2-* resources in this set: repeated elements use 'member', not 'item'. Region-scoped; paginates via Marker/PageSize, up to 400/page. state is a nested {code, reason} object, not a flat status string. Every scalar leaf is still {_text: value} from the XML->JSON conversion. Fixture account returned zero load balancers in every region tested; schema below is derived from the AWS API reference, not a live sample.
list_all_amazon_web_services_redshift_clusters
Cluster metadata via DescribeClusters — the AWS Query/XML protocol, NOT JSON. Verified live via source (xml-js compact mode): every leaf field arrives wrapped as {_text: value} after XML-to-JSON conversion, e.g. ClusterIdentifier._text, unlike our JSON-service AWS resources. Optional ClusterIdentifier narrows to one cluster; a nonexistent id 404s with ClusterNotFound (verified live). Cursor pagination via Marker/MaxRecords, max 100. No credentials returned — MasterUserPassword is never in any Redshift read response.
list_all_amazon_web_services_cloudwatch_alarms
Lists CloudWatch metric alarms in this region via AWS CloudWatch DescribeAlarms (the XML API). No required params beyond region/account_id. The integration config does not wire AWS's AlarmNames, StateValue or ActionPrefix filters, so this always returns every metric alarm in the region, paged internally via NextToken/MaxRecords (up to 100 per page) through Truto's own cursor. Composite alarms (AlarmRule instead of MetricName) are returned mixed in with metric alarms.
list_all_amazon_web_services_ecs_clusters
ECS cluster ARNs only -- ListClusters returns an array of bare ARN strings, never full cluster objects (no status, running/pending task counts, capacity providers, etc.). Verified live: this fixture account has zero ECS clusters in every region tested, and the call correctly returns an empty array rather than erroring. There is no get/describe method configured for ecs-clusters in this integration, so an ARN returned here cannot be resolved to full details through this proxy. AWS JSON RPC over POST (x-amz-target header, body always {}); region-scoped, paginates via nextToken, up to 100/page.
list_all_amazon_web_services_ecs_services
ECS service ARNs only -- ListServices returns bare ARN strings, never full objects (no desired/running count, task definition, deployment config, etc.). cluster is optional per the AWS API (falls back to a cluster named 'default'), but no such cluster exists in this fixture account -- confirmed live, omitting it or passing cluster=default both fail with ClusterNotFoundException. Pass a real cluster ARN/name from ecs-clusters. No get/describe method exists for ecs-services. AWS JSON RPC over POST; region-scoped, paginates via nextToken, up to 100/page.
list_all_amazon_web_services_ecr_repositories
ECR repositories as full objects (ARN, URI, tag mutability, encryption, scan-on-push filters) -- DescribeRepositories, unlike the ARN/name-only list APIs elsewhere in this set (ecs-clusters, ecs-services, eks-clusters, eks-nodegroups). This config's body is always {} with no repositoryNames/registryId filter exposed, so every call returns the whole registry's repositories, unfiltered. AWS JSON RPC over POST; region-scoped, paginates via nextToken, up to 1000/page. Fixture account has zero repositories in every region tested; schema below is derived from the AWS API reference, not a live sample.
list_all_amazon_web_services_secretsmanager_secrets
ListSecrets — metadata only. SecretString/SecretBinary are NEVER returned here; only GetSecretValue exposes them, and that is not one of our methods, so never describe this as a possible value leak. SortOrder (asc|desc) and IncludePlannedDeletion (bool) pass through live and are AWS-validated (confirmed: bad values 400 with ValidationException/SerializationException). Filters (AWS's {Key,Values} list) is supported by the API but not exposed as a flat query param here. Cursor pagination via NextToken/MaxResults, max 100.
list_all_amazon_web_services_dynamodb_tables
ListTables. The response is a BARE ARRAY OF TABLE NAME STRINGS (TableNames) — not objects, so there is no ARN, status, billing mode, or item count here. Get those per-table via DescribeTable (a separate call, out of scope for this method). AWS ListTables takes no filter params, only pagination (ExclusiveStartTableName/LastEvaluatedTableName), max page 100.
list_all_amazon_web_services_lambda_functions
Lambda functions as full configuration objects (ARN, runtime, handler, role, VPC config, layers, environment, logging config, etc.) -- ListFunctions, verified live with real functions. Region-scoped; paginates via Marker/MaxItems, up to 50/page. This fixture account's functions only exist in us-west-2 -- the default us-east-1 and every other region tested returned an empty array, so always pass region explicitly. Many fields are null unless the function uses that feature (VpcConfig, Environment, DeadLetterConfig, KMSKeyArn, ...) -- null means "not configured", not missing data.
list_all_amazon_web_services_eks_clusters
EKS cluster NAMES only -- ListClusters returns an array of bare strings, never full cluster objects (no ARN, version, status, endpoint, VPC config, etc.), confirmed against the AWS API reference. This account has zero EKS clusters in every region tested, so the empty-array shape was verified live but a populated response wasn't. There is no get/describe method configured for eks-clusters in this integration, so a name returned here cannot be resolved to full details through this proxy. Region-scoped; paginates via nextToken, up to 100/page.
list_all_amazon_web_services_eks_nodegroups
EKS node group NAMES only -- ListNodegroups returns an array of bare strings, never full objects (no ARN, instance types, scaling config, etc.), confirmed against the AWS API reference. cluster_name is required (path param /clusters/{cluster_name}/node-groups) and must come from eks-clusters' list; this fixture account has zero EKS clusters in any region, so no real cluster_name could be sourced and the response couldn't be verified live. No get/describe method exists for eks-nodegroups. Region-scoped; paginates via nextToken, up to 100/page.
list_all_amazon_web_services_efs_file_systems
EFS file systems. DescribeFileSystems is a plain JSON REST call -- no XML {_text} wrapping, unlike the ec2-*/elbv2-* resources in this set. Region-scoped; paginates via Marker/MaxItems, up to 100/page (the config tolerates an empty-string cursor on the last page). SizeInBytes is an object with Value/Timestamp fields, not a bare number. Fixture account returned zero file systems in every region tested; schema below is derived from the AWS API reference, not a live sample.
list_all_amazon_web_services_iam_groups
IAM groups in the account (ListGroups). IAM is a global service reached through a single endpoint, so region only affects which credentials/account are used, not where the data lives. Paginated with the classic Marker/IsTruncated cursor, same as iam-users and iam-roles. Does not include a group's attached/inline policies or its members — those need separate IAM calls.
list_all_amazon_web_services_iam_attached_user_policies
AWS-managed and customer-managed IAM policies attached directly to one IAM user (ListAttachedUserPolicies). user_name comes from iam-users (UserName). Does not include inline (embedded) user policies (see iam-users' GetUserPolicy) or policies inherited from group membership.
get_single_amazon_web_services_iam_policy_version_by_id
The full JSON policy document for one version of a customer- or AWS-managed IAM policy (GetPolicyVersion). Pass the policy ARN as the resource id (from iam-policies, Arn) and the version id as version_id (from iam-policies, DefaultVersionId, or IsDefaultVersion=true on this response). Document is returned percent-URL-encoded JSON — URL-decode it before parsing the statements. Callers must percent-encode the ARN before passing it as a path id (it contains ':' and '/').
list_all_amazon_web_services_iam_entities_for_policy
Reverse lookup for an IAM managed policy: which groups, roles and users it is attached to (ListEntitiesForPolicy). policy_arn comes from iam-policies (Arn). Unlike other iam-* list methods this returns one object with three separate member arrays (PolicyGroups/PolicyRoles/PolicyUsers), not a flat list of entities.
get_single_amazon_web_services_iam_access_key_last_used_by_id
When and where an IAM access key was last used (GetAccessKeyLastUsed) — the key signal for finding stale or unused long-term credentials. Pass the access key id as the resource id (from iam-access-keys, AccessKeyId). ServiceName and Region are absent from the response until the key has been used at least once.
list_all_amazon_web_services_config_rules
AWS Config rule definitions in the region — name, source (AWS managed check or custom Lambda), scope and evaluation mode (DescribeConfigRules). This returns rule definitions only; use config-rule-compliance for each rule's pass/fail status.
list_all_amazon_web_services_config_rule_compliance
Pass/fail compliance status for AWS Config rules in the region (DescribeComplianceByConfigRule) — COMPLIANT, NON_COMPLIANT or INSUFFICIENT_DATA per rule, with resource counts. Cross-reference ConfigRuleName against config-rules for the rule definition. Not paginated by AWS — returns every rule for the region in one call.
list_all_amazon_web_services_accessanalyzer_findings
Findings from an IAM Access Analyzer analyzer — resources shared outside the account/org, or unused permissions, depending on the analyzer's type (ListFindings). analyzer_arn comes from accessanalyzer-analyzers (arn). No analyzer was configured in this account at verification time; verified live against a well-formed but nonexistent analyzer ARN, which AWS correctly rejected with 'Analyzer not found', confirming the request reaches the service correctly. Response fields below are from the AWS API reference.
list_all_amazon_web_services_cloudtrail_list_trails
Lightweight inventory of every CloudTrail trail visible to this account/region — name, home region and ARN (ListTrails). Unlike cloudtrail-trails (DescribeTrails) this does not return the trail's logging configuration (S3 bucket, KMS key, multi-region flag); use cloudtrail-trails or cloudtrail-trail-status for that. No trail existed in this account at verification time (call returned 200 with an empty list).
get_single_amazon_web_services_guardduty_org_configuration_by_id
Whether GuardDuty is auto-enabled for new accounts joining the organization, and this account's member/data-source status (DescribeOrganizationConfiguration). Pass a detector id (from guardduty-detectors) as the resource id. Only meaningful when called from the GuardDuty delegated-administrator account. No detector existed in this account at verification time; the call correctly reached AWS and was rejected with 'detectorId is not owned by the current account', confirming the path and signing are correct. Response fields below are from the AWS API reference.
list_all_amazon_web_services_securityhub_standards
Catalog of every Security Hub compliance standard AWS offers in this region — CIS, PCI DSS, AWS Foundational Security Best Practices, and others — not just the ones enabled for this account (DescribeStandards). Use securityhub-enabled-standards to see which of these are actually subscribed; StandardsArn from this call is the id securityhub-enabled-standards' subscriptions reference.
get_single_amazon_web_services_organizations_account_by_id
Details of one AWS account inside the organization — email, status, and joined method/date (DescribeAccount). Pass the 12-digit account id as the resource id (from organizations-accounts, Id). Only callable from the organization's management or delegated-administrator account; this connection's default account returned AWS's AWSOrganizationsNotInUseException at verification time — the same error every other organizations-* resource on this integration gets from this account, so this is an environment limitation rather than a config defect.
get_single_amazon_web_services_s_3_bucket_by_id
One S3 bucket's ListBuckets entry (Name, BucketRegion, CreationDate, BucketArn), read with ListBuckets prefix=
list_all_amazon_web_services_account_information
AWS Account Management GetAccountInformation: AccountId, AccountName, AccountCreatedDate, AccountState for the calling account, or for an org member with ?truto_target_account_id= (management / delegated admin only). Needs account:GetAccountInformation.
list_all_amazon_web_services_iam_account_aliases
IAM ListAccountAliases: the calling account's alias (an account has at most one). Needs iam:ListAccountAliases.
Why Truto
Why use Truto’s MCP server for Amazon Web Services
Other MCP servers give you a static tool list for one app. Truto gives you a managed, multi-tenant MCP infrastructure across 800+ integrations.
Auto-generated, always up to date
Tools are dynamically generated from curated documentation — not hand-coded. As integrations evolve, tools stay current without manual maintenance.
Fine-grained access control
Scope each MCP server to read-only, write-only, specific methods, or tagged tool groups. Expose only what your AI agent needs — nothing more.
Multi-tenant by design
Each MCP server is scoped to a single connected account with its own credentials. The URL itself is the auth token — no shared secrets, no credential leaking across tenants.
Works with every MCP client
Standard JSON-RPC 2.0 protocol. Paste the URL into Claude, ChatGPT, Cursor, or any MCP-compatible agent framework — tools are discovered automatically.
Built-in auth, rate limits, and error handling
Tool calls execute through Truto’s proxy layer with automatic OAuth refresh, rate-limit handling, and normalized error responses. No raw API plumbing in your agent.
Expiring and auditable servers
Create time-limited MCP servers for contractors or automated workflows. Optional dual-auth requires both the URL and a Truto API token for high-security environments.
Unified APIs
Unified APIs for Amazon Web Services
Skip writing code for every integration. Use Truto’s category-specific Unified APIs out of the box or customize the mappings with AI.
Unified Cloud Infrastructure API
Access Grants
Who can do what, and at which level of the hierarchy -- organisation, grouping, account, or resource.
Account Groupings
A node in the account hierarchy -- an organisational unit, a management group, or a folder.
Accounts
An account, subscription, or project. Enumerated across the whole organisation, not limited to the connected account.
Audit Trail Configs
Whether an audit trail (change-logging configuration) exists and is switched on. Providers model this very differently: one estate-wide trail, per-scope routing, or tiered defaults.
Data Snapshots
Database and volume snapshots, including who owns the source data and who the snapshot has been shared with.
Firewall Rule Sets
Security groups, network ACLs, and firewall policies — primitives with different semantics, distinguished by scope_type.
Human Identities
A user that can sign in, whether a person or a shared login. On AWS this spans both IAM users and IAM Identity Center users, which share no identifiers.
Log Destinations
Where logs are kept, and for how long. Retention doubles as evidence for a data-retention schedule.
Managed Keys
Encryption keys held in the provider's key management service (KMS, Key Vault, Cloud KMS), including rotation and access-policy state.
Network Boundaries
Virtual networks and their subnets, normalized across providers whose networks may be regional or genuinely global.
Network Links
Network peerings, transit attachments, and shared-network connections between boundaries, potentially crossing account boundaries.
Object Stores
Bucket and blob storage across providers, with a normalized public-access and encryption posture for each store.
Password Policies
The password policy as the provider exposes it, reported at the level it actually applies (account, tenant, org unit, etc).
Permission Definitions
The contents of a custom role or policy, including wildcards and negated forms (NotAction, NotResource) preserved verbatim rather than expanded.
Policy Compliance States
The evaluation result of a policy rule that reports non-compliance rather than blocking it.
Policy Constraints
Preventative policies (e.g. AWS SCPs, Azure Policy) applied across the org, one row per policy per scope node, including inherited attachments.
Posture Findings
One row per control evaluation per resource, from the provider's own security product (Security Hub, Defender for Cloud, Security Health Analytics).
Relational Databases
Managed relational database clusters and standalone instances, with security posture (encryption, backups, network access) read at the right level.
Scan Coverages
What proportion of the estate is actually being scanned. Zero findings on an unscanned estate must not be read as a clean estate.
Security Product States
Whether the provider's own security product is switched on, per product, per account, per region.
Static Credentials
Long-lived credentials held by a principal -- access keys, client secrets, certificates, SSH keys, and service account keys.
Threat Findings
Runtime security alerts from the provider's threat detection product (GuardDuty, Defender alerts, Event Threat Detection): observed activity, not configuration drift.
Vulnerability Findings
Package and host vulnerabilities from the provider's own scanner. Read alongside scan_coverages to know how much of the estate was actually scanned.
Workload Identities
Machine identities -- roles, managed identities, service principals, and service accounts -- and who outside the estate is permitted to use them.
How It Works
From zero to integrated
Go live with Amazon Web Services in under an hour. No boilerplate, no maintenance burden.
Link your customer’s Amazon Web Services account
Use Truto’s frontend SDK to connect your customer’s Amazon Web Services account. We handle all OAuth and API key flows — you don’t need to create the OAuth app.
We handle authentication
Don’t spend time refreshing access tokens or figuring out secure storage. We handle it and inject credentials into every API request.
Call our API, we call Amazon Web Services
Truto’s Proxy API is a 1-to-1 mapping of the Amazon Web Services API. You call us, we call Amazon Web Services, and pass the response back in the same cycle.
Unified response format
Every response follows a single format across all integrations. We translate Amazon Web Services’s pagination into unified cursor-based pagination. Data is always in the result attribute.
FAQs
Common questions about Amazon Web Services on Truto
Authentication, rate limits, data freshness, and everything else you need to know before you integrate.
How do end users authenticate their AWS account?
AWS integrations are typically authorized via IAM role assumption using an external ID and a cross-account trust policy. Truto handles the STS assume-role flow and credential refresh so your application only sees a connected account ID.
Does Truto handle multi-account AWS Organizations setups?
Yes. You can list all accounts, roots, OUs, and policy targets under a management account using the Organizations tools, then query member accounts individually. This is the standard pattern for enterprise customers with dozens or hundreds of accounts.
How are regional services like GuardDuty and Inspector handled?
GuardDuty, Inspector2, Security Hub, and most EC2 resources are region-scoped. You can enumerate active regions with the EC2 regions tool and iterate the per-region list endpoints — Truto exposes region as a parameter on these calls.
What AWS data maps into Truto's Unified Cloud Infrastructure API?
AWS resources normalize into unified models including Object Stores (S3), Relational Databases (RDS), Workload Identities (IAM roles), Human Identities (IAM users, Identity Store), Static Credentials (access keys), Firewall Rule Sets (security groups), Network Boundaries (VPCs/subnets), Threat Findings (GuardDuty), Vulnerability Findings (Inspector2), Posture Findings (Security Hub), and more.
Are AWS API rate limits abstracted?
Yes. AWS enforces per-service throttling (e.g., IAM, EC2, Config each have their own limits). Truto applies backoff and retry logic transparently, and pagination across large result sets like S3 buckets, IAM entities, and findings is handled by the list endpoints.
Can I get fresh data on demand or is it synced?
Both. You can call any list or get tool on demand for real-time reads, or configure Truto to sync resources into the Unified Cloud Infrastructure models on a schedule with change events delivered via webhooks.
Is write access to AWS supported?
The current AWS tool set is read-only and optimized for discovery, inventory, and posture use cases (CSPM, CIEM, DSPM, SIEM). If you need write actions for a specific workflow, Truto can add them on request.
Amazon Web Services
Get Amazon Web Services integrated into your app
Our team understands what it takes to make a Amazon Web Services integration successful. A short, crisp 30 minute call with folks who understand the problem.