File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ import {
1818 BedrockRuntimeClient ,
1919 InvokeModelCommand ,
2020} from "@aws-sdk/client-bedrock-runtime" ;
21+ import { getAppCredentials } from "../../../lib/aws/credentials" ;
2122
2223/* ------------------------------------------------------------------ */
2324/* Types */
@@ -58,7 +59,8 @@ interface ConversationResponse {
5859const BEDROCK_REGION = process . env . BEDROCK_REGION || "us-east-1" ;
5960
6061function getBedrockClient ( ) : BedrockRuntimeClient {
61- return new BedrockRuntimeClient ( { region : BEDROCK_REGION } ) ;
62+ const credentials = getAppCredentials ( ) ;
63+ return new BedrockRuntimeClient ( { region : BEDROCK_REGION , ...( credentials && { credentials } ) } ) ;
6264}
6365
6466/* ------------------------------------------------------------------ */
Original file line number Diff line number Diff line change @@ -17,6 +17,7 @@ import {
1717 BedrockRuntimeClient ,
1818 InvokeModelCommand ,
1919} from "@aws-sdk/client-bedrock-runtime" ;
20+ import { getAppCredentials } from "../../../lib/aws/credentials" ;
2021
2122/* ------------------------------------------------------------------ */
2223/* Types */
@@ -42,7 +43,8 @@ interface GeneratedItem {
4243const BEDROCK_REGION = process . env . BEDROCK_REGION || "us-east-1" ;
4344
4445function getBedrockClient ( ) : BedrockRuntimeClient {
45- return new BedrockRuntimeClient ( { region : BEDROCK_REGION } ) ;
46+ const credentials = getAppCredentials ( ) ;
47+ return new BedrockRuntimeClient ( { region : BEDROCK_REGION , ...( credentials && { credentials } ) } ) ;
4648}
4749
4850/* ------------------------------------------------------------------ */
Original file line number Diff line number Diff line change @@ -26,6 +26,7 @@ import {
2626 InvokeModelCommand ,
2727} from "@aws-sdk/client-bedrock-runtime" ;
2828import type { BiomarkerAggregate } from "../../../types/biomarker" ;
29+ import { getAppCredentials } from "../../../lib/aws/credentials" ;
2930
3031interface ClinicalRequestBody {
3132 sessionId : string ;
@@ -45,10 +46,9 @@ interface ClinicalResponse {
4546
4647const BEDROCK_REGION = process . env . BEDROCK_REGION || "us-east-1" ;
4748
48- // Don't pass explicit credentials — the SDK default credential provider chain
49- // handles Lambda IAM roles (with session tokens) and local dev env vars.
5049function getBedrockClient ( ) : BedrockRuntimeClient {
51- return new BedrockRuntimeClient ( { region : BEDROCK_REGION } ) ;
50+ const credentials = getAppCredentials ( ) ;
51+ return new BedrockRuntimeClient ( { region : BEDROCK_REGION , ...( credentials && { credentials } ) } ) ;
5252}
5353
5454function buildMockReport (
Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ import {
1818 InvokeModelCommand ,
1919} from "@aws-sdk/client-bedrock-runtime" ;
2020import type { BiomarkerAggregate } from "../../../types/biomarker" ;
21+ import { getAppCredentials } from "../../../lib/aws/credentials" ;
2122
2223interface SummaryRequestBody {
2324 sessionId : string ;
@@ -26,10 +27,9 @@ interface SummaryRequestBody {
2627
2728const BEDROCK_REGION = process . env . BEDROCK_REGION || "us-east-1" ;
2829
29- // Don't pass explicit credentials — the SDK default credential provider chain
30- // handles Lambda IAM roles (with session tokens) and local dev env vars.
3130function getBedrockClient ( ) : BedrockRuntimeClient {
32- return new BedrockRuntimeClient ( { region : BEDROCK_REGION } ) ;
31+ const credentials = getAppCredentials ( ) ;
32+ return new BedrockRuntimeClient ( { region : BEDROCK_REGION , ...( credentials && { credentials } ) } ) ;
3333}
3434
3535function buildMockSummary ( biomarkers : BiomarkerAggregate ) : string {
Original file line number Diff line number Diff line change @@ -19,11 +19,12 @@ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
1919import { DynamoDBDocumentClient , PutCommand } from "@aws-sdk/lib-dynamodb" ;
2020import type { SessionSyncPayload } from "../../types/session" ;
2121import type { BiomarkerAggregate } from "../../types/biomarker" ;
22+ import { getAppCredentials , getAppRegion } from "../../lib/aws/credentials" ;
2223
23- // Don't pass explicit credentials — let the SDK use its default credential
24- // provider chain (Lambda IAM role on Amplify, env vars or ~/.aws on local dev).
24+ const appCredentials = getAppCredentials ( ) ;
2525const dynamoClient = new DynamoDBClient ( {
26- region : process . env . AWS_REGION ?? "ap-south-1" ,
26+ region : getAppRegion ( "ap-south-1" ) ,
27+ ...( appCredentials && { credentials : appCredentials } ) ,
2728} ) ;
2829const docClient = DynamoDBDocumentClient . from ( dynamoClient ) ;
2930
Original file line number Diff line number Diff line change @@ -18,19 +18,18 @@ import {
1818 SynthesizeSpeechCommand ,
1919 type VoiceId ,
2020} from "@aws-sdk/client-polly" ;
21+ import { getAppCredentials , getAppRegion } from "../../lib/aws/credentials" ;
2122
2223interface TtsRequestBody {
2324 text : string ;
2425 voiceId ?: string ;
2526}
2627
27- // Use POLLY_REGION if set, otherwise fall back to AWS_REGION (auto-set on Lambda)
28- const POLLY_REGION = process . env . POLLY_REGION || process . env . AWS_REGION || "ap-south-1" ;
28+ const POLLY_REGION = process . env . POLLY_REGION || getAppRegion ( "ap-south-1" ) ;
2929
30- // Don't pass explicit credentials — the SDK default credential provider chain
31- // handles Lambda IAM roles (with session tokens) and local dev env vars.
3230function getPollyClient ( ) : PollyClient {
33- return new PollyClient ( { region : POLLY_REGION } ) ;
31+ const credentials = getAppCredentials ( ) ;
32+ return new PollyClient ( { region : POLLY_REGION , ...( credentials && { credentials } ) } ) ;
3433}
3534
3635export async function POST ( req : NextRequest ) {
Original file line number Diff line number Diff line change 1010 */
1111
1212import { AUTH_CONFIG } from "./config" ;
13+ import { getAppCredentials , getAppRegion } from "../aws/credentials" ;
1314
1415// ─── Types ───────────────────────────────────────────────────────────
1516export interface AuthUser {
@@ -41,11 +42,12 @@ function shouldUseDynamo(): boolean {
4142 if (
4243 process . env . NODE_ENV === "development" &&
4344 ! process . env . AWS_ACCESS_KEY_ID &&
45+ ! process . env . APP_ACCESS_KEY_ID &&
4446 ! process . env . AWS_REGION
4547 ) {
4648 return false ;
4749 }
48- // In production (Amplify), always try DynamoDB — IAM role provides creds
50+ // In production (Amplify), always try DynamoDB
4951 return true ;
5052}
5153
@@ -123,8 +125,10 @@ async function getDynamoClient() {
123125 const { DynamoDBClient } = await import ( "@aws-sdk/client-dynamodb" ) ;
124126 const { DynamoDBDocumentClient } = await import ( "@aws-sdk/lib-dynamodb" ) ;
125127
128+ const credentials = getAppCredentials ( ) ;
126129 const client = new DynamoDBClient ( {
127- region : process . env . AWS_REGION || "ap-south-1" ,
130+ region : getAppRegion ( "ap-south-1" ) ,
131+ ...( credentials && { credentials } ) ,
128132 } ) ;
129133 return DynamoDBDocumentClient . from ( client ) ;
130134}
Original file line number Diff line number Diff line change 1+ /**
2+ * Shared AWS credential provider for Amplify deployments.
3+ *
4+ * Amplify reserves the "AWS_*" env var prefix, so we use custom-named
5+ * variables: APP_ACCESS_KEY_ID, APP_SECRET_ACCESS_KEY, APP_REGION.
6+ * The SDK default credential chain is tried first (covers Lambda IAM
7+ * roles and local dev with AWS_* env vars). If that fails, the custom
8+ * env vars are used as an explicit fallback.
9+ */
10+
11+ import type { AwsCredentialIdentity } from "@aws-sdk/types" ;
12+
13+ /**
14+ * Returns explicit credentials from APP_* env vars if set,
15+ * or undefined to let the SDK use its default provider chain.
16+ */
17+ export function getAppCredentials ( ) : AwsCredentialIdentity | undefined {
18+ const accessKeyId = process . env . APP_ACCESS_KEY_ID ;
19+ const secretAccessKey = process . env . APP_SECRET_ACCESS_KEY ;
20+
21+ if ( accessKeyId && secretAccessKey ) {
22+ return { accessKeyId, secretAccessKey } ;
23+ }
24+
25+ return undefined ;
26+ }
27+
28+ /**
29+ * Returns the AWS region from APP_REGION, AWS_REGION, or the given default.
30+ */
31+ export function getAppRegion ( fallback = "ap-south-1" ) : string {
32+ return process . env . APP_REGION || process . env . AWS_REGION || fallback ;
33+ }
Original file line number Diff line number Diff line change @@ -34,6 +34,10 @@ const nextConfig: NextConfig = {
3434 DYNAMODB_CHILD_PROFILES_TABLE : process . env . DYNAMODB_CHILD_PROFILES_TABLE ?? "" ,
3535 DYNAMODB_SESSION_SUMMARIES_TABLE : process . env . DYNAMODB_SESSION_SUMMARIES_TABLE ?? "" ,
3636 DYNAMODB_FEED_POSTS_TABLE : process . env . DYNAMODB_FEED_POSTS_TABLE ?? "" ,
37+ // Amplify blocks AWS_* prefix — use custom names for SDK credentials
38+ APP_ACCESS_KEY_ID : process . env . APP_ACCESS_KEY_ID ?? "" ,
39+ APP_SECRET_ACCESS_KEY : process . env . APP_SECRET_ACCESS_KEY ?? "" ,
40+ APP_REGION : process . env . APP_REGION ?? "" ,
3741 } ,
3842
3943 // Required for SharedArrayBuffer (ONNX WASM multi-threading)
You can’t perform that action at this time.
0 commit comments