A production-minded Spring Boot identity starter for projects that need a clean authentication foundation without bringing in a full IAM product on day one.
It includes local registration and login, guest users, JWT access tokens, opaque refresh tokens with rotation, device-aware sessions, optional OAuth2 extension points, PostgreSQL, Flyway migrations, H2 tests, validation, global error responses, and architecture guardrails.
This is a reusable backend starter for building your own application identity layer.
Use it when you want:
- Email/password registration and login.
- Guest users that can later become real app users.
- Stateless JWT access tokens.
- Opaque refresh tokens stored as hashes.
- Refresh-token rotation and reuse detection.
- PostgreSQL schema management through Flyway.
- A small feature-first package structure that is easy to customize.
This is not a full IAM platform. It does not try to replace Keycloak, Auth0, Okta, or a dedicated authorization server.
- Java 21
- Spring Boot 4
- Spring Security
- Spring Data JPA
- PostgreSQL
- Flyway
- H2 for tests
- Maven wrapper
Requirements:
- Java 21 or newer
- Docker and Docker Compose
Linux/macOS:
cp example.env .env
bash scripts/generate-jwt-rsa-keys.sh
docker compose up -d
./mvnw spring-boot:runWindows PowerShell:
Copy-Item example.env .env
.\scripts\generate-jwt-rsa-keys.ps1
docker compose up -d
.\mvnw.cmd spring-boot:runHealth check:
GET http://localhost:8080/actuator/healthFor detailed local setup, troubleshooting, and first requests, see Setup Guide.
Register a user:
POST /api/user/register
Content-Type: application/json
{
"username": "alice@example.com",
"password": "Password1",
"name": "Alice",
"phone": "+15551234567",
"deviceId": "11111111-1111-4111-8111-111111111111"
}Example response:
{
"accessToken": "eyJ...",
"refreshToken": "opaque-refresh-token",
"expiresInSeconds": 3600
}Use the access token for authenticated requests:
Authorization: Bearer <access-token>Guest access is available through POST /auth/guest, but it is a public endpoint. Keep the built-in rate limiter enabled and do not use a client-supplied deviceId as a trusted limit by itself. See Rate Limiting Guide.
- Setup Guide
- API Reference
- Architecture Guide
- Configuration Guide
- Customization Guide
- Production Checklist
- Rate Limiting Guide
- Contributing Guide
- Security Policy
- Changelog
src/main/java/com/example/identity
auth/ Login, JWT, refresh tokens, OAuth2 support, session flows
user/ AppUser model, registration, guest upgrade, profile flows
config/ Spring Security and application configuration
exception/ API error handling
The structure is intentionally feature-first. It avoids command/handler scaffolding and global DDD layers because this starter is service-oriented, not domain-heavy.
| Method | Path | Purpose | Auth |
|---|---|---|---|
POST |
/api/user/register |
Register local user and issue tokens | Public |
POST |
/auth/guest |
Create or reuse guest user and issue tokens | Public |
POST |
/auth/login |
Login with email/password | Public |
POST |
/auth/refresh |
Rotate refresh token and issue access token | Public |
POST |
/auth/logout |
Revoke one refresh token | Public |
POST |
/auth/logout/all |
Revoke all current user's refresh tokens | Bearer |
GET |
/api/user/profile |
Read current user's profile | Bearer |
PUT |
/api/user/profile |
Update current user's profile | Bearer |
POST |
/api/user/change-password |
Change local password and revoke sessions | Bearer |
See API Reference for request and response details.
The application imports .env automatically:
spring.config.import=optional:file:.env[.properties]Start from example.env, then replace secrets before deployment.
Important settings are documented in Configuration Guide.
Run the full test suite:
./mvnw testWindows PowerShell:
.\mvnw.cmd testThe test profile uses H2 in PostgreSQL compatibility mode and Flyway migrations from src/test/resources/db/migration/h2.
Before production:
- Replace the development JWT RSA key pair.
- Use a strong database password.
- Keep
.envout of git. - Run behind HTTPS.
- Keep access-token TTL short.
- Review rate limiting for public auth endpoints, especially
POST /auth/guest. - Decide whether logout must invalidate access tokens immediately.
- Review the checklist in Production Checklist.
After cloning:
- Replace Maven metadata in
pom.xml. - Rename package
com.example.identityto your real package. - Replace
identity-starterinapplication.properties,example.env, anddocker-compose.yml. - Add your own business modules beside
authanduser. - Keep identity concepts generic unless your product really needs domain-specific user types.
More guidance is in Customization Guide.
This starter intentionally keeps the package layout small:
- Controllers do not use repositories directly.
- Database schema changes live in Flyway migrations.
AppUseris the only user domain model.- Guest users are direct
AppUserrecords withROLE_GUEST. - The only built-in roles are
ROLE_USER,ROLE_GUEST, andROLE_ROOT. - No command/handler/application scaffolding is included.
Guardrail tests protect these choices.
MIT License. See LICENSE.