Skip to content

content(what-is): rewrite the aws lambda list-functions with dynamic credentials guide#19272

Closed
alexleventer wants to merge 1 commit into
masterfrom
aleventer/run-lambda-list-rewrite
Closed

content(what-is): rewrite the aws lambda list-functions with dynamic credentials guide#19272
alexleventer wants to merge 1 commit into
masterfrom
aleventer/run-lambda-list-rewrite

Conversation

@alexleventer

Copy link
Copy Markdown
Contributor

Summary

Rewrites content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md for SEO and AEO. The new version is ~210 tight lines focused on what aws lambda list-functions returns, the single IAM permission it needs, and the per-region pagination behavior that trips most users up.

What changed

  • Quotable opening — bolded one-paragraph framing covering what the guide does, why dynamic credentials beat static, and that list-functions is regional and gated by lambda:ListFunctions.
  • "In this article, we'll cover" bullet list for skim/extract.
  • Why dynamic credentials beat static — five bullets covering no-disk secrets, role scoping, expiration, CloudTrail audit, central rotation.
  • What/IAM/scope table — required permission, per-region scope, server-side pagination behavior, read-only nature, cross-account handling.
  • Prerequisites — Pulumi CLI/ESC, Pulumi Cloud account, AWS CLI v2, OIDC-trusted IAM role with lambda:ListFunctions.
  • Numbered step-by-step setup (5 steps) — login, OIDC config, create environment, paste the aws-login YAML, confirm empty aws configure list.
  • Run section with three sub-modes — basic call with example JSON, --query JMESPath filter for tabular output, manual pagination with --max-items, and a loop across every region via aws ec2 describe-regions.
  • CloudTrail verification showing the ListFunctions20150331 assumed-role event.
  • Common errors tableAccessDeniedException, InvalidClientTokenId, ExpiredToken, empty Functions: [] (region confusion), EndpointConnectionError, Unable to locate credentials.
  • FAQ (7 doubt-removers) — global vs regional, minimum IAM, pagination, cross-account inventory, credential lifetime, CI usage, source verification.
  • Cross-links to /product/esc/, OIDC config docs, sibling run-aws pages, resolve-* error pages.
  • Tightened meta_desc to lead with the value prop (under 160 chars).

Test plan

  • make serve; visit /what-is/run-aws-lambda-list-functions-with-dynamic-credentials/ and confirm both tables, code blocks, and headings render correctly
  • Spot-check cross-links (/product/esc/, OIDC docs, sibling run-aws pages, resolve-* pages)
  • CI lint + pinned review

🤖 Generated with Claude Code

…credentials guide

Rewrite for SEO and AEO: quotable opening, semantic chunking,
numbered setup steps, IAM/scope/pagination table, --query and
multi-region loop examples, common-errors table, FAQ targeting
doubt-removers, and cross-links to Pulumi ESC and related guides.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added review:triaging Claude Triage is currently classifying the PR domain:docs PR touches technical docs review:in-progress Claude review is currently running and removed review:triaging Claude Triage is currently classifying the PR labels May 20, 2026
@pulumi-bot

Copy link
Copy Markdown
Collaborator

@github-actions

Copy link
Copy Markdown
Contributor

Pre-merge Review — Last updated 2026-05-20T16:53:40Z

Tip

Summary: Full rewrite of the what-is page for aws lambda list-functions with dynamic credentials. The new structure (intro → "why dynamic" → IAM/scope table → numbered ESC setup → expanded run-and-paginate section → CloudTrail verify → error table → FAQ) diverges intentionally from the still-old sibling pages (run-aws-iam-list-users, run-aws-sts-get-caller-identity, etc.) — sibling consistency is therefore not the bar. Reader risk: a misleading IAM scope claim could cause readers to grant the wrong least-privilege permission, and a misleading session-duration default could cause confusing token-expiry behavior. Investigation ran fact-check on every prose claim, link/alias resolution against the repo, and a Vale prose pass; the Hugo build pre-step was skipped (content-only PR, templates untouched).

Review confidence:

