β¬ οΈ Back to Controller Overview
Security Endpoints Matrix
Authorization Overview
This document maps roles to endpoints across all controllers. Use this matrix to understand who can access what.
Key Principles: - ADMIN = Full
access (creation, modification, deletion, reporting) -
USER = Read & limited write (own data, standard
operations) - PUBLIC = Unauthenticated demo mode
(read-only where @appProperties.demoReadonly) -
AUTHENTICATED = Any logged-in user (role-agnostic
operations)
Role Definitions
Full Platform Access"] AUTH --> USER["ROLE_USER
Standard Operations"] AUTH --> PUBLIC["PUBLIC
Demo Mode"] AUTH --> NONE["UNAUTHENTICATED
No Access"] ADMIN --> A1["Create/Edit/Delete"] ADMIN --> A2["Analytics Reports"] ADMIN --> A3["Audit Trails"] USER --> U1["Create/Edit Own Items"] USER --> U2["View Analytics"] USER --> U3["Read Audit Trails"] PUBLIC --> P1["Read-Only (if enabled)"] NONE --> N1["Not Accessible"] style ADMIN fill:#ffcdd2 style USER fill:#fff9c4 style PUBLIC fill:#c8e6c9 style NONE fill:#eeeeee
Supplier Controller Authorization
| Endpoint | Method | Public | USER | ADMIN | Notes |
|---|---|---|---|---|---|
/api/suppliers |
GET | β | β | β | List all suppliers (paginated) |
/api/suppliers/{id} |
GET | β | β | β | Get supplier by ID |
/api/suppliers |
POST | β | β | β | Create supplier (ADMIN only) |
/api/suppliers/{id} |
PUT | β | β | β | Update supplier (ADMIN only) |
/api/suppliers/{id} |
DELETE | β | β | β | Soft delete supplier (ADMIN only) |
/api/suppliers/count |
GET | β | β | β | Count suppliers |
/api/suppliers/search |
GET | β | β | β | Search suppliers by name |
Authorization Annotations
// READ (Public allowed in demo mode)
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")
// CREATE/UPDATE/DELETE (ADMIN only)
@PreAuthorize("hasRole('ADMIN')")Inventory Item Controller Authorization
| Endpoint | Method | Public | USER | ADMIN | Notes |
|---|---|---|---|---|---|
/api/items |
GET | β | β | β | List all items (paginated) |
/api/items/{id} |
GET | β | β | β | Get item details |
/api/items |
POST | β | β | β | Create item (ADMIN only) |
/api/items/{id} |
PUT | β | β | β | Update item (ADMIN only) |
/api/items/{id} |
DELETE | β | β | β | Soft delete item (ADMIN only) |
/api/items/{id}/update-stock |
PATCH | β | β | β | Update stock quantity (ADMIN only) |
/api/items/count |
GET | β | β | β | Count items |
/api/items/search |
GET | β | β | β | Search items by name |
Authorization Pattern
// READ operations
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")
// WRITE operations (stock updates, creation)
@PreAuthorize("hasRole('ADMIN')")Critical: Stock updates
(PATCH /api/items/{id}/update-stock) require ADMIN
role and create audit trail entries via
StockHistory.
Stock History Controller Authorization
| Endpoint | Method | Public | USER | ADMIN | Notes |
|---|---|---|---|---|---|
/api/stock-history |
GET | β | β | β | List all stock changes |
/api/stock-history/{id} |
GET | β | β | β | Get specific change entry |
/api/stock-history/by-item/{itemId} |
GET | β | β | β | Changes for one item |
/api/stock-history/by-supplier/{supplierId} |
GET | β | β | β | Changes for one supplier |
Authorization Pattern
// ALL operations (Read-only audit trail)
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")Note: Stock History is immutable read-only audit trail. No write operations exposed.
Authentication Controller Authorization
| Endpoint | Method | Public | USER | ADMIN | Notes |
|---|---|---|---|---|---|
/api/me |
GET | β | β | β | Get current user profile |
/api/logout |
POST | β | β | β | Invalidate session |
Authorization Pattern
// User profile & logout (Authenticated only)
@PreAuthorize("isAuthenticated()")OAuth2 Flow: - GET /api/me
triggers auto-authentication if not logged in - POST
/api/logout clears cookies and redirects to
home
Analytics Controller Authorization
| Endpoint | Method | Public | USER | ADMIN | Notes |
|---|---|---|---|---|---|
/api/analytics/dashboard-summary |
GET | β | β | β | KPI dashboard |
/api/analytics/financial-summary |
GET | β | β | β | P&L and inventory metrics |
/api/analytics/stock-value |
GET | β | β | β | Time series data |
/api/analytics/stock-per-supplier |
GET | β | β | β | Supplier distribution |
/api/analytics/trends/price |
GET | β | β | β | Price trends over time |
/api/analytics/trends/monthly-movement |
GET | β | β | β | Monthly activity |
/api/analytics/low-stock-items |
GET | β | β | β | Items below reorder level |
/api/analytics/update-frequency |
GET | β | β | β | Item activity analysis |
Authorization Pattern
// All analytics endpoints (Read-only)
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")Feature: Analytics are safe for public demo mode (no sensitive data mutation).
Consolidated Access Matrix
ββββββββββββββββββββββββββββββββββββ¦ββββββββ¦βββββββ¦ββββββββ
β Controller Group β PUBLICβ USER β ADMIN β
β βββββββββββββββββββββββββββββββββββ¬ββββββββ¬βββββββ¬ββββββββ£
β SUPPLIER - List/Get β β
β β
β β
β
β SUPPLIER - Create/Update/Delete β β β β β β
β
β INVENTORY - List/Get β β
β β
β β
β
β INVENTORY - Create/Update/Delete β β β β β β
β
β INVENTORY - Update Stock β β β β β β
β
β STOCK HISTORY - All β β
β β
β β
β
β ANALYTICS - All β β
β β
β β
β
β AUTH - Get Profile/Logout β β β β
β β
β
ββββββββββββββββββββββββββββββββββββ©ββββββββ©βββββββ©ββββββββ
Demo Mode Behavior
When appProperties.demoReadonly = true:
// Public reads allowed
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")
// Actual behavior:
if (demoReadonly) {
// β
GET requests β Allowed
// β POST/PUT/PATCH/DELETE β Blocked (throws DemoModeException)
}Use Cases: - Public dashboards (analytics) - Preview environments - Sandboxes for training
Security Validation Checklist
Before deploying:
β ADMIN roles assigned only to trusted users (via APP_ADMIN_EMAILS)
β OAuth2 configured (ClientId, ClientSecret in environment)
β HTTPS enabled in production (secure cookies)
β Session timeout configured (15β30 minutes)
β CSRF protection enabled (Spring Security default)
β Demo mode disabled in production (@appProperties.demoReadonly = false)
β Audit logging enabled (StockHistory captures all writes)
β Rate limiting configured (if using Spring Cloud)
Role Assignment Logic
ADMIN Role Assignment
// From AuthController.java
if (APP_ADMIN_EMAILS.contains(user.getEmail())) {
grantRole("ROLE_ADMIN");
// Full platform access
} else {
grantRole("ROLE_USER");
// Read + limited write access
}Configuration: Set via environment variable:
APP_ADMIN_EMAILS=admin@company.com,ops@company.com
Summary
| Role | Access Level | Typical Users | Use Case |
|---|---|---|---|
| PUBLIC | Read-only | Unauthenticated demo visitors | Dashboards, demo environments |
| USER | Read + Limited Write | Employees, staff | Daily operations, item viewing |
| ADMIN | Full CRUD | Managers, ops team | System configuration, creation, deletion |
Default: Users logged in via OAuth2 get
ROLE_USER. Admins require email in
APP_ADMIN_EMAILS.