DEV Community

Cover image for Day 20 of 60: I Built a Production-Grade Authentication System with JWT Tokens and API Key Managemen
Cess Mbugua
Cess Mbugua

Posted on

Day 20 of 60: I Built a Production-Grade Authentication System with JWT Tokens and API Key Managemen

Every API I've built up to this point has been open. Anyone with the URL could call it. Today I fixed that.


## The Problem

Most beginner APIs have no authentication layer. Anyone who finds your endpoint can call it, abuse it, or overload it. In production that is not acceptable. Real APIs need to know who is calling them, track how often they are being called, and cut off anyone who is abusing them.

Today I built that entire layer from scratch.


## What I Built

A production-grade authenticated multi-tenant API with two separate authentication systems working together:
**
JWT Authentication for admin users**
Admin logs in with email and password. Server verifies credentials, generates a signed token valid for 30 minutes. Every admin request must include that token. No token, no access.

API Key Management for clients
Admin creates a client via a JWT-protected endpoint. Server generates a random 32-byte key using secrets.token_urlsafe(32). The raw key is shown once and never stored. Only its SHA-256 hash lives in the database. Client includes the key in every request as X-API-Key.

Usage Tracking
Every request increments the client's request counter and records the last used timestamp. Full visibility into who is calling what and when.

Rate Limiting
Sliding window algorithm. Each API key gets 10 requests per 60-second window. Exceed that and you get a 429 Too Many Requests error. Abuse is blocked automatically.

Key Revocation
Admin can deactivate any client's key instantly. One endpoint call and that client is locked out immediately.


The Tech Behind It

  • FastAPI: web framework
  • PostgreSQL: database for users and API keys
  • SQLAlchemy: ORM for database interaction
  • python-jose: JWT token generation and verification
  • passlib and bcrypt: password hashing
  • python-dotenv: environment variable management

## What I Learned

The most important lesson today: never store secrets in plain text. Not passwords. Not API keys. Ever.

Passwords are hashed with bcrypt before storage. API keys are hashed with SHA-256 before storage. The raw key is shown once at creation and never seen again. If your database is compromised the attacker still cannot use any of the credentials.

That is what production security actually looks like.


🔗 Full project on GitHub → https://github.com/mbuguacessy-glitch

40 more to go.

python #fastapi #jwt #security #authentication #learninpublic #buildinpublic #100DaysOfCode

Top comments (0)