{"id":17501,"library":"aws4-express","title":"AWS Signature V4 Express Middleware","description":"aws4-express is an Express middleware library designed for validating AWS Signature Version 4 (SigV4) authenticated requests. It enables Express applications to act as SigV4-secured endpoints, mimicking AWS service behavior without requiring an actual AWS backend for authentication. The current stable version is 0.14.1, and the project demonstrates an active release cadence, frequently updating to support newer Node.js versions (currently >=20) and incorporating security enhancements. Its primary function is to abstract the complexities of SigV4 verification, providing an `awsVerify` middleware that integrates with Express's request lifecycle, notably requiring careful handling of the raw request body for accurate signature calculation. It is actively maintained with regular updates and security audits.","status":"active","version":"0.14.1","language":"javascript","source_language":"en","source_url":"https://github.com/jerzyadamowski/aws4-express","tags":["javascript","aws4-express","express","middleware","handler","AWS","signature","verify","awsv4","typescript"],"install":[{"cmd":"npm install aws4-express","lang":"bash","label":"npm"},{"cmd":"yarn add aws4-express","lang":"bash","label":"yarn"},{"cmd":"pnpm add aws4-express","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This library provides middleware specifically for the Express.js framework.","package":"express","optional":false}],"imports":[{"note":"Primary middleware function. The package ships TypeScript types and is designed for modern ESM usage.","wrong":"const awsVerify = require('aws4-express').awsVerify;","symbol":"awsVerify","correct":"import { awsVerify } from 'aws4-express';"},{"note":"Helper function used with Express body parsers (`express.json`, `express.raw`) to ensure the raw request body is available for signature verification. Misnaming or forgetting this is a common error.","wrong":"import { verify } from 'aws4-express';","symbol":"rawBodyFromVerify","correct":"import { rawBodyFromVerify } from 'aws4-express';"},{"note":"Utility function for parsing the raw body from a stream. Useful for custom body parsing scenarios if not using standard Express parsers with `rawBodyFromVerify`.","symbol":"rawBodyFromStream","correct":"import { rawBodyFromStream } from 'aws4-express';"}],"quickstart":{"code":"import express from 'express';\nimport { awsVerify, rawBodyFromVerify } from 'aws4-express';\nimport aws4 from 'aws4';\nimport https from 'https';\n\nconst app = express();\n\n// 1. Important: We need the raw body to check the signature!\n//    Must configure Express body parsers to provide rawBody.\napp.use(express.json({ verify: rawBodyFromVerify }));\n\n// 2. Add the AWS SigV4 security middleware\napp.use(awsVerify({\n  secretKey: (message) => {\n    // 3. Implement your logic to find the secret for the incoming Access Key\n    //    In a real application, this would involve a database lookup.\n    if (message.accessKey === 'MY_COOL_KEY') {\n      return 'MY_SUPER_SECRET';\n    }\n    return undefined; // Unknown key? Access denied!\n  }\n}));\n\n// 4. This route is protected by AWS SigV4 verification\napp.get('/secret-club', (req, res) => {\n  res.send('Welcome to the VIP area! 🎉 If you see this, your signature was valid.');\n});\n\nconst PORT = 3000;\napp.listen(PORT, () => {\n  console.log(`Server listening on http://localhost:${PORT}`);\n  console.log('--- Client Test ---');\n  // Example client-side usage with aws4 library\n  const opts = aws4.sign({\n    service: 'execute-api',\n    path: '/secret-club',\n    method: 'GET',\n    host: `localhost:${PORT}`,\n    headers: { 'Content-Type': 'application/json' }\n  }, {\n    accessKeyId: 'MY_COOL_KEY',\n    secretAccessKey: 'MY_SUPER_SECRET'\n  });\n\n  // Send the signed request\n  const clientReq = https.request(opts, res => {\n    console.log(`Client received status: ${res.statusCode}`);\n    res.pipe(process.stdout);\n  });\n  clientReq.on('error', (e) => console.error(`Client request error: ${e.message}`));\n  clientReq.end();\n});","lang":"typescript","description":"This quickstart demonstrates how to set up `aws4-express` middleware on an Express server to protect a route with AWS Signature V4, including a client-side example using `aws4` to sign and send a request. It highlights the crucial raw body parsing requirement and dynamic secret key lookup."},"warnings":[{"fix":"Upgrade your Node.js runtime to version 20 or later. For example, using `nvm install 20 && nvm use 20`.","message":"Support for Node.js versions below 20.x was officially dropped starting from `v0.13.0`. Users must ensure their environment runs Node.js 20 or higher to use recent versions of this package.","severity":"breaking","affected_versions":">=0.13.0"},{"fix":"Configure your Express body parser middleware with `verify: rawBodyFromVerify`. Example: `app.use(express.json({ verify: rawBodyFromVerify }));`","message":"AWS Signature V4 verification critically depends on the exact, raw request body. If using Express body parsers (like `express.json()`, `express.raw()`, or `express.urlencoded()`), you **must** attach the `rawBodyFromVerify` helper to the `verify` option to ensure `req.rawBody` is populated. Failure to do so will lead to `SignatureDoesNotMatch` errors.","severity":"gotcha","affected_versions":">=0.4.0"},{"fix":"Consult the `CHANGELOG.md` or GitHub release notes for specific breaking changes when upgrading minor versions. Pin exact versions for production use.","message":"The library is currently in a \"beta stage\" (versions before 1.x.x). This means that minor version updates (e.g., 0.13.x to 0.14.x) may introduce breaking changes without a major version increment. Developers should carefully review the changelog for each update.","severity":"deprecated","affected_versions":"<1.0.0"},{"fix":"Upgrade to `v0.14.1` or newer to ensure correct package entrypoint resolution, especially in CommonJS environments.","message":"Version `v0.14.1` fixed an issue where the `main` field in `package.json` was incorrect, potentially causing issues with CJS `require()` statements or incorrect module resolution in some bundlers. While not a direct breaking change, users on older `0.14.0` might have experienced import problems.","severity":"gotcha","affected_versions":"0.14.0"},{"fix":"Consult the `v0.4.0` release notes and examples for updated configuration parameter usage. This is mostly relevant for very early adopters.","message":"The initial `v0.4.0` release introduced breaking changes related to configuration parameters. As an alpha release, early users faced interface adjustments.","severity":"breaking","affected_versions":"0.4.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Verify the `secretKey` callback is returning the correct secret for the `accessKey`. Ensure no middleware modifies the request body before `awsVerify` runs, and that `rawBodyFromVerify` is correctly used. Debug the client-side signing process to match server expectations.","cause":"The calculated AWS Signature V4 on the server does not match the signature provided by the client. This is often due to an incorrect secret key, a modified request body after client signing, or discrepancies in how the canonical request (headers, query params, method, body hash) is constructed between client and server.","error":"Error: SignatureDoesNotMatch"},{"fix":"If using `express.json()`, `express.raw()`, or `express.urlencoded()`, ensure you pass `{ verify: rawBodyFromVerify }` to its configuration. For custom body parsing, ensure `req.rawBody` is manually populated with the exact raw request payload.","cause":"The `awsVerify` middleware attempts to access `req.rawBody` but it is `undefined`. This commonly occurs when an Express body parser is used without the `rawBodyFromVerify` helper attached to its `verify` option, or if no body parser is configured to provide the raw body at all.","error":"TypeError: Cannot read properties of undefined (reading 'rawBody')"},{"fix":"Switch to ES Module `import` syntax (`import { awsVerify } from 'aws4-express';`) and ensure your project is configured for ESM (e.g., `\"type\": \"module\"` in `package.json`). If strictly using CommonJS, ensure you are on `v0.14.1` or later, which should have improved CJS compatibility due to the entrypoint fix.","cause":"Attempting to `require()` `aws4-express` in a CommonJS module while it is published primarily as an ES Module. While `v0.14.1` fixed the `main` entrypoint, explicit CommonJS `require` might still face issues if the environment expects strict ESM.","error":"ERR_REQUIRE_ESM: require() of ES Module ... Not supported"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}