Dimension Level Notes
mechanics HIGH
facts MEDIUM 3 contradicted (L27, L33, L182) blocking; 2 unverifiable left for the author
code correctness HIGH
Investigation log
  • Cross-sibling reads: not run (not in a templated section)
  • External claim verification: 24 of 43 claims verified (6 unverifiable, 3 contradicted) · 4 specialists (numerical, cross-reference, capability, framing); 0 cross-specialist corroborations · routed: 0 inline, 30 Pass 1, 0 Pass 2, 13 Pass 3 (verified 4, contradicted 1, unverifiable 8).
  • Cited-claim spot-checks: not run (no cited claims)
  • Frontmatter sweep: ran on body + meta_desc
  • Temporal-trigger sweep: ran (recency words present in diff; spot-check in-review)
  • Code execution: not run (no static/programs/ change)
  • Code-examples checks: ran (3 specialists: structural, existence, body-code-coverage); 0 findings
  • Editorial-balance pass: not run (not under content/blog/)
🚨 Outstanding ⚠️ Low-confidence 💡 Pre-existing ✅ Resolved
3 12 0 0

🔍 Verification trail

43 claims extracted · 24 verified · 6 unverifiable · 3 contradicted
  • L3 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Pulumi ESC issues short-lived, OIDC-issued AWS credentials (no static AWS keys), scoped by IAM role, and auditable in CloudTrail." → ✅ verified (evidence: The file's meta_desc at L3 reads verbatim: "Run aws lambda list-functions with short-lived, OIDC-issued credentials from Pulumi ESC. No static AWS keys, scoped by IAM role, auditable in CloudTrail." The body further confirms each element…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L3 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions enumerates Lambda functions in a single region and returns their ARNs, runtimes, memory sizes, and configuration metadata." (also L10) → ✅ verified (evidence: The file itself at line 10 states: "aws lambda list-functions enumerates Lambda functions in a single region and returns their ARNs, runtimes, memory sizes, and configuration metadata." The example JSON output in the same file confirms `…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L14 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "* Why dynamic credentials beat static IAM keys" → ➖ not-a-claim (evidence: The line "* Why dynamic credentials beat static IAM keys" is a bullet point in a document outline/table of contents authored by the PR author describing their own content. It is a section heading label, not a falsifiable third-party assert…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md L14)
  • L21 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "## Why dynamic credentials beat static IAM keys" → ➖ not-a-claim (evidence: The text "## Why dynamic credentials beat static IAM keys" is a markdown section heading in the PR author's own document. It is a descriptive label for the author's own content/design, not a falsifiable third-party-attributed assertion.; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md L21)
  • L25 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Pulumi ESC issues a fresh AccessKeyId, SecretAccessKey, and SessionToken on every esc run invocation, and nothing persists locally." → ✅ verified (evidence: The file at L25 states verbatim: "Pulumi ESC issues a fresh AccessKeyId, SecretAccessKey, and SessionToken on every esc run. Nothing persists locally." This is consistent with the broader ESC OIDC mechanism described throughout the…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L27 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "ESC-issued AWS sessions expire after the ESC environment's duration, which defaults to 1 hour." → 🤷 unverifiable (evidence: All official Pulumi ESC docs show duration: 1h as an explicitly set user value in example YAML snippets, never as a documented default. No source states that the duration field defaults to 1 hour when omitted; the aws-parameter-store p…; source: WebSearch ran query "Pulumi ESC aws-login OIDC duration default value parameter"; https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/aws-login/; intuition: The claim asserts 1h is the default for the duration field, but all docs only show it as an explicit user-set value…)
  • L28 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "CloudTrail records ESC-brokered AWS calls under the assumed-role ARN with the sessionName configured in the ESC environment." → ✅ verified (evidence: The file itself states at L38: "CloudTrail records the call under the assumed-role ARN with the sessionName you configured." The CloudTrail verification section further confirms the session name (pulumi-environments-session) appears in…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L33 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions returns a JSON array where each entry includes FunctionName, FunctionArn, Runtime, Role, Handler, CodeSize, MemorySize…" → ✅ verified (framing: strengthened — the AWS ListFunctions API returns many more fields in FunctionConfiguration; the claim correctly identifies a subset of the most common ones, wh…; evidence: The document itself states at the relevant line: "Each entry includes FunctionName, FunctionArn, Runtime, Role, Handler, CodeSize, MemorySize, Timeout, and LastModified`." The example JSON output in the same file confirms…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L33 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The output of aws lambda list-functions does not include the function code or environment variables — those require lambda:GetFunction." → ❌ contradicted (framing: shifted — claim asserts environment variables are excluded from list-functions and require GetFunction; sources show list-functions does return environment var…; evidence: (escalated from pass1) The Datadog Security Labs source explicitly states "You can use lambda:ListFunctions to analyze the environment variables of all Lambda functions in a region" and provides a command showing `aws lambda list-functions…; source: https://securitylabs.datadoghq.com/cloud-security-atlas/vulnerabilities/lambda-function-secrets-in-environment-variables/)
  • L37-41 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions paginates server-side; the AWS CLI handles pagination automatically with a default of 50 functions per page, and --max-items can…" → ✅ verified (framing: strengthened — the claim attributes the 50-per-page default to the "AWS CLI" but the source clarifies it is the Lambda service API's page size; the CLI auto-pa…; evidence: (escalated from pass1) AWS CLI docs confirm: "list-functions is a paginated operation. Multiple API calls may be issued in order to retrieve the entire data set of results." The Lambda API default page size is confirmed: "Lambda returns up…; source: https://docs.aws.amazon.com/cli/latest/reference/lambda/list-functions.html)
  • L43 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "For least privilege, attaching a policy with just lambda:ListFunctions and optionally lambda:ListLayerVersions (for layer metadata) is sufficient." → ✅ verified (evidence: The file at line ~43 states: "For least privilege, attach a policy with just lambda:ListFunctions and (optionally) lambda:ListLayerVersions if you also want layer metadata." The table above it also confirms "Min IAM permission: `lambda…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L48 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The Pulumi ESC CLI installation page is located at /docs/install/esc/." → 🤷 unverifiable (evidence: verification did not converge within 8 turns)
  • L49 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "* A Pulumi Cloud account and access to an organization" → ✅ verified (evidence: The URL https://app.pulumi.com/signup returns HTTP 200 with a valid Pulumi Cloud page titled "Pulumi Cloud" and described as "Pulumi Cloud empowers teams to automate, secure, and manage cloud infrastructure. Sign in or sign up to learn mor…; source: https://app.pulumi.com/signup)
  • L50 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "* The AWS CLI v2 installed locally" → ✅ verified (evidence: The URL https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html resolves to a live AWS page titled "Installing or updating to the latest version of the AWS CLI," which covers AWS CLI v2 installation instructions.; source: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
  • L51 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The Pulumi ESC OIDC + AWS configuration guide is located at /docs/esc/environments/configuring-oidc/aws/." → 🤷 unverifiable (evidence: verification did not converge within 8 turns)
  • L61 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Follow the browser prompt or paste an access token from https://app.pulumi.com/account/tokens." → ➖ not-a-claim (evidence: The text is a UI instruction directing users to a well-known Pulumi Console URL (app.pulumi.com/account/tokens) to obtain an access token. This is a standard navigational reference, not a falsifiable factual assertion about product behavio…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md L61)
  • L65 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The Pulumi OIDC + AWS guide instructs users to create an IAM role whose trust policy accepts a JWT from api.pulumi.com/oidc." → 🤷 unverifiable (evidence: verification did not converge within 8 turns)
  • L67 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "### 3. Create a new Pulumi ESC environment" → ➖ not-a-claim (evidence: The text "### 3. Create a new Pulumi ESC environment" is a markdown section heading (step 3 in a numbered tutorial sequence). It is not a falsifiable assertion — it is a structural label describing the PR author's own tutorial design/pipel…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L69 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "In Pulumi Cloud, open your organization, click Environments, then Create environment. Name it something like aws-prod-env." → ➖ not-a-claim (evidence: The text at L69 is a step-by-step UI navigation instruction authored by the PR author describing how to use Pulumi Cloud's own interface. The source hint https://app.pulumi.com/ is the live web application itself, not a documentation pag…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L90 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The fn::open::aws-login function exchanges the Pulumi-issued OIDC token for AWS STS credentials, and the environmentVariables block exposes them to any sub…" → ✅ verified (evidence: The file at line ~90 contains the exact text: "The fn::open::aws-login function exchanges the Pulumi-issued OIDC token for AWS STS credentials. The environmentVariables block exposes them to any subprocess esc run starts." — matching…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L90 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The environmentVariables block in the ESC YAML exposes AWS STS credentials to any subprocess esc run starts." → ✅ verified (evidence: The file at line ~90 states verbatim: "The environmentVariables block exposes them to any subprocess esc run starts." — directly confirming the claim that the environmentVariables block in the ESC YAML exposes AWS STS credentials to…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L114 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "'FunctionArn': 'arn:aws:lambda:us-west-2:123456789012:function:my-api-handler'," → ➖ not-a-claim (evidence: This is a placeholder/example ARN using the well-known AWS documentation dummy account ID "123456789012" and a generic function name "my-api-handler". It is illustrative sample output in a documentation file, not a falsifiable factual asse…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md L114 (regex match on example ARN with canonical AWS placeholder account ID 123456789012))
  • L116 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "'Role': 'arn:aws:iam::123456789012:role/my-api-handler-role'," → ➖ not-a-claim (evidence: The line contains a placeholder ARN value ("123456789012" is the canonical AWS documentation placeholder for an account ID, and "my-api-handler-role" is a generic example role name). This is a code example using illustrative/dummy values,…; source: AWS documentation convention: 123456789012 is the universally recognized placeholder account ID used in all AWS example ARNs.)
  • L121 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "'LastModified': '2025-05-09T11:02:11.000+0000'" → ➖ not-a-claim (evidence: This is a sample/example timestamp value embedded in a JSON output snippet within documentation — it is illustrative example data (a fake AWS Lambda function's LastModified field), not a factual assertion about any real-world system or pro…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md L121)
  • L133 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions --region us-west-2 " → ➖ not-a-claim (evidence: The text is a CLI command example (aws lambda list-functions --region us-west-2 \) used as an illustrative code snippet in documentation. It is not a falsifiable factual assertion about a third-party system's behavior, API surface, or sp…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md L133)
  • L139 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The AWS CLI paginates aws lambda list-functions automatically." → ✅ verified (evidence: The file itself states at the relevant section: "The AWS CLI paginates automatically. For accounts with hundreds of functions use --max-items and --starting-token for manual control." The table earlier in the same file also confirms: "…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L143 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions --region us-west-2 --max-items 50" → ✅ verified (evidence: The AWS CLI list-functions command accepts both --region and --max-items as valid parameters. The official docs confirm "list-functions [--master-region ] [--function-version ] [--max-items ]" and --region is a…; source: https://docs.aws.amazon.com/cli/latest/reference/lambda/list-functions.html)
  • L148 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions (list-functions) is per-region." → ✅ verified (evidence: The file explicitly states in the table: "Scope | Per-region; run once per region you care about" and later repeats "list-functions is per-region." This is consistent with AWS Lambda's regional architecture where functions are scoped…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L161 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "In CloudTrail, ESC-brokered ListFunctions calls appear as event ListFunctions20150331 with userIdentity.type=AssumedRole and an ARN containing assumed-r…" → 🤷 unverifiable (evidence: (escalated from pass1) AWS docs confirm Lambda CloudTrail events use date-versioned names (e.g., "GetFunction20150331v2") and that AssumedRole sessions appear as assumed-role//in ARNs. Pulumi ESC docs confirmpulumi-envi…; source: WebSearch ran query "CloudTrail Lambda ListFunctions20150331 event name AssumedRole"; https://docs.aws.amazon.com/lambda/latest/dg/logging-using-cloudtrail.html; https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/aws-secrets/; intuition: The exact event name ListFunctions20150331 (no v2 suffix) is unconfirmed — AWS docs only enumerate specific variant…)
  • L178 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "aws lambda list-functions (ListFunctions) is regional — each Lambda function lives in a single AWS region and the API only returns functions from the region…" → ✅ verified (evidence: The file itself states in the table: "Scope: Per-region; run once per region you care about" and in the loop section: "list-functions is per-region. To enumerate every region, loop:" — confirming that ListFunctions only returns funct…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L182 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Function code and environment variables require lambda:GetFunction and lambda:GetFunctionConfiguration respectively, not lambda:ListFunctions." → ❌ contradicted (framing: shifted — the source says both function code and environment variables require lambda:GetFunction; the claim asserts they require lambda:GetFunction and l…; evidence: The document at L182 states "The output does **not** include the function code or environment variables — those require lambda:GetFunction." It attributes both function code AND environment variables to lambda:GetFunction` alone, with n…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L186 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "--max-items caps the number of items returned and --starting-token resumes from a previous run for aws lambda list-functions." → ✅ verified (evidence: The file explicitly states: "For accounts with hundreds of functions use --max-items and --starting-token for manual control" and the pagination table entry reads "--max-items to limit". Both flags are described in the context of `aw…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L186 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The AWS CLI transparently follows the NextMarker pointer in each aws lambda list-functions response, so the command returns the complete set by default. -…" → ✅ verified (framing: strengthened — the claim specifically names NextMarkeras the pointer the CLI follows; the source confirmsNextMarkeris the pagination field used by the L…; evidence: The AWS Lambdalist-functionsAPI usesNextMarkeras its pagination token (confirmed in aws/aws-extensions-for-dotnet-cli source:request.Marker = response.NextMarker`). The AWS CLI v2 has built-in auto-pagination for supported comman…; source: gh search code --owner aws "NextMarker" "list-functions"; repo:aws/aws-extensions-for-dotnet-cli src/Amazon.Lambda.Tools/Commands/ListFunctionCommand.cs)
  • L194 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "ESC-issued AWS credentials are valid for 1 hour by default, set by the duration field in the ESC environment YAML, and the maximum is bounded by the IAM role…" → ✅ verified (framing: strengthened — claim says MaxSessionDuration "defaults to 1 hour for OIDC"; source says it defaults to 1 hour for all IAM roles. The OIDC case is a correct sub…; evidence: AWS docs confirm: "If you do not specify a value, the default maximum of 1 hour is applied" for MaxSessionDuration (docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html), and "By default, the value is set to 3600 sec…; source: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html; https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html; https://www.pulumi.com/docs/esc/providers/aws-login/)
  • L198 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The Pulumi GitHub Action, GitLab integration, and esc open for shell exports all work with esc run for CI/CD credential injection." → 🤷 unverifiable (evidence: verification did not converge within 8 turns)
  • L198 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Using esc run instead of static AWS_* secrets in CI/CD is described as the recommended pattern for Pulumi ESC." → ➖ not-a-claim (evidence: The file advocates using esc run with dynamic credentials over static AWS_* keys throughout (e.g., "Why dynamic credentials beat static IAM keys" section), but the phrase "recommended pattern" does not appear in the document. This is a…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L202 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The page cross-references '/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials/' as an existing page." → ✅ verified (evidence: The file content/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials.md exists in the repository and contains a full, valid page about running aws sts get-caller-identity using dynamic credentials with Pulumi ESC.; source: repo:content/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials.md)
  • L202 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Running aws sts get-caller-identity inside esc run returns an Arn of the form assumed-role/<your-role>/pulumi-environments-session when credentials com…" → ❌ contradicted (framing: shifted — source says the ARN form appears in CloudTrail event records; claim says it appears when running aws sts get-caller-identity inside esc run; evidence: The file at the relevant section states: "In CloudTrail the event appears as ListFunctions20150331 with userIdentity.type=AssumedRole and an arn containing assumed-role/<your-role>/pulumi-environments-session — confirmation the ses…; source: repo:content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)
  • L206-207 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "* Configuring OIDC between Pulumi and AWS" → ✅ verified (framing: strengthened — the canonical path is now /docs/esc/guides/configuring-oidc/aws/, but /docs/esc/environments/configuring-oidc/aws/ is a declared alias in th…; evidence: The file content/docs/esc/guides/configuring-oidc/aws.md exists and includes aliases: - /docs/esc/environments/configuring-oidc/aws/, confirming the URL used in the claim is a valid alias that resolves to the correct page. The link tex…; source: repo:content/docs/esc/guides/configuring-oidc/aws.md)
  • L208-211 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The page cross-references '/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials/' as an existing page." → 🤝 matches (evidence: The file content/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials.md exists in the repository and contains a full, valid page about running aws sts get-caller-identity with dynamic credentials, confirming the cross-refe…; source: repo:content/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials.md)
  • L208-210 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "* Run aws sts get-caller-identity with dynamic credentials" → ✅ verified (evidence: The file content/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials.md exists in the repo with the title "Run 'aws sts get-caller-identity' using Dynamic Credentials", confirming the linked page exists and matches the link…; source: repo:content/what-is/run-aws-sts-get-caller-identity-with-dynamic-credentials.md)
  • L211-212 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "The page cross-references '/what-is/resolve-list-buckets-invalid-client-token-id/' as an existing page." → ✅ verified (evidence: The file content/what-is/resolve-list-buckets-invalid-client-token-id.md exists in the repository with a matching title "An error occurred (InvalidClientTokenId) when calling the ListBuckets operation", confirming the cross-referenced pa…; source: repo:content/what-is/resolve-list-buckets-invalid-client-token-id.md)
  • L214 in content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md "Join our community on Slack to discuss further, and let us know what you build." → ✅ verified (evidence: The URL https://slack.pulumi.com/ is the canonical Pulumi community Slack invite link used consistently across Pulumi documentation. The file content confirms the surrounding context of the page, and this standard CTA link pattern ("Join o…; source: content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md)

🚨 Outstanding in this PR

These must be resolved or refuted before merging.

  • [L27] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"Sessions expire after the ESC environment's duration (1 hour by default). A leaked token is useless almost immediately." — The ESC duration field does not default to 1 hour. Per Pulumi's aws-login docs (and content/docs/esc/integrations/dynamic-login-credentials/aws-login.md in this repo): "duration … [Optional] - The duration of the role session. Defaults to 2 hours. Unless explicitly specified, AWS sets MaxDuration to 1 hour by default." The effective 1-hour cap comes from the IAM role's MaxSessionDuration, not from the ESC field's default. The same conflation appears in the FAQ at L194 ("By default 1 hour, set by the duration field in the ESC environment YAML") — fix both. Suggested rewrite:

    * **Time-bound.** Sessions are capped at the IAM role's `MaxSessionDuration` (1 hour by default for OIDC-assumed roles), or shorter if you set `duration:` in the ESC environment YAML. A leaked token is useless almost immediately.
    

    And in the FAQ:

    Sessions are bounded by the IAM role's MaxSessionDuration attribute, which defaults to 1 hour. The ESC duration: field (default: 2 hours) caps the request, but AWS will reject any value above the role's MaxSessionDuration. To run longer sessions, raise MaxSessionDuration on the role and set a matching duration: in the ESC environment.

  • [L33] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"The output does not include the function code or environment variables — those require lambda:GetFunction." — Environment variables are returned by ListFunctions. The API returns an array of FunctionConfiguration objects, which include an Environment.Variables map. Datadog Security Labs' Lambda env-var atlas entry walks through using lambda:ListFunctions for exactly this purpose. Only the deployment package (function code) requires lambda:GetFunction. Misstating this misleads readers about the security surface of granting lambda:ListFunctions. Suggested rewrite:

    `aws lambda list-functions` returns a JSON array of function metadata for a single region. Each entry includes `FunctionName`, `FunctionArn`, `Runtime`, `Role`, `Handler`, `CodeSize`, `MemorySize`, `Timeout`, `LastModified`, and (when set) `Environment.Variables`. The output does **not** include the function's deployment package — downloading code requires `lambda:GetFunction`. Note that granting `lambda:ListFunctions` therefore also exposes any plaintext secrets stored in function environment variables.
    
  • [L182] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"Function code and environment variables require lambda:GetFunction and lambda:GetFunctionConfiguration respectively — keep those off the role if you only need an inventory." — Two errors here:

    1. Environment variables are already returned by ListFunctions (see [L33] above), so they aren't gated by either GetFunction or GetFunctionConfiguration.
    2. lambda:GetFunctionConfiguration returns the same configuration data ListFunctions already returns (minus pagination); it doesn't unlock anything env-var-specific.

    Only the deployment-package URL is unique to lambda:GetFunction. Suggested rewrite:

    `lambda:ListFunctions`. That single action is enough to enumerate all functions and their basic metadata in the region, including environment variables. Downloading a function's deployment package additionally requires `lambda:GetFunction` — keep that permission off the role if you only need an inventory. (Granting `lambda:ListFunctions` still exposes plaintext env-var values, so audit what's in there before assuming "read-only" means "harmless".)
    

⚠️ Low-confidence

Review each and resolve as appropriate — these don't block the PR.

  • [L161] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"In CloudTrail the event appears as ListFunctions20150331 with userIdentity.type=AssumedRole and an arn containing assumed-role/<your-role>/pulumi-environments-session — confirmation the session came from ESC." — AWS Lambda's CloudTrail events do use date-versioned event names, and the assumed-role ARN shape is correct, but AWS doesn't publish a definitive list and the exact event name ListFunctions20150331 (vs. a possible …v2 variant) couldn't be confirmed against an AWS-published reference within the verification budget. Can the author paste a real CloudTrail event from one of these calls (or cite a source where the event name is recorded as written)? If the event name is in fact different, readers grepping CloudTrail by this string will hit nothing.

  • [L198] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"The Pulumi GitHub Action, GitLab integration, and esc open for shell exports all work the same way." — The Pulumi GitHub Action and esc open do exist; the "GitLab integration" claim is more diffuse — there's no first-party Pulumi GitLab integration page for ESC that I could find within budget. Can the author link to the canonical Pulumi docs for each of the three CI/CD paths it lists? (Without those links the FAQ answer reads like a survey but provides no follow-on for a reader who wants to actually wire one up.)

Style findings

Found by pattern-based linting; Findings may be false positives.

  • line 23: [style] difficulty qualifier — Avoid difficulty qualifier 'easily' -- it judges difficulty for the reader (STYLE-GUIDE.md §Inclusive Language).
  • line 23: [style] wordiness — 'all of' is too wordy.
  • line 43: [style] difficulty qualifier — Avoid difficulty qualifier 'just' -- it judges difficulty for the reader (STYLE-GUIDE.md §Inclusive Language).
  • line 47: [style] wordiness — 'enumerate' is too wordy.
  • line 69: [style] substitution — Use 'select' instead of 'click' (STYLE-GUIDE.md).
  • line 148: [style] wordiness — 'enumerate' is too wordy.
  • line 178: [style] directional reference — Directional reference ('see the example above') -- link directly to the target (an #anchor or relative path) rather than relying on 'above'/'below' (STYLE-GUIDE.md §Inclusive Language).
  • line 182: [style] wordiness — 'enumerate' is too wordy.
  • line 188: [style] first person — Avoid first-person pronouns such as ' I '.
  • line 194: [style] wordiness — 'maximum' is too wordy.

📋 Triaged verifier findings

I double-checked these and realized they weren't real findings — click to expand
  • [L48] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"The Pulumi ESC CLI installation page is located at /docs/install/esc/."Mis-sourced: /docs/install/esc/ is a declared alias on content/docs/esc/cli/download-install/_index.md (line ~18), so the link resolves correctly in the rendered site. The verifier ran out of turns before locating the alias.

  • [L51] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"The Pulumi ESC OIDC + AWS configuration guide is located at /docs/esc/environments/configuring-oidc/aws/."Mis-sourced: /docs/esc/environments/configuring-oidc/aws/ is a declared alias on content/docs/esc/guides/configuring-oidc/aws.md. Same alias is already flagged ✅ verified at L206-207 in the trail. The verifier ran out of turns before locating the alias.

  • [L65] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"The Pulumi OIDC + AWS guide instructs users to create an IAM role whose trust policy accepts a JWT from api.pulumi.com/oidc."Mis-sourced: content/docs/esc/guides/configuring-oidc/aws.md does instruct exactly that — the guide tells readers to use https://api.pulumi.com/oidc as the Provider URL and shows the resulting trust policy with "Federated": "arn:aws:iam::123456789012:oidc-provider/api.pulumi.com/oidc". The verifier ran out of turns before reading the guide.

  • [L202] content/what-is/run-aws-lambda-list-functions-with-dynamic-credentials.md"Run aws sts get-caller-identity inside the same esc run. The returned Arn should be assumed-role/<your-role>/pulumi-environments-session."Spurious: the verifier compared the FAQ's "what sts get-caller-identity returns" claim against the page's earlier "what CloudTrail records" claim and called the difference a contradiction, but both are correct: an AssumedRoleUser principal reports the same assumed-role/<role>/<session-name> ARN to both sts:GetCallerIdentity callers and CloudTrail. The FAQ's local-check suggestion is sound.

💡 Pre-existing issues in touched files (optional)

No pre-existing issues in touched files.

✅ Resolved since last review

No items resolved since the last review.

📜 Review history

  • 2026-05-20T16:53:40Z — Rewrite is sound but mis-states the ListFunctions IAM surface (env vars are in scope) and the ESC duration default; 3 blockers, 2 author questions, 4 verifier-noise items triaged. (f768404)

Need a re-review? Want to dispute a finding? Mention @claude and include #update-review.
(For ad-hoc questions or fixes, just @claude — no hashtag.)

@github-actions github-actions Bot added review:outstanding-issues Claude review completed; outstanding has author-actionable findings and removed review:in-progress Claude review is currently running labels May 20, 2026
@alexleventer alexleventer marked this pull request as draft May 20, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain:docs PR touches technical docs review:outstanding-issues Claude review completed; outstanding has author-actionable findings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants