A production-ready authentication microservice built with Go. Handles user registration, login, and JWT-based session management — designed with clean architecture, domain-driven design, and event-driven patterns.
Auth Service is the identity layer for the Toppira platform. It provides secure credential management and token-based authentication, with refresh tokens stored in Redis and domain events published through a transactional outbox to Kafka.
flowchart LR
Client([Client]) -->|HTTP| API[Gin HTTP API]
API --> App[Application Layer]
App --> Domain[Domain Layer]
App --> Infra[Infrastructure]
Infra --> PG[(PostgreSQL)]
Infra --> Redis[(Redis)]
Infra --> Kafka[(Kafka)]
- User registration & login — username/password authentication with bcrypt hashing
- JWT access tokens — short-lived, signed tokens for stateless authorization
- Refresh token sessions — long-lived tokens hashed and stored in Redis per device
- Transactional outbox — reliable domain event publishing (
UserRegistered) to Kafka - Swagger documentation — interactive API docs at
/docs/swagger/index.html - Structured logging — rotating file logs powered by Zap
- Graceful shutdown — clean HTTP server lifecycle via Uber FX
| Layer | Technology |
|---|---|
| Language | Go 1.25 |
| HTTP | Gin |
| DI / Lifecycle | Uber FX |
| Database | PostgreSQL 17 + GORM |
| Cache | Redis 8 |
| Migrations | Goose |
| Messaging | Kafka (Sarama) |
| Docs | Swaggo |
| Linting | golangci-lint |
The project follows Clean Architecture with clear separation of concerns:
auth/
├── cmd/ # Application entrypoint
├── internal/
│ ├── config/ # Environment configuration
│ ├── domain/ # Entities, value objects, contracts, events
│ ├── application/ # Use cases & application services
│ ├── infrastructure/ # DB, cache, JWT, Kafka, outbox, logger
│ └── ui/ # HTTP controllers, routers, middlewares
└── docs/
├── swagger/ # Generated OpenAPI specs
└── development/ # Dev environment guides
| Layer | Responsibility |
|---|---|
| Domain | Business rules, entities (Credential, Device), value objects, repository contracts |
| Application | Orchestration — Register, Login, and Session token issuance |
| Infrastructure | Concrete implementations — Postgres, Redis, JWT, bcrypt, outbox publisher |
| UI | HTTP transport — Gin routes, DTOs, error middleware |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/auth/register |
Create a new account and receive tokens |
POST |
/api/v1/auth/login |
Authenticate and receive tokens |
GET |
/docs/swagger/index.html |
Interactive Swagger UI |
curl -X POST http://localhost:8080/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"username": "auth_username", "password": "auth_password123"}'{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"access_token_expires_at": "2026-05-30T17:00:00Z",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.refresh",
"refresh_token_expires_at": "2026-06-04T17:00:00Z"
}- Go 1.25+
- Task — task runner
- Docker & Docker Compose
- Air — live reload (optional)
- Goose — migrations
- Swag — Swagger generation
See docs/development/tools.md for detailed installation instructions.
git clone <repository-url>
cd Echo_Server_Auth
cp .env.example .envFill in your .env file:
APP_PORT=8080
APP_MODE=dev
APP_ORIGINS=http://localhost:3000
AUTH_TOKEN_SECRET=your-secret-key
AUTH_ACCESS_TOKEN_TTL=5h
AUTH_REFRESH_TOKEN_TTL=120h
DB_POSTGRES_USER=auth
DB_POSTGRES_PASSWORD=secret
DB_POSTGRES_HOST=localhost
DB_POSTGRES_PORT=5432
DB_POSTGRES_DB=auth_db
CACHE_REDIS_PASSWORD=secret
CACHE_REDIS_HOST=localhost
CACHE_REDIS_PORT=6379
CACHE_REDIS_DB=0
LOG_LEVEL=info
KAFKA_BROKERS=localhost:9092docker compose up -dtask mig:up# Standard run
task run
# With live reload
task devThe server starts on http://localhost:8080. Open Swagger at http://localhost:8080/docs/swagger/index.html.
All common tasks are defined in Taskfile.yml:
| Task | Command | Description |
|---|---|---|
| Run | task run |
Start the server |
| Dev | task dev |
Start with live reload (Air) |
| Build | task build |
Compile binary to bin/auth-service |
| Test | task test |
Run all tests |
| Lint | task lint |
Run golangci-lint |
| Format | task fmt |
Format Go source |
| Swagger | task swag |
Regenerate OpenAPI docs |
| Migrate up | task mig:up |
Apply pending migrations |
| Migrate down | task mig:down |
Roll back last migration |
| New migration | task mig:new name=create_foo |
Create a new migration file |
| DAO generate | task dao:gen |
Regenerate GORM DAO code |
| Variable | Required | Default | Description |
|---|---|---|---|
APP_PORT |
Yes | — | HTTP server port |
APP_MODE |
No | dev |
App mode (dev, prod) |
APP_ORIGINS |
No | — | CORS allowed origins (comma-separated) |
AUTH_TOKEN_SECRET |
Yes | — | JWT signing secret |
AUTH_ACCESS_TOKEN_TTL |
No | 5h |
Access token lifetime |
AUTH_REFRESH_TOKEN_TTL |
No | 120h |
Refresh token lifetime |
DB_POSTGRES_* |
Yes | — | PostgreSQL connection settings |
CACHE_REDIS_* |
Yes | — | Redis connection settings |
LOG_* |
No | — | Log level, path, rotation settings |
KAFKA_BROKERS |
No | — | Kafka broker addresses (comma-separated) |
GitHub Actions runs on every push and pull request to main:
- test —
go test ./... - lint — golangci-lint
Ali Moradi — info@toppira.com · toppira.com/support
Built with care by Toppira