A simple Identity and Access Management (IAM) system built with Go. This project shows how to handle user authentication, roles, and permissions in a backend service.
This is a learning project. Some parts are simplified for clarity.
An IAM system manages who users are and what they can do:
- Login/Register: Users create accounts and log in
- Roles: Assign roles like "admin" or "user" to people
- Permissions: Control what each role can do (read users, delete users, etc.)
- Audit logs: Track who did what and when
The project uses something called Hexagonal Architecture. The idea is simple:
- Core (middle): All the business logic. No database stuff, no HTTP stuff.
- Ports (circle edge): Interfaces that say "I need a way to store users" or "I need a way to generate tokens"
- Adapters (outside): Actual implementations. PostgreSQL adapter for storing users, JWT adapter for tokens, etc.
Why? Makes testing easy. Want to test login without a real database? Use a fake adapter. Want to switch databases? Just swap the adapter.
# Using Docker
docker-compose up
# Server runs on http://localhost:8080-
Start PostgreSQL and Redis
-
Create database:
psql -U postgres CREATE DATABASE iam; -
Run migrations:
psql -U iam -d iam -f migrations/001_init.sql
-
Run the server:
go run cmd/server/main.go
POST /auth/register- Create accountPOST /auth/login- Get tokensPOST /auth/refresh- Get new access token
GET /users/me- Get current userGET /users- List all usersPUT /users/:id- Update user
POST /roles- Create roleGET /roles- List rolesPOST /roles/:id/permissions- Add permission to role
GET /audit- View audit logs
- User registers with email and password
- Password is hashed with bcrypt and stored
- User logs in with email/password
- Server creates JWT token and returns it
- User sends token in
Authorization: Bearer <token>header - Server validates token and lets request through
- All actions (login, create user, etc.) are logged to audit table
internal/core/services/auth_service.go- Login/register logicinternal/core/services/rbac_service.go- Role/permission logicinternal/adapters/postgres/- Database queriesinternal/adapters/http/- REST endpointsinternal/adapters/auth/jwt/- JWT token stuff
SERVER_ADDR=:8080
DB_HOST=localhost
DB_PORT=5432
DB_USER=iam
DB_PASS=iam
DB_NAME=iam
REDIS_ADDR=localhost:6379
JWT_SECRET=super-secret-key
go test ./...Tests use mock adapters instead of real database.
Building this project taught me:
- Implementing GO backends
- Separation of concerns (core logic vs infrastructure)
- Advanced JWT Tokens
- role-based access control
- Add SAML support
- Add OAuth2 flows
- Add 2FA
- Better error messages
- Rate limiting