# JWT And Security

Use HS256 JWT auth when you control the signing secret and want simple issuer and audience validation. This guide walks through configuring the authorizer block with a shared secret, setting the algorithm, and enabling auth on specific routes. HS256 is the simplest JWT setup and works well for internal APIs and single-tenant applications.

**Last reviewed:** 2026-03-06

## When to use this

Use the JWT and security guides when you need to protect routes with token-based authentication. The gateway validates JWT tokens at the edge before the request reaches your upstream, reducing load on your backend and centralizing auth checks in one place.

## Key concepts

* The gateway supports HS256 JWT validation with a shared secret. The secret is configured in the `authorizer` block and should be stored as a Cloudflare secret, not hardcoded in config.
* Issuer (`iss`) and audience (`aud`) claims are validated when configured. If either check fails, the gateway returns a 401 with a specific error message identifying which claim was invalid.
* Auth is opt-in per route: only paths with `auth: true` require a valid JWT. All other paths are public by default, even when an authorizer is configured.
* The gateway extracts the token from the `Authorization: Bearer <token>` header. No other token locations (cookies, query params) are supported.
* The gateway does not implement role-based access control, token revocation, or scope-based permissions. These must be handled by your upstream service or a pre-process hook.

## Repo-grounded example

```json
{
  "authorizer": {
    "type": "jwt",
    "secret": "$env.JWT_SECRET",
    "algorithm": "HS256",
    "issuer": "https://issuer.example.com",
    "audience": "api-audience"
  },
  "paths": [
    {
      "method": "GET",
      "path": "/private",
      "auth": true,
      "response": { "private": true }
    }
  ]
}
```

This snippet configures the `authorizer` with `type: "jwt"`, an HS256 algorithm, and a secret loaded from `$env.JWT_SECRET`. The `issuer` and `audience` fields add claim validation, and the `/private` path has `auth: true` to require a valid token.

## Troubleshooting

* If you get a 401 "missing authorization header" error, confirm the client sends the `Authorization` header with the `Bearer` prefix (note the space after Bearer).
* If you get a 401 "token expired" error, check the `exp` claim in your JWT -- the gateway compares it against the current UTC time on the Cloudflare edge node.
* If issuer or audience validation fails, decode your token at jwt.io and compare the `iss` and `aud` claims exactly (case-sensitive) against the values in your authorizer config.
* If a public route unexpectedly returns 401, verify that the route does not have `auth: true` set -- check for typos like `"auth": "true"` (string vs boolean).

## Related docs

* [authorizer](/configuration/authorizer.md)
* [authentication](/configuration/authentication.md)
* [gateway troubleshooting matrix](/troubleshooting/wrangler-deploy-guide/gateway-troubleshooting-matrix.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.serverlessapigateway.com/security/jwt-hs256-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
