aws.ts
1 import { logForDebugging } from './debug.js' 2 3 /** AWS short-term credentials format. */ 4 export type AwsCredentials = { 5 AccessKeyId: string 6 SecretAccessKey: string 7 SessionToken: string 8 Expiration?: string 9 } 10 11 /** Output from `aws sts get-session-token` or `aws sts assume-role`. */ 12 export type AwsStsOutput = { 13 Credentials: AwsCredentials 14 } 15 16 type AwsError = { 17 name: string 18 } 19 20 export function isAwsCredentialsProviderError(err: unknown) { 21 return (err as AwsError | undefined)?.name === 'CredentialsProviderError' 22 } 23 24 /** Typeguard to validate AWS STS assume-role output */ 25 export function isValidAwsStsOutput(obj: unknown): obj is AwsStsOutput { 26 if (!obj || typeof obj !== 'object') { 27 return false 28 } 29 30 const output = obj as Record<string, unknown> 31 32 // Check if Credentials exists and has required fields 33 if (!output.Credentials || typeof output.Credentials !== 'object') { 34 return false 35 } 36 37 const credentials = output.Credentials as Record<string, unknown> 38 39 return ( 40 typeof credentials.AccessKeyId === 'string' && 41 typeof credentials.SecretAccessKey === 'string' && 42 typeof credentials.SessionToken === 'string' && 43 credentials.AccessKeyId.length > 0 && 44 credentials.SecretAccessKey.length > 0 && 45 credentials.SessionToken.length > 0 46 ) 47 } 48 49 /** Throws if STS caller identity cannot be retrieved. */ 50 export async function checkStsCallerIdentity(): Promise<void> { 51 const { STSClient, GetCallerIdentityCommand } = await import( 52 '@aws-sdk/client-sts' 53 ) 54 await new STSClient().send(new GetCallerIdentityCommand({})) 55 } 56 57 /** 58 * Clear AWS credential provider cache by forcing a refresh 59 * This ensures that any changes to ~/.aws/credentials are picked up immediately 60 */ 61 export async function clearAwsIniCache(): Promise<void> { 62 try { 63 logForDebugging('Clearing AWS credential provider cache') 64 const { fromIni } = await import('@aws-sdk/credential-providers') 65 const iniProvider = fromIni({ ignoreCache: true }) 66 await iniProvider() // This updates the global file cache 67 logForDebugging('AWS credential provider cache refreshed') 68 } catch (_error) { 69 // Ignore errors - we're just clearing the cache 70 logForDebugging( 71 'Failed to clear AWS credential cache (this is expected if no credentials are configured)', 72 ) 73 } 74 }