Cloud Lab.The pattern, deployable.
Cross-account access through STS AssumeRole is how Cloud Waste Hunter scans AWS accounts without ever holding visitor credentials. This page emits the same pattern as ready-to-deploy infrastructure — paste your parent-account id below, copy the CloudFormation or Terraform, and verify the trust policy from your terminal. Nothing leaves your shell.
The architecture has three actors. Your AWS account holds the resources you want to expose. The parent account is whatever account needs scoped access — could be Cloud Waste Hunter, could be your CI, could be a partner platform. The external id is a shared secret that both sides know, used to mitigate the confused-deputy problem.
- You deploy a role in your account. Its trust policy says only the parent account can assume it, and only when it presents the external id.
- You hand the parent two values: the role's ARN and the external id.
- The parent calls
sts:AssumeRolewith both, receives temporary credentials scoped to whatever permissions your role policy grants, and acts on your behalf.
The visitor (parent account) never sees your long-term credentials. Your role policy controls exactly what they can do. Revocation is a single AWS console click.
AWSTemplateFormatVersion: '2010-09-09'
Description: >
Cross-account IAM role for the Cloud Lab pattern.
Deploying this stack creates a role in YOUR account that account
000000000000 can assume — and ONLY that account, ONLY with
the external-id below. The role permissions below are an example;
replace them with the AWS API surface you actually need to grant.
Parameters:
RoleName:
Type: String
Default: cloud-lab-cross-account-role
Description: Name for the IAM role.
Resources:
CrossAccountRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: TrustParentAccount
Effect: Allow
Principal:
# The parent account that will be allowed to AssumeRole.
AWS: 'arn:aws:iam::000000000000:root'
Action: 'sts:AssumeRole'
Condition:
StringEquals:
# The external-id is a shared secret. The parent MUST
# pass it on AssumeRole or the trust policy denies —
# this is the confused-deputy mitigation.
'sts:ExternalId': 'REGENERATE_AND_PASTE'
Policies:
- PolicyName: CloudLabExamplePermissions
PolicyDocument:
Version: '2012-10-17'
Statement:
# Replace this Statement with the permissions you
# want to grant. The example below allows the parent
# account to invoke Claude Haiku via Bedrock — the
# narrowest reasonable demo permission.
- Sid: ExampleInvokeBedrock
Effect: Allow
Action: 'bedrock:InvokeModel'
Resource:
- !Sub 'arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude-3-5-haiku-20241022-v1:0'
Outputs:
RoleArn:
Description: ARN to paste back into the parent system.
Value: !GetAtt CrossAccountRole.Arn
ExternalId:
Description: External-id value the parent must pass on AssumeRole.
Value: 'REGENERATE_AND_PASTE'
Content-only·No server-side AWS calls·Inputs stay in your browser
