LDAP Group-to-Role Mapping in FastAPI
A service-layer policy that turns directory group claims into roles, tested as a full permission matrix.
- Runs out of the box: yes
- Tests: yes
- CI: yes
- Docs: yes
- Used in production: yes
Purpose#
A FastAPI back end for an internal planning tool. Users sign in with directory credentials, and every request carries a short-lived session whose roles were derived from group membership at login. All authorization decisions live in one policy module that services call before any write, so route handlers never contain role checks.
The repository includes a permission matrix test: every role is exercised against every action and the expected result is a table in the test file, so a policy change is a visible diff.
What you will learn#
- Keep authorization in one policy function that services call before every mutation
- Generate a role-by-action test matrix from a single table
- Refresh roles on a schedule without forcing users to sign in again
Technologies & features#
- Technologies
- PythonFastAPILDAPActive DirectorySQLAlchemyPostgreSQL
- Features
- LDAP AuthenticationRole-Based Access Control
- Topics
- Directory IntegrationprimaryAccess Control
Lessons learned#
- Worked
Putting every role check in the service layer made the policy testable without HTTP. The matrix test caught two over-permissive rules before release.
- Decision
Roles are recomputed from groups every 15 minutes in a background task instead of on each request, trading a short delay for far fewer directory queries.
- Limitation
Group changes made in the directory are not reflected until the next refresh; urgent removals require an admin to revoke the session manually.
Try it#
git clone https://git.example.internal/business-systems/planner-api.git
cd planner-api
uv sync
docker compose up -d db directory
uv run pytest tests/policy -q
uv run fastapi dev app/main.pyCommands come from the owner’s README. Credentials are never stored here.


