Build simple authentication API using FAST API with ES256 encryption in 10 mins

This article covered the following topics:

  1. Creating a FAST API project and install PyJWT package.
  2. Create and validate ES256 JWT token.
  3. Validation by accessing the protected endpoints with JWT token
  4. Build this project into a container image for microservice.

Technology used

  1. FastAPI for serving authentication API with asynchronous pattern.
  2. PyJWT for generating and validating ES256 JWT token.
  3. JWT dashboard for visualising the token we created.
  4. OpenAPI(previously known as swagger) for documenting API specification.
  5. Docker for building container image.
  6. Postman

Getting Started

Step 1: Creating a FAST API project and install PyJWT package.

# Create new directory for this project
mkdir auth-fastapi
cd auth-fastapi
# Install the fastapi module
pip install fastapi
pip install uvicorn[standard]

Define root endpoint

from fastapi import FastAPI
app = FastAPI()
async def root():
return {"message": "Hello World"}

Run the project

uvicorn main:app --reload

Install PyJWT python module

pip install pyjwt

Step 2: Create and validate ES256 JWT token.

  1. /login endpoint to login user and generate token for the user.
  2. /secret endpoint, only user with validate token can access this endpoint.

Generate ES256 public and private key set in JSON Web Key(JWK) format

# example 
"keys": [
"kty": "EC",
"d": "jwrAjoo8YOk-ryUgQtarw4P-id8c3BD0jOoWJ3PgNyU",
"use": "sig",
"crv": "P-256",
"kid": "LEu_K_tGsARSVoaGxP6nCjhYl9XB6jpuZH0vdpTEDOU",
"x": "o4lf0hDz0oej8fsiPP5UjrO8B0X-96ssgMxh1NVAVzA",
"y": "9LQcldbXC9e8KUzw6pVU-QFY2hVluMHc9-7s08iZEY4",
"alg": "ES256"

Convert JWK key set into BASE64 and use in environment variables

base64 jwks-es.json > output.txt
  1. SECRET_KEY : any value for hashing the password
  2. JWT_ALGO value from JWK key set alg , which is the algorithm we used : ES256.
  3. ES256_KID value from JWK key set kid
  4. ES256_KEY is the entire base64 string converted from the previous step.
# .env example
# base64 jwks-es.json > output.txt

Read environment variable using python-decouple

├── jwks-es.json
└── output.txt
from pydantic import BaseSettings
from decouple import config
class AuthSettings(BaseSettings):
JWT_SECRET_KEY: str = config('SECRET_KEY')
ES256_KEY: str = config("ES256_KEY")
JWT_ALGO: str = config("JWT_ALGO")
ES256_KID: str = config("ES256_KID")
class Settings( AuthSettings):
settings = Settings()

Create models to validate user email and password

├── config
│ ├──
│ ├── jwks-es.json
│ └── output.txt
├── models
│ ├──
│ └──
└── requirements.txt
from .user import DB_User_Model, AuthModel_User
import re
from typing import Optional
from pydantic import BaseModel, validator
from pydantic.dataclasses import dataclass
class DB_User_Model():
key: str
email: str
hashed_password: str
is_active: Optional[bool]
is_verified: Optional[bool]
is_superuser: Optional[bool]
class AuthModel_User(BaseModel):
email: str
password: str
def passwords_validation(cls, v):
if not custom_password_validator(v):
raise ValueError("Password must have minimum 8 characters to maximum 20 characters, 1 capital letter, 1 small letter, and 1 special character from '!@#$%^&*()'")
return v
def custom_password_validator(password):
reg = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,20}$"
pat = re.compile(reg)
mat =, password)
return mat

Code for generating JWT token from JWK key set

Final step for generating JWT token

How pip-tools works, from

Step 3: Validation by accessing the protected endpoints with JWT token

"email": "",
"password": "!Kingh_a1234"
"Top Secret data only authorized users can access this info"

Step 4: Build this project into container image for microservice.

FROM tiangolo/uvicorn-gunicorn:python3.9-slim
LABEL maintainer="danielchu"
ENV LOG_LEVEL="warning"
RUN mkdir /auth
COPY requirements.txt /auth
RUN pip install -r requirements.txt
COPY . /auth
CMD ["uvicorn", "main:app", "--host", "", "--port", "8000"]
docker build -t auth-es256:0.0.1 .
docker run -p 8080:8000 auth-es256:0.0.1




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store