Skip to content

feat(trigger): reach AWS from trigger.dev runs through workload identity - #9578

Merged
waleedlatif1 merged 6 commits into
stagingfrom
feat/trigger-workload-identity
Nov 2, 2026
Merged

waleedlatif1 merged 6 commits into
stagingfrom
feat/trigger-workload-identity

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Why

Trigger.dev runs reach Sim's own AWS resources (S3 file storage, AppConfig, the hosted-key CloudWatch metrics, hosted Bedrock) with long-lived IAM access keys stored as Trigger.dev environment variables. Trigger.dev 4.8.3 issues short-lived workload-identity (OIDC) tokens to executing runs, which AWS STS exchanges for temporary credentials. With that, no AWS key needs to live in Trigger.dev at all.

What

lib/core/config/aws.ts: getAwsCredentials() is now the single source of credentials for Sim's own AWS clients. It picks one of three sources, in this order:

  1. TRIGGER_AWS_ROLE_ARN is set (deployed Trigger.dev runs): temporary credentials for that role, from awsCredentialProvider in @trigger.dev/sdk/oidc/aws. This takes precedence over static keys, so a failed exchange shows up as an error instead of silently falling back to a stored key, as Trigger.dev's docs require.
  2. Static keys: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, unchanged for self-hosted deployments.
  3. Neither: undefined, so the default chain applies (the ECS task role).

Wiring

  • The S3, AppConfig, hosted-key CloudWatch and hosted-Bedrock clients pass this explicitly. CloudWatch and the Bedrock path used to rely on the default chain finding env keys.
  • A user's own Bedrock keys still take precedence, and no user integration ever receives these credentials.

Credential lifetime. Sim's AWS clients live for the whole process, while a token can only be minted while an attempt is executing. So:

  • One session per worker process. It is fixed-name, sim-trigger-worker, rather than run-named, so later runs' calls aren't attributed to the run that minted it.
  • Refreshed in trigger.config.ts init at the start of each attempt, whenever less than 30 minutes remain. Work a run leaves behind, such as the 5-second metrics flush, still has valid credentials after the attempt ends.
  • Refreshed 10 minutes before expiry otherwise. That's longer than the AWS SDK's own 5-minute window, so a client never spins on credentials this module still considers fresh. Concurrent callers share one exchange.

Hosted-key metrics now turn on based on isHosted rather than on whether AWS_ACCESS_KEY_ID is present. Hosted keys only exist on Sim Cloud, and removing static keys must not turn the metrics off.

Trigger.dev 4.8.3

  • SDK, core, build and both workflows' CLI pins move from 4.8.2 to 4.8.3. Release notes: workload identity, plus one chat resume-cursor fix.
  • 4.8.3 was published 2026-10-30. It sits in minimumReleaseAgeExcludes until it clears the 7-day window on 2026-11-06; the comment says to drop it then.

Rollout

Nothing changes until TRIGGER_AWS_ROLE_ARN is set in a Trigger.dev environment. Without it, runs keep today's static keys.

For each environment:

  1. Set the variable.
  2. Confirm the role is being assumed and the static key's last-used time stops moving.
  3. Remove the static keys from that Trigger.dev environment.

ECS is unaffected: it never sets the variable.

Verification

Type-check passes across all 29 workspaces. The real proof is end to end, on staging after merge:

  • STS AssumeRoleWithWebIdentity events from staging runs appear in CloudTrail.
  • S3, AppConfig and metrics calls succeed under the role session.
  • The static key's last-used time stops advancing.

Trigger.dev runs reached S3, AppConfig, CloudWatch and hosted Bedrock with
the app IAM user's static keys. With TRIGGER_AWS_ROLE_ARN set, Sim's own AWS
clients now use temporary credentials for that role, exchanged for the run's
Trigger.dev workload-identity token (SDK 4.8.3). One session serves the
worker process, refreshed at each attempt's start so the post-run metrics
flush keeps valid credentials. Static keys and the default chain are
unchanged for ECS and self-hosted deployments.
4.8.3 is the first release with workload identity. The exclusion is
temporary and comes out once it clears the 7-day threshold on 2026-11-06.
Hosted-key metrics now key off Sim Cloud itself instead of the presence of
static AWS keys, so removing those keys never silences them.
@waleedlatif1
waleedlatif1 requested a review from a team as a code owner November 2, 2026 20:22
@vercel

vercel Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Nov 2, 2026 9:23pm UTC

Request Review

@greptile-apps

greptile-apps Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[High impact] The PR appears safe to merge; no actionable issues remain in the reviewed changes.

Summary

Adds workload identity for Sim-owned AWS clients in Trigger.dev runs.

  • Trigger.dev runs can use temporary AWS role credentials for Sim’s services.
  • Hosted-key metrics follow the hosted deployment setting.

Both earlier review threads are addressed: the default lookup preserves session tokens, and SES now receives workload credentials. No new actionable issues were found.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Sim-owned AWS client] --> B{Workload role configured?}
  B -->|No| C[AWS default credential lookup]
  B -->|Yes| D{Cached credentials fresh enough?}
  D -->|Yes| E[Use cached credentials]
  D -->|No| F[Exchange workload token]
  F -->|Success| G[Save temporary credentials]
  F -->|Failure| H{More than 60 seconds remain?}
  H -->|Yes| E
  H -->|No| I[Return error]
Loading

Reviews (3) · Last reviewed commit: "fix(aws): serve unexpired workload crede..." · Reviewed by Greptile

Comment thread apps/sim/providers/bedrock/index.ts Resolved
Comment thread apps/sim/lib/core/config/aws.ts Resolved

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 13 files

Turn on auto-fix | Re-trigger cubic

Comment thread bunfig.toml Resolved
Comment thread apps/sim/lib/core/config/aws.ts Resolved
Comment thread apps/sim/lib/core/config/aws.ts Resolved
The init hook loads app modules by relative path, which the source-convention
ratchet caps. Warming Redis and refreshing workload-identity credentials now
sit behind prepareTriggerAttempt, so init still imports one module.
getAwsCredentials returned explicit static keys when present, which dropped
AWS_SESSION_TOKEN for clients that used to reach it through the default chain
(Bedrock, CloudWatch). It now returns the workload-identity provider or
undefined, so every non-Trigger path resolves exactly as before. The SES email
client reads it too, so worker email keeps working once static keys leave
Trigger.dev. The release-age comment records why the exclusions are bare names.
…ads them

The S3 client resolves credentials through the SDK default chain, which reads
process.env, so the presigner test stubs the keys there instead of the env
module mock.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 16 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/lib/core/config/aws.ts Resolved
Outside an executing attempt no workload-identity token can be minted, so a
post-run metrics flush near the refresh window failed even though the cached
credentials were still valid. A failed exchange now keeps serving the cached
credentials until a minute before they expire.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 16 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1
waleedlatif1 merged commit 478d9ec into staging Nov 2, 2026
89 checks passed
@waleedlatif1
waleedlatif1 deleted the feat/trigger-workload-identity branch November 2, 2026 23:25

This branch was previously deployed

1 inactive deployment
Preview — 1e97ce1e Deployed Nov 2, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant