Simulated STS
Yulin simulates AssumeRole and GetCallerIdentity. Access the service through simAws.sts() or an
intercepted STSClient.
Basic usage
Section titled “Basic usage”Create a role with a trust policy, then call assumeRole. A request with no caller runs as the
account root.
/** * Assuming a simulated IAM Role through simulated STS. */
import { CreateRoleCommand } from "@aws-sdk/client-iam";import { AssumeRoleCommand } from "@aws-sdk/client-sts";import { SimAws } from "@kensio/yulin";
const simAws = new SimAws();const account = simAws.account("123456789012");
await account.iam().createRole( new CreateRoleCommand({ RoleName: "TargetRole", AssumeRolePolicyDocument: JSON.stringify({ Version: "2012-10-17", Statement: { Effect: "Allow", Principal: { AWS: "arn:aws:iam::123456789012:root" }, Action: "sts:AssumeRole", }, }), }),);
const assumeRoleOutput = await account.sts().assumeRole( new AssumeRoleCommand({ RoleArn: "arn:aws:iam::123456789012:role/TargetRole", RoleSessionName: "test-session", }),);
console.log(assumeRoleOutput.AssumedRoleUser?.Arn);console.log(assumeRoleOutput.Credentials?.AccessKeyId);console.log(assumeRoleOutput.Credentials?.Expiration);AssumedRoleUser.Arn is the session ARN, such as
arn:aws:sts::123456789012:assumed-role/TargetRole/test-session, and Credentials carries the
temporary AccessKeyId, SecretAccessKey, SessionToken, and Expiration.
Yulin registers the credentials with simulated IAM in the target account. Later requests use the
role’s identity policies. See STS sessions in simulated IAM.
Credentials fail after Expiration or when the session token is missing.
DurationSeconds defaults to 3,600 seconds and must be a positive integer.
Reading the current identity
Section titled “Reading the current identity”getCallerIdentity reports the caller’s ARN, account ID and user ID. It handles account roots, IAM
users and assumed-role sessions. The intercepted and served STS APIs also support
GetCallerIdentityCommand.
An unattributed request reports the configured default caller, or the account root when no default
caller is configured. An anonymous caller receives AccessDenied.
Role-to-Role assumption
Section titled “Role-to-Role assumption”Pass caller to assume a role as a specific principal. STS checks both sides of the request:
- The target Role’s trust policy must allow the caller to perform
sts:AssumeRole - A non-root caller also needs an identity policy allowing
sts:AssumeRoleon the target Role’s ARN
/** * One simulated IAM Role assuming another through simulated STS. */
import { CreateRoleCommand, PutRolePolicyCommand } from "@aws-sdk/client-iam";import { AssumeRoleCommand } from "@aws-sdk/client-sts";import { SimAws } from "@kensio/yulin";
const simAws = new SimAws();const account = simAws.account("123456789012");const simIam = account.iam();
const sourceRoleArn = "arn:aws:iam::123456789012:role/SourceRole";const targetRoleArn = "arn:aws:iam::123456789012:role/TargetRole";
await simIam.createRole( new CreateRoleCommand({ RoleName: "SourceRole", AssumeRolePolicyDocument: JSON.stringify({ Version: "2012-10-17", Statement: { Effect: "Allow", Principal: { AWS: "arn:aws:iam::123456789012:root" }, Action: "sts:AssumeRole", }, }), }),);
await simIam.putRolePolicy( new PutRolePolicyCommand({ RoleName: "SourceRole", PolicyName: "AssumeTargetRole", PolicyDocument: JSON.stringify({ Version: "2012-10-17", Statement: { Effect: "Allow", Action: "sts:AssumeRole", Resource: targetRoleArn, }, }), }),);
await simIam.createRole( new CreateRoleCommand({ RoleName: "TargetRole", AssumeRolePolicyDocument: JSON.stringify({ Version: "2012-10-17", Statement: { Effect: "Allow", Principal: { AWS: sourceRoleArn }, Action: "sts:AssumeRole", }, }), }),);
const assumeRoleOutput = await account.sts().assumeRole( new AssumeRoleCommand({ RoleArn: targetRoleArn, RoleSessionName: "role-session", }), { caller: { kind: "arn", arn: sourceRoleArn }, },);
console.log(assumeRoleOutput.AssumedRoleUser?.Arn);If either check fails, STS raises a 403 access-denied error naming sts:AssumeRole and the target
role ARN. No session is created.
Cross-account assumption uses the same checks. Call assumeRole through the source account. The
session belongs to the target role’s account.
Role chaining
Section titled “Role chaining”For role chaining, use the first session as the caller of the second assumeRole request. The target
trust policy names the first role, and that role needs identity permission to assume the target.
A trust policy may name the role ARN or one assumed-role session ARN. Prefer the role ARN when the session name is chosen at run time.
The served endpoint resolves session credentials in the same way.
ExternalId
Section titled “ExternalId”A trust policy can require sts:ExternalId. Pass the matching ExternalId to AssumeRoleCommand.
/** * Requiring an ExternalId in a simulated Role trust policy. */
import { CreateRoleCommand } from "@aws-sdk/client-iam";import { AssumeRoleCommand } from "@aws-sdk/client-sts";import { SimAws } from "@kensio/yulin";
const simAws = new SimAws();const account = simAws.account("123456789012");
await account.iam().createRole( new CreateRoleCommand({ RoleName: "PartnerRole", AssumeRolePolicyDocument: JSON.stringify({ Version: "2012-10-17", Statement: { Effect: "Allow", Principal: { AWS: "arn:aws:iam::123456789012:root" }, Action: "sts:AssumeRole", Condition: { StringEquals: { "sts:ExternalId": "expected-external-id", }, }, }, }), }),);
const assumeRoleOutput = await account.sts().assumeRole( new AssumeRoleCommand({ RoleArn: "arn:aws:iam::123456789012:role/PartnerRole", RoleSessionName: "partner-session", ExternalId: "expected-external-id", }),);
console.log(assumeRoleOutput.AssumedRoleUser?.Arn);An omitted or mismatched value denies the request.
Available functionality
Section titled “Available functionality”Sim STS currently supports:
AssumeRoleCommandGetCallerIdentityCommand- Trust-policy evaluation against the target Role’s assume-role policy document
- Identity-policy evaluation of the source caller, requiring
sts:AssumeRolepermission on the target Role - Role-to-Role and cross-Account assumption
ExternalIdmatching through thests:ExternalIdtrust-policy condition key- Session duration with
DurationSeconds, defaulting to one hour - Temporary credentials registered with the target Account’s sim IAM, including session-token and expiry validation
Limitations
Section titled “Limitations”- Federation, web identity and session-token commands are unsupported.
- Session policies (
Policy/PolicyArns), tags, andSourceIdentityrequests are not evaluated - Condition support in trust policies is limited to the operators supported by sim IAM
