Skip to content

Commit 65aaae3

Browse files
FTMahringerCopilot
andcommitted
docs: add v1.2.0 release notes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 96e5b62 commit 65aaae3

1 file changed

Lines changed: 266 additions & 0 deletions

File tree

docs/release-notes/v1.2.0.md

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
# v1.2.0 - Auth and Users
2+
3+
**Release Date:** 2026-05-08
4+
5+
**Milestone:** v1.2.0 (Auth and Users)
6+
7+
This milestone delivers a complete authentication and user management system with modern password hashing and JWT-based stateless authentication. All API endpoints now require authentication, providing a secure foundation for multi-user platform access.
8+
9+
## Added
10+
11+
### User Management with Argon2id Password Hashing
12+
13+
- **PasswordHashingService** using Argon2id algorithm for secure password storage
14+
- 64MB memory requirement (m=65536)
15+
- 3 iterations (t=3)
16+
- Parallelism factor of 1 (p=1)
17+
- Argon2id variant for resistance to both GPU cracking attacks and side-channel attacks
18+
- Bouncy Castle provider (bcprov-jdk18on 1.78.1) for Argon2 implementation
19+
- Constant-time hash comparison to prevent timing attacks
20+
- PHC string format: `$argon2id$v=19$m=65536,t=3,p=1$[salt]$[hash]`
21+
22+
### User CRUD APIs
23+
24+
- **UserController** REST endpoints:
25+
- `GET /api/users` - List all users
26+
- `GET /api/users/{id}` - Get user by ID
27+
- `POST /api/users` - Create new user with password hashing
28+
- `PATCH /api/users/{id}` - Update user (username, email, role)
29+
- `PATCH /api/users/{id}/password` - Change user password
30+
- `DELETE /api/users/{id}` - Delete user
31+
32+
- **UserService** enhancements:
33+
- `create(user, plainPassword)` - Hash password and create user
34+
- `update(id, updates)` - Update user with change tracking
35+
- `updatePassword(id, newPlainPassword)` - Securely change password
36+
- Username and email uniqueness validation
37+
- Structured logging for all user operations (create, update, password change, delete)
38+
- Change tracking for user updates (before/after values logged)
39+
40+
- **DTOs**:
41+
- `UpdatePasswordRequest` - Password change request validation
42+
- `UpdateUserRequest` - User update with email and role validation
43+
44+
### JWT Infrastructure
45+
46+
- **JJWT library** version 0.12.6 for JWT token management
47+
- jjwt-api - JWT API
48+
- jjwt-impl - JWT implementation
49+
- jjwt-jackson - Jackson integration for JSON serialization
50+
51+
- **JwtService** for token generation and validation:
52+
- `generateAccessToken(userId, username, role)` - Create short-lived access token
53+
- `generateRefreshToken(userId)` - Create long-lived refresh token
54+
- `parseToken(token)` - Parse and validate JWT claims
55+
- `isTokenValid(token)` - Check token validity and expiration
56+
- Extract userId, username, role, and token type from tokens
57+
- Access tokens valid for 15 minutes (configurable via `jwt.access-token-validity-ms`)
58+
- Refresh tokens valid for 7 days (configurable via `jwt.refresh-token-validity-ms`)
59+
- Tokens signed with HS256 (HMAC-SHA256) algorithm
60+
- JWT secret configurable via `jwt.secret` property (MUST change in production)
61+
62+
- **Token Claims**:
63+
- `sub` (subject) - User ID
64+
- `username` - Username
65+
- `role` - User role (OWNER, ADMIN, USER, VIEWER)
66+
- `type` - Token type (access or refresh)
67+
- `iat` - Issued at timestamp
68+
- `exp` - Expiration timestamp
69+
70+
### Authentication Endpoints
71+
72+
- **AuthenticationService**:
73+
- `login(username, password)` - Authenticate user and generate tokens
74+
- `refreshToken(refreshToken)` - Generate new access token from refresh token
75+
- Password verification using PasswordHashingService
76+
- Structured logging for login attempts (success and failure)
77+
- Structured logging for token refresh operations
78+
- BadCredentialsException for invalid credentials or tokens
79+
80+
- **AuthenticationController** REST endpoints:
81+
- `POST /api/auth/login` - User login with username and password
82+
- `POST /api/auth/refresh` - Refresh access token using refresh token
83+
84+
- **DTOs**:
85+
- `LoginRequest` - Login credentials validation
86+
- `RefreshTokenRequest` - Refresh token validation
87+
- `AuthenticationResponse` - Login/refresh response with tokens and user info
88+
89+
### JWT Authentication and Authorization
90+
91+
- **JwtAuthenticationFilter**:
92+
- Extracts JWT from `Authorization: Bearer <token>` header
93+
- Validates token signature and expiration
94+
- Only accepts access tokens (rejects refresh tokens)
95+
- Populates Spring Security context with user information
96+
- Creates `UsernamePasswordAuthenticationToken` with user ID as principal
97+
- Attaches `JwtAuthenticationDetails` with userId, username, and role
98+
- Grants `ROLE_<role>` authority for role-based authorization
99+
- Silently skips authentication for invalid/expired tokens (401 returned by framework)
100+
101+
- **SecurityContextHelper** utility:
102+
- `getCurrentUserId()` - Get current authenticated user ID
103+
- `getCurrentUsername()` - Get current authenticated username
104+
- `getCurrentUserRole()` - Get current authenticated user role
105+
- `isAuthenticated()` - Check if user is authenticated
106+
- `hasRole(role)` - Check if user has specific role
107+
108+
- **SecurityConfig** enhancements:
109+
- CSRF protection disabled (stateless JWT authentication)
110+
- Stateless session management
111+
- Method-level security enabled with `@EnableMethodSecurity`
112+
- Public endpoints: `/api/auth/**`, `/api/health`, `/actuator/**`
113+
- All other `/api/**` endpoints require authentication
114+
- JWT filter registered before `UsernamePasswordAuthenticationFilter`
115+
116+
### Security Features
117+
118+
- **Role-Based Access Control**:
119+
- User roles: OWNER, ADMIN, USER, VIEWER
120+
- Spring Security authorities with `ROLE_` prefix
121+
- Method security annotations supported: `@PreAuthorize`, `@Secured`, `@RolesAllowed`
122+
123+
- **Security Logging**:
124+
- Login success and failure events
125+
- Token refresh events
126+
- User creation, updates, password changes, deletion
127+
- Failed login attempts logged with reason for security monitoring
128+
129+
## Changed
130+
131+
- **BREAKING CHANGE**: All API endpoints now require authentication except:
132+
- `/api/auth/**` - Authentication endpoints
133+
- `/api/health` - Health check endpoint
134+
- `/actuator/**` - Spring Boot Actuator endpoints
135+
136+
- **User Management**: All user operations now use Argon2id instead of BCrypt
137+
- Existing BCrypt hashes incompatible (users must reset passwords)
138+
139+
## Security Notes
140+
141+
- **Production Deployment**:
142+
- **MUST** change `jwt.secret` property in production (default is for development only)
143+
- Recommended JWT secret length: at least 256 bits (32 characters) for HS256
144+
- Consider using environment variables for secret management
145+
146+
- **Token Security**:
147+
- Access tokens are short-lived (15 minutes) to limit exposure window
148+
- Refresh tokens are long-lived (7 days) but minimal (only userId and type)
149+
- Only access tokens contain sensitive claims (username, role)
150+
- Tokens are stateless - no server-side session storage required
151+
152+
- **Password Security**:
153+
- Argon2id with 64MB memory makes brute-force attacks computationally expensive
154+
- Constant-time comparison prevents timing attack exploitation
155+
- Salt is randomly generated per password (16 bytes)
156+
- Hash output is 32 bytes
157+
158+
## Configuration
159+
160+
New configuration properties:
161+
162+
```yaml
163+
jwt:
164+
secret: "CHANGE_ME_IN_PRODUCTION_THIS_MUST_BE_AT_LEAST_256_BITS_LONG_FOR_HS256"
165+
access-token-validity-ms: 900000 # 15 minutes
166+
refresh-token-validity-ms: 604800000 # 7 days
167+
```
168+
169+
## Migration Guide
170+
171+
### For API Clients
172+
173+
All API requests (except auth endpoints) now require authentication:
174+
175+
```bash
176+
# 1. Login to get tokens
177+
curl -X POST http://localhost:8080/api/auth/login \
178+
-H "Content-Type: application/json" \
179+
-d '{"username": "admin", "password": "password"}'
180+
181+
# Response: {"accessToken": "...", "refreshToken": "...", "userId": "...", "username": "admin", "role": "ADMIN"}
182+
183+
# 2. Use access token for authenticated requests
184+
curl http://localhost:8080/api/users \
185+
-H "Authorization: Bearer <accessToken>"
186+
187+
# 3. Refresh access token when expired
188+
curl -X POST http://localhost:8080/api/auth/refresh \
189+
-H "Content-Type: application/json" \
190+
-d '{"refreshToken": "<refreshToken>"}'
191+
```
192+
193+
### For Developers
194+
195+
Access current user in Spring components:
196+
197+
```java
198+
@Service
199+
public class MyService {
200+
private final SecurityContextHelper securityHelper;
201+
202+
public void myMethod() {
203+
UUID userId = securityHelper.getCurrentUserId();
204+
String username = securityHelper.getCurrentUsername();
205+
String role = securityHelper.getCurrentUserRole();
206+
207+
if (securityHelper.hasRole("ADMIN")) {
208+
// Admin-only logic
209+
}
210+
}
211+
}
212+
```
213+
214+
Use method security annotations:
215+
216+
```java
217+
@PreAuthorize("hasRole('ADMIN')")
218+
public void adminOnlyMethod() {
219+
// Only ADMIN role can call this
220+
}
221+
222+
@PreAuthorize("hasAnyRole('ADMIN', 'OWNER')")
223+
public void privilegedMethod() {
224+
// ADMIN or OWNER can call this
225+
}
226+
```
227+
228+
## Technical Details
229+
230+
- **Dependencies**:
231+
- Spring Boot Starter Security 4.0.0
232+
- JJWT 0.12.6 (jjwt-api, jjwt-impl, jjwt-jackson)
233+
- Bouncy Castle bcprov-jdk18on 1.78.1
234+
235+
- **Database Schema**: Uses existing `users` table from v1.0.0
236+
- `password_hash` column stores Argon2id hashes in PHC format
237+
238+
- **Logging**: All authentication and user management operations logged to `system_logs` table
239+
- Categories: AUTH, API
240+
- Events: USER_CREATED, USER_UPDATED, PASSWORD_UPDATED, USER_DELETED, LOGIN_SUCCESS, LOGIN_FAILED, TOKEN_REFRESHED
241+
242+
## Included Patches
243+
244+
This milestone includes development patches v1.0.7-dev through v1.0.10-dev:
245+
246+
- **v1.0.7-dev**: User CRUD with password hashing (initially BCrypt)
247+
- **v1.0.8-dev**: JWT infrastructure (JwtService, AuthenticationService)
248+
- **v1.0.9-dev**: Switch from BCrypt to Argon2id
249+
- **v1.0.10-dev**: JWT authentication filter and authorization enforcement
250+
251+
## Known Limitations
252+
253+
- Single JWT secret for all tokens (consider key rotation in future)
254+
- No token revocation mechanism (tokens valid until expiration)
255+
- No password complexity requirements enforced (validation in future)
256+
- No rate limiting on login attempts (future enhancement)
257+
- No account lockout after failed login attempts (future enhancement)
258+
259+
## Next Steps
260+
261+
The next milestone (v1.3.0) will focus on Model Providers, implementing:
262+
- Model provider registry and configuration
263+
- Ollama provider integration
264+
- OpenAI provider integration
265+
- Anthropic provider integration
266+
- Provider health checks and fallback mechanisms

0 commit comments

Comments
 (0)