How IAM Identity Center Powers Secure Access for Claude AI Agents in Node.js, Explained Simply A developer outlined a pattern for giving Claude-powered Lambda functions short-lived, automatically rotated AWS credentials by using IAM Identity Center permission sets and STS AssumeRoleWithSAML instead of hard-coded static keys. The approach defines a minimal policy in TypeScript using the satisfies operator to catch typos at compile time, then exchanges a SAML assertion for temporary credentials valid for up to one hour before calling Bedrock. The pattern is presented as reusable for any LLM-backed tool. Human users and AI agents both need the right permissions, but mixing SSO with programmatic access is tricky. In just a few minutes you’ll see how to let a Claude‑powered Lambda speak to Bedrock without ever hard‑coding static keys. The pattern works for any LLM‑backed tool you build today. When a human logs into the AWS console we usually think about IAM Identity Center formerly AWS SSO as a single‑sign‑on SSO portal. It lets people click a link, type a password, and get a web console with all the permissions they need. An AI agent —for example a Lambda function that talks to Claude on Bedrock—needs the same “right‑things‑can‑do” guarantee, but it can’t click a button. If you give the function long‑lived static credentials, you expose a secret that never rotates. In plain English : IAM Identity Center can hand out short‑lived, automatically‑rotated credentials for programs, just like it hands a temporary badge to a visitor. The benefit is two‑fold: Think of IAM Identity Center as a hotel front desk. A human guest gets a room key that works for a few hours. An AI agent is a robot concierge that needs a key to fetch a specific amenity the Claude model . The front desk can issue a temporary key for the robot, and the key expires automatically, keeping the hotel secure. A permission set groups one or more IAM policies and is assigned to a user or group in IAM Identity Center. For a machine, you create a dedicated permission set that includes only the actions needed to call Bedrock and read any supporting resources like a Secrets Manager secret that holds the SAML assertion . Tip : Keep the permission set tiny. If the agent only needs bedrock:InvokeModel , don’t also grant s3: . ClaudeAgentAccess . bedrock:InvokeModel on the Claude model ARN. sts:AssumeRoleWithSAML on the SAML provider you will use. secretsmanager:GetSecretValue . satisfies Instead of hand‑editing JSON in the console, you can write the policy in TypeScript and let the compiler verify its shape. The satisfies operator ensures the object conforms to the IAM policy schema at compile time. python // src/policy.ts import type { PolicyDocument } from "aws-sdk/clients/iam"; / Inline policy granting the minimal rights for a Claude‑powered Lambda. The satisfies keyword makes TypeScript check that every required field exists. / export const claudeAgentPolicy = { Version: "2012-10-17", Statement: { Effect: "Allow", Action: "bedrock:InvokeModel", // call Claude on Bedrock "sts:AssumeRoleWithSAML", // exchange SAML for temporary creds "secretsmanager:GetSecretValue", // read the SAML assertion stored securely , Resource: " ", // you could lock this down to specific ARNs for tighter security }, , } satisfies PolicyDocument; Key takeaway : Using satisfies catches typos like "bedrock:InvokModel" before you ever deploy, turning a runtime surprise into a compile‑time warning. You can copy the resulting JSON into the console’s Inline Policy editor when you create the permission set. Now that the permission set exists, the Lambda must assume the role represented by that set. The standard way is to call the AWS Security Token Service STS operation AssumeRoleWithSAML . The flow looks like this: AssumeRoleWithSAML , passing the SAML assertion and the ARN of the permission set’s AccessKeyId , SecretAccessKey , SessionToken that are valid for up to 1 hour. Below is a minimal, fully‑commented Lambda handler written in TypeScript for Node.js 22 . It uses the AWS SDK v3 packages you asked for: @aws-sdk/client-sts , @aws-sdk/client-secrets-manager , and @aws-sdk/client-bedrock-runtime . The client-iam and client-lambda packages are not needed directly in the handler but are listed in the service context for completeness. js // src/handler.ts import { STSClient, AssumeRoleWithSAMLCommand, } from "@aws-sdk/client-sts"; import { SecretsManagerClient, GetSecretValueCommand, } from "@aws-sdk/client-secrets-manager"; import { BedrockRuntimeClient, InvokeModelCommand, } from "@aws-sdk/client-bedrock-runtime"; import type { Handler, Context, Callback } from "aws-lambda"; // Environment variables you set in the Lambda console const { SAML SECRET ID, // Secrets Manager name that holds the Base64‑encoded SAML assertion IAM ROLE ARN, // The role ARN linked to the permission set CLAUDE MODEL ID, // e.g. "anthropic.claude-v2:1" REGION = "us-east-1", // Bedrock region } = process.env; // Re‑use SDK clients – they are cheap to create and benefit from connection pooling const sts = new STSClient { region: REGION } ; const secrets = new SecretsManagerClient { region: REGION } ; / Helper: fetch the raw SAML assertion Base64 string from Secrets Manager. / async function getSamlAssertion : Promise