# How to Manage JWT Settings in FastAPI: Secret Keys and Token Expiration

> Easily manage JWT settings in FastAPI secrets and token expiration using environment variables in fastapi-boilerplate. Configure your app securely and efficiently.

- Repository: [Benav Labs/fastapi-boilerplate](https://github.com/benavlabs/fastapi-boilerplate)
- Tags: tutorial
- Published: 2026-02-26

---

**Manage JWT settings in the fastapi-boilerplate by configuring the `CryptSettings` class in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py) via environment variables for the secret key, algorithm, and token lifetimes.**

The `benavlabs/fastapi-boilerplate` repository centralizes all cryptographic configuration in a dedicated settings group, making it straightforward to manage JWT settings like secret keys and expiration times without modifying application logic. This approach leverages Pydantic Settings to load sensitive values from environment variables, ensuring your secret key never resides in source control.

## Where JWT Settings Are Stored

All JWT configuration lives in the **`CryptSettings`** class defined in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py). This class is aggregated into the global `settings` object when the application starts.

The following parameters control token behavior:

- **SECRET_KEY** – A `SecretStr` field that defaults to `"secret-key"` but should be overridden via the `SECRET_KEY` environment variable.
- **ALGORITHM** – The signing algorithm (default `HS256`).
- **ACCESS_TOKEN_EXPIRE_MINUTES** – Lifetime of access tokens (default 30 minutes).
- **REFRESH_TOKEN_EXPIRE_DAYS** – Lifetime of refresh tokens (default 7 days).

These values are referenced throughout the authentication layer to ensure consistent token generation and validation.

## How to Configure JWT Parameters via Environment Variables

To manage JWT settings securely, define them in a `.env` file at the project root or export them directly in your deployment environment.

```dotenv

# .env

SECRET_KEY=MyVerySecretKey123!
ACCESS_TOKEN_EXPIRE_MINUTES=45
REFRESH_TOKEN_EXPIRE_DAYS=10
ALGORITHM=HS256

```

The `Settings` object automatically reads these variables via `pydantic-settings`. After modifying the environment, restart the application to load the new values. All JWT creation and verification logic in [`src/app/core/security.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/security.py) will immediately use the updated secret key and lifetimes without requiring code changes.

## How JWT Settings Are Used in Token Operations

The [`src/app/core/security.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/security.py) module consumes the global settings to implement token lifecycle management.

**Token Creation**

The `create_access_token` function uses `settings.ACCESS_TOKEN_EXPIRE_MINUTES` to compute the `exp` claim:

```python
from datetime import timedelta
from src.app.core.security import create_access_token, settings

payload = {"sub": "alice"}
access_token = await create_access_token(
    data=payload,
    expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
)

```

Similarly, `create_refresh_token` references `settings.REFRESH_TOKEN_EXPIRE_DAYS` for extended lifetimes.

**Token Verification**

The `verify_token` function decodes tokens using the same secret key and algorithm defined in `CryptSettings`, ensuring that only tokens issued by the application are accepted.

**Login Route Integration**

The login endpoint in [`src/app/api/v1/login.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/api/v1/login.py) demonstrates practical usage by reading `ACCESS_TOKEN_EXPIRE_MINUTES` to construct token expiration deltas and setting refresh cookie `max_age` based on `REFRESH_TOKEN_EXPIRE_DAYS`.

## Practical Configuration Examples

**Changing the Algorithm**

While `HS256` is the default, you can upgrade to `HS512` for stronger signatures:

```dotenv
ALGORITHM=HS512

```

**Creating Tokens with Custom Expiration**

Override the default expiration programmatically when needed:

```python
from datetime import timedelta

# Short-lived token for sensitive operations

token = await create_access_token(
    data={"sub": "user@example.com"},
    expires_delta=timedelta(minutes=5)
)

```

**Refreshing Tokens**

The refresh flow uses the configured expiration settings automatically:

```python
from fastapi import Request, Depends
from src.app.core.security import verify_token, TokenType, create_access_token
from src.app.core.db.database import async_get_db

async def refresh(request: Request, db=Depends(async_get_db)):
    refresh_token = request.cookies.get("refresh_token")
    user_data = await verify_token(refresh_token, TokenType.REFRESH, db)
    
    new_access = await create_access_token({"sub": user_data.username_or_email})
    return {"access_token": new_access, "token_type": "bearer"}

```

## Summary

- **Centralized Configuration**: All JWT settings reside in `CryptSettings` within [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py), aggregated into a global `settings` object.
- **Environment-Driven**: Manage the secret key, algorithm, and token lifetimes via environment variables (`SECRET_KEY`, `ACCESS_TOKEN_EXPIRE_MINUTES`, `REFRESH_TOKEN_EXPIRE_DAYS`) rather than hard-coding values.
- **Automatic Integration**: The [`src/app/core/security.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/security.py) module automatically consumes these settings for token creation and verification, while [`src/app/api/v1/login.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/api/v1/login.py) demonstrates practical usage in authentication flows.
- **Security Best Practice**: Never commit secrets to source control; use `.env` files or deployment environment variables to manage sensitive JWT configuration.

## Frequently Asked Questions

### How do I rotate the JWT secret key in production?

To rotate the secret key, update the `SECRET_KEY` environment variable in your deployment platform or `.env` file and restart the application. Note that changing the secret will invalidate all existing tokens issued with the previous key, forcing users to re-authenticate. Plan rotations during maintenance windows to minimize disruption.

### Can I use asymmetric algorithms like RS256 instead of HS256?

Yes, you can change the algorithm by setting the `ALGORITHM` environment variable to `RS256` and providing the corresponding private/public key pair. However, you must modify the `CryptSettings` class in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py) to handle the additional key variables (e.g., `PRIVATE_KEY` and `PUBLIC_KEY`) and update the [`security.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/security.py) functions to use the appropriate key for signing versus verification.

### Why are refresh tokens configured in days while access tokens use minutes?

This distinction reflects standard security practices for token lifetimes. **Access tokens** are short-lived (minutes) to minimize the window of exposure if they are intercepted, while **refresh tokens** are long-lived (days) to provide a better user experience by reducing the frequency of full re-authentication. You can adjust these values via `ACCESS_TOKEN_EXPIRE_MINUTES` and `REFRESH_TOKEN_EXPIRE_DAYS` to balance security requirements against user convenience.