queen-mq 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +862 -752
- package/AUTH.md +2044 -0
- package/LICENSE.md +202 -0
- package/README.md +1705 -1051
- package/WEBAPP.md +1889 -0
- package/assets/dashboard-01.png +0 -0
- package/assets/queen-logo-blue.svg +210 -0
- package/assets/queen-logo-cyan.svg +210 -0
- package/assets/queen-logo-indigo.svg +210 -0
- package/assets/queen-logo-orange.svg +210 -0
- package/assets/queen-logo-pink.svg +210 -0
- package/assets/queen-logo-purple.svg +210 -0
- package/assets/queen-logo-rose.svg +239 -0
- package/assets/queen-logo.svg +263 -0
- package/examples/batch-processing.js +58 -0
- package/examples/test-complete-client.js +260 -0
- package/examples/test-dashboard-api.js +200 -0
- package/examples/test-traceid.js +147 -0
- package/package.json +17 -4
- package/server.log +1 -0
- package/src/benchmark/consumer.js +207 -0
- package/src/benchmark/consumer_multi.js +216 -0
- package/src/benchmark/producer.js +75 -0
- package/src/benchmark/producer_multi.js +115 -0
- package/src/client/client.js +300 -31
- package/src/client/queenClient.js +5 -0
- package/src/cluster-server.js +242 -0
- package/src/config.js +19 -5
- package/src/database/connection.js +42 -16
- package/src/database/poolManager.js +7 -0
- package/src/database/schema-v2.sql +194 -130
- package/src/managers/queueManagerOptimized.js +823 -933
- package/src/managers/systemEventManager.js +8 -3
- package/src/routes/messages.js +127 -57
- package/src/routes/pop.js +27 -43
- package/src/routes/resources.js +61 -27
- package/src/routes/status.js +1037 -0
- package/src/server.js +308 -272
- package/src/services/evictionService.js +57 -28
- package/src/services/retentionService.js +44 -11
- package/src/test/MIGRATION_ISSUES.md +174 -0
- package/src/test/README.md +203 -0
- package/src/test/advanced-pattern-tests.js +1137 -0
- package/src/test/bus-mode-tests.js +361 -0
- package/src/test/core-tests.js +342 -0
- package/src/test/edge-case-tests.js +561 -0
- package/src/test/enterprise-tests.js +637 -0
- package/src/test/partition-locking-tests.js +545 -0
- package/src/test/test-new.js +278 -0
- package/src/test/test.js +6 -3
- package/src/test/utils.js +169 -0
- package/src/utils/streaming.js +231 -0
- package/src/utils/uuid.js +2 -2
- package/src/websocket/wsServer.js +10 -3
- package/test-keepalive-v2.sh +22 -0
- package/webapp/COLOR_GUIDE.md +118 -0
- package/webapp/README.md +143 -0
- package/webapp/index.html +14 -0
- package/webapp/package-lock.json +3184 -0
- package/webapp/package.json +25 -0
- package/webapp/postcss.config.js +7 -0
- package/webapp/public/assets/queen-logo-blue.svg +210 -0
- package/webapp/public/assets/queen-logo-cyan.svg +210 -0
- package/webapp/public/assets/queen-logo-indigo.svg +210 -0
- package/webapp/public/assets/queen-logo-orange.svg +210 -0
- package/webapp/public/assets/queen-logo-pink.svg +210 -0
- package/webapp/public/assets/queen-logo-purple.svg +210 -0
- package/webapp/public/assets/queen-logo-rose.svg +239 -0
- package/webapp/public/assets/queen-logo.svg +263 -0
- package/webapp/src/App.vue +19 -0
- package/webapp/src/api/analytics.js +10 -0
- package/webapp/src/api/client.js +29 -0
- package/webapp/src/api/consumers.js +52 -0
- package/webapp/src/api/health.js +7 -0
- package/webapp/src/api/messages.js +26 -0
- package/webapp/src/api/queues.js +14 -0
- package/webapp/src/api/resources.js +8 -0
- package/webapp/src/assets/styles/main.css +357 -0
- package/webapp/src/components/analytics/AnalyticsFilters.vue +87 -0
- package/webapp/src/components/analytics/AnalyticsMetrics.vue +57 -0
- package/webapp/src/components/analytics/MessageDistributionChart.vue +111 -0
- package/webapp/src/components/analytics/MessageFlowChart.vue +173 -0
- package/webapp/src/components/analytics/TimeRangeSelector.vue +27 -0
- package/webapp/src/components/analytics/TopQueuesChart.vue +132 -0
- package/webapp/src/components/common/ConfirmDialog.vue +56 -0
- package/webapp/src/components/common/LoadingSpinner.vue +6 -0
- package/webapp/src/components/common/MetricCard.vue +43 -0
- package/webapp/src/components/common/StatusBadge.vue +45 -0
- package/webapp/src/components/dashboard/MessageStatusCard.vue +50 -0
- package/webapp/src/components/dashboard/PerformanceCard.vue +38 -0
- package/webapp/src/components/dashboard/ThroughputChart.vue +182 -0
- package/webapp/src/components/dashboard/TopQueuesTable.vue +53 -0
- package/webapp/src/components/layout/AppLayout.vue +110 -0
- package/webapp/src/components/layout/AppSidebar.vue +304 -0
- package/webapp/src/components/messages/MessageDetailPanel.vue +242 -0
- package/webapp/src/components/messages/MessageFilters.vue +114 -0
- package/webapp/src/components/queue-detail/PartitionList.vue +79 -0
- package/webapp/src/components/queue-detail/PushMessageModal.vue +175 -0
- package/webapp/src/components/queue-detail/QueueConfig.vue +63 -0
- package/webapp/src/components/queue-detail/QueueDetailHeader.vue +53 -0
- package/webapp/src/components/queue-detail/RecentMessages.vue +76 -0
- package/webapp/src/components/queues/CreateQueueModal.vue +193 -0
- package/webapp/src/components/queues/QueueFilters.vue +90 -0
- package/webapp/src/composables/useApi.js +34 -0
- package/webapp/src/composables/useTheme.js +36 -0
- package/webapp/src/main.js +11 -0
- package/webapp/src/router/index.js +42 -0
- package/webapp/src/utils/colors.js +96 -0
- package/webapp/src/utils/formatters.js +49 -0
- package/webapp/src/views/Analytics.vue +377 -0
- package/webapp/src/views/ConsumerGroups.vue +433 -0
- package/webapp/src/views/Dashboard.vue +418 -0
- package/webapp/src/views/Messages.vue +361 -0
- package/webapp/src/views/QueueDetail.vue +582 -0
- package/webapp/src/views/Queues.vue +496 -0
- package/webapp/tailwind.config.js +25 -0
- package/webapp/vite.config.js +10 -0
- package/CACHE.md +0 -519
- package/DASHBOARD-V3.md +0 -478
- package/DASHBOARD.md +0 -382
- package/MOD_QUEUE.md +0 -453
- package/PARTITION_LOCKING_DESIGN.md +0 -989
- package/PLAN.md +0 -707
- package/QUERY_ANALSYS.md +0 -72
- package/QUEUE_BUS.md +0 -334
- package/V2-PLAN.md +0 -236
- package/dashboard/.vscode/extensions.json +0 -3
- package/dashboard/README.md +0 -5
- package/dashboard/index.html +0 -14
- package/dashboard/package-lock.json +0 -1458
- package/dashboard/package.json +0 -25
- package/dashboard/public/vite.svg +0 -1
- package/dashboard/src/App.vue +0 -29
- package/dashboard/src/assets/styles/main.css +0 -908
- package/dashboard/src/assets/vue.svg +0 -1
- package/dashboard/src/components/cards/MetricCard.vue +0 -298
- package/dashboard/src/components/charts/QueueDepthChart.vue +0 -276
- package/dashboard/src/components/charts/QueueLagChart.vue +0 -436
- package/dashboard/src/components/charts/ThroughputChart.vue +0 -302
- package/dashboard/src/components/common/ActivityFeed.vue +0 -251
- package/dashboard/src/components/layout/AppHeader.vue +0 -208
- package/dashboard/src/components/layout/AppLayout.vue +0 -88
- package/dashboard/src/components/layout/AppSidebar.vue +0 -261
- package/dashboard/src/main.js +0 -44
- package/dashboard/src/router.js +0 -54
- package/dashboard/src/services/api.js +0 -187
- package/dashboard/src/services/websocket.js +0 -167
- package/dashboard/src/utils/constants.js +0 -56
- package/dashboard/src/utils/helpers.js +0 -118
- package/dashboard/src/views/Analytics.vue +0 -912
- package/dashboard/src/views/Dashboard.vue +0 -906
- package/dashboard/src/views/Messages.vue +0 -437
- package/dashboard/src/views/QueueDetail.vue +0 -501
- package/dashboard/src/views/Queues.vue +0 -333
- package/dashboard/vite.config.js +0 -30
- package/debug-namespace.js +0 -110
- package/docs/long-polling.md +0 -159
- package/docs/multi-server-cache-solutions.md +0 -185
- package/docs/performance-tuning.md +0 -222
- package/src/routes/analytics.js +0 -812
package/AUTH.md
ADDED
|
@@ -0,0 +1,2044 @@
|
|
|
1
|
+
# Authentication System for Queen
|
|
2
|
+
|
|
3
|
+
**Status:** Planning Phase
|
|
4
|
+
**Version:** 1.0
|
|
5
|
+
**Last Updated:** October 13, 2025
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Overview](#overview)
|
|
12
|
+
- [Architecture](#architecture)
|
|
13
|
+
- [Database Schema](#database-schema)
|
|
14
|
+
- [Token Types](#token-types)
|
|
15
|
+
- [Role-Based Access Control](#role-based-access-control)
|
|
16
|
+
- [Authentication Flows](#authentication-flows)
|
|
17
|
+
- [API Endpoints](#api-endpoints)
|
|
18
|
+
- [CLI Tool](#cli-tool)
|
|
19
|
+
- [Configuration](#configuration)
|
|
20
|
+
- [Security Considerations](#security-considerations)
|
|
21
|
+
- [Implementation Roadmap](#implementation-roadmap)
|
|
22
|
+
- [Future Enhancements](#future-enhancements)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Overview
|
|
27
|
+
|
|
28
|
+
Queen's authentication system is designed to be:
|
|
29
|
+
|
|
30
|
+
- **Optional:** Disabled by default (`QUEEN_AUTH_ENABLED=false`)
|
|
31
|
+
- **Backward Compatible:** Existing deployments continue to work without changes
|
|
32
|
+
- **Zero Overhead:** No performance impact when disabled
|
|
33
|
+
- **Token-Based:** Stateless authentication using JWT and service tokens
|
|
34
|
+
- **Role-Based:** Three roles with clear permission boundaries
|
|
35
|
+
- **Flexible:** Support for both microservices and human users
|
|
36
|
+
|
|
37
|
+
### Design Principles
|
|
38
|
+
|
|
39
|
+
1. **Security First:** Industry-standard encryption, hashing, and token management
|
|
40
|
+
2. **Developer-Friendly:** Simple CLI tools for token generation and user management
|
|
41
|
+
3. **Production-Ready:** Audit logging, token revocation, and monitoring
|
|
42
|
+
4. **Scalable:** Stateless design works across multiple Queen server instances
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Architecture
|
|
47
|
+
|
|
48
|
+
### Request Flow
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Client Request
|
|
52
|
+
↓
|
|
53
|
+
[CORS Middleware]
|
|
54
|
+
↓
|
|
55
|
+
[Auth Middleware] ← Checks QUEEN_AUTH_ENABLED
|
|
56
|
+
├─ Extract token from Authorization header
|
|
57
|
+
├─ Identify token type (service token vs JWT)
|
|
58
|
+
├─ Validate token signature/hash
|
|
59
|
+
├─ Check expiration (if applicable)
|
|
60
|
+
├─ Load permissions from database
|
|
61
|
+
├─ Attach auth context to request
|
|
62
|
+
↓
|
|
63
|
+
[Permission Middleware]
|
|
64
|
+
├─ Check role-based permissions
|
|
65
|
+
├─ Check queue-level access (if restricted)
|
|
66
|
+
├─ Check operation-level access (if restricted)
|
|
67
|
+
↓
|
|
68
|
+
[Route Handler]
|
|
69
|
+
↓
|
|
70
|
+
[Audit Logging] ← Log auth events
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Component Structure
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
src/
|
|
77
|
+
auth/
|
|
78
|
+
middleware.js # Auth middleware for request validation
|
|
79
|
+
permissions.js # Permission checking logic
|
|
80
|
+
tokens.js # Token generation, validation, hashing
|
|
81
|
+
jwt.js # JWT utilities (sign, verify)
|
|
82
|
+
passwords.js # Password hashing (bcrypt)
|
|
83
|
+
audit.js # Audit logging functions
|
|
84
|
+
routes/
|
|
85
|
+
auth.js # Auth endpoints (login, refresh, logout)
|
|
86
|
+
users.js # User management endpoints (admin only)
|
|
87
|
+
tokens.js # Service token management endpoints (admin only)
|
|
88
|
+
cli/
|
|
89
|
+
auth.js # CLI tool for auth management
|
|
90
|
+
database/
|
|
91
|
+
auth-schema.sql # Auth tables schema
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Database Schema
|
|
97
|
+
|
|
98
|
+
### Tables
|
|
99
|
+
|
|
100
|
+
#### 1. `queen.auth_users`
|
|
101
|
+
|
|
102
|
+
User accounts for dashboard access and CLI operations.
|
|
103
|
+
|
|
104
|
+
```sql
|
|
105
|
+
CREATE TABLE queen.auth_users (
|
|
106
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
107
|
+
username VARCHAR(255) UNIQUE NOT NULL,
|
|
108
|
+
email VARCHAR(255) UNIQUE,
|
|
109
|
+
password_hash TEXT NOT NULL, -- bcrypt hash
|
|
110
|
+
role VARCHAR(50) NOT NULL CHECK (role IN ('admin', 'rw', 'read')),
|
|
111
|
+
enabled BOOLEAN DEFAULT true,
|
|
112
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
113
|
+
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
114
|
+
last_login_at TIMESTAMPTZ,
|
|
115
|
+
created_by UUID REFERENCES queen.auth_users(id),
|
|
116
|
+
|
|
117
|
+
CONSTRAINT username_not_empty CHECK (length(username) > 0)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
CREATE INDEX idx_auth_users_username ON queen.auth_users(username);
|
|
121
|
+
CREATE INDEX idx_auth_users_role ON queen.auth_users(role);
|
|
122
|
+
CREATE INDEX idx_auth_users_enabled ON queen.auth_users(enabled) WHERE enabled = true;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### 2. `queen.auth_service_tokens`
|
|
126
|
+
|
|
127
|
+
Long-lived tokens for microservices and automated systems.
|
|
128
|
+
|
|
129
|
+
```sql
|
|
130
|
+
CREATE TABLE queen.auth_service_tokens (
|
|
131
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
132
|
+
name VARCHAR(255) NOT NULL, -- Descriptive name: "payment-service", "analytics-worker"
|
|
133
|
+
token_hash TEXT UNIQUE NOT NULL, -- SHA-256 hash of the token
|
|
134
|
+
role VARCHAR(50) NOT NULL CHECK (role IN ('admin', 'rw', 'read')),
|
|
135
|
+
|
|
136
|
+
-- Queue-level access control
|
|
137
|
+
allowed_queues JSONB DEFAULT NULL, -- null = all queues ("*"), or ["orders", "payments"]
|
|
138
|
+
|
|
139
|
+
-- Operation-level access control (optional fine-grained control)
|
|
140
|
+
allowed_operations JSONB DEFAULT NULL, -- null = all operations based on role, or ["push", "pop"]
|
|
141
|
+
|
|
142
|
+
enabled BOOLEAN DEFAULT true,
|
|
143
|
+
expires_at TIMESTAMPTZ DEFAULT NULL, -- NULL = never expires
|
|
144
|
+
|
|
145
|
+
created_by UUID REFERENCES queen.auth_users(id),
|
|
146
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
147
|
+
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
148
|
+
last_used_at TIMESTAMPTZ,
|
|
149
|
+
|
|
150
|
+
CONSTRAINT name_not_empty CHECK (length(name) > 0)
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
CREATE INDEX idx_auth_service_tokens_hash ON queen.auth_service_tokens(token_hash);
|
|
154
|
+
CREATE INDEX idx_auth_service_tokens_enabled ON queen.auth_service_tokens(enabled) WHERE enabled = true;
|
|
155
|
+
CREATE INDEX idx_auth_service_tokens_expires ON queen.auth_service_tokens(expires_at) WHERE expires_at IS NOT NULL;
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### 3. `queen.auth_refresh_tokens`
|
|
159
|
+
|
|
160
|
+
Refresh tokens for user sessions (dashboard, CLI).
|
|
161
|
+
|
|
162
|
+
```sql
|
|
163
|
+
CREATE TABLE queen.auth_refresh_tokens (
|
|
164
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
165
|
+
user_id UUID REFERENCES queen.auth_users(id) ON DELETE CASCADE,
|
|
166
|
+
token_hash TEXT UNIQUE NOT NULL, -- SHA-256 hash
|
|
167
|
+
expires_at TIMESTAMPTZ NOT NULL,
|
|
168
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
169
|
+
revoked_at TIMESTAMPTZ DEFAULT NULL,
|
|
170
|
+
revoked_by UUID REFERENCES queen.auth_users(id),
|
|
171
|
+
revoke_reason TEXT,
|
|
172
|
+
|
|
173
|
+
-- Session tracking
|
|
174
|
+
ip_address VARCHAR(45),
|
|
175
|
+
user_agent TEXT
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
CREATE INDEX idx_auth_refresh_tokens_user ON queen.auth_refresh_tokens(user_id);
|
|
179
|
+
CREATE INDEX idx_auth_refresh_tokens_hash ON queen.auth_refresh_tokens(token_hash);
|
|
180
|
+
CREATE INDEX idx_auth_refresh_tokens_expires ON queen.auth_refresh_tokens(expires_at);
|
|
181
|
+
CREATE INDEX idx_auth_refresh_tokens_active ON queen.auth_refresh_tokens(user_id, revoked_at)
|
|
182
|
+
WHERE revoked_at IS NULL;
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### 4. `queen.auth_audit_log`
|
|
186
|
+
|
|
187
|
+
Comprehensive audit trail for security and compliance.
|
|
188
|
+
|
|
189
|
+
```sql
|
|
190
|
+
CREATE TABLE queen.auth_audit_log (
|
|
191
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
192
|
+
|
|
193
|
+
-- Actor (who performed the action)
|
|
194
|
+
user_id UUID REFERENCES queen.auth_users(id),
|
|
195
|
+
service_token_id UUID REFERENCES queen.auth_service_tokens(id),
|
|
196
|
+
|
|
197
|
+
-- Event details
|
|
198
|
+
event_type VARCHAR(50) NOT NULL, -- 'login', 'logout', 'token_created', 'unauthorized_access', etc.
|
|
199
|
+
resource_type VARCHAR(50), -- 'user', 'token', 'queue', 'message'
|
|
200
|
+
resource_id VARCHAR(255),
|
|
201
|
+
|
|
202
|
+
-- Request context
|
|
203
|
+
ip_address VARCHAR(45),
|
|
204
|
+
user_agent TEXT,
|
|
205
|
+
endpoint VARCHAR(255),
|
|
206
|
+
http_method VARCHAR(10),
|
|
207
|
+
|
|
208
|
+
-- Result
|
|
209
|
+
success BOOLEAN NOT NULL,
|
|
210
|
+
error_message TEXT,
|
|
211
|
+
|
|
212
|
+
-- Additional context
|
|
213
|
+
details JSONB,
|
|
214
|
+
|
|
215
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
CREATE INDEX idx_auth_audit_log_user ON queen.auth_audit_log(user_id);
|
|
219
|
+
CREATE INDEX idx_auth_audit_log_service_token ON queen.auth_audit_log(service_token_id);
|
|
220
|
+
CREATE INDEX idx_auth_audit_log_event_type ON queen.auth_audit_log(event_type);
|
|
221
|
+
CREATE INDEX idx_auth_audit_log_created_at ON queen.auth_audit_log(created_at DESC);
|
|
222
|
+
CREATE INDEX idx_auth_audit_log_success ON queen.auth_audit_log(success) WHERE success = false;
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Token Types
|
|
228
|
+
|
|
229
|
+
### 1. Service Tokens (Long-Lived)
|
|
230
|
+
|
|
231
|
+
**Purpose:** Microservices, workers, automated systems
|
|
232
|
+
|
|
233
|
+
**Format:**
|
|
234
|
+
```
|
|
235
|
+
qn_svc_<base58_encoded_32_bytes>
|
|
236
|
+
|
|
237
|
+
Example:
|
|
238
|
+
qn_svc_8K7jQm3pN2xR5wV9yB4cE6fH8jL1mN3qT5uW7xZ9a
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Properties:**
|
|
242
|
+
- Long-lived or never expires (configurable)
|
|
243
|
+
- Stored as SHA-256 hash in database
|
|
244
|
+
- Can be scoped to specific queues
|
|
245
|
+
- Can be scoped to specific operations
|
|
246
|
+
- No refresh mechanism (regenerate if compromised)
|
|
247
|
+
|
|
248
|
+
**Storage:**
|
|
249
|
+
```javascript
|
|
250
|
+
{
|
|
251
|
+
id: "uuid",
|
|
252
|
+
name: "payment-service",
|
|
253
|
+
token_hash: "sha256_hash_of_actual_token",
|
|
254
|
+
role: "rw",
|
|
255
|
+
allowed_queues: null, // "*" = all queues
|
|
256
|
+
allowed_operations: null, // null = all operations based on role
|
|
257
|
+
expires_at: null // never expires
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Queue Access Examples:**
|
|
262
|
+
- `allowed_queues: null` → Access to all queues ("*")
|
|
263
|
+
- `allowed_queues: ["orders", "payments"]` → Only these queues
|
|
264
|
+
- `allowed_queues: ["orders/*"]` → All partitions in orders queue (future enhancement)
|
|
265
|
+
|
|
266
|
+
### 2. JWT Access Tokens (Short-Lived)
|
|
267
|
+
|
|
268
|
+
**Purpose:** Dashboard users, CLI users (short-term access)
|
|
269
|
+
|
|
270
|
+
**Format:** Standard JWT
|
|
271
|
+
```
|
|
272
|
+
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLXV1aWQiLCJ1c2VybmFtZSI6ImFsaWNlIiwicm9sZSI6ImFkbWluIiwidHlwZSI6ImFjY2VzcyIsImlhdCI6MTY5NzE5MzYwMCwiZXhwIjoxNjk3MTk0NTAwfQ.signature
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Payload:**
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"sub": "user-uuid",
|
|
279
|
+
"username": "alice",
|
|
280
|
+
"role": "admin",
|
|
281
|
+
"type": "access",
|
|
282
|
+
"iat": 1697193600,
|
|
283
|
+
"exp": 1697194500
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Properties:**
|
|
288
|
+
- Short-lived (15 minutes default)
|
|
289
|
+
- Stateless (no database lookup required)
|
|
290
|
+
- Verified via JWT signature
|
|
291
|
+
- No revocation (use short expiration instead)
|
|
292
|
+
|
|
293
|
+
### 3. JWT Refresh Tokens (Medium-Lived)
|
|
294
|
+
|
|
295
|
+
**Purpose:** Renew access tokens without re-authentication
|
|
296
|
+
|
|
297
|
+
**Format:** Standard JWT
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"sub": "user-uuid",
|
|
301
|
+
"type": "refresh",
|
|
302
|
+
"jti": "refresh-token-uuid",
|
|
303
|
+
"iat": 1697193600,
|
|
304
|
+
"exp": 1697798400
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Properties:**
|
|
309
|
+
- Medium-lived (7 days default)
|
|
310
|
+
- Stored as hash in `auth_refresh_tokens` table
|
|
311
|
+
- Can be revoked (logout, security breach)
|
|
312
|
+
- Single-use (rotate on each refresh)
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Role-Based Access Control
|
|
317
|
+
|
|
318
|
+
### Roles
|
|
319
|
+
|
|
320
|
+
| Role | Description | Primary Use Case |
|
|
321
|
+
|------|-------------|------------------|
|
|
322
|
+
| `admin` | Full system access | System administrators, DevOps |
|
|
323
|
+
| `rw` | Read-write access + queue configuration | Microservices, workers, producers/consumers |
|
|
324
|
+
| `read` | Read-only access | Monitoring, analytics, observability |
|
|
325
|
+
|
|
326
|
+
### Permission Matrix
|
|
327
|
+
|
|
328
|
+
| Operation | admin | rw | read |
|
|
329
|
+
|-----------|-------|----|----- |
|
|
330
|
+
| **Queue Operations** | | | |
|
|
331
|
+
| Configure queue | ✅ | ✅ | ❌ |
|
|
332
|
+
| Delete queue | ✅ | ❌ | ❌ |
|
|
333
|
+
| **Message Operations** | | | |
|
|
334
|
+
| Push message | ✅ | ✅ | ❌ |
|
|
335
|
+
| Pop message | ✅ | ✅ | ❌ |
|
|
336
|
+
| Acknowledge message | ✅ | ✅ | ❌ |
|
|
337
|
+
| Delete message | ✅ | ❌ | ❌ |
|
|
338
|
+
| Browse messages | ✅ | ✅ | ✅ |
|
|
339
|
+
| Retry message | ✅ | ✅ | ❌ |
|
|
340
|
+
| **Analytics** | | | |
|
|
341
|
+
| View queue stats | ✅ | ✅ | ✅ |
|
|
342
|
+
| View throughput | ✅ | ✅ | ✅ |
|
|
343
|
+
| View system health | ✅ | ✅ | ✅ |
|
|
344
|
+
| **Auth Management** | | | |
|
|
345
|
+
| Manage users | ✅ | ❌ | ❌ |
|
|
346
|
+
| Manage service tokens | ✅ | ❌ | ❌ |
|
|
347
|
+
| View audit logs | ✅ | ❌ | ❌ |
|
|
348
|
+
|
|
349
|
+
### Permission Identifiers
|
|
350
|
+
|
|
351
|
+
```javascript
|
|
352
|
+
const PERMISSIONS = {
|
|
353
|
+
// Queue permissions
|
|
354
|
+
'queue:configure': ['admin', 'rw'],
|
|
355
|
+
'queue:delete': ['admin'],
|
|
356
|
+
'queue:view': ['admin', 'rw', 'read'],
|
|
357
|
+
|
|
358
|
+
// Message permissions
|
|
359
|
+
'message:push': ['admin', 'rw'],
|
|
360
|
+
'message:pop': ['admin', 'rw'],
|
|
361
|
+
'message:ack': ['admin', 'rw'],
|
|
362
|
+
'message:delete': ['admin'],
|
|
363
|
+
'message:browse': ['admin', 'rw', 'read'],
|
|
364
|
+
'message:retry': ['admin', 'rw'],
|
|
365
|
+
|
|
366
|
+
// Analytics permissions
|
|
367
|
+
'analytics:read': ['admin', 'rw', 'read'],
|
|
368
|
+
|
|
369
|
+
// System permissions
|
|
370
|
+
'system:health': ['admin', 'rw', 'read'],
|
|
371
|
+
'system:metrics': ['admin', 'rw', 'read'],
|
|
372
|
+
|
|
373
|
+
// Auth permissions
|
|
374
|
+
'auth:manage_users': ['admin'],
|
|
375
|
+
'auth:manage_tokens': ['admin'],
|
|
376
|
+
'auth:view_audit': ['admin']
|
|
377
|
+
};
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Queue-Level Access Control
|
|
381
|
+
|
|
382
|
+
Service tokens can be restricted to specific queues:
|
|
383
|
+
|
|
384
|
+
**Examples:**
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
// Full access to all queues
|
|
388
|
+
{
|
|
389
|
+
name: "payment-service",
|
|
390
|
+
role: "rw",
|
|
391
|
+
allowed_queues: null // or ["*"]
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Access only to specific queues
|
|
395
|
+
{
|
|
396
|
+
name: "analytics-worker",
|
|
397
|
+
role: "rw",
|
|
398
|
+
allowed_queues: ["events", "analytics", "metrics"]
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Read-only access to all queues
|
|
402
|
+
{
|
|
403
|
+
name: "monitoring-service",
|
|
404
|
+
role: "read",
|
|
405
|
+
allowed_queues: null // "*"
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**Validation Logic:**
|
|
410
|
+
```
|
|
411
|
+
if (token.allowed_queues === null || token.allowed_queues.includes("*")) {
|
|
412
|
+
// Access to all queues
|
|
413
|
+
return true;
|
|
414
|
+
} else if (token.allowed_queues.includes(requestedQueue)) {
|
|
415
|
+
// Access granted
|
|
416
|
+
return true;
|
|
417
|
+
} else {
|
|
418
|
+
// Access denied
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Authentication Flows
|
|
426
|
+
|
|
427
|
+
### Flow 1: Service Token Authentication
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
Microservice Queen Server
|
|
431
|
+
| |
|
|
432
|
+
| POST /api/v1/push |
|
|
433
|
+
| Authorization: Bearer qn_svc_...|
|
|
434
|
+
|----------------------------------->
|
|
435
|
+
| |
|
|
436
|
+
| [Validate Token] |
|
|
437
|
+
| 1. Extract token |
|
|
438
|
+
| 2. Hash with SHA-256 |
|
|
439
|
+
| 3. Look up in DB |
|
|
440
|
+
| 4. Check enabled & expiration|
|
|
441
|
+
| 5. Load role & permissions |
|
|
442
|
+
| 6. Check queue access |
|
|
443
|
+
| |
|
|
444
|
+
| 200 OK |
|
|
445
|
+
| { messages: [...] } |
|
|
446
|
+
|<-----------------------------------
|
|
447
|
+
| |
|
|
448
|
+
| [Update last_used_at] |
|
|
449
|
+
| [Log audit event] |
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Flow 2: User Login (Dashboard/CLI)
|
|
453
|
+
|
|
454
|
+
```
|
|
455
|
+
User/CLI Queen Server Database
|
|
456
|
+
| | |
|
|
457
|
+
| POST /api/v1/auth/login | |
|
|
458
|
+
| { username, password } | |
|
|
459
|
+
|-----------------------------------> |
|
|
460
|
+
| | |
|
|
461
|
+
| [Authenticate] |
|
|
462
|
+
| | SELECT * FROM users |
|
|
463
|
+
| | WHERE username = ? |
|
|
464
|
+
| |------------------------->|
|
|
465
|
+
| | { user } |
|
|
466
|
+
| |<-------------------------|
|
|
467
|
+
| | |
|
|
468
|
+
| [Verify bcrypt] |
|
|
469
|
+
| [Generate tokens] |
|
|
470
|
+
| | INSERT refresh_token |
|
|
471
|
+
| |------------------------->|
|
|
472
|
+
| | |
|
|
473
|
+
| 200 OK | |
|
|
474
|
+
| { accessToken, refreshToken } | |
|
|
475
|
+
|<----------------------------------- |
|
|
476
|
+
| | |
|
|
477
|
+
| [Store tokens] | [Log audit event] |
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Flow 3: Token Refresh
|
|
481
|
+
|
|
482
|
+
```
|
|
483
|
+
User/CLI Queen Server Database
|
|
484
|
+
| | |
|
|
485
|
+
| POST /api/v1/auth/refresh | |
|
|
486
|
+
| { refreshToken } | |
|
|
487
|
+
|-----------------------------------> |
|
|
488
|
+
| | |
|
|
489
|
+
| [Validate JWT] |
|
|
490
|
+
| | SELECT * FROM refresh |
|
|
491
|
+
| | WHERE hash = ? AND |
|
|
492
|
+
| | revoked_at IS NULL |
|
|
493
|
+
| |------------------------->|
|
|
494
|
+
| | { refresh_token } |
|
|
495
|
+
| |<-------------------------|
|
|
496
|
+
| | |
|
|
497
|
+
| [Generate new access token] |
|
|
498
|
+
| [Rotate refresh token] |
|
|
499
|
+
| | UPDATE old token |
|
|
500
|
+
| | INSERT new token |
|
|
501
|
+
| |------------------------->|
|
|
502
|
+
| | |
|
|
503
|
+
| 200 OK | |
|
|
504
|
+
| { accessToken, refreshToken } | |
|
|
505
|
+
|<----------------------------------- |
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Flow 4: Logout
|
|
509
|
+
|
|
510
|
+
```
|
|
511
|
+
User/CLI Queen Server Database
|
|
512
|
+
| | |
|
|
513
|
+
| POST /api/v1/auth/logout | |
|
|
514
|
+
| Authorization: Bearer <jwt> | |
|
|
515
|
+
| { refreshToken } | |
|
|
516
|
+
|-----------------------------------> |
|
|
517
|
+
| | |
|
|
518
|
+
| [Validate JWT] |
|
|
519
|
+
| | UPDATE refresh_tokens |
|
|
520
|
+
| | SET revoked_at = NOW() |
|
|
521
|
+
| | WHERE hash = ? |
|
|
522
|
+
| |------------------------->|
|
|
523
|
+
| | |
|
|
524
|
+
| 200 OK | |
|
|
525
|
+
| { message: "Logged out" } | |
|
|
526
|
+
|<----------------------------------- |
|
|
527
|
+
| | [Log audit event] |
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## API Endpoints
|
|
533
|
+
|
|
534
|
+
### Authentication Endpoints
|
|
535
|
+
|
|
536
|
+
#### POST `/api/v1/auth/login`
|
|
537
|
+
|
|
538
|
+
User login with username/password.
|
|
539
|
+
|
|
540
|
+
**Request:**
|
|
541
|
+
```json
|
|
542
|
+
{
|
|
543
|
+
"username": "alice",
|
|
544
|
+
"password": "secret123"
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Response:**
|
|
549
|
+
```json
|
|
550
|
+
{
|
|
551
|
+
"accessToken": "eyJhbGc...",
|
|
552
|
+
"refreshToken": "eyJhbGc...",
|
|
553
|
+
"expiresIn": 900,
|
|
554
|
+
"user": {
|
|
555
|
+
"id": "uuid",
|
|
556
|
+
"username": "alice",
|
|
557
|
+
"role": "admin",
|
|
558
|
+
"email": "alice@company.com"
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**Status Codes:**
|
|
564
|
+
- `200 OK` - Login successful
|
|
565
|
+
- `401 Unauthorized` - Invalid credentials
|
|
566
|
+
- `403 Forbidden` - Account disabled
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
#### POST `/api/v1/auth/refresh`
|
|
571
|
+
|
|
572
|
+
Refresh access token using refresh token.
|
|
573
|
+
|
|
574
|
+
**Request:**
|
|
575
|
+
```json
|
|
576
|
+
{
|
|
577
|
+
"refreshToken": "eyJhbGc..."
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
**Response:**
|
|
582
|
+
```json
|
|
583
|
+
{
|
|
584
|
+
"accessToken": "eyJhbGc...",
|
|
585
|
+
"refreshToken": "eyJhbGc...", // New refresh token (rotation)
|
|
586
|
+
"expiresIn": 900
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
**Status Codes:**
|
|
591
|
+
- `200 OK` - Token refreshed
|
|
592
|
+
- `401 Unauthorized` - Invalid or expired refresh token
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
#### POST `/api/v1/auth/logout`
|
|
597
|
+
|
|
598
|
+
Logout and revoke refresh token.
|
|
599
|
+
|
|
600
|
+
**Request:**
|
|
601
|
+
```json
|
|
602
|
+
{
|
|
603
|
+
"refreshToken": "eyJhbGc..."
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
**Response:**
|
|
608
|
+
```json
|
|
609
|
+
{
|
|
610
|
+
"message": "Logged out successfully"
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
**Status Codes:**
|
|
615
|
+
- `200 OK` - Logged out
|
|
616
|
+
- `401 Unauthorized` - Invalid token
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
#### GET `/api/v1/auth/me`
|
|
621
|
+
|
|
622
|
+
Get current authenticated user info.
|
|
623
|
+
|
|
624
|
+
**Headers:**
|
|
625
|
+
```
|
|
626
|
+
Authorization: Bearer <access_token or service_token>
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
**Response:**
|
|
630
|
+
```json
|
|
631
|
+
{
|
|
632
|
+
"type": "user", // or "service"
|
|
633
|
+
"id": "uuid",
|
|
634
|
+
"username": "alice", // or "name" for service tokens
|
|
635
|
+
"role": "admin",
|
|
636
|
+
"permissions": ["queue:configure", "message:push", ...]
|
|
637
|
+
}
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
**Status Codes:**
|
|
641
|
+
- `200 OK` - User info returned
|
|
642
|
+
- `401 Unauthorized` - Invalid token
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
### User Management Endpoints (Admin Only)
|
|
647
|
+
|
|
648
|
+
#### POST `/api/v1/auth/users`
|
|
649
|
+
|
|
650
|
+
Create a new user.
|
|
651
|
+
|
|
652
|
+
**Request:**
|
|
653
|
+
```json
|
|
654
|
+
{
|
|
655
|
+
"username": "bob",
|
|
656
|
+
"email": "bob@company.com",
|
|
657
|
+
"password": "secret123",
|
|
658
|
+
"role": "rw"
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**Response:**
|
|
663
|
+
```json
|
|
664
|
+
{
|
|
665
|
+
"id": "uuid",
|
|
666
|
+
"username": "bob",
|
|
667
|
+
"email": "bob@company.com",
|
|
668
|
+
"role": "rw",
|
|
669
|
+
"enabled": true,
|
|
670
|
+
"created_at": "2025-10-13T10:00:00Z"
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
---
|
|
675
|
+
|
|
676
|
+
#### GET `/api/v1/auth/users`
|
|
677
|
+
|
|
678
|
+
List all users.
|
|
679
|
+
|
|
680
|
+
**Query Parameters:**
|
|
681
|
+
- `role` - Filter by role
|
|
682
|
+
- `enabled` - Filter by enabled status
|
|
683
|
+
- `limit` - Page size (default: 100)
|
|
684
|
+
- `offset` - Page offset (default: 0)
|
|
685
|
+
|
|
686
|
+
**Response:**
|
|
687
|
+
```json
|
|
688
|
+
{
|
|
689
|
+
"users": [
|
|
690
|
+
{
|
|
691
|
+
"id": "uuid",
|
|
692
|
+
"username": "alice",
|
|
693
|
+
"email": "alice@company.com",
|
|
694
|
+
"role": "admin",
|
|
695
|
+
"enabled": true,
|
|
696
|
+
"created_at": "2025-10-13T10:00:00Z",
|
|
697
|
+
"last_login_at": "2025-10-13T12:00:00Z"
|
|
698
|
+
}
|
|
699
|
+
],
|
|
700
|
+
"total": 10
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
#### GET `/api/v1/auth/users/:id`
|
|
707
|
+
|
|
708
|
+
Get user details.
|
|
709
|
+
|
|
710
|
+
**Response:**
|
|
711
|
+
```json
|
|
712
|
+
{
|
|
713
|
+
"id": "uuid",
|
|
714
|
+
"username": "alice",
|
|
715
|
+
"email": "alice@company.com",
|
|
716
|
+
"role": "admin",
|
|
717
|
+
"enabled": true,
|
|
718
|
+
"created_at": "2025-10-13T10:00:00Z",
|
|
719
|
+
"updated_at": "2025-10-13T10:00:00Z",
|
|
720
|
+
"last_login_at": "2025-10-13T12:00:00Z"
|
|
721
|
+
}
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
#### PUT `/api/v1/auth/users/:id`
|
|
727
|
+
|
|
728
|
+
Update user details.
|
|
729
|
+
|
|
730
|
+
**Request:**
|
|
731
|
+
```json
|
|
732
|
+
{
|
|
733
|
+
"email": "newemail@company.com",
|
|
734
|
+
"role": "admin",
|
|
735
|
+
"enabled": true
|
|
736
|
+
}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
#### PUT `/api/v1/auth/users/:id/password`
|
|
742
|
+
|
|
743
|
+
Change user password.
|
|
744
|
+
|
|
745
|
+
**Request:**
|
|
746
|
+
```json
|
|
747
|
+
{
|
|
748
|
+
"newPassword": "newsecret123"
|
|
749
|
+
}
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
#### DELETE `/api/v1/auth/users/:id`
|
|
755
|
+
|
|
756
|
+
Delete user (soft delete - disable account).
|
|
757
|
+
|
|
758
|
+
---
|
|
759
|
+
|
|
760
|
+
### Service Token Management Endpoints (Admin Only)
|
|
761
|
+
|
|
762
|
+
#### POST `/api/v1/auth/tokens`
|
|
763
|
+
|
|
764
|
+
Create a new service token.
|
|
765
|
+
|
|
766
|
+
**Request:**
|
|
767
|
+
```json
|
|
768
|
+
{
|
|
769
|
+
"name": "payment-service",
|
|
770
|
+
"role": "rw",
|
|
771
|
+
"allowed_queues": ["orders", "payments"], // null or ["*"] for all queues
|
|
772
|
+
"allowed_operations": null, // null for all operations based on role
|
|
773
|
+
"expires_at": "2026-10-13T00:00:00Z" // null for never expires
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
**Response:**
|
|
778
|
+
```json
|
|
779
|
+
{
|
|
780
|
+
"id": "uuid",
|
|
781
|
+
"name": "payment-service",
|
|
782
|
+
"token": "qn_svc_8K7jQm3pN2xR5wV9yB4cE6fH8jL1mN3qT5uW7xZ9a",
|
|
783
|
+
"role": "rw",
|
|
784
|
+
"allowed_queues": ["orders", "payments"],
|
|
785
|
+
"allowed_operations": null,
|
|
786
|
+
"expires_at": "2026-10-13T00:00:00Z",
|
|
787
|
+
"created_at": "2025-10-13T10:00:00Z"
|
|
788
|
+
}
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
**⚠️ Note:** The actual token is only shown once during creation. Store it securely.
|
|
792
|
+
|
|
793
|
+
---
|
|
794
|
+
|
|
795
|
+
#### GET `/api/v1/auth/tokens`
|
|
796
|
+
|
|
797
|
+
List all service tokens.
|
|
798
|
+
|
|
799
|
+
**Query Parameters:**
|
|
800
|
+
- `role` - Filter by role
|
|
801
|
+
- `enabled` - Filter by enabled status
|
|
802
|
+
- `limit` - Page size (default: 100)
|
|
803
|
+
- `offset` - Page offset (default: 0)
|
|
804
|
+
|
|
805
|
+
**Response:**
|
|
806
|
+
```json
|
|
807
|
+
{
|
|
808
|
+
"tokens": [
|
|
809
|
+
{
|
|
810
|
+
"id": "uuid",
|
|
811
|
+
"name": "payment-service",
|
|
812
|
+
"role": "rw",
|
|
813
|
+
"allowed_queues": ["orders", "payments"],
|
|
814
|
+
"allowed_operations": null,
|
|
815
|
+
"enabled": true,
|
|
816
|
+
"expires_at": "2026-10-13T00:00:00Z",
|
|
817
|
+
"created_at": "2025-10-13T10:00:00Z",
|
|
818
|
+
"last_used_at": "2025-10-13T12:00:00Z"
|
|
819
|
+
}
|
|
820
|
+
],
|
|
821
|
+
"total": 5
|
|
822
|
+
}
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
**Note:** Actual token values are never returned (only shown during creation).
|
|
826
|
+
|
|
827
|
+
---
|
|
828
|
+
|
|
829
|
+
#### GET `/api/v1/auth/tokens/:id`
|
|
830
|
+
|
|
831
|
+
Get service token details.
|
|
832
|
+
|
|
833
|
+
---
|
|
834
|
+
|
|
835
|
+
#### PUT `/api/v1/auth/tokens/:id`
|
|
836
|
+
|
|
837
|
+
Update service token (name, role, queues, expiration, enabled status).
|
|
838
|
+
|
|
839
|
+
**Request:**
|
|
840
|
+
```json
|
|
841
|
+
{
|
|
842
|
+
"name": "payment-service-v2",
|
|
843
|
+
"role": "rw",
|
|
844
|
+
"allowed_queues": ["*"],
|
|
845
|
+
"enabled": true,
|
|
846
|
+
"expires_at": null
|
|
847
|
+
}
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
#### POST `/api/v1/auth/tokens/:id/rotate`
|
|
853
|
+
|
|
854
|
+
Rotate service token (generate new token, invalidate old one).
|
|
855
|
+
|
|
856
|
+
**Response:**
|
|
857
|
+
```json
|
|
858
|
+
{
|
|
859
|
+
"id": "uuid",
|
|
860
|
+
"name": "payment-service",
|
|
861
|
+
"token": "qn_svc_NEW_TOKEN_HERE",
|
|
862
|
+
"role": "rw",
|
|
863
|
+
"allowed_queues": ["orders", "payments"],
|
|
864
|
+
"expires_at": null,
|
|
865
|
+
"created_at": "2025-10-13T10:00:00Z"
|
|
866
|
+
}
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
---
|
|
870
|
+
|
|
871
|
+
#### DELETE `/api/v1/auth/tokens/:id`
|
|
872
|
+
|
|
873
|
+
Delete (revoke) service token.
|
|
874
|
+
|
|
875
|
+
---
|
|
876
|
+
|
|
877
|
+
### Audit Log Endpoints (Admin Only)
|
|
878
|
+
|
|
879
|
+
#### GET `/api/v1/auth/audit`
|
|
880
|
+
|
|
881
|
+
Query audit logs.
|
|
882
|
+
|
|
883
|
+
**Query Parameters:**
|
|
884
|
+
- `user_id` - Filter by user
|
|
885
|
+
- `service_token_id` - Filter by service token
|
|
886
|
+
- `event_type` - Filter by event type
|
|
887
|
+
- `success` - Filter by success status
|
|
888
|
+
- `from` - Start date (ISO 8601)
|
|
889
|
+
- `to` - End date (ISO 8601)
|
|
890
|
+
- `limit` - Page size (default: 100)
|
|
891
|
+
- `offset` - Page offset (default: 0)
|
|
892
|
+
|
|
893
|
+
**Response:**
|
|
894
|
+
```json
|
|
895
|
+
{
|
|
896
|
+
"logs": [
|
|
897
|
+
{
|
|
898
|
+
"id": "uuid",
|
|
899
|
+
"event_type": "login",
|
|
900
|
+
"user_id": "uuid",
|
|
901
|
+
"username": "alice",
|
|
902
|
+
"ip_address": "192.168.1.100",
|
|
903
|
+
"user_agent": "Mozilla/5.0...",
|
|
904
|
+
"endpoint": "/api/v1/auth/login",
|
|
905
|
+
"success": true,
|
|
906
|
+
"created_at": "2025-10-13T12:00:00Z"
|
|
907
|
+
}
|
|
908
|
+
],
|
|
909
|
+
"total": 150
|
|
910
|
+
}
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
---
|
|
914
|
+
|
|
915
|
+
## CLI Tool
|
|
916
|
+
|
|
917
|
+
### Installation
|
|
918
|
+
|
|
919
|
+
The CLI tool will be part of the Queen repository:
|
|
920
|
+
|
|
921
|
+
```bash
|
|
922
|
+
# Make CLI executable
|
|
923
|
+
chmod +x cli/auth.js
|
|
924
|
+
|
|
925
|
+
# Or use directly with node
|
|
926
|
+
node cli/auth.js <command>
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
### Commands
|
|
930
|
+
|
|
931
|
+
#### User Management
|
|
932
|
+
|
|
933
|
+
**Create User:**
|
|
934
|
+
```bash
|
|
935
|
+
node cli/auth.js user create \
|
|
936
|
+
--username admin \
|
|
937
|
+
--password secret123 \
|
|
938
|
+
--role admin \
|
|
939
|
+
--email admin@company.com
|
|
940
|
+
|
|
941
|
+
# Interactive mode (prompts for password)
|
|
942
|
+
node cli/auth.js user create \
|
|
943
|
+
--username admin \
|
|
944
|
+
--role admin \
|
|
945
|
+
--interactive
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
**List Users:**
|
|
949
|
+
```bash
|
|
950
|
+
node cli/auth.js user list
|
|
951
|
+
|
|
952
|
+
# With filters
|
|
953
|
+
node cli/auth.js user list --role admin --enabled
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
**Update User:**
|
|
957
|
+
```bash
|
|
958
|
+
node cli/auth.js user update \
|
|
959
|
+
--username alice \
|
|
960
|
+
--email newemail@company.com \
|
|
961
|
+
--role admin
|
|
962
|
+
|
|
963
|
+
# Enable/disable user
|
|
964
|
+
node cli/auth.js user disable --username bob
|
|
965
|
+
node cli/auth.js user enable --username bob
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
**Change Password:**
|
|
969
|
+
```bash
|
|
970
|
+
node cli/auth.js user password \
|
|
971
|
+
--username alice \
|
|
972
|
+
--new-password newsecret123
|
|
973
|
+
|
|
974
|
+
# Interactive mode (prompts for passwords)
|
|
975
|
+
node cli/auth.js user password --username alice --interactive
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
**Delete User:**
|
|
979
|
+
```bash
|
|
980
|
+
node cli/auth.js user delete --username bob
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
---
|
|
984
|
+
|
|
985
|
+
#### Service Token Management
|
|
986
|
+
|
|
987
|
+
**Create Token:**
|
|
988
|
+
```bash
|
|
989
|
+
# Basic token (all queues)
|
|
990
|
+
node cli/auth.js token create \
|
|
991
|
+
--name payment-service \
|
|
992
|
+
--role rw
|
|
993
|
+
|
|
994
|
+
# Token with queue restrictions
|
|
995
|
+
node cli/auth.js token create \
|
|
996
|
+
--name analytics-worker \
|
|
997
|
+
--role rw \
|
|
998
|
+
--queues "orders,payments,events"
|
|
999
|
+
|
|
1000
|
+
# Token with all queues (explicit)
|
|
1001
|
+
node cli/auth.js token create \
|
|
1002
|
+
--name monitoring-service \
|
|
1003
|
+
--role read \
|
|
1004
|
+
--queues "*"
|
|
1005
|
+
|
|
1006
|
+
# Token with expiration
|
|
1007
|
+
node cli/auth.js token create \
|
|
1008
|
+
--name temp-worker \
|
|
1009
|
+
--role rw \
|
|
1010
|
+
--expires-in 90d
|
|
1011
|
+
|
|
1012
|
+
# Token with operation restrictions
|
|
1013
|
+
node cli/auth.js token create \
|
|
1014
|
+
--name push-only-service \
|
|
1015
|
+
--role rw \
|
|
1016
|
+
--queues "*" \
|
|
1017
|
+
--operations "push"
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
**Output:**
|
|
1021
|
+
```
|
|
1022
|
+
✅ Service token created successfully
|
|
1023
|
+
|
|
1024
|
+
Token Details:
|
|
1025
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1026
|
+
ID: 550e8400-e29b-41d4-a716-446655440000
|
|
1027
|
+
Name: payment-service
|
|
1028
|
+
Role: rw
|
|
1029
|
+
Queues: orders, payments
|
|
1030
|
+
Operations: all (based on role)
|
|
1031
|
+
Expires: never
|
|
1032
|
+
Created: 2025-10-13T10:00:00Z
|
|
1033
|
+
|
|
1034
|
+
Token (⚠️ shown only once):
|
|
1035
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1036
|
+
qn_svc_8K7jQm3pN2xR5wV9yB4cE6fH8jL1mN3qT5uW7xZ9a
|
|
1037
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1038
|
+
|
|
1039
|
+
⚠️ IMPORTANT: Store this token securely!
|
|
1040
|
+
- This token will NOT be shown again
|
|
1041
|
+
- It provides access to your Queen instance
|
|
1042
|
+
- Treat it like a password
|
|
1043
|
+
```
|
|
1044
|
+
|
|
1045
|
+
**List Tokens:**
|
|
1046
|
+
```bash
|
|
1047
|
+
node cli/auth.js token list
|
|
1048
|
+
|
|
1049
|
+
# With filters
|
|
1050
|
+
node cli/auth.js token list --role rw --enabled
|
|
1051
|
+
|
|
1052
|
+
# Show last usage
|
|
1053
|
+
node cli/auth.js token list --show-usage
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
**Update Token:**
|
|
1057
|
+
```bash
|
|
1058
|
+
node cli/auth.js token update \
|
|
1059
|
+
--id <token-id> \
|
|
1060
|
+
--name payment-service-v2 \
|
|
1061
|
+
--queues "*"
|
|
1062
|
+
|
|
1063
|
+
# Enable/disable token
|
|
1064
|
+
node cli/auth.js token disable --id <token-id>
|
|
1065
|
+
node cli/auth.js token enable --id <token-id>
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
**Rotate Token:**
|
|
1069
|
+
```bash
|
|
1070
|
+
node cli/auth.js token rotate --id <token-id>
|
|
1071
|
+
|
|
1072
|
+
# Will output new token (old one is invalidated)
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
**Revoke Token:**
|
|
1076
|
+
```bash
|
|
1077
|
+
node cli/auth.js token revoke --id <token-id>
|
|
1078
|
+
|
|
1079
|
+
# With confirmation prompt
|
|
1080
|
+
node cli/auth.js token revoke --id <token-id> --confirm
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
---
|
|
1084
|
+
|
|
1085
|
+
#### Audit Logs
|
|
1086
|
+
|
|
1087
|
+
**View Audit Logs:**
|
|
1088
|
+
```bash
|
|
1089
|
+
# Recent logs
|
|
1090
|
+
node cli/auth.js audit logs --limit 50
|
|
1091
|
+
|
|
1092
|
+
# Filter by event type
|
|
1093
|
+
node cli/auth.js audit logs --event-type login --limit 20
|
|
1094
|
+
|
|
1095
|
+
# Filter by user
|
|
1096
|
+
node cli/auth.js audit logs --username alice
|
|
1097
|
+
|
|
1098
|
+
# Filter by date range
|
|
1099
|
+
node cli/auth.js audit logs \
|
|
1100
|
+
--from 2025-10-01 \
|
|
1101
|
+
--to 2025-10-13
|
|
1102
|
+
|
|
1103
|
+
# Failed attempts only
|
|
1104
|
+
node cli/auth.js audit logs --failed-only
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
---
|
|
1108
|
+
|
|
1109
|
+
#### System Setup
|
|
1110
|
+
|
|
1111
|
+
**Initialize Auth System:**
|
|
1112
|
+
```bash
|
|
1113
|
+
# Create auth tables and initial admin user
|
|
1114
|
+
node cli/auth.js init
|
|
1115
|
+
|
|
1116
|
+
# Will prompt for admin username and password
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
**Check Auth Status:**
|
|
1120
|
+
```bash
|
|
1121
|
+
node cli/auth.js status
|
|
1122
|
+
|
|
1123
|
+
# Output:
|
|
1124
|
+
# Authentication: enabled
|
|
1125
|
+
# JWT Secret: configured ✅
|
|
1126
|
+
# Admin Users: 2
|
|
1127
|
+
# Service Tokens: 5 (3 active)
|
|
1128
|
+
# Last Login: alice @ 2025-10-13T12:00:00Z
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1131
|
+
---
|
|
1132
|
+
|
|
1133
|
+
## Configuration
|
|
1134
|
+
|
|
1135
|
+
### Environment Variables
|
|
1136
|
+
|
|
1137
|
+
```bash
|
|
1138
|
+
# ============================================
|
|
1139
|
+
# Authentication Configuration
|
|
1140
|
+
# ============================================
|
|
1141
|
+
|
|
1142
|
+
# Enable/disable authentication system
|
|
1143
|
+
QUEEN_AUTH_ENABLED=false # default: false (disabled)
|
|
1144
|
+
|
|
1145
|
+
# JWT Configuration
|
|
1146
|
+
QUEEN_JWT_SECRET=<random_64_hex_chars> # Required when auth is enabled
|
|
1147
|
+
QUEEN_JWT_ACCESS_EXPIRY=900 # 15 minutes (in seconds)
|
|
1148
|
+
QUEEN_JWT_REFRESH_EXPIRY=604800 # 7 days (in seconds)
|
|
1149
|
+
|
|
1150
|
+
# Password Policy
|
|
1151
|
+
QUEEN_PASSWORD_MIN_LENGTH=8 # Minimum password length
|
|
1152
|
+
QUEEN_PASSWORD_REQUIRE_UPPERCASE=true # Require uppercase letter
|
|
1153
|
+
QUEEN_PASSWORD_REQUIRE_LOWERCASE=true # Require lowercase letter
|
|
1154
|
+
QUEEN_PASSWORD_REQUIRE_NUMBER=true # Require number
|
|
1155
|
+
QUEEN_PASSWORD_REQUIRE_SPECIAL=false # Require special character
|
|
1156
|
+
|
|
1157
|
+
# Bcrypt Configuration
|
|
1158
|
+
QUEEN_BCRYPT_ROUNDS=12 # bcrypt cost factor (10-14 recommended)
|
|
1159
|
+
|
|
1160
|
+
# Session Configuration
|
|
1161
|
+
QUEEN_SESSION_MAX_REFRESH_TOKENS=5 # Max refresh tokens per user
|
|
1162
|
+
QUEEN_SESSION_ABSOLUTE_TIMEOUT=2592000 # 30 days (in seconds)
|
|
1163
|
+
|
|
1164
|
+
# Audit Logging
|
|
1165
|
+
QUEEN_AUDIT_ENABLED=true # Enable audit logging
|
|
1166
|
+
QUEEN_AUDIT_LOG_SUCCESS=true # Log successful operations
|
|
1167
|
+
QUEEN_AUDIT_LOG_FAILURES=true # Log failed operations
|
|
1168
|
+
QUEEN_AUDIT_RETENTION_DAYS=90 # Keep audit logs for 90 days
|
|
1169
|
+
|
|
1170
|
+
# Service Token Configuration
|
|
1171
|
+
QUEEN_SERVICE_TOKEN_PREFIX=qn_svc_ # Token prefix
|
|
1172
|
+
QUEEN_SERVICE_TOKEN_LENGTH=32 # Token length in bytes
|
|
1173
|
+
QUEEN_SERVICE_TOKEN_DEFAULT_EXPIRY=0 # 0 = never expires
|
|
1174
|
+
|
|
1175
|
+
# Security Headers (when auth is enabled)
|
|
1176
|
+
QUEEN_REQUIRE_HTTPS=false # Enforce HTTPS (set to true in production)
|
|
1177
|
+
QUEEN_HSTS_ENABLED=false # Enable HSTS header
|
|
1178
|
+
QUEEN_HSTS_MAX_AGE=31536000 # 1 year
|
|
1179
|
+
|
|
1180
|
+
# CORS Configuration (when auth is enabled)
|
|
1181
|
+
QUEEN_AUTH_CORS_CREDENTIALS=true # Allow credentials in CORS
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
### Generating Secrets
|
|
1185
|
+
|
|
1186
|
+
**JWT Secret:**
|
|
1187
|
+
```bash
|
|
1188
|
+
# Generate secure random secret (64 hex chars)
|
|
1189
|
+
openssl rand -hex 32
|
|
1190
|
+
|
|
1191
|
+
# Or use Node.js
|
|
1192
|
+
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
**Initial Setup:**
|
|
1196
|
+
```bash
|
|
1197
|
+
# 1. Generate JWT secret
|
|
1198
|
+
export QUEEN_JWT_SECRET=$(openssl rand -hex 32)
|
|
1199
|
+
|
|
1200
|
+
# 2. Enable auth
|
|
1201
|
+
export QUEEN_AUTH_ENABLED=true
|
|
1202
|
+
|
|
1203
|
+
# 3. Start Queen
|
|
1204
|
+
npm start
|
|
1205
|
+
|
|
1206
|
+
# 4. Initialize auth system (creates tables + admin user)
|
|
1207
|
+
node cli/auth.js init
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
### Configuration File (Optional)
|
|
1211
|
+
|
|
1212
|
+
Alternative to environment variables: `config/auth.json`
|
|
1213
|
+
|
|
1214
|
+
```json
|
|
1215
|
+
{
|
|
1216
|
+
"enabled": false,
|
|
1217
|
+
"jwt": {
|
|
1218
|
+
"secret": "env:QUEEN_JWT_SECRET",
|
|
1219
|
+
"accessExpiry": 900,
|
|
1220
|
+
"refreshExpiry": 604800
|
|
1221
|
+
},
|
|
1222
|
+
"password": {
|
|
1223
|
+
"minLength": 8,
|
|
1224
|
+
"requireUppercase": true,
|
|
1225
|
+
"requireLowercase": true,
|
|
1226
|
+
"requireNumber": true,
|
|
1227
|
+
"requireSpecial": false
|
|
1228
|
+
},
|
|
1229
|
+
"audit": {
|
|
1230
|
+
"enabled": true,
|
|
1231
|
+
"logSuccess": true,
|
|
1232
|
+
"logFailures": true,
|
|
1233
|
+
"retentionDays": 90
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
---
|
|
1239
|
+
|
|
1240
|
+
## Security Considerations
|
|
1241
|
+
|
|
1242
|
+
### Best Practices Implemented
|
|
1243
|
+
|
|
1244
|
+
#### 1. Token Security
|
|
1245
|
+
|
|
1246
|
+
**Storage:**
|
|
1247
|
+
- ✅ Service tokens stored as SHA-256 hashes in database
|
|
1248
|
+
- ✅ Refresh tokens stored as SHA-256 hashes
|
|
1249
|
+
- ✅ Access tokens are JWTs (stateless, not stored)
|
|
1250
|
+
- ✅ Actual tokens never logged or returned after creation
|
|
1251
|
+
|
|
1252
|
+
**Transmission:**
|
|
1253
|
+
- ✅ Tokens sent via `Authorization: Bearer <token>` header
|
|
1254
|
+
- ✅ HTTPS enforced in production (`QUEEN_REQUIRE_HTTPS=true`)
|
|
1255
|
+
- ✅ Tokens never sent in URL query parameters
|
|
1256
|
+
|
|
1257
|
+
**Expiration:**
|
|
1258
|
+
- ✅ Access tokens: short-lived (15 minutes)
|
|
1259
|
+
- ✅ Refresh tokens: medium-lived (7 days)
|
|
1260
|
+
- ✅ Service tokens: long-lived or never expire (configurable)
|
|
1261
|
+
- ✅ Automatic cleanup of expired tokens
|
|
1262
|
+
|
|
1263
|
+
**Revocation:**
|
|
1264
|
+
- ✅ Refresh tokens can be revoked (logout, security breach)
|
|
1265
|
+
- ✅ Service tokens can be disabled or deleted
|
|
1266
|
+
- ✅ Audit trail for all token operations
|
|
1267
|
+
|
|
1268
|
+
#### 2. Password Security
|
|
1269
|
+
|
|
1270
|
+
**Hashing:**
|
|
1271
|
+
- ✅ bcrypt with configurable cost factor (default: 12)
|
|
1272
|
+
- ✅ Salts automatically managed by bcrypt
|
|
1273
|
+
- ✅ Password hashes never exposed via API
|
|
1274
|
+
|
|
1275
|
+
**Password Policy:**
|
|
1276
|
+
- ✅ Configurable minimum length (default: 8)
|
|
1277
|
+
- ✅ Optional complexity requirements (uppercase, lowercase, numbers, special chars)
|
|
1278
|
+
- ✅ Password validation before hashing
|
|
1279
|
+
|
|
1280
|
+
**Password Reset:**
|
|
1281
|
+
- 🔄 Future: Email-based password reset flow
|
|
1282
|
+
- 🔄 Future: Password reset tokens with short expiration
|
|
1283
|
+
|
|
1284
|
+
#### 3. Authentication Security
|
|
1285
|
+
|
|
1286
|
+
**Brute Force Protection:**
|
|
1287
|
+
- 🔄 Future: Rate limiting on login endpoint (not in v1)
|
|
1288
|
+
- 🔄 Future: Account lockout after N failed attempts
|
|
1289
|
+
- ✅ Failed login attempts logged in audit log
|
|
1290
|
+
|
|
1291
|
+
**Session Management:**
|
|
1292
|
+
- ✅ Refresh token rotation on each use
|
|
1293
|
+
- ✅ Single refresh token active per session
|
|
1294
|
+
- ✅ Absolute session timeout (30 days default)
|
|
1295
|
+
- ✅ Manual logout revokes refresh token
|
|
1296
|
+
|
|
1297
|
+
**JWT Security:**
|
|
1298
|
+
- ✅ HS256 algorithm (HMAC with SHA-256)
|
|
1299
|
+
- ✅ Short expiration prevents replay attacks
|
|
1300
|
+
- ✅ No sensitive data in JWT payload
|
|
1301
|
+
- ✅ JWT secret stored in environment variable
|
|
1302
|
+
|
|
1303
|
+
#### 4. Authorization Security
|
|
1304
|
+
|
|
1305
|
+
**Permission Checks:**
|
|
1306
|
+
- ✅ Every protected endpoint checks authentication
|
|
1307
|
+
- ✅ Every protected endpoint checks authorization (role + permissions)
|
|
1308
|
+
- ✅ Queue-level access control for service tokens
|
|
1309
|
+
- ✅ Operation-level access control (optional)
|
|
1310
|
+
|
|
1311
|
+
**Principle of Least Privilege:**
|
|
1312
|
+
- ✅ Three roles with clear permission boundaries
|
|
1313
|
+
- ✅ Service tokens can be scoped to specific queues
|
|
1314
|
+
- ✅ Service tokens can be scoped to specific operations
|
|
1315
|
+
- ✅ Users/tokens can be disabled without deletion
|
|
1316
|
+
|
|
1317
|
+
#### 5. Audit Logging
|
|
1318
|
+
|
|
1319
|
+
**Comprehensive Logging:**
|
|
1320
|
+
- ✅ All authentication events (login, logout, failures)
|
|
1321
|
+
- ✅ All authorization failures (unauthorized access attempts)
|
|
1322
|
+
- ✅ All user/token management operations
|
|
1323
|
+
- ✅ IP address and user agent for all requests
|
|
1324
|
+
|
|
1325
|
+
**Log Contents:**
|
|
1326
|
+
- ✅ Who performed the action (user or service token)
|
|
1327
|
+
- ✅ What action was performed
|
|
1328
|
+
- ✅ When it was performed
|
|
1329
|
+
- ✅ Where it came from (IP, user agent)
|
|
1330
|
+
- ✅ Result (success or failure)
|
|
1331
|
+
|
|
1332
|
+
**Log Protection:**
|
|
1333
|
+
- ✅ Audit logs cannot be modified or deleted via API
|
|
1334
|
+
- ✅ Configurable retention period
|
|
1335
|
+
- ✅ Admin-only access to audit logs
|
|
1336
|
+
|
|
1337
|
+
#### 6. API Security
|
|
1338
|
+
|
|
1339
|
+
**HTTPS:**
|
|
1340
|
+
- ✅ Enforced in production (`QUEEN_REQUIRE_HTTPS=true`)
|
|
1341
|
+
- ✅ HSTS header support (`QUEEN_HSTS_ENABLED=true`)
|
|
1342
|
+
|
|
1343
|
+
**CORS:**
|
|
1344
|
+
- ✅ Credentials allowed when auth enabled
|
|
1345
|
+
- ✅ Configurable allowed origins
|
|
1346
|
+
- ✅ Preflight request support
|
|
1347
|
+
|
|
1348
|
+
**Headers:**
|
|
1349
|
+
- ✅ `X-Content-Type-Options: nosniff`
|
|
1350
|
+
- ✅ `X-Frame-Options: DENY`
|
|
1351
|
+
- ✅ `X-XSS-Protection: 1; mode=block`
|
|
1352
|
+
- ✅ `Content-Security-Policy` for dashboard
|
|
1353
|
+
|
|
1354
|
+
#### 7. Database Security
|
|
1355
|
+
|
|
1356
|
+
**SQL Injection:**
|
|
1357
|
+
- ✅ Parameterized queries for all database operations
|
|
1358
|
+
- ✅ Input validation before database queries
|
|
1359
|
+
- ✅ No string concatenation in SQL queries
|
|
1360
|
+
|
|
1361
|
+
**Data Protection:**
|
|
1362
|
+
- ✅ Token hashes stored, not actual tokens
|
|
1363
|
+
- ✅ Password hashes stored, not passwords
|
|
1364
|
+
- ✅ Sensitive data encrypted at rest (via Queen's encryption feature)
|
|
1365
|
+
|
|
1366
|
+
**Access Control:**
|
|
1367
|
+
- ✅ Database user with minimal required permissions
|
|
1368
|
+
- ✅ Connection pooling with proper timeout handling
|
|
1369
|
+
- ✅ Separate auth tables (can be isolated)
|
|
1370
|
+
|
|
1371
|
+
### Security Checklist
|
|
1372
|
+
|
|
1373
|
+
**Before Enabling Auth in Production:**
|
|
1374
|
+
|
|
1375
|
+
- [ ] Generate strong JWT secret (32+ bytes, random)
|
|
1376
|
+
- [ ] Set `QUEEN_AUTH_ENABLED=true`
|
|
1377
|
+
- [ ] Set `QUEEN_REQUIRE_HTTPS=true` (enforce HTTPS)
|
|
1378
|
+
- [ ] Configure password policy
|
|
1379
|
+
- [ ] Create initial admin user via CLI
|
|
1380
|
+
- [ ] Generate service tokens for all microservices
|
|
1381
|
+
- [ ] Update all clients to use tokens
|
|
1382
|
+
- [ ] Enable audit logging
|
|
1383
|
+
- [ ] Configure audit log retention
|
|
1384
|
+
- [ ] Test authentication flows in staging
|
|
1385
|
+
- [ ] Review audit logs regularly
|
|
1386
|
+
- [ ] Document token management procedures
|
|
1387
|
+
- [ ] Set up token rotation schedule
|
|
1388
|
+
- [ ] Configure alerts for unauthorized access attempts
|
|
1389
|
+
|
|
1390
|
+
---
|
|
1391
|
+
|
|
1392
|
+
## Implementation Roadmap
|
|
1393
|
+
|
|
1394
|
+
### Phase 1: Foundation (Week 1)
|
|
1395
|
+
|
|
1396
|
+
**Database Schema:**
|
|
1397
|
+
- [ ] Create `queen.auth_users` table
|
|
1398
|
+
- [ ] Create `queen.auth_service_tokens` table
|
|
1399
|
+
- [ ] Create `queen.auth_refresh_tokens` table
|
|
1400
|
+
- [ ] Create `queen.auth_audit_log` table
|
|
1401
|
+
- [ ] Create database migration script
|
|
1402
|
+
- [ ] Add indexes for performance
|
|
1403
|
+
|
|
1404
|
+
**Core Auth Library:**
|
|
1405
|
+
- [ ] Implement bcrypt password hashing
|
|
1406
|
+
- [ ] Implement JWT signing and verification
|
|
1407
|
+
- [ ] Implement service token generation and validation
|
|
1408
|
+
- [ ] Implement SHA-256 hashing for tokens
|
|
1409
|
+
- [ ] Create token format validators
|
|
1410
|
+
- [ ] Create password policy validator
|
|
1411
|
+
|
|
1412
|
+
### Phase 2: Middleware & Permissions (Week 2)
|
|
1413
|
+
|
|
1414
|
+
**Authentication Middleware:**
|
|
1415
|
+
- [ ] Create auth middleware (token extraction and validation)
|
|
1416
|
+
- [ ] Implement service token authentication
|
|
1417
|
+
- [ ] Implement JWT authentication
|
|
1418
|
+
- [ ] Handle auth disabled state (bypass middleware)
|
|
1419
|
+
- [ ] Attach auth context to request
|
|
1420
|
+
|
|
1421
|
+
**Authorization Middleware:**
|
|
1422
|
+
- [ ] Define permission matrix
|
|
1423
|
+
- [ ] Create permission checking function
|
|
1424
|
+
- [ ] Create role-based authorization middleware
|
|
1425
|
+
- [ ] Implement queue-level access control
|
|
1426
|
+
- [ ] Implement operation-level access control
|
|
1427
|
+
|
|
1428
|
+
**Audit Logging:**
|
|
1429
|
+
- [ ] Create audit logging functions
|
|
1430
|
+
- [ ] Log authentication events
|
|
1431
|
+
- [ ] Log authorization failures
|
|
1432
|
+
- [ ] Log user/token management operations
|
|
1433
|
+
- [ ] Implement audit log cleanup job
|
|
1434
|
+
|
|
1435
|
+
### Phase 3: API Endpoints (Week 3)
|
|
1436
|
+
|
|
1437
|
+
**Auth Endpoints:**
|
|
1438
|
+
- [ ] POST `/api/v1/auth/login` - User login
|
|
1439
|
+
- [ ] POST `/api/v1/auth/refresh` - Refresh access token
|
|
1440
|
+
- [ ] POST `/api/v1/auth/logout` - Logout and revoke refresh token
|
|
1441
|
+
- [ ] GET `/api/v1/auth/me` - Get current user info
|
|
1442
|
+
|
|
1443
|
+
**User Management Endpoints:**
|
|
1444
|
+
- [ ] POST `/api/v1/auth/users` - Create user
|
|
1445
|
+
- [ ] GET `/api/v1/auth/users` - List users
|
|
1446
|
+
- [ ] GET `/api/v1/auth/users/:id` - Get user
|
|
1447
|
+
- [ ] PUT `/api/v1/auth/users/:id` - Update user
|
|
1448
|
+
- [ ] PUT `/api/v1/auth/users/:id/password` - Change password
|
|
1449
|
+
- [ ] DELETE `/api/v1/auth/users/:id` - Delete user
|
|
1450
|
+
|
|
1451
|
+
**Service Token Endpoints:**
|
|
1452
|
+
- [ ] POST `/api/v1/auth/tokens` - Create service token
|
|
1453
|
+
- [ ] GET `/api/v1/auth/tokens` - List tokens
|
|
1454
|
+
- [ ] GET `/api/v1/auth/tokens/:id` - Get token details
|
|
1455
|
+
- [ ] PUT `/api/v1/auth/tokens/:id` - Update token
|
|
1456
|
+
- [ ] POST `/api/v1/auth/tokens/:id/rotate` - Rotate token
|
|
1457
|
+
- [ ] DELETE `/api/v1/auth/tokens/:id` - Revoke token
|
|
1458
|
+
|
|
1459
|
+
**Audit Endpoints:**
|
|
1460
|
+
- [ ] GET `/api/v1/auth/audit` - Query audit logs
|
|
1461
|
+
|
|
1462
|
+
### Phase 4: CLI Tool (Week 4)
|
|
1463
|
+
|
|
1464
|
+
**User Management Commands:**
|
|
1465
|
+
- [ ] `user create` - Create user
|
|
1466
|
+
- [ ] `user list` - List users
|
|
1467
|
+
- [ ] `user update` - Update user
|
|
1468
|
+
- [ ] `user password` - Change password
|
|
1469
|
+
- [ ] `user enable/disable` - Enable/disable user
|
|
1470
|
+
- [ ] `user delete` - Delete user
|
|
1471
|
+
|
|
1472
|
+
**Token Management Commands:**
|
|
1473
|
+
- [ ] `token create` - Create service token
|
|
1474
|
+
- [ ] `token list` - List tokens
|
|
1475
|
+
- [ ] `token update` - Update token
|
|
1476
|
+
- [ ] `token rotate` - Rotate token
|
|
1477
|
+
- [ ] `token enable/disable` - Enable/disable token
|
|
1478
|
+
- [ ] `token revoke` - Revoke token
|
|
1479
|
+
|
|
1480
|
+
**System Commands:**
|
|
1481
|
+
- [ ] `init` - Initialize auth system
|
|
1482
|
+
- [ ] `status` - Check auth system status
|
|
1483
|
+
- [ ] `audit logs` - View audit logs
|
|
1484
|
+
|
|
1485
|
+
### Phase 5: Integration (Week 5)
|
|
1486
|
+
|
|
1487
|
+
**Protected Endpoints:**
|
|
1488
|
+
- [ ] Add auth middleware to all protected routes
|
|
1489
|
+
- [ ] Update route handlers to check permissions
|
|
1490
|
+
- [ ] Test with auth enabled and disabled
|
|
1491
|
+
- [ ] Update WebSocket server for auth
|
|
1492
|
+
|
|
1493
|
+
**Client SDK Update:**
|
|
1494
|
+
- [ ] Add token support to Queen client
|
|
1495
|
+
- [ ] Add authentication error handling
|
|
1496
|
+
- [ ] Update examples to use tokens
|
|
1497
|
+
- [ ] Update documentation
|
|
1498
|
+
|
|
1499
|
+
**Dashboard Integration:**
|
|
1500
|
+
- [ ] Create login page
|
|
1501
|
+
- [ ] Implement token storage (httpOnly cookies)
|
|
1502
|
+
- [ ] Add auth guards to routes
|
|
1503
|
+
- [ ] Add logout functionality
|
|
1504
|
+
- [ ] Add WebSocket auth
|
|
1505
|
+
- [ ] Handle token refresh
|
|
1506
|
+
|
|
1507
|
+
### Phase 6: Testing & Documentation (Week 6)
|
|
1508
|
+
|
|
1509
|
+
**Testing:**
|
|
1510
|
+
- [ ] Unit tests for auth library
|
|
1511
|
+
- [ ] Unit tests for middleware
|
|
1512
|
+
- [ ] Integration tests for auth endpoints
|
|
1513
|
+
- [ ] Integration tests for protected endpoints
|
|
1514
|
+
- [ ] Security testing (token validation, permissions)
|
|
1515
|
+
- [ ] Performance testing (auth overhead)
|
|
1516
|
+
|
|
1517
|
+
**Documentation:**
|
|
1518
|
+
- [ ] Complete AUTH.md (this document)
|
|
1519
|
+
- [ ] Update README.md with auth section
|
|
1520
|
+
- [ ] Create migration guide
|
|
1521
|
+
- [ ] Create deployment guide
|
|
1522
|
+
- [ ] Update API.md with auth requirements
|
|
1523
|
+
- [ ] Create security best practices guide
|
|
1524
|
+
|
|
1525
|
+
**Configuration:**
|
|
1526
|
+
- [ ] Add auth config to `src/config.js`
|
|
1527
|
+
- [ ] Add auth environment variables
|
|
1528
|
+
- [ ] Update Docker Compose example
|
|
1529
|
+
- [ ] Update Kubernetes manifests (if applicable)
|
|
1530
|
+
|
|
1531
|
+
### Phase 7: Polish & Release (Week 7)
|
|
1532
|
+
|
|
1533
|
+
**Final Touches:**
|
|
1534
|
+
- [ ] Code review and refactoring
|
|
1535
|
+
- [ ] Security audit
|
|
1536
|
+
- [ ] Performance optimization
|
|
1537
|
+
- [ ] Error message improvements
|
|
1538
|
+
- [ ] CLI UX improvements
|
|
1539
|
+
|
|
1540
|
+
**Release:**
|
|
1541
|
+
- [ ] Create release notes
|
|
1542
|
+
- [ ] Update CHANGELOG.md
|
|
1543
|
+
- [ ] Tag release (e.g., v2.0.0)
|
|
1544
|
+
- [ ] Publish to npm (if applicable)
|
|
1545
|
+
- [ ] Announce on GitHub
|
|
1546
|
+
|
|
1547
|
+
---
|
|
1548
|
+
|
|
1549
|
+
## Future Enhancements
|
|
1550
|
+
|
|
1551
|
+
### Planned but Not in v1
|
|
1552
|
+
|
|
1553
|
+
#### 1. OAuth2 / OpenID Connect (OIDC)
|
|
1554
|
+
|
|
1555
|
+
**Use Case:** Enterprise SSO integration (Okta, Auth0, Azure AD, Google)
|
|
1556
|
+
|
|
1557
|
+
**Design:**
|
|
1558
|
+
- Add OAuth2 provider configuration
|
|
1559
|
+
- Implement authorization code flow
|
|
1560
|
+
- Map OIDC claims to Queen roles
|
|
1561
|
+
- Support multiple identity providers
|
|
1562
|
+
- Maintain service token system alongside OAuth2
|
|
1563
|
+
|
|
1564
|
+
**Tables:**
|
|
1565
|
+
```sql
|
|
1566
|
+
CREATE TABLE queen.auth_oauth_providers (
|
|
1567
|
+
id UUID PRIMARY KEY,
|
|
1568
|
+
name VARCHAR(255) UNIQUE NOT NULL,
|
|
1569
|
+
issuer VARCHAR(255) NOT NULL,
|
|
1570
|
+
client_id VARCHAR(255) NOT NULL,
|
|
1571
|
+
client_secret TEXT NOT NULL,
|
|
1572
|
+
authorization_endpoint TEXT NOT NULL,
|
|
1573
|
+
token_endpoint TEXT NOT NULL,
|
|
1574
|
+
userinfo_endpoint TEXT NOT NULL,
|
|
1575
|
+
enabled BOOLEAN DEFAULT true
|
|
1576
|
+
);
|
|
1577
|
+
|
|
1578
|
+
CREATE TABLE queen.auth_oauth_tokens (
|
|
1579
|
+
id UUID PRIMARY KEY,
|
|
1580
|
+
user_id UUID REFERENCES queen.auth_users(id),
|
|
1581
|
+
provider_id UUID REFERENCES queen.auth_oauth_providers(id),
|
|
1582
|
+
access_token_hash TEXT NOT NULL,
|
|
1583
|
+
refresh_token_hash TEXT,
|
|
1584
|
+
expires_at TIMESTAMPTZ,
|
|
1585
|
+
scope TEXT
|
|
1586
|
+
);
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1589
|
+
**Implementation Effort:** ~2 weeks
|
|
1590
|
+
|
|
1591
|
+
---
|
|
1592
|
+
|
|
1593
|
+
#### 2. Rate Limiting
|
|
1594
|
+
|
|
1595
|
+
**Use Case:** Prevent abuse, DDoS protection, API quota management
|
|
1596
|
+
|
|
1597
|
+
**Design:**
|
|
1598
|
+
- Token bucket algorithm
|
|
1599
|
+
- Per-user and per-token rate limits
|
|
1600
|
+
- Configurable limits per endpoint
|
|
1601
|
+
- Redis-backed for multi-server support
|
|
1602
|
+
- Sliding window counters
|
|
1603
|
+
|
|
1604
|
+
**Configuration:**
|
|
1605
|
+
```bash
|
|
1606
|
+
QUEEN_RATE_LIMIT_ENABLED=true
|
|
1607
|
+
QUEEN_RATE_LIMIT_WINDOW=60000 # 1 minute
|
|
1608
|
+
QUEEN_RATE_LIMIT_MAX_REQUESTS=100
|
|
1609
|
+
QUEEN_RATE_LIMIT_REDIS_URL=redis://localhost:6379
|
|
1610
|
+
```
|
|
1611
|
+
|
|
1612
|
+
**Tables:**
|
|
1613
|
+
```sql
|
|
1614
|
+
CREATE TABLE queen.auth_rate_limits (
|
|
1615
|
+
id UUID PRIMARY KEY,
|
|
1616
|
+
user_id UUID REFERENCES queen.auth_users(id),
|
|
1617
|
+
service_token_id UUID REFERENCES queen.auth_service_tokens(id),
|
|
1618
|
+
endpoint VARCHAR(255),
|
|
1619
|
+
max_requests INTEGER NOT NULL,
|
|
1620
|
+
window_seconds INTEGER NOT NULL
|
|
1621
|
+
);
|
|
1622
|
+
```
|
|
1623
|
+
|
|
1624
|
+
**Response Headers:**
|
|
1625
|
+
```
|
|
1626
|
+
X-RateLimit-Limit: 100
|
|
1627
|
+
X-RateLimit-Remaining: 87
|
|
1628
|
+
X-RateLimit-Reset: 1697194500
|
|
1629
|
+
```
|
|
1630
|
+
|
|
1631
|
+
**Implementation Effort:** ~1 week
|
|
1632
|
+
|
|
1633
|
+
---
|
|
1634
|
+
|
|
1635
|
+
#### 3. Multi-Tenancy
|
|
1636
|
+
|
|
1637
|
+
**Use Case:** SaaS deployment, isolated customer environments
|
|
1638
|
+
|
|
1639
|
+
**Design:**
|
|
1640
|
+
- Tenant isolation at database level (RLS)
|
|
1641
|
+
- Tenant-specific queues and messages
|
|
1642
|
+
- Tenant-specific users and tokens
|
|
1643
|
+
- Cross-tenant queries forbidden
|
|
1644
|
+
- Tenant ID in all auth tokens
|
|
1645
|
+
|
|
1646
|
+
**Tables:**
|
|
1647
|
+
```sql
|
|
1648
|
+
CREATE TABLE queen.tenants (
|
|
1649
|
+
id UUID PRIMARY KEY,
|
|
1650
|
+
name VARCHAR(255) UNIQUE NOT NULL,
|
|
1651
|
+
subdomain VARCHAR(255) UNIQUE,
|
|
1652
|
+
enabled BOOLEAN DEFAULT true,
|
|
1653
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
1654
|
+
);
|
|
1655
|
+
|
|
1656
|
+
-- Add tenant_id to all tables
|
|
1657
|
+
ALTER TABLE queen.auth_users ADD COLUMN tenant_id UUID REFERENCES queen.tenants(id);
|
|
1658
|
+
ALTER TABLE queen.queues ADD COLUMN tenant_id UUID REFERENCES queen.tenants(id);
|
|
1659
|
+
ALTER TABLE queen.partitions ADD COLUMN tenant_id UUID REFERENCES queen.tenants(id);
|
|
1660
|
+
ALTER TABLE queen.messages ADD COLUMN tenant_id UUID REFERENCES queen.tenants(id);
|
|
1661
|
+
|
|
1662
|
+
-- Row Level Security
|
|
1663
|
+
ALTER TABLE queen.auth_users ENABLE ROW LEVEL SECURITY;
|
|
1664
|
+
CREATE POLICY tenant_isolation ON queen.auth_users
|
|
1665
|
+
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
1666
|
+
```
|
|
1667
|
+
|
|
1668
|
+
**Token Format:**
|
|
1669
|
+
```
|
|
1670
|
+
qn_svc_<tenant_id>_<token>
|
|
1671
|
+
```
|
|
1672
|
+
|
|
1673
|
+
**Implementation Effort:** ~3 weeks (significant refactoring required)
|
|
1674
|
+
|
|
1675
|
+
---
|
|
1676
|
+
|
|
1677
|
+
#### 4. Advanced Audit Features
|
|
1678
|
+
|
|
1679
|
+
**Enhancements:**
|
|
1680
|
+
- Real-time audit log streaming (WebSocket)
|
|
1681
|
+
- Audit log export (CSV, JSON)
|
|
1682
|
+
- Audit log search with Elasticsearch
|
|
1683
|
+
- Compliance reports (SOC 2, HIPAA)
|
|
1684
|
+
- Alert rules for suspicious activity
|
|
1685
|
+
|
|
1686
|
+
**Implementation Effort:** ~1-2 weeks
|
|
1687
|
+
|
|
1688
|
+
---
|
|
1689
|
+
|
|
1690
|
+
#### 5. API Key Management UI
|
|
1691
|
+
|
|
1692
|
+
**Features:**
|
|
1693
|
+
- Dashboard page for managing service tokens
|
|
1694
|
+
- Token usage analytics
|
|
1695
|
+
- Token expiration alerts
|
|
1696
|
+
- Token rotation wizard
|
|
1697
|
+
- QR codes for token sharing (mobile apps)
|
|
1698
|
+
|
|
1699
|
+
**Implementation Effort:** ~1 week
|
|
1700
|
+
|
|
1701
|
+
---
|
|
1702
|
+
|
|
1703
|
+
#### 6. Advanced Permissions
|
|
1704
|
+
|
|
1705
|
+
**Enhancements:**
|
|
1706
|
+
- Custom roles (beyond admin/rw/read)
|
|
1707
|
+
- Granular permissions per queue
|
|
1708
|
+
- Partition-level access control
|
|
1709
|
+
- Namespace/task-level access control
|
|
1710
|
+
- Time-based access (tokens valid only during business hours)
|
|
1711
|
+
|
|
1712
|
+
**Example:**
|
|
1713
|
+
```json
|
|
1714
|
+
{
|
|
1715
|
+
"name": "analytics-service",
|
|
1716
|
+
"role": "custom",
|
|
1717
|
+
"permissions": {
|
|
1718
|
+
"orders": ["pop", "ack"],
|
|
1719
|
+
"payments": ["pop", "ack"],
|
|
1720
|
+
"events": ["push"],
|
|
1721
|
+
"analytics/*": ["push", "pop", "ack"]
|
|
1722
|
+
},
|
|
1723
|
+
"schedule": {
|
|
1724
|
+
"timezone": "UTC",
|
|
1725
|
+
"allowed_hours": "09:00-17:00",
|
|
1726
|
+
"allowed_days": ["Mon", "Tue", "Wed", "Thu", "Fri"]
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
```
|
|
1730
|
+
|
|
1731
|
+
**Implementation Effort:** ~2 weeks
|
|
1732
|
+
|
|
1733
|
+
---
|
|
1734
|
+
|
|
1735
|
+
#### 7. Two-Factor Authentication (2FA)
|
|
1736
|
+
|
|
1737
|
+
**Use Case:** Enhanced security for dashboard users
|
|
1738
|
+
|
|
1739
|
+
**Design:**
|
|
1740
|
+
- TOTP-based 2FA (Google Authenticator, Authy)
|
|
1741
|
+
- Backup codes for recovery
|
|
1742
|
+
- 2FA enforcement per user or globally
|
|
1743
|
+
- Remember device option
|
|
1744
|
+
|
|
1745
|
+
**Tables:**
|
|
1746
|
+
```sql
|
|
1747
|
+
CREATE TABLE queen.auth_2fa (
|
|
1748
|
+
id UUID PRIMARY KEY,
|
|
1749
|
+
user_id UUID REFERENCES queen.auth_users(id),
|
|
1750
|
+
secret TEXT NOT NULL,
|
|
1751
|
+
enabled BOOLEAN DEFAULT false,
|
|
1752
|
+
backup_codes JSONB,
|
|
1753
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
1754
|
+
);
|
|
1755
|
+
```
|
|
1756
|
+
|
|
1757
|
+
**Implementation Effort:** ~1 week
|
|
1758
|
+
|
|
1759
|
+
---
|
|
1760
|
+
|
|
1761
|
+
#### 8. Webhook Notifications
|
|
1762
|
+
|
|
1763
|
+
**Use Case:** Security alerts, audit notifications
|
|
1764
|
+
|
|
1765
|
+
**Design:**
|
|
1766
|
+
- Configurable webhooks for auth events
|
|
1767
|
+
- Failed login attempts → Slack/PagerDuty
|
|
1768
|
+
- New token created → Email notification
|
|
1769
|
+
- Suspicious activity → Security team alert
|
|
1770
|
+
|
|
1771
|
+
**Tables:**
|
|
1772
|
+
```sql
|
|
1773
|
+
CREATE TABLE queen.auth_webhooks (
|
|
1774
|
+
id UUID PRIMARY KEY,
|
|
1775
|
+
name VARCHAR(255) NOT NULL,
|
|
1776
|
+
url TEXT NOT NULL,
|
|
1777
|
+
events JSONB NOT NULL, -- ["login.failed", "token.created"]
|
|
1778
|
+
enabled BOOLEAN DEFAULT true,
|
|
1779
|
+
secret TEXT -- HMAC signature
|
|
1780
|
+
);
|
|
1781
|
+
```
|
|
1782
|
+
|
|
1783
|
+
**Implementation Effort:** ~3 days
|
|
1784
|
+
|
|
1785
|
+
---
|
|
1786
|
+
|
|
1787
|
+
## Appendices
|
|
1788
|
+
|
|
1789
|
+
### Appendix A: Token Format Specification
|
|
1790
|
+
|
|
1791
|
+
**Service Token Format:**
|
|
1792
|
+
```
|
|
1793
|
+
qn_svc_<base58_encoded_32_bytes>
|
|
1794
|
+
|
|
1795
|
+
Prefix: qn_svc_
|
|
1796
|
+
Encoding: Base58 (Bitcoin alphabet)
|
|
1797
|
+
Length: 32 bytes (44 characters in base58)
|
|
1798
|
+
Total: 51 characters
|
|
1799
|
+
|
|
1800
|
+
Example:
|
|
1801
|
+
qn_svc_8K7jQm3pN2xR5wV9yB4cE6fH8jL1mN3qT5uW7xZ9a
|
|
1802
|
+
```
|
|
1803
|
+
|
|
1804
|
+
**Why Base58?**
|
|
1805
|
+
- No ambiguous characters (0/O, I/l)
|
|
1806
|
+
- URL-safe without encoding
|
|
1807
|
+
- Human-readable
|
|
1808
|
+
- Copy-paste friendly
|
|
1809
|
+
|
|
1810
|
+
**JWT Format:**
|
|
1811
|
+
```
|
|
1812
|
+
header.payload.signature
|
|
1813
|
+
|
|
1814
|
+
Header:
|
|
1815
|
+
{
|
|
1816
|
+
"alg": "HS256",
|
|
1817
|
+
"typ": "JWT"
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
Payload (Access Token):
|
|
1821
|
+
{
|
|
1822
|
+
"sub": "user-uuid",
|
|
1823
|
+
"username": "alice",
|
|
1824
|
+
"role": "admin",
|
|
1825
|
+
"type": "access",
|
|
1826
|
+
"iat": 1697193600,
|
|
1827
|
+
"exp": 1697194500
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
Payload (Refresh Token):
|
|
1831
|
+
{
|
|
1832
|
+
"sub": "user-uuid",
|
|
1833
|
+
"type": "refresh",
|
|
1834
|
+
"jti": "refresh-token-uuid",
|
|
1835
|
+
"iat": 1697193600,
|
|
1836
|
+
"exp": 1697798400
|
|
1837
|
+
}
|
|
1838
|
+
```
|
|
1839
|
+
|
|
1840
|
+
---
|
|
1841
|
+
|
|
1842
|
+
### Appendix B: Error Codes
|
|
1843
|
+
|
|
1844
|
+
**Authentication Errors:**
|
|
1845
|
+
|
|
1846
|
+
| Code | Message | HTTP Status | Description |
|
|
1847
|
+
|------|---------|-------------|-------------|
|
|
1848
|
+
| `AUTH_DISABLED` | Authentication is not enabled | 501 | Auth system is disabled |
|
|
1849
|
+
| `MISSING_TOKEN` | No authentication token provided | 401 | Authorization header missing |
|
|
1850
|
+
| `INVALID_TOKEN` | Invalid authentication token | 401 | Token format invalid |
|
|
1851
|
+
| `EXPIRED_TOKEN` | Authentication token expired | 401 | JWT expired |
|
|
1852
|
+
| `REVOKED_TOKEN` | Token has been revoked | 401 | Refresh token revoked |
|
|
1853
|
+
| `INVALID_CREDENTIALS` | Invalid username or password | 401 | Login failed |
|
|
1854
|
+
| `ACCOUNT_DISABLED` | User account is disabled | 403 | Account not enabled |
|
|
1855
|
+
| `TOKEN_DISABLED` | Service token is disabled | 403 | Token not enabled |
|
|
1856
|
+
|
|
1857
|
+
**Authorization Errors:**
|
|
1858
|
+
|
|
1859
|
+
| Code | Message | HTTP Status | Description |
|
|
1860
|
+
|------|---------|-------------|-------------|
|
|
1861
|
+
| `INSUFFICIENT_PERMISSIONS` | Insufficient permissions | 403 | Role lacks required permission |
|
|
1862
|
+
| `QUEUE_ACCESS_DENIED` | Access denied to this queue | 403 | Queue not in allowed_queues |
|
|
1863
|
+
| `OPERATION_NOT_ALLOWED` | Operation not allowed | 403 | Operation not in allowed_operations |
|
|
1864
|
+
|
|
1865
|
+
**Example Error Response:**
|
|
1866
|
+
```json
|
|
1867
|
+
{
|
|
1868
|
+
"error": {
|
|
1869
|
+
"code": "INVALID_TOKEN",
|
|
1870
|
+
"message": "Invalid authentication token",
|
|
1871
|
+
"details": "Token signature verification failed"
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
```
|
|
1875
|
+
|
|
1876
|
+
---
|
|
1877
|
+
|
|
1878
|
+
### Appendix C: Migration Guide
|
|
1879
|
+
|
|
1880
|
+
**Migrating from No-Auth to Auth-Enabled:**
|
|
1881
|
+
|
|
1882
|
+
1. **Preparation (No Downtime):**
|
|
1883
|
+
```bash
|
|
1884
|
+
# 1. Generate JWT secret
|
|
1885
|
+
export QUEEN_JWT_SECRET=$(openssl rand -hex 32)
|
|
1886
|
+
|
|
1887
|
+
# 2. Deploy Queen with auth disabled (default)
|
|
1888
|
+
# Auth tables will be created but not used
|
|
1889
|
+
npm start
|
|
1890
|
+
|
|
1891
|
+
# 3. Initialize auth system
|
|
1892
|
+
node cli/auth.js init
|
|
1893
|
+
# Creates admin user interactively
|
|
1894
|
+
|
|
1895
|
+
# 4. Generate service tokens for all microservices
|
|
1896
|
+
node cli/auth.js token create --name service-1 --role rw
|
|
1897
|
+
node cli/auth.js token create --name service-2 --role rw
|
|
1898
|
+
# ... etc
|
|
1899
|
+
```
|
|
1900
|
+
|
|
1901
|
+
2. **Testing (Staging Environment):**
|
|
1902
|
+
```bash
|
|
1903
|
+
# 1. Enable auth in staging
|
|
1904
|
+
export QUEEN_AUTH_ENABLED=true
|
|
1905
|
+
npm start
|
|
1906
|
+
|
|
1907
|
+
# 2. Update staging clients to use tokens
|
|
1908
|
+
# 3. Test all workflows
|
|
1909
|
+
# 4. Monitor audit logs
|
|
1910
|
+
```
|
|
1911
|
+
|
|
1912
|
+
3. **Production Deployment (Staged Rollout):**
|
|
1913
|
+
```bash
|
|
1914
|
+
# Week 1: Dashboard only
|
|
1915
|
+
# - Enable auth for dashboard
|
|
1916
|
+
# - API remains open (QUEEN_AUTH_ENABLED=false)
|
|
1917
|
+
# - Users get familiar with login
|
|
1918
|
+
|
|
1919
|
+
# Week 2: Read-only services
|
|
1920
|
+
# - Enable auth (QUEEN_AUTH_ENABLED=true)
|
|
1921
|
+
# - Deploy tokens to monitoring services
|
|
1922
|
+
# - API still accepts unauthenticated requests (grace period)
|
|
1923
|
+
|
|
1924
|
+
# Week 3: All services
|
|
1925
|
+
# - Deploy tokens to all microservices
|
|
1926
|
+
# - Monitor errors
|
|
1927
|
+
# - Provide support for issues
|
|
1928
|
+
|
|
1929
|
+
# Week 4: Enforce
|
|
1930
|
+
# - Remove grace period
|
|
1931
|
+
# - All requests require authentication
|
|
1932
|
+
# - Monitor audit logs for unauthorized attempts
|
|
1933
|
+
```
|
|
1934
|
+
|
|
1935
|
+
4. **Rollback Plan:**
|
|
1936
|
+
```bash
|
|
1937
|
+
# If issues arise, disable auth immediately
|
|
1938
|
+
export QUEEN_AUTH_ENABLED=false
|
|
1939
|
+
# Restart Queen servers
|
|
1940
|
+
# System returns to no-auth mode
|
|
1941
|
+
# No data loss, no breaking changes
|
|
1942
|
+
```
|
|
1943
|
+
|
|
1944
|
+
---
|
|
1945
|
+
|
|
1946
|
+
### Appendix D: Performance Considerations
|
|
1947
|
+
|
|
1948
|
+
**Authentication Overhead:**
|
|
1949
|
+
|
|
1950
|
+
| Operation | No Auth | With Auth | Overhead |
|
|
1951
|
+
|-----------|---------|-----------|----------|
|
|
1952
|
+
| Service Token Validation | N/A | ~2-3ms | SHA-256 hash + DB lookup |
|
|
1953
|
+
| JWT Validation | N/A | ~0.5-1ms | Signature verification (no DB) |
|
|
1954
|
+
| Permission Check | N/A | ~0.1ms | In-memory check |
|
|
1955
|
+
| **Total per request** | 0ms | **~1-4ms** | Minimal |
|
|
1956
|
+
|
|
1957
|
+
**Optimizations:**
|
|
1958
|
+
|
|
1959
|
+
1. **Token Cache:** Cache validated service tokens in memory (5 min TTL)
|
|
1960
|
+
- First request: ~3ms (DB lookup)
|
|
1961
|
+
- Subsequent requests: ~0.1ms (cache hit)
|
|
1962
|
+
|
|
1963
|
+
2. **JWT Stateless:** JWT access tokens require no DB lookup
|
|
1964
|
+
- Signature verification only
|
|
1965
|
+
- ~0.5ms per request
|
|
1966
|
+
|
|
1967
|
+
3. **Permission Matrix:** Pre-computed in memory
|
|
1968
|
+
- No DB queries for permission checks
|
|
1969
|
+
- ~0.1ms lookup time
|
|
1970
|
+
|
|
1971
|
+
4. **Batch Operations:** Auth overhead is per-request, not per-message
|
|
1972
|
+
- Pushing 1000 messages: ~3ms auth + ~100ms processing
|
|
1973
|
+
- Overhead: ~3% of total time
|
|
1974
|
+
|
|
1975
|
+
**Database Impact:**
|
|
1976
|
+
|
|
1977
|
+
- Auth tables are small and heavily indexed
|
|
1978
|
+
- Token lookups use hash index (O(1))
|
|
1979
|
+
- Audit logs written asynchronously
|
|
1980
|
+
- No impact on message queue performance
|
|
1981
|
+
|
|
1982
|
+
**Recommended Settings:**
|
|
1983
|
+
|
|
1984
|
+
```bash
|
|
1985
|
+
# For high-traffic production
|
|
1986
|
+
QUEEN_JWT_ACCESS_EXPIRY=900 # 15 min (balance security vs cache hit rate)
|
|
1987
|
+
QUEEN_AUTH_CACHE_ENABLED=true # Enable token caching
|
|
1988
|
+
QUEEN_AUTH_CACHE_TTL=300 # 5 min cache TTL
|
|
1989
|
+
```
|
|
1990
|
+
|
|
1991
|
+
---
|
|
1992
|
+
|
|
1993
|
+
### Appendix E: Compliance & Standards
|
|
1994
|
+
|
|
1995
|
+
**Standards Followed:**
|
|
1996
|
+
|
|
1997
|
+
- ✅ **OWASP Top 10:** Protection against common vulnerabilities
|
|
1998
|
+
- ✅ **NIST 800-63B:** Digital identity guidelines (password requirements)
|
|
1999
|
+
- ✅ **JWT RFC 7519:** JSON Web Token standard
|
|
2000
|
+
- ✅ **OAuth 2.0 RFC 6749:** (future: OAuth2 support)
|
|
2001
|
+
- ✅ **OpenID Connect:** (future: OIDC support)
|
|
2002
|
+
|
|
2003
|
+
**Compliance Support:**
|
|
2004
|
+
|
|
2005
|
+
| Requirement | Supported | How |
|
|
2006
|
+
|-------------|-----------|-----|
|
|
2007
|
+
| **SOC 2** | ✅ | Audit logs, access control, encryption |
|
|
2008
|
+
| **HIPAA** | ✅ | Encryption at rest/transit, audit trails, access control |
|
|
2009
|
+
| **GDPR** | ✅ | User data export, right to deletion, audit logs |
|
|
2010
|
+
| **PCI DSS** | ⚠️ | Partial (use separate DB for card data) |
|
|
2011
|
+
|
|
2012
|
+
---
|
|
2013
|
+
|
|
2014
|
+
## Conclusion
|
|
2015
|
+
|
|
2016
|
+
This authentication system is designed to be:
|
|
2017
|
+
|
|
2018
|
+
- **Production-ready** from day one
|
|
2019
|
+
- **Secure** by following industry standards
|
|
2020
|
+
- **Flexible** for various deployment scenarios
|
|
2021
|
+
- **Performant** with minimal overhead
|
|
2022
|
+
- **Developer-friendly** with CLI tools and clear documentation
|
|
2023
|
+
|
|
2024
|
+
The phased implementation approach (7 weeks) allows for:
|
|
2025
|
+
- Incremental development and testing
|
|
2026
|
+
- Early feedback and course correction
|
|
2027
|
+
- Low-risk deployment with rollback options
|
|
2028
|
+
- Zero impact on existing Queen installations
|
|
2029
|
+
|
|
2030
|
+
**Next Steps:**
|
|
2031
|
+
|
|
2032
|
+
1. Review this plan and gather feedback
|
|
2033
|
+
2. Prioritize features (if needed)
|
|
2034
|
+
3. Begin Phase 1 implementation
|
|
2035
|
+
4. Set up staging environment for testing
|
|
2036
|
+
5. Develop migration guide for existing users
|
|
2037
|
+
|
|
2038
|
+
---
|
|
2039
|
+
|
|
2040
|
+
**Document Version:** 1.0
|
|
2041
|
+
**Last Updated:** October 13, 2025
|
|
2042
|
+
**Status:** Planning Phase - Ready for Implementation
|
|
2043
|
+
**Estimated Implementation Time:** 7 weeks (one developer)
|
|
2044
|
+
|