Node.js / AWS SDK v3

Secure Your AWS API Key in Node.js

AWS long-term access keys committed to git or leaked in CI logs give attackers full access to your cloud infrastructure. A single AKIA key can spin up EC2 instances and rack up thousands in charges within hours. IAM roles remove long-term keys entirely.

The Problem

This is what most Node.js codebases look like today. The AWS_SECRET_ACCESS_KEY key (AKIA...) lives directly in the process environment. If your repo, your CI logs, or your deployment config leaks — so does your key.

JavaScript
// storage.js — raw AWS credentials in environment
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  region: "us-east-1",
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,         // AKIAIOSFODNN7EXAMPLE
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, // wJalrXUtnFEMI/K7...
  },
});

export async function uploadFile(key, body) {
  await s3.send(new PutObjectCommand({
    Bucket: "my-app-uploads",
    Key: key,
    Body: body,
  }));
}

The Fix

AWS doesn't use a single bearer key: every request is signed with Signature Version 4 using your secret key. The KeyVault Edge proxy injects a key into a header and does not sign AWS requests, so it can't front AWS today. The right fix for AWS is to stop using long-term keys at all: give your workload an IAM role and let the SDK fetch short-lived credentials.

JavaScript
// storage.js — no long-term keys: the SDK uses the IAM role's short-lived credentials
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

// No credentials here. On EC2/ECS/Lambda/EKS the SDK picks up the role
// attached to the workload; in CI, use GitHub OIDC to assume a role.
const s3 = new S3Client({ region: "us-east-1" });

export async function uploadFile(key, body) {
  await s3.send(new PutObjectCommand({ Bucket: "my-app-uploads", Key: key, Body: body }));
}

Setup in 4 steps

1

Create an IAM role with least privilege

Create a role that allows only what the app needs, e.g. s3:PutObject on arn:aws:s3:::my-app-uploads/*. Attach it to the EC2 instance profile, ECS task role, Lambda execution role or EKS service account.

2

Delete the long-term keys

Remove AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from .env files, CI secrets and deployment config, then deactivate and delete the access key in IAM.

3

Use OIDC in CI instead of stored keys

For GitHub Actions, configure the aws-actions/configure-aws-credentials action with role-to-assume and an OIDC trust policy, so workflows get credentials that expire after the job.

4

Use KeyVault Edge for your bearer-key APIs

KeyVault Edge doesn't support AWS SigV4 signing yet. It does cover providers that authenticate with a single API key header, such as OpenAI, Anthropic, Stripe, SendGrid and Google AI.

Start protecting your keys

Your AWS key is one leaked .env file away from being exploited. With KeyVault Edge the real key stays at the edge, and the token that replaces it is capped, scoped and revocable in one click.