An open API service indexing awesome lists of open source software.

https://github.com/echo298327/auth-gateway-fastapi-keycloak

Starter template for building scalable FastAPI microservices with Docker Compose and Keycloak for authentication.
https://github.com/echo298327/auth-gateway-fastapi-keycloak

api-gateway authentication docker-compose fastapi keycloak microservices mongodb

Last synced: 2 months ago
JSON representation

Starter template for building scalable FastAPI microservices with Docker Compose and Keycloak for authentication.

Awesome Lists containing this project

README

          

# Auth Gateway — IAM, Authentication & Authorization

A complete **IAM (Identity & Access Management)** solution with **Keycloak**. Provides authentication, authorization, user management, role-based access control, and an API gateway — ready to plug into any project.

## What's Included

- **Gateway Service** — routes all API requests, validates JWT tokens, checks permissions via Keycloak
- **IAM Service** — user management (CRUD), role assignment, Keycloak initialization
- **Keycloak** — authentication, token issuing, role-based permission evaluation
- **MongoDB** — stores users, service versions
- **PostgreSQL** — Keycloak's database
- **PgAdmin** — PostgreSQL admin UI
- **auth-gateway-serverkit** — shared library for auth middleware, Keycloak API, request handling
- **MFA / 2FA** — optional TOTP-based multi-factor authentication via a custom Keycloak extension
- **Security Headers** — X-Content-Type-Options, CSP, HSTS, Referrer-Policy, Permissions-Policy
- **Configurable RBAC** — define roles, policies, and per-endpoint permissions in JSON files
- **CI/CD Pipeline** — linting, security scanning, and tests on pull requests

## Documentation

- [Workflow Guide](docs/WORKFLOW_GUIDE.md) — step-by-step: login, create users, manage roles, add new services
- [API Documentation](docs/API.md) — all endpoint references
- [Authorization Guide](docs/AUTHORIZATION_GUIDE.md) — how roles, policies, and permissions work; how to add new roles/endpoints/services
- [Serverkit & Initializer Guide](docs/SERVERKIT_GUIDE.md) — how the Keycloak initializer works, customizing the serverkit
- [Postman Collection](postman_collection.json) — import into Postman to test all endpoints

---

## Getting Started

### Prerequisites

