PrototypePythonHackathon · 2025

API Auth Gateway

A university's asset inventory API returned the whole inventory to anyone who asked, and it could not be modified.

What it does: Puts users and permissions in front of that API: each person sees only the assets they own and superusers see everything, without touching the original API.

Repository temporarily unlinked; the code is available on request.

Overview

Hackathon project. The university's asset inventory API already existed and had no users: anyone who queried it got the full inventory.

The gateway sits in front of it. It authenticates with JWT access and refresh tokens, queries the original API and filters the response by the dueno_de_activo (asset owner) field, so each user sees only their own. It is built with FastAPI and PostgreSQL, async end to end, deployed on Railway and reports errors to Sentry.

The need

The university's asset inventory API already existed and returned everything to anyone who asked. What each user could see had to be limited.

Constraints

  • The original API could not be modified: access control had to live outside it.
  • A hackathon deadline.

The solution

A gateway that requires sign-in, queries the original API on the user's behalf and returns only the assets they own. Superusers get the full inventory.

How it works

The gateway sits in front of the original API: it authenticates, queries and filters. Layers are split into routers, async SQLAlchemy 2.0 models and Pydantic schemas.

Data flow
  1. POST /auth/login: checks the user in PostgreSQL (bcrypt passwords) and issues an access token and a refresh token
  2. GET /inventario with the token: the gateway validates the JWT and loads the user
  3. Queries the external API with async httpx
  4. Filters the response by the dueno_de_activo field; superusers get everything
  5. Errors and traces go to Sentry

Technical decisions

  • Authorization lives in the gateway because the original API couldn't be changed.
  • Every token carries a type claim that the gateway checks, so a refresh token can't be used as an access token.
  • Everything is async (FastAPI, async SQLAlchemy, httpx) so the process doesn't block while it waits on the external API.

Limits & next steps

  • Filtering happens after fetching up to 2,000 assets from the external API on every request; with more data it would need to filter at the source or cache.
  • It's a hackathon project: there are no automated tests, only manual check scripts.

My part

Hackathon project. I developed the gateway: authentication, the owner filter and the deployment on Railway with Sentry.

Stack

  • Python
  • FastAPI
  • JWT
  • PostgreSQL
  • SQLAlchemy
  • Docker
  • Railway

Interested in this kind of work?

I'm looking for remote work as a Full Stack Engineer. If you'd like to talk about this project or your team, get in touch.

Other projects