Objective
Implement a secure authentication and authorization system using JWT tokens, password hashing, role-based access control (RBAC), and middleware-protected routes.
Authentication Flow
Registration
- Client sends
POST /api/auth/register with email, password, first_name, last_name
- Server validates input (email format, password strength, uniqueness)
- Server hashes password with Argon2id
- Server creates user record with
role = 'member'
- Server sends verification email (optional, can be stubbed for v1)
- Server returns JWT access token + refresh token
Login
- Client sends
POST /api/auth/login with email and password
- Server looks up user by email
- Server verifies password hash with Argon2id
- Server checks
is_active flag
- Server updates
last_login_at
- Server returns JWT access token + refresh token
Token Refresh
- Client sends
POST /api/auth/refresh with refresh token
- Server validates refresh token signature and expiry
- Server issues new access token + refresh token
- Old refresh token is invalidated
Logout
- Client sends
POST /api/auth/logout with refresh token
- Server invalidates refresh token
- Server clears any server-side session state
JWT Implementation
Token Structure
- Access Token: Short-lived (15 minutes), contains user ID, role, email
- Refresh Token: Long-lived (7 days), stored in HTTP-only secure cookie or database
Claims
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Claims {
pub sub: Uuid, // User ID
pub email: String,
pub role: UserRole,
pub iat: i64, // Issued at
pub exp: i64, // Expiration
}
Middleware
AuthMiddleware — Extracts and validates JWT from Authorization: Bearer <token> header
RoleMiddleware — Checks if user has required role for the route
OwnerMiddleware — Verifies user owns the resource being accessed
Password Security
Hashing
- Use Argon2id with OWASP-recommended parameters:
- Memory: 64 MB
- Iterations: 3
- Parallelism: 4
- Use
argon2 crate
Validation
- Minimum 8 characters
- At least one uppercase letter
- At least one number
- At least one special character
- Check against common password breach list (optional: integrate HaveIBeenPwned API)
RBAC Implementation
Roles and Permissions
| Role |
Projects |
Items |
Comments |
Users |
Audit Logs |
| admin |
CRUD |
CRUD |
CRUD |
CRUD |
Read |
| manager |
CRUD (own) |
CRUD |
CRUD |
Read |
Read |
| member |
Read (invited) |
CRUD (assigned) |
CRUD |
Read |
None |
| viewer |
Read (invited) |
Read |
Read |
Read |
None |
Permission Checking
- Implement as Axum extractors
- Use
#[derive(FromRequest)] for CurrentUser extractor
- Check permissions at the service layer, not just the route level
API Endpoints
Authentication
POST /api/auth/register — Register new user
POST /api/auth/login — Login and get tokens
POST /api/auth/logout — Logout and invalidate tokens
POST /api/auth/refresh — Refresh access token
POST /api/auth/forgot-password — Request password reset
POST /api/auth/reset-password — Reset password with token
POST /api/auth/verify-email — Verify email address
GET /api/auth/me — Get current user profile
PUT /api/auth/me — Update current user profile
PUT /api/auth/me/password — Change password
Error Responses
pub struct AuthError {
pub code: String, // e.g., "INVALID_CREDENTIALS", "TOKEN_EXPIRED"
pub message: String, // Human-readable message
pub details: Option<serde_json::Value>,
}
Request/Response Types
Register Request
#[derive(Debug, Deserialize, Validate)]
pub struct RegisterRequest {
#[validate(email)]
pub email: String,
#[validate(length(min = 8))]
pub password: String,
#[validate(length(min = 1, max = 100))]
pub first_name: String,
#[validate(length(min = 1, max = 100))]
pub last_name: String,
}
Login Request
#[derive(Debug, Deserialize)]
pub struct LoginRequest {
pub email: String,
pub password: String,
}
Auth Response
#[derive(Debug, Serialize)]
pub struct AuthResponse {
pub user: UserResponse,
pub access_token: String,
pub refresh_token: String,
pub token_type: String, // "Bearer"
pub expires_in: i64, // seconds
}
Security Considerations
- Rate Limiting: Implement rate limiting on auth endpoints using
governor crate
- Brute Force Protection: Lock account after 5 failed attempts for 15 minutes
- Token Storage: Refresh tokens in HTTP-only, Secure, SameSite=Strict cookies
- CORS: Configure strict CORS policy for frontend origin only
- Headers: Set security headers (HSTS, X-Content-Type-Options, etc.)
- Logging: Log all auth events (login, logout, failed attempts) without sensitive data
Testing Requirements
Unit Tests
- Password hashing and verification
- JWT token generation and validation
- Claims serialization/deserialization
- Role permission checks
- Input validation
Integration Tests
- Registration flow (happy path + validation errors)
- Login flow (correct credentials + incorrect credentials)
- Token refresh flow
- Logout flow
- Protected route access with valid/invalid/expired tokens
- Role-based route access
Acceptance Criteria
Notes
- Use
tower-http for CORS, compression, and security headers
- Use
axum-extra for cookie extraction
- Consider using
jsonwebtoken crate for JWT handling
- Store refresh tokens in database for revocation capability
- Use
secrecy crate for handling sensitive data (passwords, tokens)
Objective
Implement a secure authentication and authorization system using JWT tokens, password hashing, role-based access control (RBAC), and middleware-protected routes.
Authentication Flow
Registration
POST /api/auth/registerwith email, password, first_name, last_namerole = 'member'Login
POST /api/auth/loginwith email and passwordis_activeflaglast_login_atToken Refresh
POST /api/auth/refreshwith refresh tokenLogout
POST /api/auth/logoutwith refresh tokenJWT Implementation
Token Structure
Claims
Middleware
AuthMiddleware— Extracts and validates JWT fromAuthorization: Bearer <token>headerRoleMiddleware— Checks if user has required role for the routeOwnerMiddleware— Verifies user owns the resource being accessedPassword Security
Hashing
argon2crateValidation
RBAC Implementation
Roles and Permissions
Permission Checking
#[derive(FromRequest)]forCurrentUserextractorAPI Endpoints
Authentication
Error Responses
Request/Response Types
Register Request
Login Request
Auth Response
Security Considerations
governorcrateTesting Requirements
Unit Tests
Integration Tests
Acceptance Criteria
Notes
tower-httpfor CORS, compression, and security headersaxum-extrafor cookie extractionjsonwebtokencrate for JWT handlingsecrecycrate for handling sensitive data (passwords, tokens)