diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index fe7b24783..d6236e4ed 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -94,7 +94,9 @@ export const identityAwsAuthServiceFactory = ({ const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); const body: string = Buffer.from(iamRequestBody, "base64").toString(); - const region = headers.Authorization ? awsRegionFromHeader(headers.Authorization) : null; + + const authHeader = headers.Authorization || headers.authorization; + const region = authHeader ? awsRegionFromHeader(authHeader) : null; if (!isValidAwsRegion(region)) { throw new BadRequestError({ message: "Invalid AWS region" }); diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-types.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-types.ts index 785b37bbc..9844c8a63 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-types.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-types.ts @@ -40,7 +40,8 @@ export type TAwsGetCallerIdentityHeaders = { "X-Amz-Date": string; "Content-Length": number; "x-amz-security-token": string; - Authorization: string; + Authorization?: string; + authorization?: string; }; export type TGetCallerIdentityResponse = { diff --git a/docs/documentation/platform/identities/aws-auth.mdx b/docs/documentation/platform/identities/aws-auth.mdx index f27d5c7bf..ab2b5cd3a 100644 --- a/docs/documentation/platform/identities/aws-auth.mdx +++ b/docs/documentation/platform/identities/aws-auth.mdx @@ -173,11 +173,10 @@ access the Infisical API using the AWS Auth authentication method. console.error(err); } }; - ```` + ``` + - + The following query construction is an example of how you can authenticate with Infisical from inside a EC2 instance. The shown example uses Node.js but you can use other language you wish. @@ -243,11 +242,9 @@ access the Infisical API using the AWS Auth authentication method. } main(); - ```` + ``` - + The following query construction provides a generic example of how you can construct a signed `GetCallerIdentity` query and obtain the required payload components. The shown example uses Node.js but you can use any language you wish. @@ -274,7 +271,7 @@ access the Infisical API using the AWS Auth authentication method. const signer = new AWS.Signers.V4(request, "sts"); signer.addAuthorization(AWS.config.credentials, new Date()); - ```` + ``` #### Sample request @@ -304,6 +301,96 @@ access the Infisical API using the AWS Auth authentication method. Next, you can use the access token to access the [Infisical API](/api-reference/overview/introduction) + + + The following query construction is an example of how you can authenticate with Infisical from inside an EKS pod. + + The shown example uses Node.js Typescript but you can use any language you wish. + + ```javascript + import axios from "axios"; + import { Sha256 } from "@aws-crypto/sha256-js"; + import { fromNodeProviderChain } from "@aws-sdk/credential-providers"; + import { HttpRequest } from "@aws-sdk/protocol-http"; + import { SignatureV4 } from "@aws-sdk/signature-v4"; + + const main = async () => { + try { + const tokenRes = await axios.put("http://169.254.169.254/latest/api/token", undefined, { + headers: { + "X-aws-ec2-metadata-token-ttl-seconds": "21600" + } + }); + + const { + data: { region } + } = await axios.get<{ region: string }>("http://169.254.169.254/latest/dynamic/instance-identity/document", { + headers: { + "X-aws-ec2-metadata-token": tokenRes.data, + Accept: "application/json" + } + }); + + const credentials = await fromNodeProviderChain()(); + + if (!credentials.accessKeyId || !credentials.secretAccessKey) { + throw new Error("Credentials not found"); + } + + const iamRequestURL = `https://sts.${region}.amazonaws.com/`; + const iamRequestBody = "Action=GetCallerIdentity&Version=2011-06-15"; + const iamRequestHeaders = { + "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", + Host: `sts.${region}.amazonaws.com` + }; + + const request = new HttpRequest({ + protocol: "https:", + hostname: `sts.${region}.amazonaws.com`, + path: "/", + method: "POST", + headers: { + ...iamRequestHeaders, + "Content-Length": String(Buffer.byteLength(iamRequestBody)) + }, + body: iamRequestBody + }); + + const signer = new SignatureV4({ + credentials, + region, + service: "sts", + sha256: Sha256 + }); + + const signedRequest = await signer.sign(request); + + const headers: Record = {}; + Object.entries(signedRequest.headers).forEach(([key, value]) => { + if (typeof value === "string") headers[key] = value; + }); + + const iamRequest = { + iamHttpRequestMethod: "POST", + iamRequestUrl: iamRequestURL, + iamRequestBody: iamRequestBody, + iamRequestHeaders: headers + }; + + const { + data: { accessToken } + } = await axios.post<{ accessToken: string }>("https://app.infisical.com/api/v1/auth/aws-auth/login", { + ...iamRequest, + identityId: "" + }); + + console.log(`Infisical Access Token: ${accessToken}`); + } catch (e) { + console.error("Failed to do AWS auth", e); + } + }; + ``` +