- [Docker](https://www.docker.com/get-started) and [Docker Compose](https://docs.docker.com/compose/install/)
- [Python 3.12+](https://www.python.org/)
- [MongoDB](https://www.mongodb.com/) (running locally or cloud-hosted)

### Installation

1. Clone the repository:

```bash
git clone https://github.com/Echo298327/auth-gateway-fastapi-keycloak.git
cd auth-gateway-fastapi-keycloak
```

2. Configure environment variables:

```bash
cp .env.docker.example .env.docker
cp .env.example .env
```

The `.example` files come pre-configured with default dev values that work out of the box. Change passwords/secrets as needed for your environment.

- `.env.docker` — used by Docker Compose (not committed to git)
- `.env` — used for local development without Docker

3. Start all services:

```bash
docker compose up --build -d
```

4. Access the services:

| Service | URL |
|---------|-----|
| Gateway | http://localhost:8080 |
| IAM | http://localhost:8081 |
| Keycloak Admin Console | http://localhost:9000 |
| PgAdmin | http://localhost:5050 |

### First Login

A system admin account is created automatically on first startup.

```
POST http://localhost:8080/api/login
Body: {
"username": "sysadmin",
"password": ""
}
```

The response contains `access_token`, `refresh_token`, and user data. Use the access token in the `Authorization: Bearer ` header for all subsequent requests.

> **Note:** If the user has MFA enabled, an optional `"totp"` field is required. See the [MFA section](#mfa--two-factor-authentication) for the full flow.

### Postman

1. Import `postman_collection.json` into Postman
2. Run the Login request
3. The token is automatically saved to the environment
4. All other requests use it automatically

---

## Project Structure

```
auth-gateway-fastapi-keycloak/
|
|-- .env.example # Local dev environment template
|-- .env.docker.example # Docker environment template
|-- docker-compose.yml # All services orchestration
|-- postman_collection.json # Postman collection
|
|-- docs/ # Documentation
| |-- API.md # API endpoint reference
| |-- AUTHORIZATION_GUIDE.md # Role & permission guide
| |-- WORKFLOW_GUIDE.md # Usage workflow guide
| |-- SERVERKIT_GUIDE.md # Serverkit & initializer guide
|
|-- deployment/
| |-- docker/
| | |-- gateway.Dockerfile
| | |-- iam.Dockerfile
| | |-- keycloak.Dockerfile
| | |-- keycloak.conf
| |-- pgadmin_server.json
|
|-- shared/ # Shared utilities across services
| |-- logging/
| |-- log_header.py
|
|-- gateway/ # Gateway Service
| |-- requirements.txt
| |-- src/
| |-- main.py
| |-- api/routes/
| | |-- gateway.py # Routes: login, refresh, logout, proxy
| |-- core/
| | |-- config.py # Service map, app settings
| |-- schemas/
| | |-- gateway.py # Login, Refresh request models
| |-- middleware/
| | |-- security_headers.py # Security headers middleware
| |-- services/
| | |-- proxy.py # Request forwarding, access control
| | |-- auth.py # Login, refresh, logout handlers
| | |-- mfa.py # MFA helpers: enroll, verify, Keycloak calls
|
|-- iam/ # IAM Service (Identity & Access Management)
| |-- requirements.txt
| |-- src/
| |-- main.py # Startup: DB init, Keycloak init, admin creation
| |-- api/routes/
| | |-- user.py # User CRUD endpoints
| |-- authorization/ # Role & permission config (JSON)
| | |-- roles.json # Realm roles + policies
| | |-- services/
| | |-- iam.json # Resources + permissions for IAM
| |-- core/
| | |-- config.py # DB, Keycloak, app settings
| |-- domains/
| | |-- users/ # User domain
| | | |-- models/user.py # Beanie document model
| | | |-- schemas/user.py # Pydantic schemas + AllowedRoles
| | | |-- services/user_manager.py
| | | |-- db/mongo/user.py # DB operations
| | |-- service_versions/ # Config version tracking
| | | |-- models/service_version.py
| | | |-- db/mongo/service_version.py
| | |-- organizations/ # Placeholder for future domain
| | |-- licenses/ # Placeholder for future domain
| |-- utils/
| | |-- admin.py # System admin helpers
| | |-- roles.py # Role validation
| | |-- validation.py # Input validation
| | |-- exception_handler.py
| |-- keycloak_extensions/ # Custom Keycloak SPI extensions
| | |-- mfa-provider/ # TOTP/2FA REST API (Java/Maven)
| | |-- pom.xml
| | |-- src/main/java/com/authgateway/keycloak/mfa/
| | |-- target/mfa-provider-1.0.0.jar
```

---

## Services

| Service | Port | Description |
|---------|------|-------------|
| Gateway | 8080 | API gateway, JWT validation, permission checks, request routing |
| IAM | 8081 | User management, Keycloak initialization, role management |
| Keycloak | 9000 | Identity provider, token issuer, authorization server |
| PostgreSQL | 5432 | Keycloak database |
| PgAdmin | 5050 | PostgreSQL admin interface |

---

## Role System

Three default roles: `user`, `admin`, `systemAdmin`.

- Users can have **multiple roles** at the same time
- Roles are assigned when creating a user and can be changed via update
- `systemAdmin` is created automatically and cannot be assigned through the API
- Roles, policies, and permissions are defined in JSON files under `iam/src/authorization/`

For full details on how to add roles, restrict endpoints, and add new services, see the [Authorization Guide](docs/AUTHORIZATION_GUIDE.md).

---

## MFA / Two-Factor Authentication

The project includes optional TOTP-based 2FA powered by a custom Keycloak SPI extension (`iam/src/keycloak_extensions/mfa-provider/`).

### How It Works

1. **Enable MFA for a user** — set `"enable_mfa": true` when creating a user via `POST /api/user/create`. This sets the Keycloak `CONFIGURE_TOTP` required action.
2. **First login** — user logs in with username + password. The gateway detects the required action and returns a QR code.
3. **Scan & verify** — user scans the QR code with an authenticator app (Google Authenticator, Authy, etc.), then sends the OTP code. The gateway verifies it and completes setup.
4. **Subsequent logins** — user sends `username`, `password`, and `totp` in the login request. Keycloak validates all three.

### Login Response States

| `mfa_action` | Meaning | Frontend should... |
|---|---|---|
| `"setup"` | First-time MFA setup | Show QR code, ask for OTP |
| `"setup_complete"` | OTP verified, setup done | Ask user to login again with a fresh OTP |
| `"verify"` | User has MFA, needs OTP | Show OTP input |

### Building the MFA Extension

The Keycloak extension is a Java JAR built with Maven. It is automatically included in the Keycloak Docker image via the Dockerfile.

```bash
cd iam/src/keycloak_extensions/mfa-provider
mvn clean package -DskipTests
```

For full MFA extension documentation see [mfa-provider/README.md](iam/src/keycloak_extensions/mfa-provider/README.md).

---

## Keycloak Config Versioning

The IAM service tracks a `KEYCLOAK_CONFIG_VERSION` in code. On startup it compares with the version stored in MongoDB:

- **Different**: runs full Keycloak sync (delete + recreate roles, policies, resources, permissions)
- **Same**: skips, only verifies connection

Bump the version in `iam/src/core/config.py` whenever you change `roles.json` or any file in `authorization/services/`.

---

## Keycloak Admin Console

For advanced management you can access Keycloak directly:

- **URL**: http://localhost:9000
- **Username**: `admin` (from `KC_BOOTSTRAP_ADMIN_USERNAME`)
- **Password**: from `KC_BOOTSTRAP_ADMIN_PASSWORD` in `.env.docker`

---

## CI/CD Pipeline

Runs automatically on pull requests to `main`:

| Check | Description |
|-------|-------------|
| Lint | Flake8 (unused imports, variables) |
| Security (Dependencies) | Trivy vulnerability scan |
| Security (Docker) | Trivy Docker image scan |
| Tests | pytest |

---

## Production Checklist

Before deploying to production, review the following:

- [ ] Set `CORS_ORIGINS` to specific trusted domains (not `*`)
- [ ] Set `ENVIRONMENT=production` to enable HSTS headers
- [ ] Use a secrets manager (e.g. Docker Secrets, Vault, AWS Secrets Manager) instead of `.env` files for credentials
- [ ] Place a reverse proxy (Nginx / Caddy) in front for HTTPS termination
- [ ] Use managed databases (e.g. MongoDB Atlas, AWS RDS for PostgreSQL) instead of containerized ones
- [ ] Remove or restrict `pgadmin` from the compose file
- [ ] Set Keycloak `hostname` to your actual domain in `keycloak.conf`
- [ ] Review and restrict Keycloak admin credentials (`KC_BOOTSTRAP_ADMIN_*`)
- [ ] Ensure `.env` and `.env.docker` are never committed (already in `.gitignore`)

The Dockerfiles, health endpoints (`/health`, `/readyz`), and environment-based configuration are designed to be portable — they work with Docker Compose, Kubernetes, or any container orchestrator.

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

## License

[MIT License](LICENSE)