AWS powertools documentation change
Summary
Replaced JWT token verification middleware example with correlation ID middleware example, updated code to use generic Router with AppEnv type, and changed date from 2026-03-19 to 2026-04-14
Security assessment
The change replaces a security-related example (JWT authentication) with a non-security example (correlation ID tracking). This removes security documentation rather than adding it. The change demonstrates better patterns for request context isolation but doesn't address any specific security vulnerability or weakness.
Diff
diff --git a/powertools/typescript/latest/features/event-handler/http.md b/powertools/typescript/latest/features/event-handler/http.md index 6dce829cb..425838079 100644 --- a//powertools/typescript/latest/features/event-handler/http.md +++ b//powertools/typescript/latest/features/event-handler/http.md @@ -2770,13 +2769,0 @@ index.ts - 38 - 39 - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 - 48 - 49 - 50 @@ -2787,5 +2774 @@ index.ts - import { getStringFromEnv } from '@aws-lambda-powertools/commons/utils/env'; - import { - Router, - UnauthorizedError, - } from '@aws-lambda-powertools/event-handler/http'; + import { Router } from '@aws-lambda-powertools/event-handler/http'; @@ -2796,4 +2779,5 @@ index.ts - const jwtSecret = getStringFromEnv({ - key: 'JWT_SECRET', - errorMessage: 'JWT_SECRET is not set', - }); + type AppEnv = { + store: { + request: { correlationId: string }; + }; + }; @@ -2802,2 +2786 @@ index.ts - const app = new Router(); - const store: { userId: string; roles: string[] } = { userId: '', roles: [] }; + const app = new Router<AppEnv>(); @@ -2806,15 +2789,6 @@ index.ts - const verifyToken = (options: { jwtSecret: string }): Middleware => { - return async ({ reqCtx: { req }, next }) => { - const auth = req.headers.get('Authorization'); - if (!auth || !auth.startsWith('Bearer ')) - throw new UnauthorizedError('Missing or invalid Authorization header'); - - const token = auth.slice(7); - try { - const payload = jwt.verify(token, options.jwtSecret); - store.userId = payload.sub; - store.roles = payload.roles; - } catch (error) { - logger.error('Token verification failed', { error }); - throw new UnauthorizedError('Invalid token'); - } + const correlationId = (options: { header: string }): Middleware<AppEnv> => { + return async ({ reqCtx, next }) => { + const id = reqCtx.req.headers.get(options.header) ?? randomUUID(); + + reqCtx.set('correlationId', id); + logger.appendKeys({ correlationId: id }); @@ -2827 +2801 @@ index.ts - app.use(verifyToken({ jwtSecret })); + app.use(correlationId({ header: 'X-Correlation-Id' })); @@ -2829,4 +2803,4 @@ index.ts - app.post('/todos', async () => { - const { userId } = store; - const todos = await getUserTodos(userId); - return { todos }; + app.post('/orders', async (reqCtx) => { + const id = reqCtx.get('correlationId') ?? randomUUID(); + const result = await processOrder('order-123', id); + return { correlationId: id, ...result }; @@ -2841 +2815 @@ index.ts -In this example we have a middleware that acts only in the post-processing stage as all the logic occurs after the `next` function has been called. This is so as to ensure that the handler has run and we have access to request body. +In this example we have a middleware that extracts a correlation ID from a request header or generates a new one if absent. It stores the ID in the request context using `reqCtx.set()` so that route handlers can retrieve it with `reqCtx.get()`. This ensures each invocation has its own isolated state without relying on module-level variables. @@ -4996 +4970 @@ index.test.tsevent_helper.tsindex.ts -2026-03-19 +2026-04-14