Uh oh!
There was an error while loading. Please reload this page.
feat: support standard AWS env vars and default credential chain - #401
Conversation
Replace non-standard AWS_ACCESS_KEY / AWS_SECRET_KEY with the AWS-standard AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY. The old names are kept as fallbacks in the runtimeEnv for backward compatibility. Both vars are now optional. When omitted, the credentials object is not passed to SESv2Client, STSClient, or SNSClient — the AWS SDK then falls back to its default provider chain (IAM roles, ECS task roles, instance profiles, etc.), which is the recommended approach for cloud-native deployments. Closes#316 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…al-config guard - Move the credential spread logic into a single credentials.ts helper so SESv2Client, STSClient, and SNSClient all share one implementation - Throw a clear error if only one of AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY is set, preventing silent fallback to the default provider chain with a half-configured environment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughThis PR standardizes AWS credential environment variable names from 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying usesend with |
| Latest commit: | b2147df |
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6f7e6eeb.usesend.pages.dev |
| Branch Preview URL: | https://fix-aws-env-vars-on-pr-395.usesend.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
apps/docs/get-started/set-up-docker.mdx (1)
55-57: ⚡ Quick winDocument AWS static credentials as optional in standalone Docker flow.
Line 55–57 and Line 63 currently imply static AWS keys are always needed. Since credentials are now optional, please note that users can omit these vars when their runtime provides IAM-role/default credential chain access.
Proposed doc patch
docker run -d \ -p 3000:3000 \ -e NEXTAUTH_URL="<your-nextauth-url>" \ -e NEXTAUTH_SECRET="<your-nextauth-secret>" \ -e DATABASE_URL="<your-next-private-database-url>" \ -e REDIS_URL="<your-next-private-redis-url>" \ - -e AWS_ACCESS_KEY_ID="<your-next-private-aws-access-key-id>" \- -e AWS_SECRET_ACCESS_KEY="<your-next-private-aws-secret-access-key>" \ -e AWS_DEFAULT_REGION="<your-next-private-aws-region>" \ -e GITHUB_ID="<your-next-private-github-id>" \ -e GITHUB_SECRET="<your-next-private-github-secret>" \ usesend/usesend-Replace the placeholders with your actual database and AWS details.
+Replace the placeholders with your actual database details.
+If your environment does not provide AWS credentials via IAM/default provider chain, also set:
+AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY.</details> Also applies to: 63-63 <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@apps/docs/get-started/set-up-docker.mdxaround lines 55 - 57, Update the
Docker setup instructions so the AWS static credential environment variables
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION) are documented as
optional: change the text that currently tells users to "Replace the
placeholders with your actual database and AWS details." to "Replace the
placeholders with your actual database details. If your environment does not
provide AWS credentials via IAM/default provider chain, also set:
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY." Ensure this change is applied to
the same explanatory lines that contain the three environment variable
placeholders and the similar line around the later occurrence (the one
referenced at line 63).</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Inline comments:
In@apps/web/src/env.js:
- Around line 102-103: The current fallback uses independent || for
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY which can mix standard and legacy
values; update the logic so the code selects either the standard pair
(AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY) or, only if both are absent, the
legacy pair (AWS_ACCESS_KEY + AWS_SECRET) as a unit. In practice change the
assignment for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to a small
conditional that prefers the standard env vars together, otherwise uses the
legacy pair only when both legacy vars exist, and yields undefined/null if
neither full pair is present; reference the AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY symbols when locating where to implement this.In
@apps/web/src/server/aws/ses.ts:
- Line 20: Replace the relative import of getAwsCredentialOptions from
"./credentials" with the repo-standard src alias import (e.g. import {
getAwsCredentialOptions } from "~/server/aws/credentials";) so the module uses
the~/alias form consistent with apps/web src imports.In
@apps/web/src/server/aws/sns.ts:
- Line 8: Replace the relative import for getAwsCredentialOptions with the
project src alias; change the import source from "./credentials" to the aliased
module (e.g. "/server/aws/credentials") so the import reads: import {/server/aws/credentials"; this aligns the
getAwsCredentialOptions } from "
getAwsCredentialOptions import with the apps/web src alias convention.Nitpick comments:
In@apps/docs/get-started/set-up-docker.mdx:
- Around line 55-57: Update the Docker setup instructions so the AWS static
credential environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
AWS_DEFAULT_REGION) are documented as optional: change the text that currently
tells users to "Replace the placeholders with your actual database and AWS
details." to "Replace the placeholders with your actual database details. If
your environment does not provide AWS credentials via IAM/default provider
chain, also set: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY." Ensure this
change is applied to the same explanatory lines that contain the three
environment variable placeholders and the similar line around the later
occurrence (the one referenced at line 63).</details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: Organization UI **Review profile**: CHILL **Plan**: Pro **Run ID**: `b582a91e-d79f-48e3-bf7b-c0e17c7b23fc` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 31a49fbdca243a4674ec07946f69e8479c86f1f9 and 1c6317daccebc1e2b2afe54cec38e735ac58d913. </details> <details> <summary>📒 Files selected for processing (18)</summary> * `.env.example` * `.env.selfhost.example` * `.github/workflows/test-web.yml` * `CONTRIBUTION.md` * `apps/docs/get-started/create-aws-credentials.mdx` * `apps/docs/get-started/local.mdx` * `apps/docs/get-started/set-up-docker.mdx` * `apps/docs/self-hosting/overview.mdx` * `apps/docs/self-hosting/railway.mdx` * `apps/web/.env.test.example` * `apps/web/src/env.js` * `apps/web/src/server/aws/credentials.ts` * `apps/web/src/server/aws/ses.ts` * `apps/web/src/server/aws/sns.ts` * `apps/web/src/test/setup/setup-env.ts` * `docker/README.md` * `docker/prod/compose.yml` * `turbo.json` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID || process.env.AWS_ACCESS_KEY, | ||
| AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY || process.env.AWS_SECRET_KEY, |
There was a problem hiding this comment.
Avoid mixing standard and legacy credential sources across fields.
Line 102 and Line 103 independently fall back with ||, which can combine AWS_ACCESS_KEY_ID with legacy AWS_SECRET_KEY (or vice versa). That can create an invalid pair and undercut partial-config safeguards.
Suggested fix
- AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID || process.env.AWS_ACCESS_KEY,- AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY || process.env.AWS_SECRET_KEY,+ AWS_ACCESS_KEY_ID:+ process.env.AWS_ACCESS_KEY_ID ?? process.env.AWS_ACCESS_KEY,+ AWS_SECRET_ACCESS_KEY:+ process.env.AWS_ACCESS_KEY_ID != null ||+ process.env.AWS_SECRET_ACCESS_KEY != null+ ? process.env.AWS_SECRET_ACCESS_KEY+ : process.env.AWS_SECRET_KEY,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID||process.env.AWS_ACCESS_KEY, | |
| AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY||process.env.AWS_SECRET_KEY, | |
| AWS_ACCESS_KEY_ID: | |
| process.env.AWS_ACCESS_KEY_ID??process.env.AWS_ACCESS_KEY, | |
| AWS_SECRET_ACCESS_KEY: | |
| process.env.AWS_ACCESS_KEY_ID!=null|| | |
| process.env.AWS_SECRET_ACCESS_KEY!=null | |
| ? process.env.AWS_SECRET_ACCESS_KEY | |
| : process.env.AWS_SECRET_KEY, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/env.js` around lines 102 - 103, The current fallback uses
independent || for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY which can mix
standard and legacy values; update the logic so the code selects either the
standard pair (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY) or, only if both are
absent, the legacy pair (AWS_ACCESS_KEY + AWS_SECRET) as a unit. In practice
change the assignment for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to a small
conditional that prefers the standard env vars together, otherwise uses the
legacy pair only when both legacy vars exist, and yields undefined/null if
neither full pair is present; reference the AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY symbols when locating where to implement this.
There was a problem hiding this comment.
nah thats fine, we should give responsibilty to users
There was a problem hiding this comment.
@KMKoushik, understood — the independent fallback is intentional, and the partial-config guard in getAwsCredentialOptions in credentials.ts will still catch the case where only one standard key is set at runtime. Acknowledged!
(ᵔ ᵕ ᵔ) 🐇
✏️ Learnings added
Learnt from: KMKoushik
Repo: usesend/useSend PR: 401
File: apps/web/src/env.js:102-103
Timestamp: 2026-05-17T11:17:08.286Z
Learning: In `apps/web/src/env.js` (usesend/useSend), the independent `||` fallback for `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` (falling back to legacy `AWS_ACCESS_KEY`/`AWS_SECRET_KEY` respectively) is intentional. The project maintainer explicitly chose to give users responsibility for providing consistent credential pairs rather than enforcing paired fallback logic at the env layer. The partial-config guard is handled at runtime in `apps/web/src/server/aws/credentials.ts` via `getAwsCredentialOptions()`.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
Summary
Based on #395 by @purva-8, with maintainer fixes on top.
Closes#316
Verification
Merge note
If squash-merging and you want co-author credit preserved on the squash commit, include:
Co-authored-by: Purva Kandalgaonkar 136103488+purva-8@users.noreply.github.com
Summary by cubic
Switches to the standard AWS env vars
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYand enables the AWS SDK default credential chain when both are unset. Updates code, Docker, CI, docs, and Turbo config; legacy envs still work as fallbacks.New Features
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY;AWS_ACCESS_KEY/AWS_SECRET_KEYremain as runtime fallbacks.getAwsCredentialOptionswith a guard that errors on partial config.Migration
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY, or rely on IAM/instance roles by leaving both unset..env, CI, Docker, and Turbo env lists to the new names; examples and docs are aligned.Written for commit b2147df. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
New Features
Documentation
Chores