@authrim/setup 0.1.134 → 0.1.136
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/dist/core/cloudflare.d.ts.map +1 -1
- package/dist/core/cloudflare.js +15 -0
- package/dist/core/cloudflare.js.map +1 -1
- package/dist/web/api.d.ts.map +1 -1
- package/dist/web/api.js +55 -31
- package/dist/web/api.js.map +1 -1
- package/migrations/000_fresh_schema.sql +1966 -0
- package/migrations/admin/001_admin_users.sql +189 -0
- package/migrations/admin/002_admin_rbac.sql +256 -0
- package/migrations/admin/003_admin_audit.sql +175 -0
- package/migrations/admin/004_admin_security.sql +132 -0
- package/migrations/admin/005_admin_abac_rebac.sql +345 -0
- package/migrations/admin/006_admin_setup_tokens.sql +91 -0
- package/migrations/pii/001_pii_initial.sql +466 -0
- package/migrations/pii/002_pii_log_tables.sql +139 -0
- package/migrations/pii/003_tombstone_timestamps.sql +12 -0
- package/migrations/pii/004_cleanup_admin_from_pii.sql +50 -0
- package/package.json +2 -1
|
@@ -0,0 +1,1966 @@
|
|
|
1
|
+
-- =============================================================================
|
|
2
|
+
-- Fresh Schema for Authrim Core DB
|
|
3
|
+
-- Generated from conformance environment
|
|
4
|
+
-- =============================================================================
|
|
5
|
+
|
|
6
|
+
CREATE TABLE access_review_items (
|
|
7
|
+
id TEXT PRIMARY KEY,
|
|
8
|
+
review_id TEXT NOT NULL REFERENCES access_reviews(id) ON DELETE CASCADE,
|
|
9
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
10
|
+
user_id TEXT NOT NULL, -- User being reviewed
|
|
11
|
+
permission_type TEXT NOT NULL, -- role, permission, group_membership
|
|
12
|
+
permission_value TEXT NOT NULL, -- The specific permission/role/group
|
|
13
|
+
decision TEXT, -- approved, revoked, pending
|
|
14
|
+
decided_by TEXT, -- Reviewer who made decision
|
|
15
|
+
decided_at TEXT, -- When decision was made
|
|
16
|
+
justification TEXT, -- Reason for decision
|
|
17
|
+
created_at TEXT NOT NULL
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE access_reviews (
|
|
21
|
+
id TEXT PRIMARY KEY,
|
|
22
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
23
|
+
name TEXT NOT NULL, -- Review campaign name
|
|
24
|
+
description TEXT, -- Campaign description
|
|
25
|
+
scope TEXT NOT NULL, -- all_users, role, organization, application
|
|
26
|
+
scope_value TEXT, -- Value for scope (role_id, org_id, client_id)
|
|
27
|
+
status TEXT NOT NULL DEFAULT 'pending', -- pending, in_progress, completed, cancelled
|
|
28
|
+
reviewer_id TEXT, -- User assigned to review
|
|
29
|
+
total_items INTEGER NOT NULL DEFAULT 0, -- Total items to review
|
|
30
|
+
reviewed_items INTEGER NOT NULL DEFAULT 0, -- Items reviewed
|
|
31
|
+
approved_items INTEGER NOT NULL DEFAULT 0, -- Items approved (access retained)
|
|
32
|
+
revoked_items INTEGER NOT NULL DEFAULT 0, -- Items revoked (access removed)
|
|
33
|
+
created_at TEXT NOT NULL,
|
|
34
|
+
started_at TEXT, -- When review started
|
|
35
|
+
completed_at TEXT, -- When review completed
|
|
36
|
+
due_date TEXT -- Review deadline
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
CREATE TABLE admin_jobs (
|
|
40
|
+
-- Primary key
|
|
41
|
+
id TEXT PRIMARY KEY,
|
|
42
|
+
|
|
43
|
+
-- Multi-tenant support
|
|
44
|
+
tenant_id TEXT NOT NULL,
|
|
45
|
+
|
|
46
|
+
-- Job type (e.g., 'users/import', 'users/bulk-update', 'reports/generate')
|
|
47
|
+
job_type TEXT NOT NULL,
|
|
48
|
+
|
|
49
|
+
-- Job status (pending, processing, completed, failed, partial_failure)
|
|
50
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
51
|
+
|
|
52
|
+
-- Progress tracking (JSON)
|
|
53
|
+
-- { "total": 100, "processed": 45, "succeeded": 43, "failed": 2 }
|
|
54
|
+
progress TEXT,
|
|
55
|
+
|
|
56
|
+
-- Job configuration (JSON)
|
|
57
|
+
-- Input parameters for the job
|
|
58
|
+
config TEXT,
|
|
59
|
+
|
|
60
|
+
-- R2 key for input file (for import jobs)
|
|
61
|
+
input_r2_key TEXT,
|
|
62
|
+
|
|
63
|
+
-- R2 key for result file (for completed jobs with large results)
|
|
64
|
+
result_r2_key TEXT,
|
|
65
|
+
|
|
66
|
+
-- Result summary (JSON, for completed jobs)
|
|
67
|
+
-- { "summary": {...}, "failures": [...] }
|
|
68
|
+
result TEXT,
|
|
69
|
+
|
|
70
|
+
-- Error information (for failed jobs)
|
|
71
|
+
error_code TEXT,
|
|
72
|
+
error_message TEXT,
|
|
73
|
+
|
|
74
|
+
-- Actor who created the job
|
|
75
|
+
created_by TEXT NOT NULL,
|
|
76
|
+
|
|
77
|
+
-- Timestamps (Unix timestamp in seconds)
|
|
78
|
+
created_at INTEGER NOT NULL,
|
|
79
|
+
updated_at INTEGER NOT NULL,
|
|
80
|
+
started_at INTEGER,
|
|
81
|
+
completed_at INTEGER,
|
|
82
|
+
|
|
83
|
+
-- Estimated completion time
|
|
84
|
+
estimated_completion INTEGER
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
CREATE TABLE ai_grants (
|
|
88
|
+
id TEXT PRIMARY KEY,
|
|
89
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
90
|
+
client_id TEXT NOT NULL,
|
|
91
|
+
ai_principal TEXT NOT NULL,
|
|
92
|
+
scopes TEXT NOT NULL,
|
|
93
|
+
scope_targets TEXT,
|
|
94
|
+
is_active INTEGER NOT NULL DEFAULT 1,
|
|
95
|
+
expires_at INTEGER,
|
|
96
|
+
created_by TEXT,
|
|
97
|
+
created_at INTEGER NOT NULL,
|
|
98
|
+
updated_at INTEGER NOT NULL,
|
|
99
|
+
revoked_at INTEGER,
|
|
100
|
+
revoked_by TEXT,
|
|
101
|
+
UNIQUE(tenant_id, client_id, ai_principal)
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
CREATE TABLE attribute_verifications (
|
|
105
|
+
id TEXT PRIMARY KEY,
|
|
106
|
+
tenant_id TEXT NOT NULL,
|
|
107
|
+
user_id TEXT NOT NULL,
|
|
108
|
+
vp_request_id TEXT REFERENCES vp_requests(id),
|
|
109
|
+
-- Issuer DID
|
|
110
|
+
issuer_did TEXT NOT NULL,
|
|
111
|
+
-- Verifiable Credential Type
|
|
112
|
+
credential_type TEXT NOT NULL,
|
|
113
|
+
-- Format: 'dc+sd-jwt' | 'mso_mdoc'
|
|
114
|
+
format TEXT NOT NULL,
|
|
115
|
+
-- Verification result: 'verified' | 'failed' | 'expired'
|
|
116
|
+
verification_result TEXT NOT NULL,
|
|
117
|
+
-- Individual verification flags
|
|
118
|
+
holder_binding_verified INTEGER DEFAULT 0,
|
|
119
|
+
issuer_trusted INTEGER DEFAULT 0,
|
|
120
|
+
status_valid INTEGER DEFAULT 0,
|
|
121
|
+
-- JSON array of user_verified_attributes IDs
|
|
122
|
+
mapped_attribute_ids TEXT,
|
|
123
|
+
verified_at TEXT DEFAULT (datetime('now')),
|
|
124
|
+
expires_at TEXT
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
CREATE TABLE audit_log (
|
|
128
|
+
id TEXT PRIMARY KEY,
|
|
129
|
+
user_id TEXT,
|
|
130
|
+
action TEXT NOT NULL,
|
|
131
|
+
resource_type TEXT,
|
|
132
|
+
resource_id TEXT,
|
|
133
|
+
ip_address TEXT,
|
|
134
|
+
user_agent TEXT,
|
|
135
|
+
metadata_json TEXT,
|
|
136
|
+
created_at INTEGER NOT NULL
|
|
137
|
+
, tenant_id TEXT NOT NULL DEFAULT 'default', severity TEXT DEFAULT 'info');
|
|
138
|
+
|
|
139
|
+
CREATE TABLE branding_settings (
|
|
140
|
+
id TEXT PRIMARY KEY DEFAULT 'default',
|
|
141
|
+
custom_css TEXT,
|
|
142
|
+
custom_html_header TEXT,
|
|
143
|
+
custom_html_footer TEXT,
|
|
144
|
+
logo_url TEXT,
|
|
145
|
+
background_image_url TEXT,
|
|
146
|
+
primary_color TEXT DEFAULT '#3B82F6',
|
|
147
|
+
secondary_color TEXT DEFAULT '#10B981',
|
|
148
|
+
font_family TEXT DEFAULT 'Inter',
|
|
149
|
+
-- Authentication method settings
|
|
150
|
+
enabled_auth_methods TEXT DEFAULT '["passkey","magic_link"]', -- JSON array
|
|
151
|
+
password_policy_json TEXT, -- Password policy config (if password auth enabled)
|
|
152
|
+
updated_at INTEGER NOT NULL
|
|
153
|
+
, tenant_id TEXT NOT NULL DEFAULT 'default');
|
|
154
|
+
|
|
155
|
+
CREATE TABLE check_api_keys (
|
|
156
|
+
id TEXT PRIMARY KEY,
|
|
157
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
158
|
+
client_id TEXT NOT NULL,
|
|
159
|
+
name TEXT NOT NULL,
|
|
160
|
+
key_hash TEXT NOT NULL, -- SHA-256 hash of the API key
|
|
161
|
+
key_prefix TEXT NOT NULL, -- First 8 chars (chk_xxxx) for identification
|
|
162
|
+
allowed_operations TEXT DEFAULT '["check"]', -- JSON array: check, batch, subscribe
|
|
163
|
+
rate_limit_tier TEXT DEFAULT 'moderate', -- strict, moderate, lenient
|
|
164
|
+
is_active INTEGER DEFAULT 1,
|
|
165
|
+
expires_at INTEGER, -- Unix timestamp, NULL = no expiry
|
|
166
|
+
created_by TEXT, -- User ID who created this key
|
|
167
|
+
created_at INTEGER NOT NULL,
|
|
168
|
+
updated_at INTEGER NOT NULL
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
CREATE TABLE "ciba_requests" (
|
|
172
|
+
auth_req_id TEXT PRIMARY KEY,
|
|
173
|
+
client_id TEXT NOT NULL,
|
|
174
|
+
scope TEXT NOT NULL,
|
|
175
|
+
login_hint TEXT,
|
|
176
|
+
login_hint_token TEXT,
|
|
177
|
+
id_token_hint TEXT,
|
|
178
|
+
binding_message TEXT,
|
|
179
|
+
user_code TEXT,
|
|
180
|
+
acr_values TEXT,
|
|
181
|
+
requested_expiry INTEGER,
|
|
182
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'approved', 'denied', 'expired')),
|
|
183
|
+
delivery_mode TEXT NOT NULL CHECK (delivery_mode IN ('poll', 'ping', 'push')),
|
|
184
|
+
client_notification_token TEXT,
|
|
185
|
+
client_notification_endpoint TEXT,
|
|
186
|
+
created_at INTEGER NOT NULL,
|
|
187
|
+
expires_at INTEGER NOT NULL,
|
|
188
|
+
last_poll_at INTEGER,
|
|
189
|
+
poll_count INTEGER DEFAULT 0,
|
|
190
|
+
interval INTEGER NOT NULL DEFAULT 5,
|
|
191
|
+
user_id TEXT,
|
|
192
|
+
sub TEXT,
|
|
193
|
+
nonce TEXT,
|
|
194
|
+
token_issued INTEGER DEFAULT 0,
|
|
195
|
+
token_issued_at INTEGER,
|
|
196
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
197
|
+
FOREIGN KEY (client_id) REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
|
|
198
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
CREATE TABLE compliance_reports (
|
|
202
|
+
id TEXT PRIMARY KEY,
|
|
203
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
204
|
+
type TEXT NOT NULL, -- audit_log, access_report, user_activity, etc.
|
|
205
|
+
name TEXT NOT NULL, -- Report name/title
|
|
206
|
+
status TEXT NOT NULL DEFAULT 'pending', -- pending, generating, completed, failed
|
|
207
|
+
requested_by TEXT, -- User who requested the report
|
|
208
|
+
parameters TEXT, -- JSON: Report generation parameters
|
|
209
|
+
result_url TEXT, -- URL to download completed report
|
|
210
|
+
error_message TEXT, -- Error message if failed
|
|
211
|
+
created_at TEXT NOT NULL,
|
|
212
|
+
completed_at TEXT, -- When report generation completed
|
|
213
|
+
expires_at TEXT -- When report download expires
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
CREATE TABLE consent_history (
|
|
217
|
+
id TEXT PRIMARY KEY,
|
|
218
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
219
|
+
user_id TEXT NOT NULL,
|
|
220
|
+
client_id TEXT NOT NULL,
|
|
221
|
+
action TEXT NOT NULL, -- 'granted' | 'updated' | 'revoked' | 'version_upgraded' | 'expired' | 'scopes_updated'
|
|
222
|
+
scopes_before TEXT, -- JSON array of previous scopes (null for initial grant)
|
|
223
|
+
scopes_after TEXT, -- JSON array of new scopes (null for revocation)
|
|
224
|
+
privacy_policy_version TEXT,
|
|
225
|
+
tos_version TEXT,
|
|
226
|
+
ip_address_hash TEXT, -- Hashed IP for privacy
|
|
227
|
+
user_agent TEXT,
|
|
228
|
+
created_at INTEGER NOT NULL,
|
|
229
|
+
metadata_json TEXT, -- Additional context as JSON
|
|
230
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
CREATE TABLE consent_policy_versions (
|
|
234
|
+
id TEXT PRIMARY KEY,
|
|
235
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
236
|
+
version TEXT NOT NULL,
|
|
237
|
+
policy_type TEXT NOT NULL, -- 'privacy_policy' | 'terms_of_service' | 'cookie_policy'
|
|
238
|
+
policy_uri TEXT,
|
|
239
|
+
policy_hash TEXT, -- SHA-256 hash of policy content for integrity verification
|
|
240
|
+
effective_at INTEGER NOT NULL, -- Unix timestamp when this version becomes effective
|
|
241
|
+
created_at INTEGER NOT NULL,
|
|
242
|
+
UNIQUE (tenant_id, policy_type, version)
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
CREATE TABLE credential_configurations (
|
|
246
|
+
id TEXT PRIMARY KEY,
|
|
247
|
+
tenant_id TEXT NOT NULL,
|
|
248
|
+
-- Configuration ID (used in metadata)
|
|
249
|
+
configuration_id TEXT NOT NULL,
|
|
250
|
+
-- Format: 'dc+sd-jwt' | 'mso_mdoc'
|
|
251
|
+
format TEXT NOT NULL,
|
|
252
|
+
-- Verifiable Credential Type
|
|
253
|
+
vct TEXT NOT NULL,
|
|
254
|
+
-- JSON of display information
|
|
255
|
+
display TEXT,
|
|
256
|
+
-- JSON of claims configuration
|
|
257
|
+
claims TEXT,
|
|
258
|
+
-- JSON of proof types supported
|
|
259
|
+
proof_types_supported TEXT,
|
|
260
|
+
-- Signing algorithm
|
|
261
|
+
signing_alg TEXT DEFAULT 'ES256',
|
|
262
|
+
-- Active status
|
|
263
|
+
is_active INTEGER DEFAULT 1,
|
|
264
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
265
|
+
updated_at TEXT DEFAULT (datetime('now')),
|
|
266
|
+
UNIQUE(tenant_id, configuration_id)
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
CREATE TABLE credential_offers (
|
|
270
|
+
id TEXT PRIMARY KEY,
|
|
271
|
+
tenant_id TEXT NOT NULL,
|
|
272
|
+
user_id TEXT NOT NULL,
|
|
273
|
+
-- Credential configuration ID
|
|
274
|
+
credential_configuration_id TEXT NOT NULL,
|
|
275
|
+
-- Pre-authorized code
|
|
276
|
+
pre_authorized_code TEXT,
|
|
277
|
+
-- Transaction code (PIN)
|
|
278
|
+
tx_code TEXT,
|
|
279
|
+
-- JSON of grants configuration
|
|
280
|
+
grants TEXT NOT NULL,
|
|
281
|
+
-- Status: 'pending' | 'accepted' | 'issued' | 'failed' | 'expired'
|
|
282
|
+
status TEXT DEFAULT 'pending',
|
|
283
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
284
|
+
expires_at TEXT NOT NULL,
|
|
285
|
+
issued_at TEXT,
|
|
286
|
+
issued_credential_id TEXT REFERENCES issued_credentials(id)
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
CREATE TABLE d1_migrations(
|
|
290
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
291
|
+
name TEXT UNIQUE,
|
|
292
|
+
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
CREATE TABLE data_export_requests (
|
|
296
|
+
id TEXT PRIMARY KEY,
|
|
297
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
298
|
+
user_id TEXT NOT NULL,
|
|
299
|
+
status TEXT NOT NULL DEFAULT 'pending', -- 'pending' | 'processing' | 'completed' | 'failed' | 'expired'
|
|
300
|
+
format TEXT NOT NULL DEFAULT 'json', -- 'json' | 'csv'
|
|
301
|
+
include_sections TEXT NOT NULL, -- JSON array: ["profile", "consents", "sessions", "audit_log", "passkeys"]
|
|
302
|
+
requested_at INTEGER NOT NULL,
|
|
303
|
+
started_at INTEGER,
|
|
304
|
+
completed_at INTEGER,
|
|
305
|
+
expires_at INTEGER, -- Download link expiration
|
|
306
|
+
file_path TEXT, -- R2 object path (for async exports)
|
|
307
|
+
file_size INTEGER,
|
|
308
|
+
error_message TEXT,
|
|
309
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
CREATE TABLE device_codes (
|
|
313
|
+
device_code TEXT PRIMARY KEY,
|
|
314
|
+
user_code TEXT UNIQUE NOT NULL,
|
|
315
|
+
client_id TEXT NOT NULL,
|
|
316
|
+
scope TEXT NOT NULL,
|
|
317
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'approved', 'denied', 'expired')),
|
|
318
|
+
user_id TEXT,
|
|
319
|
+
sub TEXT,
|
|
320
|
+
created_at INTEGER NOT NULL,
|
|
321
|
+
expires_at INTEGER NOT NULL,
|
|
322
|
+
last_poll_at INTEGER,
|
|
323
|
+
poll_count INTEGER DEFAULT 0, tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
324
|
+
FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE CASCADE
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
CREATE TABLE did_document_cache (
|
|
328
|
+
did TEXT PRIMARY KEY,
|
|
329
|
+
-- JSON of DID Document
|
|
330
|
+
document TEXT NOT NULL,
|
|
331
|
+
resolved_at TEXT DEFAULT (datetime('now')),
|
|
332
|
+
expires_at TEXT NOT NULL
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
CREATE TABLE external_idp_auth_states (
|
|
336
|
+
id TEXT PRIMARY KEY,
|
|
337
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
338
|
+
provider_id TEXT NOT NULL, -- References upstream_providers(id)
|
|
339
|
+
state TEXT UNIQUE NOT NULL, -- OAuth state parameter
|
|
340
|
+
nonce TEXT, -- OIDC nonce for ID token validation
|
|
341
|
+
code_verifier TEXT, -- PKCE code verifier
|
|
342
|
+
redirect_uri TEXT NOT NULL, -- Where to redirect after auth
|
|
343
|
+
|
|
344
|
+
-- For linking flow
|
|
345
|
+
user_id TEXT, -- Set if linking to existing account
|
|
346
|
+
session_id TEXT, -- Authrim session (for linking flow)
|
|
347
|
+
|
|
348
|
+
-- For OIDC proxy flow (future)
|
|
349
|
+
original_auth_request TEXT, -- JSON of original OIDC auth request
|
|
350
|
+
|
|
351
|
+
-- OIDC Core 1.0 parameters (for validation in callback)
|
|
352
|
+
max_age INTEGER, -- max_age parameter for auth_time validation
|
|
353
|
+
acr_values TEXT, -- acr_values parameter for acr validation
|
|
354
|
+
|
|
355
|
+
-- Timestamps
|
|
356
|
+
expires_at INTEGER NOT NULL,
|
|
357
|
+
created_at INTEGER NOT NULL,
|
|
358
|
+
consumed_at INTEGER, -- When state was consumed (for single-use)
|
|
359
|
+
|
|
360
|
+
FOREIGN KEY (provider_id) REFERENCES upstream_providers(id) ON DELETE CASCADE
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
CREATE TABLE "flows" (
|
|
364
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
365
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
366
|
+
client_id TEXT,
|
|
367
|
+
profile_id TEXT NOT NULL,
|
|
368
|
+
name TEXT NOT NULL,
|
|
369
|
+
description TEXT,
|
|
370
|
+
graph_definition TEXT NOT NULL,
|
|
371
|
+
compiled_plan TEXT,
|
|
372
|
+
version TEXT NOT NULL DEFAULT '1.0.0',
|
|
373
|
+
is_active INTEGER NOT NULL DEFAULT 1,
|
|
374
|
+
is_builtin INTEGER NOT NULL DEFAULT 0,
|
|
375
|
+
created_by TEXT,
|
|
376
|
+
created_at INTEGER NOT NULL,
|
|
377
|
+
updated_by TEXT,
|
|
378
|
+
updated_at INTEGER NOT NULL
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
CREATE TABLE idempotency_keys (
|
|
382
|
+
id TEXT PRIMARY KEY, -- Composite: tenant_id:actor_id:method:path:resource_id:key
|
|
383
|
+
tenant_id TEXT NOT NULL,
|
|
384
|
+
actor_id TEXT NOT NULL, -- admin_id who made the request
|
|
385
|
+
method TEXT NOT NULL, -- HTTP method (POST, PUT, DELETE)
|
|
386
|
+
path TEXT NOT NULL, -- API path pattern
|
|
387
|
+
resource_id TEXT, -- Target resource ID (if applicable)
|
|
388
|
+
idempotency_key TEXT NOT NULL,-- The Idempotency-Key header value
|
|
389
|
+
body_hash TEXT NOT NULL, -- SHA-256 hash of request body
|
|
390
|
+
response_status INTEGER NOT NULL,
|
|
391
|
+
response_body TEXT NOT NULL, -- Sanitized response (PII removed)
|
|
392
|
+
created_at INTEGER NOT NULL,
|
|
393
|
+
expires_at INTEGER NOT NULL,
|
|
394
|
+
|
|
395
|
+
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
CREATE TABLE identity_providers (
|
|
399
|
+
id TEXT PRIMARY KEY,
|
|
400
|
+
name TEXT NOT NULL,
|
|
401
|
+
provider_type TEXT NOT NULL,
|
|
402
|
+
config_json TEXT NOT NULL,
|
|
403
|
+
enabled INTEGER DEFAULT 1,
|
|
404
|
+
created_at INTEGER NOT NULL,
|
|
405
|
+
updated_at INTEGER NOT NULL
|
|
406
|
+
, tenant_id TEXT NOT NULL DEFAULT 'default');
|
|
407
|
+
|
|
408
|
+
CREATE TABLE issued_credentials (
|
|
409
|
+
id TEXT PRIMARY KEY,
|
|
410
|
+
tenant_id TEXT NOT NULL,
|
|
411
|
+
user_id TEXT NOT NULL,
|
|
412
|
+
-- Verifiable Credential Type
|
|
413
|
+
credential_type TEXT NOT NULL,
|
|
414
|
+
-- Format: 'dc+sd-jwt' | 'mso_mdoc'
|
|
415
|
+
format TEXT NOT NULL,
|
|
416
|
+
-- JSON of claims included in credential
|
|
417
|
+
claims TEXT NOT NULL,
|
|
418
|
+
-- Status: 'active' | 'suspended' | 'revoked'
|
|
419
|
+
status TEXT DEFAULT 'active',
|
|
420
|
+
-- Status list index for revocation
|
|
421
|
+
status_list_index INTEGER,
|
|
422
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
423
|
+
expires_at TEXT,
|
|
424
|
+
revoked_at TEXT,
|
|
425
|
+
revoked_reason TEXT
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
CREATE TABLE "linked_identities" (
|
|
429
|
+
id TEXT PRIMARY KEY,
|
|
430
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
431
|
+
user_id TEXT NOT NULL,
|
|
432
|
+
provider_id TEXT NOT NULL,
|
|
433
|
+
provider_user_id TEXT NOT NULL,
|
|
434
|
+
provider_email TEXT,
|
|
435
|
+
email_verified INTEGER DEFAULT 0,
|
|
436
|
+
access_token_encrypted TEXT,
|
|
437
|
+
refresh_token_encrypted TEXT,
|
|
438
|
+
token_expires_at INTEGER,
|
|
439
|
+
raw_claims TEXT,
|
|
440
|
+
profile_data TEXT,
|
|
441
|
+
linked_at INTEGER NOT NULL,
|
|
442
|
+
last_login_at INTEGER,
|
|
443
|
+
updated_at INTEGER NOT NULL,
|
|
444
|
+
UNIQUE(provider_id, provider_user_id),
|
|
445
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE,
|
|
446
|
+
FOREIGN KEY (provider_id) REFERENCES upstream_providers(id) ON DELETE CASCADE
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
CREATE TABLE migration_metadata (
|
|
450
|
+
id TEXT PRIMARY KEY DEFAULT 'global',
|
|
451
|
+
|
|
452
|
+
-- Current schema version (highest applied migration version)
|
|
453
|
+
current_version INTEGER NOT NULL DEFAULT 0,
|
|
454
|
+
|
|
455
|
+
-- Last migration applied timestamp
|
|
456
|
+
last_migration_at INTEGER,
|
|
457
|
+
|
|
458
|
+
-- Environment (development, staging, production)
|
|
459
|
+
environment TEXT DEFAULT 'development',
|
|
460
|
+
|
|
461
|
+
-- Additional metadata as JSON
|
|
462
|
+
metadata_json TEXT
|
|
463
|
+
, tenant_id TEXT NOT NULL DEFAULT 'default');
|
|
464
|
+
|
|
465
|
+
CREATE TABLE "oauth_client_consents" (
|
|
466
|
+
id TEXT PRIMARY KEY,
|
|
467
|
+
user_id TEXT NOT NULL,
|
|
468
|
+
client_id TEXT NOT NULL,
|
|
469
|
+
scope TEXT NOT NULL,
|
|
470
|
+
granted_at INTEGER NOT NULL,
|
|
471
|
+
expires_at INTEGER,
|
|
472
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
473
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
474
|
+
tenant_id TEXT NOT NULL DEFAULT 'default', selected_scopes TEXT, privacy_policy_version TEXT, tos_version TEXT, consent_version INTEGER DEFAULT 1,
|
|
475
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE,
|
|
476
|
+
FOREIGN KEY (client_id) REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
|
|
477
|
+
UNIQUE (user_id, client_id)
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
CREATE TABLE oauth_clients (
|
|
481
|
+
client_id TEXT PRIMARY KEY,
|
|
482
|
+
client_name TEXT NOT NULL,
|
|
483
|
+
redirect_uris TEXT NOT NULL,
|
|
484
|
+
grant_types TEXT NOT NULL,
|
|
485
|
+
response_types TEXT NOT NULL,
|
|
486
|
+
scope TEXT,
|
|
487
|
+
logo_uri TEXT,
|
|
488
|
+
client_uri TEXT,
|
|
489
|
+
policy_uri TEXT,
|
|
490
|
+
tos_uri TEXT,
|
|
491
|
+
contacts TEXT,
|
|
492
|
+
subject_type TEXT DEFAULT 'public',
|
|
493
|
+
sector_identifier_uri TEXT,
|
|
494
|
+
token_endpoint_auth_method TEXT DEFAULT 'client_secret_basic',
|
|
495
|
+
-- RFC 8693: Token Exchange settings
|
|
496
|
+
token_exchange_allowed INTEGER DEFAULT 0,
|
|
497
|
+
allowed_subject_token_clients TEXT, -- JSON array of client IDs
|
|
498
|
+
allowed_token_exchange_resources TEXT, -- JSON array of resource URIs
|
|
499
|
+
delegation_mode TEXT DEFAULT 'delegation', -- 'none' | 'delegation' | 'impersonation'
|
|
500
|
+
-- RFC 6749 Section 4.4: Client Credentials settings
|
|
501
|
+
client_credentials_allowed INTEGER DEFAULT 0,
|
|
502
|
+
allowed_scopes TEXT, -- JSON array of allowed scopes
|
|
503
|
+
default_scope TEXT, -- Default scope for Client Credentials
|
|
504
|
+
default_audience TEXT, -- Default audience for Client Credentials
|
|
505
|
+
created_at INTEGER NOT NULL,
|
|
506
|
+
updated_at INTEGER NOT NULL
|
|
507
|
+
, is_trusted INTEGER DEFAULT 0, skip_consent INTEGER DEFAULT 0, allow_claims_without_scope INTEGER DEFAULT 0, backchannel_token_delivery_mode TEXT, backchannel_client_notification_endpoint TEXT, backchannel_authentication_request_signing_alg TEXT, backchannel_user_code_parameter INTEGER DEFAULT 0, tenant_id TEXT NOT NULL DEFAULT 'default', jwks TEXT, jwks_uri TEXT, userinfo_signed_response_alg TEXT, post_logout_redirect_uris TEXT, allowed_redirect_origins TEXT, backchannel_logout_uri TEXT, backchannel_logout_session_required INTEGER DEFAULT 0, frontchannel_logout_uri TEXT, frontchannel_logout_session_required INTEGER DEFAULT 0, logout_webhook_uri TEXT, logout_webhook_secret_encrypted TEXT, registration_access_token_hash TEXT, initiate_login_uri TEXT, id_token_signed_response_alg TEXT, request_object_signing_alg TEXT, client_secret_hash TEXT, software_id TEXT, software_version TEXT, requestable_scopes TEXT);
|
|
508
|
+
|
|
509
|
+
CREATE TABLE operational_logs (
|
|
510
|
+
id TEXT PRIMARY KEY,
|
|
511
|
+
tenant_id TEXT NOT NULL,
|
|
512
|
+
subject_type TEXT NOT NULL, -- Code expects: 'user', 'client', 'session'
|
|
513
|
+
subject_id TEXT NOT NULL, -- Code expects this name, not 'resource_id'
|
|
514
|
+
actor_id TEXT NOT NULL, -- Who performed the operation
|
|
515
|
+
action TEXT NOT NULL, -- 'user.suspend', 'user.lock', etc.
|
|
516
|
+
reason_detail_encrypted TEXT,-- AES-GCM encrypted reason_detail
|
|
517
|
+
encryption_key_version INTEGER NOT NULL DEFAULT 1, -- Code expects this column
|
|
518
|
+
request_id TEXT, -- X-Request-ID header value
|
|
519
|
+
created_at INTEGER NOT NULL,
|
|
520
|
+
expires_at INTEGER NOT NULL, -- When this log should be deleted
|
|
521
|
+
|
|
522
|
+
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
|
|
523
|
+
);
|
|
524
|
+
|
|
525
|
+
CREATE TABLE org_domain_mappings (
|
|
526
|
+
-- Primary key
|
|
527
|
+
id TEXT PRIMARY KEY,
|
|
528
|
+
|
|
529
|
+
-- Multi-tenant support
|
|
530
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
531
|
+
|
|
532
|
+
-- Domain identification (hashed for privacy)
|
|
533
|
+
-- Algorithm: HMAC-SHA256(lowercase(domain), secret_key)
|
|
534
|
+
domain_hash TEXT NOT NULL,
|
|
535
|
+
|
|
536
|
+
-- Key rotation support
|
|
537
|
+
domain_hash_version INTEGER DEFAULT 1,
|
|
538
|
+
|
|
539
|
+
-- Target organization
|
|
540
|
+
org_id TEXT NOT NULL, -- Reference to organizations.id
|
|
541
|
+
|
|
542
|
+
-- Auto-join settings
|
|
543
|
+
auto_join_enabled INTEGER DEFAULT 1, -- 0 = mapping exists but auto-join disabled
|
|
544
|
+
membership_type TEXT NOT NULL DEFAULT 'member', -- member, admin, owner
|
|
545
|
+
auto_assign_role_id TEXT, -- Optional: auto-assign this role on join
|
|
546
|
+
|
|
547
|
+
-- Verification status
|
|
548
|
+
verified INTEGER DEFAULT 0, -- 1 = domain ownership verified (DNS TXT, etc.)
|
|
549
|
+
|
|
550
|
+
-- Priority for multiple mappings
|
|
551
|
+
priority INTEGER DEFAULT 0, -- Higher = preferred when multiple match
|
|
552
|
+
|
|
553
|
+
-- Status
|
|
554
|
+
is_active INTEGER DEFAULT 1,
|
|
555
|
+
|
|
556
|
+
-- Timestamps
|
|
557
|
+
created_at INTEGER NOT NULL,
|
|
558
|
+
updated_at INTEGER NOT NULL, verification_token TEXT, verification_status TEXT DEFAULT 'unverified', verification_expires_at INTEGER, verification_method TEXT,
|
|
559
|
+
|
|
560
|
+
-- Constraints
|
|
561
|
+
-- Allow same domain to map to multiple orgs with different versions
|
|
562
|
+
UNIQUE(tenant_id, domain_hash, domain_hash_version, org_id)
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
CREATE TABLE organizations (
|
|
566
|
+
id TEXT PRIMARY KEY,
|
|
567
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
568
|
+
name TEXT NOT NULL,
|
|
569
|
+
display_name TEXT,
|
|
570
|
+
description TEXT,
|
|
571
|
+
org_type TEXT NOT NULL DEFAULT 'enterprise', -- distributor, enterprise, department
|
|
572
|
+
parent_org_id TEXT REFERENCES organizations(id),
|
|
573
|
+
plan TEXT DEFAULT 'free', -- free, starter, professional, enterprise
|
|
574
|
+
is_active INTEGER DEFAULT 1,
|
|
575
|
+
metadata_json TEXT,
|
|
576
|
+
created_at INTEGER NOT NULL,
|
|
577
|
+
updated_at INTEGER NOT NULL
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
CREATE TABLE "passkeys" (
|
|
581
|
+
id TEXT PRIMARY KEY,
|
|
582
|
+
user_id TEXT NOT NULL,
|
|
583
|
+
credential_id TEXT UNIQUE NOT NULL,
|
|
584
|
+
public_key TEXT NOT NULL,
|
|
585
|
+
counter INTEGER DEFAULT 0,
|
|
586
|
+
transports TEXT,
|
|
587
|
+
device_name TEXT,
|
|
588
|
+
created_at INTEGER NOT NULL,
|
|
589
|
+
last_used_at INTEGER,
|
|
590
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
591
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
592
|
+
);
|
|
593
|
+
|
|
594
|
+
CREATE TABLE "password_reset_tokens" (
|
|
595
|
+
id TEXT PRIMARY KEY,
|
|
596
|
+
user_id TEXT NOT NULL,
|
|
597
|
+
token_hash TEXT UNIQUE NOT NULL,
|
|
598
|
+
expires_at INTEGER NOT NULL,
|
|
599
|
+
used INTEGER DEFAULT 0,
|
|
600
|
+
created_at INTEGER NOT NULL,
|
|
601
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
602
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
603
|
+
);
|
|
604
|
+
|
|
605
|
+
CREATE TABLE permission_change_audit (
|
|
606
|
+
id TEXT PRIMARY KEY,
|
|
607
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
608
|
+
event_type TEXT NOT NULL, -- 'grant', 'revoke', 'modify'
|
|
609
|
+
subject_id TEXT NOT NULL,
|
|
610
|
+
resource TEXT, -- Resource affected (optional)
|
|
611
|
+
relation TEXT, -- Relation affected (optional)
|
|
612
|
+
permission TEXT, -- Permission affected (optional)
|
|
613
|
+
timestamp INTEGER NOT NULL, -- Event timestamp (Unix milliseconds)
|
|
614
|
+
created_at INTEGER NOT NULL -- Record creation time (Unix seconds)
|
|
615
|
+
);
|
|
616
|
+
|
|
617
|
+
CREATE TABLE permission_check_audit (
|
|
618
|
+
id TEXT PRIMARY KEY,
|
|
619
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
620
|
+
subject_id TEXT NOT NULL,
|
|
621
|
+
permission TEXT NOT NULL, -- Original permission string
|
|
622
|
+
permission_json TEXT, -- Structured permission (if provided)
|
|
623
|
+
allowed INTEGER NOT NULL, -- 1 = allowed, 0 = denied
|
|
624
|
+
resolved_via_json TEXT NOT NULL, -- JSON array: ["role", "rebac"]
|
|
625
|
+
final_decision TEXT NOT NULL, -- 'allow' | 'deny'
|
|
626
|
+
reason TEXT, -- Denial reason (when denied)
|
|
627
|
+
api_key_id TEXT, -- Which API key was used (if any)
|
|
628
|
+
client_id TEXT, -- Client ID (from API key or token)
|
|
629
|
+
checked_at INTEGER NOT NULL -- Unix timestamp
|
|
630
|
+
);
|
|
631
|
+
|
|
632
|
+
CREATE TABLE policy_rules (
|
|
633
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
634
|
+
tenant_id TEXT NOT NULL,
|
|
635
|
+
|
|
636
|
+
-- Rule identification
|
|
637
|
+
name TEXT NOT NULL,
|
|
638
|
+
description TEXT,
|
|
639
|
+
|
|
640
|
+
-- Rule configuration
|
|
641
|
+
priority INTEGER NOT NULL DEFAULT 100,
|
|
642
|
+
effect TEXT NOT NULL CHECK (effect IN ('allow', 'deny')),
|
|
643
|
+
|
|
644
|
+
-- Target matching (JSON arrays)
|
|
645
|
+
resource_types TEXT, -- JSON array of resource types to match
|
|
646
|
+
actions TEXT, -- JSON array of actions to match
|
|
647
|
+
|
|
648
|
+
-- Conditions (JSON array of PolicyCondition objects)
|
|
649
|
+
conditions TEXT NOT NULL DEFAULT '[]',
|
|
650
|
+
|
|
651
|
+
-- Status
|
|
652
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
653
|
+
|
|
654
|
+
-- Audit
|
|
655
|
+
created_by TEXT,
|
|
656
|
+
created_at INTEGER NOT NULL,
|
|
657
|
+
updated_by TEXT,
|
|
658
|
+
updated_at INTEGER NOT NULL,
|
|
659
|
+
|
|
660
|
+
-- Indexes
|
|
661
|
+
UNIQUE(tenant_id, name)
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
CREATE TABLE policy_simulations (
|
|
665
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
666
|
+
tenant_id TEXT NOT NULL,
|
|
667
|
+
|
|
668
|
+
-- Simulation input (JSON)
|
|
669
|
+
context TEXT NOT NULL,
|
|
670
|
+
|
|
671
|
+
-- Simulation result
|
|
672
|
+
allowed INTEGER NOT NULL,
|
|
673
|
+
reason TEXT NOT NULL,
|
|
674
|
+
decided_by TEXT,
|
|
675
|
+
|
|
676
|
+
-- Details (JSON)
|
|
677
|
+
details TEXT,
|
|
678
|
+
matched_rules TEXT, -- JSON array of rule IDs that were evaluated
|
|
679
|
+
|
|
680
|
+
-- Audit
|
|
681
|
+
simulated_by TEXT,
|
|
682
|
+
simulated_at INTEGER NOT NULL
|
|
683
|
+
);
|
|
684
|
+
|
|
685
|
+
CREATE TABLE presentation_definitions (
|
|
686
|
+
id TEXT PRIMARY KEY,
|
|
687
|
+
tenant_id TEXT NOT NULL,
|
|
688
|
+
name TEXT NOT NULL,
|
|
689
|
+
purpose TEXT,
|
|
690
|
+
-- JSON: {"dc+sd-jwt": {...}, "mso_mdoc": {...}}
|
|
691
|
+
format TEXT NOT NULL,
|
|
692
|
+
-- JSON array of input descriptors
|
|
693
|
+
input_descriptors TEXT NOT NULL,
|
|
694
|
+
-- JSON for complex submission requirements
|
|
695
|
+
submission_requirements TEXT,
|
|
696
|
+
-- DCQL query (preferred for HAIP)
|
|
697
|
+
dcql_query TEXT,
|
|
698
|
+
-- Active status
|
|
699
|
+
is_active INTEGER DEFAULT 1,
|
|
700
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
701
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
CREATE TABLE refresh_token_shard_configs (
|
|
705
|
+
id TEXT PRIMARY KEY, -- UUID
|
|
706
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
707
|
+
client_id TEXT, -- NULL = global config
|
|
708
|
+
generation INTEGER NOT NULL,
|
|
709
|
+
shard_count INTEGER NOT NULL,
|
|
710
|
+
activated_at INTEGER NOT NULL, -- When this config was activated (ms)
|
|
711
|
+
deprecated_at INTEGER, -- When this config was deprecated (ms)
|
|
712
|
+
created_by TEXT, -- Admin user who created this config
|
|
713
|
+
notes TEXT, -- Human-readable notes
|
|
714
|
+
|
|
715
|
+
UNIQUE(tenant_id, client_id, generation)
|
|
716
|
+
);
|
|
717
|
+
|
|
718
|
+
CREATE TABLE relation_definitions (
|
|
719
|
+
id TEXT PRIMARY KEY,
|
|
720
|
+
tenant_id TEXT NOT NULL,
|
|
721
|
+
-- Object type this definition applies to
|
|
722
|
+
object_type TEXT NOT NULL, -- 'document', 'folder', 'org', etc.
|
|
723
|
+
-- Relation name being defined
|
|
724
|
+
relation_name TEXT NOT NULL, -- 'viewer', 'editor', 'owner', etc.
|
|
725
|
+
-- Relation composition rule (JSON)
|
|
726
|
+
definition_json TEXT NOT NULL,
|
|
727
|
+
-- Description for documentation
|
|
728
|
+
description TEXT,
|
|
729
|
+
-- Evaluation priority (higher = evaluated first)
|
|
730
|
+
priority INTEGER DEFAULT 0,
|
|
731
|
+
-- Whether this definition is active
|
|
732
|
+
is_active INTEGER DEFAULT 1,
|
|
733
|
+
-- Timestamps
|
|
734
|
+
created_at INTEGER NOT NULL,
|
|
735
|
+
updated_at INTEGER NOT NULL
|
|
736
|
+
);
|
|
737
|
+
|
|
738
|
+
CREATE TABLE relationship_closure (
|
|
739
|
+
id TEXT PRIMARY KEY,
|
|
740
|
+
tenant_id TEXT NOT NULL,
|
|
741
|
+
-- Ancestor (source) entity
|
|
742
|
+
ancestor_type TEXT NOT NULL, -- 'subject', 'org', 'group'
|
|
743
|
+
ancestor_id TEXT NOT NULL,
|
|
744
|
+
-- Descendant (target) entity
|
|
745
|
+
descendant_type TEXT NOT NULL, -- 'document', 'folder', 'org', 'resource'
|
|
746
|
+
descendant_id TEXT NOT NULL,
|
|
747
|
+
-- Computed relation (derived from relationship chain)
|
|
748
|
+
relation TEXT NOT NULL, -- 'viewer', 'editor', 'owner'
|
|
749
|
+
-- Path information
|
|
750
|
+
depth INTEGER NOT NULL, -- Number of hops (0 = direct)
|
|
751
|
+
path_json TEXT, -- JSON array of relationship IDs in the path
|
|
752
|
+
-- Computed metadata
|
|
753
|
+
effective_permission TEXT, -- Most restrictive permission in path
|
|
754
|
+
-- Timestamps
|
|
755
|
+
created_at INTEGER NOT NULL,
|
|
756
|
+
updated_at INTEGER NOT NULL
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
CREATE TABLE relationships (
|
|
760
|
+
id TEXT PRIMARY KEY,
|
|
761
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
762
|
+
relationship_type TEXT NOT NULL, -- parent_child, guardian, delegate, manager, reseller_of
|
|
763
|
+
from_type TEXT NOT NULL DEFAULT 'subject', -- subject, org (future)
|
|
764
|
+
from_id TEXT NOT NULL, -- subject_id or org_id
|
|
765
|
+
to_type TEXT NOT NULL DEFAULT 'subject', -- subject, org (future)
|
|
766
|
+
to_id TEXT NOT NULL, -- subject_id or org_id
|
|
767
|
+
permission_level TEXT NOT NULL DEFAULT 'full', -- full, limited, read_only
|
|
768
|
+
expires_at INTEGER, -- Optional expiration (UNIX seconds)
|
|
769
|
+
is_bidirectional INTEGER DEFAULT 0, -- Phase 1: always 0
|
|
770
|
+
metadata_json TEXT, -- Additional constraints, notes, etc.
|
|
771
|
+
created_at INTEGER NOT NULL,
|
|
772
|
+
updated_at INTEGER NOT NULL
|
|
773
|
+
, evidence_type TEXT DEFAULT 'manual', evidence_ref TEXT);
|
|
774
|
+
|
|
775
|
+
CREATE TABLE resource_permissions (
|
|
776
|
+
-- Primary key
|
|
777
|
+
id TEXT PRIMARY KEY,
|
|
778
|
+
|
|
779
|
+
-- Multi-tenant support
|
|
780
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
781
|
+
|
|
782
|
+
-- Subject (who has the permission)
|
|
783
|
+
subject_type TEXT NOT NULL DEFAULT 'user', -- 'user' | 'role' | 'org'
|
|
784
|
+
subject_id TEXT NOT NULL, -- user_id, role_id, or org_id
|
|
785
|
+
|
|
786
|
+
-- Resource (what is being accessed)
|
|
787
|
+
resource_type TEXT NOT NULL, -- e.g., 'documents', 'projects'
|
|
788
|
+
resource_id TEXT NOT NULL, -- e.g., 'doc_123', 'proj_456'
|
|
789
|
+
|
|
790
|
+
-- Actions allowed (JSON array)
|
|
791
|
+
-- Example: ["read", "write", "delete"]
|
|
792
|
+
actions_json TEXT NOT NULL,
|
|
793
|
+
|
|
794
|
+
-- Optional condition for permission (JSON)
|
|
795
|
+
-- Example: {"time_restricted": true, "hours": [9, 17]}
|
|
796
|
+
condition_json TEXT,
|
|
797
|
+
|
|
798
|
+
-- Expiration (UNIX seconds)
|
|
799
|
+
-- NULL = no expiration
|
|
800
|
+
-- Evaluated at token generation time only
|
|
801
|
+
expires_at INTEGER,
|
|
802
|
+
|
|
803
|
+
-- Status
|
|
804
|
+
is_active INTEGER DEFAULT 1,
|
|
805
|
+
|
|
806
|
+
-- Audit fields
|
|
807
|
+
granted_by TEXT, -- Admin or system that granted
|
|
808
|
+
created_at INTEGER NOT NULL,
|
|
809
|
+
updated_at INTEGER NOT NULL,
|
|
810
|
+
|
|
811
|
+
-- Constraints
|
|
812
|
+
-- Same subject can have only one permission entry per resource
|
|
813
|
+
UNIQUE(tenant_id, subject_type, subject_id, resource_type, resource_id)
|
|
814
|
+
);
|
|
815
|
+
|
|
816
|
+
CREATE TABLE role_assignment_rules (
|
|
817
|
+
-- Primary key
|
|
818
|
+
id TEXT PRIMARY KEY,
|
|
819
|
+
|
|
820
|
+
-- Multi-tenant support
|
|
821
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
822
|
+
|
|
823
|
+
-- Rule identification
|
|
824
|
+
name TEXT NOT NULL,
|
|
825
|
+
description TEXT,
|
|
826
|
+
|
|
827
|
+
-- Target role (reference only, no FK for flexibility)
|
|
828
|
+
role_id TEXT NOT NULL,
|
|
829
|
+
|
|
830
|
+
-- Scope for assigned role
|
|
831
|
+
scope_type TEXT NOT NULL DEFAULT 'global', -- global, org, resource
|
|
832
|
+
scope_target TEXT NOT NULL DEFAULT '', -- e.g., 'org:org_123' or '' for global
|
|
833
|
+
|
|
834
|
+
-- Conditions (JSON format)
|
|
835
|
+
-- Example: {"type": "and", "conditions": [
|
|
836
|
+
-- {"field": "email_domain_hash", "operator": "eq", "value": "abc123..."},
|
|
837
|
+
-- {"field": "idp_claim", "claim_path": "groups", "operator": "contains", "value": "admin"}
|
|
838
|
+
-- ]}
|
|
839
|
+
conditions_json TEXT NOT NULL,
|
|
840
|
+
|
|
841
|
+
-- Actions (JSON format)
|
|
842
|
+
-- Example: [
|
|
843
|
+
-- {"type": "assign_role", "role_id": "role_org_admin", "scope_type": "org", "scope_target": "auto"},
|
|
844
|
+
-- {"type": "join_org", "org_id": "auto"}
|
|
845
|
+
-- ]
|
|
846
|
+
actions_json TEXT NOT NULL,
|
|
847
|
+
|
|
848
|
+
-- Priority and control
|
|
849
|
+
priority INTEGER NOT NULL DEFAULT 0, -- Higher = evaluated first (DESC order)
|
|
850
|
+
stop_processing INTEGER DEFAULT 0, -- 1 = stop evaluating further rules after match
|
|
851
|
+
is_active INTEGER DEFAULT 1, -- 0 = disabled
|
|
852
|
+
|
|
853
|
+
-- Validity period (optional, UNIX seconds)
|
|
854
|
+
valid_from INTEGER, -- NULL = no start restriction
|
|
855
|
+
valid_until INTEGER, -- NULL = no end restriction
|
|
856
|
+
|
|
857
|
+
-- Audit fields
|
|
858
|
+
created_by TEXT, -- Admin user ID who created
|
|
859
|
+
created_at INTEGER NOT NULL,
|
|
860
|
+
updated_at INTEGER NOT NULL,
|
|
861
|
+
|
|
862
|
+
-- Constraints
|
|
863
|
+
UNIQUE(tenant_id, name)
|
|
864
|
+
);
|
|
865
|
+
|
|
866
|
+
CREATE TABLE "role_assignments" (
|
|
867
|
+
id TEXT PRIMARY KEY,
|
|
868
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
869
|
+
subject_id TEXT NOT NULL,
|
|
870
|
+
role_id TEXT NOT NULL,
|
|
871
|
+
scope_type TEXT NOT NULL DEFAULT 'global',
|
|
872
|
+
scope_target TEXT NOT NULL DEFAULT '',
|
|
873
|
+
expires_at INTEGER,
|
|
874
|
+
assigned_by TEXT,
|
|
875
|
+
metadata_json TEXT,
|
|
876
|
+
created_at INTEGER NOT NULL,
|
|
877
|
+
updated_at INTEGER NOT NULL,
|
|
878
|
+
FOREIGN KEY (subject_id) REFERENCES users_core(id) ON DELETE CASCADE,
|
|
879
|
+
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
CREATE TABLE roles (
|
|
883
|
+
id TEXT PRIMARY KEY,
|
|
884
|
+
name TEXT UNIQUE NOT NULL,
|
|
885
|
+
description TEXT,
|
|
886
|
+
permissions_json TEXT NOT NULL,
|
|
887
|
+
created_at INTEGER NOT NULL
|
|
888
|
+
, tenant_id TEXT NOT NULL DEFAULT 'default', role_type TEXT NOT NULL DEFAULT 'custom', hierarchy_level INTEGER DEFAULT 0, is_assignable INTEGER DEFAULT 1, parent_role_id TEXT REFERENCES roles(id), display_name TEXT, is_system INTEGER NOT NULL DEFAULT 0, updated_at INTEGER);
|
|
889
|
+
|
|
890
|
+
CREATE TABLE schema_migrations (
|
|
891
|
+
-- Migration version (from filename: 001_initial_schema.sql -> version = 1)
|
|
892
|
+
version INTEGER PRIMARY KEY,
|
|
893
|
+
|
|
894
|
+
-- Human-readable migration name (from filename: 001_initial_schema.sql -> name = "initial_schema")
|
|
895
|
+
name TEXT NOT NULL,
|
|
896
|
+
|
|
897
|
+
-- When the migration was applied (Unix timestamp in seconds)
|
|
898
|
+
applied_at INTEGER NOT NULL,
|
|
899
|
+
|
|
900
|
+
-- SHA-256 checksum of the migration SQL file (detects file modifications)
|
|
901
|
+
checksum TEXT NOT NULL,
|
|
902
|
+
|
|
903
|
+
-- How long the migration took to execute (milliseconds)
|
|
904
|
+
execution_time_ms INTEGER,
|
|
905
|
+
|
|
906
|
+
-- Optional: SQL for rolling back this migration
|
|
907
|
+
rollback_sql TEXT
|
|
908
|
+
);
|
|
909
|
+
|
|
910
|
+
CREATE TABLE scope_mappings (
|
|
911
|
+
scope TEXT NOT NULL,
|
|
912
|
+
claim_name TEXT NOT NULL,
|
|
913
|
+
source_table TEXT NOT NULL,
|
|
914
|
+
source_column TEXT NOT NULL,
|
|
915
|
+
transformation TEXT,
|
|
916
|
+
condition TEXT,
|
|
917
|
+
created_at INTEGER NOT NULL, tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
918
|
+
PRIMARY KEY (scope, claim_name)
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
CREATE TABLE security_alerts (
|
|
922
|
+
id TEXT PRIMARY KEY,
|
|
923
|
+
tenant_id TEXT NOT NULL,
|
|
924
|
+
type TEXT NOT NULL CHECK (type IN (
|
|
925
|
+
'brute_force',
|
|
926
|
+
'credential_stuffing',
|
|
927
|
+
'suspicious_login',
|
|
928
|
+
'impossible_travel',
|
|
929
|
+
'account_takeover',
|
|
930
|
+
'mfa_bypass_attempt',
|
|
931
|
+
'token_abuse',
|
|
932
|
+
'rate_limit_exceeded',
|
|
933
|
+
'config_change',
|
|
934
|
+
'privilege_escalation',
|
|
935
|
+
'data_exfiltration',
|
|
936
|
+
'other'
|
|
937
|
+
)),
|
|
938
|
+
severity TEXT NOT NULL CHECK (severity IN ('critical', 'high', 'medium', 'low', 'info')),
|
|
939
|
+
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'acknowledged', 'resolved', 'dismissed')),
|
|
940
|
+
title TEXT NOT NULL,
|
|
941
|
+
description TEXT,
|
|
942
|
+
source_ip TEXT,
|
|
943
|
+
user_id TEXT,
|
|
944
|
+
client_id TEXT,
|
|
945
|
+
metadata TEXT, -- JSON string for additional context
|
|
946
|
+
created_at INTEGER NOT NULL,
|
|
947
|
+
updated_at INTEGER NOT NULL,
|
|
948
|
+
acknowledged_at INTEGER,
|
|
949
|
+
acknowledged_by TEXT,
|
|
950
|
+
resolved_at INTEGER,
|
|
951
|
+
resolved_by TEXT,
|
|
952
|
+
|
|
953
|
+
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
|
|
954
|
+
);
|
|
955
|
+
|
|
956
|
+
CREATE TABLE security_threats (
|
|
957
|
+
id TEXT PRIMARY KEY,
|
|
958
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
959
|
+
type TEXT NOT NULL, -- credential_compromise, attack_pattern, vulnerability, etc.
|
|
960
|
+
severity TEXT NOT NULL, -- critical, high, medium, low, info
|
|
961
|
+
status TEXT NOT NULL DEFAULT 'active', -- active, investigating, mitigated, resolved
|
|
962
|
+
title TEXT NOT NULL, -- Short title
|
|
963
|
+
description TEXT, -- Detailed description
|
|
964
|
+
source TEXT, -- Detection source (system, external, manual)
|
|
965
|
+
affected_resources TEXT, -- JSON: List of affected resources
|
|
966
|
+
indicators TEXT, -- JSON: Indicators of compromise (IOCs)
|
|
967
|
+
metadata TEXT, -- JSON: Additional context
|
|
968
|
+
created_at TEXT NOT NULL,
|
|
969
|
+
updated_at TEXT NOT NULL,
|
|
970
|
+
detected_at TEXT NOT NULL, -- When threat was detected
|
|
971
|
+
mitigated_at TEXT -- When threat was mitigated
|
|
972
|
+
);
|
|
973
|
+
|
|
974
|
+
CREATE TABLE "session_clients" (
|
|
975
|
+
id TEXT PRIMARY KEY,
|
|
976
|
+
session_id TEXT NOT NULL,
|
|
977
|
+
client_id TEXT NOT NULL,
|
|
978
|
+
first_token_at INTEGER NOT NULL,
|
|
979
|
+
last_token_at INTEGER NOT NULL,
|
|
980
|
+
last_seen_at INTEGER,
|
|
981
|
+
|
|
982
|
+
-- Only keep the client_id foreign key
|
|
983
|
+
FOREIGN KEY (client_id) REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
|
|
984
|
+
|
|
985
|
+
UNIQUE (session_id, client_id)
|
|
986
|
+
);
|
|
987
|
+
|
|
988
|
+
CREATE TABLE "sessions" (
|
|
989
|
+
id TEXT PRIMARY KEY,
|
|
990
|
+
user_id TEXT NOT NULL,
|
|
991
|
+
expires_at INTEGER NOT NULL,
|
|
992
|
+
created_at INTEGER NOT NULL,
|
|
993
|
+
external_provider_id TEXT,
|
|
994
|
+
external_provider_sub TEXT,
|
|
995
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
996
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
997
|
+
);
|
|
998
|
+
|
|
999
|
+
CREATE TABLE settings_history (
|
|
1000
|
+
-- Primary key
|
|
1001
|
+
id TEXT PRIMARY KEY,
|
|
1002
|
+
|
|
1003
|
+
-- Multi-tenant support
|
|
1004
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1005
|
+
|
|
1006
|
+
-- Category (oauth, rate_limit, logout, webhook, feature_flags, etc.)
|
|
1007
|
+
category TEXT NOT NULL,
|
|
1008
|
+
|
|
1009
|
+
-- Version number (auto-incremented per tenant+category)
|
|
1010
|
+
version INTEGER NOT NULL,
|
|
1011
|
+
|
|
1012
|
+
-- Full configuration snapshot (JSON)
|
|
1013
|
+
-- This allows complete restoration without dependencies
|
|
1014
|
+
snapshot TEXT NOT NULL,
|
|
1015
|
+
|
|
1016
|
+
-- Change summary (JSON)
|
|
1017
|
+
-- { "added": [...], "removed": [...], "modified": [...] }
|
|
1018
|
+
changes TEXT NOT NULL,
|
|
1019
|
+
|
|
1020
|
+
-- Actor who made the change
|
|
1021
|
+
actor_id TEXT, -- User ID or 'system'
|
|
1022
|
+
actor_type TEXT, -- 'user', 'admin', 'system', 'api'
|
|
1023
|
+
|
|
1024
|
+
-- Change metadata
|
|
1025
|
+
change_reason TEXT, -- Optional reason for the change
|
|
1026
|
+
change_source TEXT, -- 'admin_api', 'settings_ui', 'migration', 'rollback'
|
|
1027
|
+
|
|
1028
|
+
-- Timestamps
|
|
1029
|
+
created_at INTEGER NOT NULL,
|
|
1030
|
+
|
|
1031
|
+
-- Constraints
|
|
1032
|
+
UNIQUE(tenant_id, category, version)
|
|
1033
|
+
);
|
|
1034
|
+
|
|
1035
|
+
CREATE TABLE status_lists (
|
|
1036
|
+
id TEXT PRIMARY KEY,
|
|
1037
|
+
tenant_id TEXT NOT NULL,
|
|
1038
|
+
-- Purpose: 'revocation' | 'suspension'
|
|
1039
|
+
purpose TEXT NOT NULL DEFAULT 'revocation',
|
|
1040
|
+
-- Bitstring of status values (base64url encoded)
|
|
1041
|
+
encoded_list TEXT NOT NULL,
|
|
1042
|
+
-- Current index for new credentials
|
|
1043
|
+
current_index INTEGER DEFAULT 0,
|
|
1044
|
+
-- Total capacity
|
|
1045
|
+
capacity INTEGER DEFAULT 131072,
|
|
1046
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
1047
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
1048
|
+
);
|
|
1049
|
+
|
|
1050
|
+
CREATE TABLE subject_identifiers (
|
|
1051
|
+
id TEXT PRIMARY KEY,
|
|
1052
|
+
tenant_id TEXT NOT NULL,
|
|
1053
|
+
-- User this identifier belongs to
|
|
1054
|
+
subject_id TEXT NOT NULL, -- References users(id)
|
|
1055
|
+
-- Identifier details
|
|
1056
|
+
identifier_type TEXT NOT NULL, -- 'email', 'did', 'phone', 'username'
|
|
1057
|
+
identifier_value TEXT NOT NULL, -- 'user@example.com', 'did:key:z6Mk...'
|
|
1058
|
+
-- Flags
|
|
1059
|
+
is_primary INTEGER DEFAULT 0, -- Whether this is the primary identifier
|
|
1060
|
+
-- Verification
|
|
1061
|
+
verified_at INTEGER, -- When the identifier was verified
|
|
1062
|
+
verification_method TEXT, -- 'email_verification', 'did_auth', 'phone_sms'
|
|
1063
|
+
-- Timestamps
|
|
1064
|
+
created_at INTEGER NOT NULL,
|
|
1065
|
+
updated_at INTEGER NOT NULL
|
|
1066
|
+
);
|
|
1067
|
+
|
|
1068
|
+
CREATE TABLE "subject_org_membership" (
|
|
1069
|
+
id TEXT PRIMARY KEY,
|
|
1070
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1071
|
+
subject_id TEXT NOT NULL,
|
|
1072
|
+
org_id TEXT NOT NULL,
|
|
1073
|
+
membership_type TEXT NOT NULL DEFAULT 'member',
|
|
1074
|
+
is_primary INTEGER DEFAULT 0,
|
|
1075
|
+
created_at INTEGER NOT NULL,
|
|
1076
|
+
updated_at INTEGER NOT NULL,
|
|
1077
|
+
FOREIGN KEY (subject_id) REFERENCES users_core(id) ON DELETE CASCADE,
|
|
1078
|
+
FOREIGN KEY (org_id) REFERENCES organizations(id) ON DELETE CASCADE
|
|
1079
|
+
);
|
|
1080
|
+
|
|
1081
|
+
CREATE TABLE suspicious_activities (
|
|
1082
|
+
id TEXT PRIMARY KEY,
|
|
1083
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1084
|
+
type TEXT NOT NULL, -- brute_force, credential_stuffing, anomalous_login, etc.
|
|
1085
|
+
severity TEXT NOT NULL, -- critical, high, medium, low, info
|
|
1086
|
+
user_id TEXT, -- Associated user (nullable for pre-auth events)
|
|
1087
|
+
client_id TEXT, -- Associated OAuth client
|
|
1088
|
+
source_ip TEXT, -- Source IP address
|
|
1089
|
+
user_agent TEXT, -- User agent string
|
|
1090
|
+
description TEXT, -- Human-readable description
|
|
1091
|
+
metadata TEXT, -- JSON: Additional context data
|
|
1092
|
+
created_at TEXT NOT NULL, -- When detected
|
|
1093
|
+
resolved_at TEXT -- When resolved/dismissed
|
|
1094
|
+
);
|
|
1095
|
+
|
|
1096
|
+
CREATE TABLE token_claim_rules (
|
|
1097
|
+
-- Primary key
|
|
1098
|
+
id TEXT PRIMARY KEY,
|
|
1099
|
+
|
|
1100
|
+
-- Multi-tenant support
|
|
1101
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1102
|
+
|
|
1103
|
+
-- Rule identification
|
|
1104
|
+
name TEXT NOT NULL,
|
|
1105
|
+
description TEXT,
|
|
1106
|
+
|
|
1107
|
+
-- Target token type
|
|
1108
|
+
token_type TEXT NOT NULL DEFAULT 'access', -- 'access' | 'id' | 'both'
|
|
1109
|
+
|
|
1110
|
+
-- Conditions (JSON format, same structure as role_assignment_rules)
|
|
1111
|
+
-- Example: {"type": "and", "conditions": [
|
|
1112
|
+
-- {"field": "has_role", "operator": "contains", "value": "premium_user"},
|
|
1113
|
+
-- {"field": "org_type", "operator": "eq", "value": "enterprise"}
|
|
1114
|
+
-- ]}
|
|
1115
|
+
conditions_json TEXT NOT NULL,
|
|
1116
|
+
|
|
1117
|
+
-- Actions (JSON format)
|
|
1118
|
+
-- Example: [
|
|
1119
|
+
-- {"type": "add_claim", "claim_name": "tier", "claim_value": "premium"},
|
|
1120
|
+
-- {"type": "add_claim_template", "claim_name": "greeting", "template": "Hello {{user_type}}"},
|
|
1121
|
+
-- {"type": "copy_from_context", "claim_name": "org", "context_field": "org_id"}
|
|
1122
|
+
-- ]
|
|
1123
|
+
actions_json TEXT NOT NULL,
|
|
1124
|
+
|
|
1125
|
+
-- Priority and control
|
|
1126
|
+
priority INTEGER NOT NULL DEFAULT 0, -- Higher = evaluated first (DESC order)
|
|
1127
|
+
stop_processing INTEGER DEFAULT 0, -- 1 = stop evaluating further rules after match
|
|
1128
|
+
is_active INTEGER DEFAULT 1, -- 0 = disabled
|
|
1129
|
+
|
|
1130
|
+
-- Validity period (optional, UNIX seconds)
|
|
1131
|
+
valid_from INTEGER, -- NULL = no start restriction
|
|
1132
|
+
valid_until INTEGER, -- NULL = no end restriction
|
|
1133
|
+
|
|
1134
|
+
-- Audit fields
|
|
1135
|
+
created_by TEXT, -- Admin user ID who created
|
|
1136
|
+
created_at INTEGER NOT NULL,
|
|
1137
|
+
updated_at INTEGER NOT NULL,
|
|
1138
|
+
|
|
1139
|
+
-- Constraints
|
|
1140
|
+
UNIQUE(tenant_id, name)
|
|
1141
|
+
);
|
|
1142
|
+
|
|
1143
|
+
CREATE TABLE trusted_issuers (
|
|
1144
|
+
id TEXT PRIMARY KEY,
|
|
1145
|
+
tenant_id TEXT NOT NULL,
|
|
1146
|
+
issuer_did TEXT NOT NULL,
|
|
1147
|
+
display_name TEXT,
|
|
1148
|
+
-- JSON array of accepted Verifiable Credential Types
|
|
1149
|
+
credential_types TEXT,
|
|
1150
|
+
-- Trust level: 'standard' | 'high' (HAIP-compliant)
|
|
1151
|
+
trust_level TEXT DEFAULT 'standard',
|
|
1152
|
+
-- JWKS URI for issuer public keys
|
|
1153
|
+
jwks_uri TEXT,
|
|
1154
|
+
-- Issuer status: 'active' | 'suspended' | 'revoked'
|
|
1155
|
+
status TEXT DEFAULT 'active',
|
|
1156
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
1157
|
+
updated_at TEXT DEFAULT (datetime('now')),
|
|
1158
|
+
UNIQUE(tenant_id, issuer_did)
|
|
1159
|
+
);
|
|
1160
|
+
|
|
1161
|
+
CREATE TABLE upstream_providers (
|
|
1162
|
+
id TEXT PRIMARY KEY,
|
|
1163
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1164
|
+
name TEXT NOT NULL, -- Display name: "Google", "GitHub"
|
|
1165
|
+
provider_type TEXT NOT NULL, -- 'oidc' | 'oauth2'
|
|
1166
|
+
enabled INTEGER DEFAULT 1,
|
|
1167
|
+
priority INTEGER DEFAULT 0, -- Display order (lower = higher priority)
|
|
1168
|
+
|
|
1169
|
+
-- OIDC/OAuth2 endpoints
|
|
1170
|
+
issuer TEXT, -- OIDC issuer URL (for discovery)
|
|
1171
|
+
client_id TEXT NOT NULL,
|
|
1172
|
+
client_secret_encrypted TEXT NOT NULL, -- Encrypted with RP_TOKEN_ENCRYPTION_KEY
|
|
1173
|
+
authorization_endpoint TEXT, -- Override for non-standard providers
|
|
1174
|
+
token_endpoint TEXT,
|
|
1175
|
+
userinfo_endpoint TEXT,
|
|
1176
|
+
jwks_uri TEXT,
|
|
1177
|
+
scopes TEXT NOT NULL DEFAULT 'openid email profile', -- Space-separated
|
|
1178
|
+
|
|
1179
|
+
-- Configuration
|
|
1180
|
+
attribute_mapping TEXT DEFAULT '{}', -- JSON: {"sub": "sub", "email": "email"}
|
|
1181
|
+
auto_link_email INTEGER DEFAULT 1, -- Enable email-based identity stitching
|
|
1182
|
+
jit_provisioning INTEGER DEFAULT 1, -- Create user on first login
|
|
1183
|
+
require_email_verified INTEGER DEFAULT 1, -- Only link if email is verified
|
|
1184
|
+
|
|
1185
|
+
-- Provider-specific settings
|
|
1186
|
+
provider_quirks TEXT DEFAULT '{}', -- JSON for provider-specific handling
|
|
1187
|
+
|
|
1188
|
+
-- UI customization
|
|
1189
|
+
icon_url TEXT, -- Provider icon for login button
|
|
1190
|
+
button_color TEXT, -- Brand color for login button (hex)
|
|
1191
|
+
button_text TEXT, -- Custom button text (optional)
|
|
1192
|
+
|
|
1193
|
+
-- Metadata
|
|
1194
|
+
created_at INTEGER NOT NULL,
|
|
1195
|
+
updated_at INTEGER NOT NULL
|
|
1196
|
+
, slug TEXT, token_endpoint_auth_method TEXT DEFAULT 'client_secret_post', always_fetch_userinfo INTEGER DEFAULT 0, use_request_object INTEGER DEFAULT 0, request_object_signing_alg TEXT, private_key_jwk_encrypted TEXT, public_key_jwk TEXT);
|
|
1197
|
+
|
|
1198
|
+
CREATE TABLE "user_custom_fields" (
|
|
1199
|
+
user_id TEXT NOT NULL,
|
|
1200
|
+
field_name TEXT NOT NULL,
|
|
1201
|
+
field_value TEXT,
|
|
1202
|
+
field_type TEXT,
|
|
1203
|
+
searchable INTEGER DEFAULT 1,
|
|
1204
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1205
|
+
PRIMARY KEY (user_id, field_name),
|
|
1206
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
1207
|
+
);
|
|
1208
|
+
|
|
1209
|
+
CREATE TABLE "user_roles" (
|
|
1210
|
+
user_id TEXT NOT NULL,
|
|
1211
|
+
role_id TEXT NOT NULL,
|
|
1212
|
+
created_at INTEGER NOT NULL,
|
|
1213
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1214
|
+
PRIMARY KEY (user_id, role_id),
|
|
1215
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE,
|
|
1216
|
+
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
|
|
1217
|
+
);
|
|
1218
|
+
|
|
1219
|
+
CREATE TABLE "user_token_families" (
|
|
1220
|
+
jti TEXT PRIMARY KEY,
|
|
1221
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1222
|
+
user_id TEXT NOT NULL,
|
|
1223
|
+
client_id TEXT NOT NULL,
|
|
1224
|
+
generation INTEGER NOT NULL,
|
|
1225
|
+
expires_at INTEGER NOT NULL,
|
|
1226
|
+
is_revoked INTEGER DEFAULT 0,
|
|
1227
|
+
FOREIGN KEY (user_id) REFERENCES users_core(id) ON DELETE CASCADE
|
|
1228
|
+
);
|
|
1229
|
+
|
|
1230
|
+
CREATE TABLE user_verified_attributes (
|
|
1231
|
+
id TEXT PRIMARY KEY,
|
|
1232
|
+
tenant_id TEXT NOT NULL,
|
|
1233
|
+
user_id TEXT NOT NULL,
|
|
1234
|
+
-- Attribute name: 'age_over_18', 'country', 'organization', etc.
|
|
1235
|
+
attribute_name TEXT NOT NULL,
|
|
1236
|
+
-- Attribute value: 'true', 'JP', 'Acme Corp', etc.
|
|
1237
|
+
attribute_value TEXT NOT NULL,
|
|
1238
|
+
-- Source type: 'vc' | 'saml' | 'oidc' | 'manual'
|
|
1239
|
+
source_type TEXT NOT NULL DEFAULT 'vc',
|
|
1240
|
+
-- Issuer DID (for VC-sourced attributes)
|
|
1241
|
+
issuer_did TEXT,
|
|
1242
|
+
-- Reference to verification record
|
|
1243
|
+
verification_id TEXT REFERENCES attribute_verifications(id),
|
|
1244
|
+
verified_at TEXT DEFAULT (datetime('now')),
|
|
1245
|
+
expires_at TEXT,
|
|
1246
|
+
-- Each user can have only one value per attribute
|
|
1247
|
+
UNIQUE(tenant_id, user_id, attribute_name)
|
|
1248
|
+
);
|
|
1249
|
+
|
|
1250
|
+
CREATE TABLE users (
|
|
1251
|
+
id TEXT PRIMARY KEY,
|
|
1252
|
+
email TEXT UNIQUE NOT NULL,
|
|
1253
|
+
email_verified INTEGER DEFAULT 0,
|
|
1254
|
+
name TEXT,
|
|
1255
|
+
given_name TEXT,
|
|
1256
|
+
family_name TEXT,
|
|
1257
|
+
middle_name TEXT,
|
|
1258
|
+
nickname TEXT,
|
|
1259
|
+
preferred_username TEXT,
|
|
1260
|
+
profile TEXT,
|
|
1261
|
+
picture TEXT,
|
|
1262
|
+
website TEXT,
|
|
1263
|
+
gender TEXT,
|
|
1264
|
+
birthdate TEXT,
|
|
1265
|
+
zoneinfo TEXT,
|
|
1266
|
+
locale TEXT,
|
|
1267
|
+
phone_number TEXT,
|
|
1268
|
+
phone_number_verified INTEGER DEFAULT 0,
|
|
1269
|
+
address_json TEXT,
|
|
1270
|
+
custom_attributes_json TEXT,
|
|
1271
|
+
parent_user_id TEXT REFERENCES users(id),
|
|
1272
|
+
identity_provider_id TEXT REFERENCES identity_providers(id),
|
|
1273
|
+
-- Password authentication fields (optional, disabled by default)
|
|
1274
|
+
password_hash TEXT,
|
|
1275
|
+
password_changed_at INTEGER,
|
|
1276
|
+
failed_login_attempts INTEGER DEFAULT 0,
|
|
1277
|
+
locked_until INTEGER,
|
|
1278
|
+
-- Timestamps
|
|
1279
|
+
created_at INTEGER NOT NULL,
|
|
1280
|
+
updated_at INTEGER NOT NULL,
|
|
1281
|
+
last_login_at INTEGER
|
|
1282
|
+
, tenant_id TEXT NOT NULL DEFAULT 'default', user_type TEXT NOT NULL DEFAULT 'end_user', status TEXT DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'locked')), suspended_at INTEGER, suspended_until INTEGER, locked_at INTEGER);
|
|
1283
|
+
|
|
1284
|
+
CREATE TABLE users_core (
|
|
1285
|
+
-- Primary key (UUID, same as users_pii.id)
|
|
1286
|
+
id TEXT PRIMARY KEY,
|
|
1287
|
+
|
|
1288
|
+
-- Multi-tenant support
|
|
1289
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1290
|
+
|
|
1291
|
+
-- Verification status (not PII - just flags)
|
|
1292
|
+
email_verified INTEGER DEFAULT 0,
|
|
1293
|
+
phone_number_verified INTEGER DEFAULT 0,
|
|
1294
|
+
|
|
1295
|
+
-- Blind index for domain-based role assignment (Phase 8)
|
|
1296
|
+
-- Stored as hash, cannot be reversed to original domain
|
|
1297
|
+
email_domain_hash TEXT,
|
|
1298
|
+
|
|
1299
|
+
-- Authentication
|
|
1300
|
+
password_hash TEXT,
|
|
1301
|
+
|
|
1302
|
+
-- Soft delete (1 = active, 0 = deleted)
|
|
1303
|
+
is_active INTEGER DEFAULT 1,
|
|
1304
|
+
|
|
1305
|
+
-- User type: end_user | admin | m2m
|
|
1306
|
+
user_type TEXT NOT NULL DEFAULT 'end_user',
|
|
1307
|
+
|
|
1308
|
+
-- PII partition info
|
|
1309
|
+
-- Which database contains this user's PII (e.g., 'default', 'eu', 'tenant-acme')
|
|
1310
|
+
pii_partition TEXT NOT NULL DEFAULT 'default',
|
|
1311
|
+
|
|
1312
|
+
-- PII write status
|
|
1313
|
+
-- none: No PII (M2M clients)
|
|
1314
|
+
-- pending: Core created, PII write in progress
|
|
1315
|
+
-- active: Both Core and PII created successfully
|
|
1316
|
+
-- failed: PII write failed (requires retry via Admin UI)
|
|
1317
|
+
-- deleted: PII deleted (GDPR), tombstone created
|
|
1318
|
+
pii_status TEXT NOT NULL DEFAULT 'pending',
|
|
1319
|
+
|
|
1320
|
+
-- Timestamps
|
|
1321
|
+
created_at INTEGER NOT NULL,
|
|
1322
|
+
updated_at INTEGER NOT NULL,
|
|
1323
|
+
last_login_at INTEGER
|
|
1324
|
+
, email_domain_hash_version INTEGER DEFAULT 1, external_id TEXT DEFAULT NULL, status TEXT DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'locked')), suspended_at INTEGER, suspended_until INTEGER, locked_at INTEGER, locked_until INTEGER);
|
|
1325
|
+
|
|
1326
|
+
CREATE TABLE verified_attributes (
|
|
1327
|
+
id TEXT PRIMARY KEY,
|
|
1328
|
+
tenant_id TEXT NOT NULL,
|
|
1329
|
+
-- Subject this attribute belongs to
|
|
1330
|
+
subject_id TEXT NOT NULL, -- References users(id)
|
|
1331
|
+
-- Attribute details
|
|
1332
|
+
attribute_name TEXT NOT NULL, -- 'age_over_18', 'medical_license', 'subscription_tier'
|
|
1333
|
+
attribute_value TEXT, -- 'true', 'MD12345', 'premium'
|
|
1334
|
+
-- Source information (for auditing and trust evaluation)
|
|
1335
|
+
source TEXT NOT NULL DEFAULT 'manual', -- 'manual', 'vc', 'jwt_sd', 'kyc_provider'
|
|
1336
|
+
issuer TEXT, -- Issuer DID or URL (Phase 4+)
|
|
1337
|
+
credential_id TEXT, -- VC ID for traceability (Phase 4+)
|
|
1338
|
+
-- Validity
|
|
1339
|
+
verified_at INTEGER NOT NULL, -- When the attribute was verified/extracted
|
|
1340
|
+
expires_at INTEGER, -- When the attribute expires (from VC exp)
|
|
1341
|
+
revoked_at INTEGER, -- When the attribute was revoked
|
|
1342
|
+
-- Timestamps
|
|
1343
|
+
created_at INTEGER NOT NULL,
|
|
1344
|
+
updated_at INTEGER NOT NULL
|
|
1345
|
+
);
|
|
1346
|
+
|
|
1347
|
+
CREATE TABLE vp_requests (
|
|
1348
|
+
id TEXT PRIMARY KEY,
|
|
1349
|
+
tenant_id TEXT NOT NULL,
|
|
1350
|
+
client_id TEXT NOT NULL,
|
|
1351
|
+
-- Nonce for replay protection (single-use, enforced by DO)
|
|
1352
|
+
nonce TEXT NOT NULL,
|
|
1353
|
+
state TEXT,
|
|
1354
|
+
-- Reference to presentation definition (optional, can use inline)
|
|
1355
|
+
presentation_definition_id TEXT REFERENCES presentation_definitions(id),
|
|
1356
|
+
response_uri TEXT NOT NULL,
|
|
1357
|
+
-- Response mode: 'direct_post' | 'direct_post.jwt' | 'fragment' | 'query'
|
|
1358
|
+
response_mode TEXT DEFAULT 'direct_post',
|
|
1359
|
+
-- Request status: 'pending' | 'submitted' | 'verified' | 'failed' | 'expired'
|
|
1360
|
+
status TEXT DEFAULT 'pending',
|
|
1361
|
+
-- Error information if failed
|
|
1362
|
+
error_code TEXT,
|
|
1363
|
+
error_description TEXT,
|
|
1364
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
1365
|
+
expires_at TEXT NOT NULL,
|
|
1366
|
+
verified_at TEXT
|
|
1367
|
+
);
|
|
1368
|
+
|
|
1369
|
+
CREATE TABLE webhook_configs (
|
|
1370
|
+
id TEXT PRIMARY KEY,
|
|
1371
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1372
|
+
client_id TEXT,
|
|
1373
|
+
scope TEXT NOT NULL DEFAULT 'tenant',
|
|
1374
|
+
name TEXT NOT NULL,
|
|
1375
|
+
url TEXT NOT NULL,
|
|
1376
|
+
events TEXT NOT NULL,
|
|
1377
|
+
secret_encrypted TEXT,
|
|
1378
|
+
headers TEXT,
|
|
1379
|
+
retry_policy TEXT NOT NULL,
|
|
1380
|
+
timeout_ms INTEGER NOT NULL DEFAULT 10000,
|
|
1381
|
+
active INTEGER NOT NULL DEFAULT 1,
|
|
1382
|
+
created_at TEXT NOT NULL,
|
|
1383
|
+
updated_at TEXT NOT NULL,
|
|
1384
|
+
last_success_at TEXT,
|
|
1385
|
+
last_failure_at TEXT
|
|
1386
|
+
);
|
|
1387
|
+
|
|
1388
|
+
CREATE TABLE webhook_delivery_logs (
|
|
1389
|
+
id TEXT PRIMARY KEY,
|
|
1390
|
+
webhook_id TEXT NOT NULL,
|
|
1391
|
+
event_id TEXT NOT NULL,
|
|
1392
|
+
event_type TEXT NOT NULL,
|
|
1393
|
+
tenant_id TEXT NOT NULL,
|
|
1394
|
+
attempt INTEGER NOT NULL DEFAULT 1,
|
|
1395
|
+
status TEXT NOT NULL,
|
|
1396
|
+
status_code INTEGER,
|
|
1397
|
+
error_message TEXT,
|
|
1398
|
+
duration_ms INTEGER,
|
|
1399
|
+
created_at TEXT NOT NULL,
|
|
1400
|
+
FOREIGN KEY (webhook_id) REFERENCES webhook_configs(id) ON DELETE CASCADE
|
|
1401
|
+
);
|
|
1402
|
+
|
|
1403
|
+
CREATE TABLE websocket_subscriptions (
|
|
1404
|
+
id TEXT PRIMARY KEY,
|
|
1405
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
1406
|
+
connection_id TEXT NOT NULL,
|
|
1407
|
+
subject_id TEXT NOT NULL,
|
|
1408
|
+
watched_subjects TEXT DEFAULT '[]', -- JSON array of subject IDs to watch
|
|
1409
|
+
watched_resources TEXT DEFAULT '[]', -- JSON array of resource patterns
|
|
1410
|
+
watched_relations TEXT DEFAULT '[]', -- JSON array of relation types
|
|
1411
|
+
connected_at INTEGER NOT NULL,
|
|
1412
|
+
is_active INTEGER DEFAULT 1
|
|
1413
|
+
);
|
|
1414
|
+
|
|
1415
|
+
-- =============================================================================
|
|
1416
|
+
-- Indexes
|
|
1417
|
+
-- =============================================================================
|
|
1418
|
+
|
|
1419
|
+
CREATE INDEX idx_access_review_items_decision ON access_review_items(review_id, decision);
|
|
1420
|
+
|
|
1421
|
+
CREATE INDEX idx_access_review_items_review ON access_review_items(review_id);
|
|
1422
|
+
|
|
1423
|
+
CREATE INDEX idx_access_review_items_user ON access_review_items(tenant_id, user_id);
|
|
1424
|
+
|
|
1425
|
+
CREATE INDEX idx_access_reviews_created ON access_reviews(tenant_id, created_at);
|
|
1426
|
+
|
|
1427
|
+
CREATE INDEX idx_access_reviews_due ON access_reviews(tenant_id, due_date);
|
|
1428
|
+
|
|
1429
|
+
CREATE INDEX idx_access_reviews_reviewer ON access_reviews(tenant_id, reviewer_id);
|
|
1430
|
+
|
|
1431
|
+
CREATE INDEX idx_access_reviews_status ON access_reviews(tenant_id, status);
|
|
1432
|
+
|
|
1433
|
+
CREATE INDEX idx_access_reviews_tenant ON access_reviews(tenant_id);
|
|
1434
|
+
|
|
1435
|
+
CREATE INDEX idx_admin_jobs_cleanup ON admin_jobs(
|
|
1436
|
+
status,
|
|
1437
|
+
completed_at
|
|
1438
|
+
);
|
|
1439
|
+
|
|
1440
|
+
CREATE INDEX idx_admin_jobs_status ON admin_jobs(
|
|
1441
|
+
tenant_id,
|
|
1442
|
+
status,
|
|
1443
|
+
created_at DESC
|
|
1444
|
+
);
|
|
1445
|
+
|
|
1446
|
+
CREATE INDEX idx_admin_jobs_tenant ON admin_jobs(
|
|
1447
|
+
tenant_id,
|
|
1448
|
+
created_at DESC
|
|
1449
|
+
);
|
|
1450
|
+
|
|
1451
|
+
CREATE INDEX idx_admin_jobs_type ON admin_jobs(
|
|
1452
|
+
tenant_id,
|
|
1453
|
+
job_type,
|
|
1454
|
+
created_at DESC
|
|
1455
|
+
);
|
|
1456
|
+
|
|
1457
|
+
CREATE INDEX idx_ai_grants_active ON ai_grants(is_active) WHERE is_active = 1;
|
|
1458
|
+
|
|
1459
|
+
CREATE INDEX idx_ai_grants_client ON ai_grants(client_id);
|
|
1460
|
+
|
|
1461
|
+
CREATE INDEX idx_ai_grants_expires ON ai_grants(expires_at) WHERE expires_at IS NOT NULL;
|
|
1462
|
+
|
|
1463
|
+
CREATE INDEX idx_ai_grants_principal ON ai_grants(ai_principal);
|
|
1464
|
+
|
|
1465
|
+
CREATE INDEX idx_ai_grants_tenant ON ai_grants(tenant_id);
|
|
1466
|
+
|
|
1467
|
+
CREATE INDEX idx_attribute_verifications_result ON attribute_verifications(verification_result);
|
|
1468
|
+
|
|
1469
|
+
CREATE INDEX idx_attribute_verifications_user ON attribute_verifications(tenant_id, user_id);
|
|
1470
|
+
|
|
1471
|
+
CREATE INDEX idx_audit_log_action ON audit_log(action);
|
|
1472
|
+
|
|
1473
|
+
CREATE INDEX idx_audit_log_created_at ON audit_log(created_at);
|
|
1474
|
+
|
|
1475
|
+
CREATE INDEX idx_audit_log_resource ON audit_log(resource_type, resource_id);
|
|
1476
|
+
|
|
1477
|
+
CREATE INDEX idx_audit_log_severity ON audit_log(severity);
|
|
1478
|
+
|
|
1479
|
+
CREATE INDEX idx_audit_log_tenant_id ON audit_log(tenant_id);
|
|
1480
|
+
|
|
1481
|
+
CREATE INDEX idx_audit_log_user_id ON audit_log(user_id);
|
|
1482
|
+
|
|
1483
|
+
CREATE INDEX idx_check_api_keys_client
|
|
1484
|
+
ON check_api_keys(client_id);
|
|
1485
|
+
|
|
1486
|
+
CREATE UNIQUE INDEX idx_check_api_keys_hash
|
|
1487
|
+
ON check_api_keys(key_hash);
|
|
1488
|
+
|
|
1489
|
+
CREATE INDEX idx_check_api_keys_prefix
|
|
1490
|
+
ON check_api_keys(key_prefix);
|
|
1491
|
+
|
|
1492
|
+
CREATE INDEX idx_check_api_keys_tenant_active
|
|
1493
|
+
ON check_api_keys(tenant_id, is_active);
|
|
1494
|
+
|
|
1495
|
+
CREATE INDEX idx_ciba_client ON ciba_requests(client_id);
|
|
1496
|
+
|
|
1497
|
+
CREATE INDEX idx_ciba_status ON ciba_requests(status);
|
|
1498
|
+
|
|
1499
|
+
CREATE INDEX idx_ciba_user ON ciba_requests(user_id);
|
|
1500
|
+
|
|
1501
|
+
CREATE INDEX idx_clients_claims_setting ON oauth_clients(allow_claims_without_scope);
|
|
1502
|
+
|
|
1503
|
+
CREATE INDEX idx_clients_created_at ON oauth_clients(created_at);
|
|
1504
|
+
|
|
1505
|
+
CREATE INDEX idx_clients_software_id_tenant ON oauth_clients(software_id, tenant_id);
|
|
1506
|
+
|
|
1507
|
+
CREATE INDEX idx_clients_trusted ON oauth_clients(is_trusted);
|
|
1508
|
+
|
|
1509
|
+
CREATE INDEX idx_closure_ancestor_lookup
|
|
1510
|
+
ON relationship_closure(tenant_id, ancestor_type, ancestor_id, relation);
|
|
1511
|
+
|
|
1512
|
+
CREATE INDEX idx_closure_depth
|
|
1513
|
+
ON relationship_closure(tenant_id, depth);
|
|
1514
|
+
|
|
1515
|
+
CREATE INDEX idx_closure_descendant_lookup
|
|
1516
|
+
ON relationship_closure(tenant_id, descendant_type, descendant_id, relation);
|
|
1517
|
+
|
|
1518
|
+
CREATE UNIQUE INDEX idx_closure_unique
|
|
1519
|
+
ON relationship_closure(tenant_id, ancestor_type, ancestor_id, descendant_type, descendant_id, relation);
|
|
1520
|
+
|
|
1521
|
+
CREATE INDEX idx_compliance_reports_created ON compliance_reports(tenant_id, created_at);
|
|
1522
|
+
|
|
1523
|
+
CREATE INDEX idx_compliance_reports_requested ON compliance_reports(tenant_id, requested_by);
|
|
1524
|
+
|
|
1525
|
+
CREATE INDEX idx_compliance_reports_status ON compliance_reports(tenant_id, status);
|
|
1526
|
+
|
|
1527
|
+
CREATE INDEX idx_compliance_reports_tenant ON compliance_reports(tenant_id);
|
|
1528
|
+
|
|
1529
|
+
CREATE INDEX idx_compliance_reports_type ON compliance_reports(tenant_id, type);
|
|
1530
|
+
|
|
1531
|
+
CREATE INDEX idx_consent_history_action
|
|
1532
|
+
ON consent_history(action, created_at);
|
|
1533
|
+
|
|
1534
|
+
CREATE INDEX idx_consent_history_client
|
|
1535
|
+
ON consent_history(client_id, created_at);
|
|
1536
|
+
|
|
1537
|
+
CREATE INDEX idx_consent_history_tenant
|
|
1538
|
+
ON consent_history(tenant_id, created_at);
|
|
1539
|
+
|
|
1540
|
+
CREATE INDEX idx_consent_history_user
|
|
1541
|
+
ON consent_history(user_id, created_at);
|
|
1542
|
+
|
|
1543
|
+
CREATE INDEX idx_consent_policy_versions_effective
|
|
1544
|
+
ON consent_policy_versions(effective_at);
|
|
1545
|
+
|
|
1546
|
+
CREATE INDEX idx_consent_policy_versions_tenant
|
|
1547
|
+
ON consent_policy_versions(tenant_id, policy_type);
|
|
1548
|
+
|
|
1549
|
+
CREATE INDEX idx_consents_client ON oauth_client_consents(client_id);
|
|
1550
|
+
|
|
1551
|
+
CREATE INDEX idx_consents_expires_at_active
|
|
1552
|
+
ON oauth_client_consents(expires_at) WHERE expires_at IS NOT NULL;
|
|
1553
|
+
|
|
1554
|
+
CREATE INDEX idx_consents_user ON oauth_client_consents(user_id);
|
|
1555
|
+
|
|
1556
|
+
CREATE INDEX idx_credential_configurations_tenant ON credential_configurations(tenant_id);
|
|
1557
|
+
|
|
1558
|
+
CREATE INDEX idx_credential_offers_code ON credential_offers(pre_authorized_code);
|
|
1559
|
+
|
|
1560
|
+
CREATE INDEX idx_credential_offers_status ON credential_offers(tenant_id, status);
|
|
1561
|
+
|
|
1562
|
+
CREATE INDEX idx_data_export_expires
|
|
1563
|
+
ON data_export_requests(expires_at) WHERE expires_at IS NOT NULL;
|
|
1564
|
+
|
|
1565
|
+
CREATE INDEX idx_data_export_status
|
|
1566
|
+
ON data_export_requests(status, requested_at);
|
|
1567
|
+
|
|
1568
|
+
CREATE INDEX idx_data_export_user
|
|
1569
|
+
ON data_export_requests(user_id, status);
|
|
1570
|
+
|
|
1571
|
+
CREATE INDEX idx_device_codes_client_id ON device_codes(client_id);
|
|
1572
|
+
|
|
1573
|
+
CREATE INDEX idx_device_codes_expires_at ON device_codes(expires_at);
|
|
1574
|
+
|
|
1575
|
+
CREATE INDEX idx_device_codes_status ON device_codes(status);
|
|
1576
|
+
|
|
1577
|
+
CREATE INDEX idx_device_codes_user_code ON device_codes(user_code);
|
|
1578
|
+
|
|
1579
|
+
CREATE INDEX idx_did_document_cache_expires ON did_document_cache(expires_at);
|
|
1580
|
+
|
|
1581
|
+
CREATE INDEX idx_external_idp_auth_states_consumed_at
|
|
1582
|
+
ON external_idp_auth_states(consumed_at);
|
|
1583
|
+
|
|
1584
|
+
CREATE INDEX idx_external_idp_auth_states_expires_at
|
|
1585
|
+
ON external_idp_auth_states(expires_at);
|
|
1586
|
+
|
|
1587
|
+
CREATE INDEX idx_external_idp_auth_states_state
|
|
1588
|
+
ON external_idp_auth_states(state);
|
|
1589
|
+
|
|
1590
|
+
CREATE INDEX idx_flows_builtin ON flows(is_builtin);
|
|
1591
|
+
|
|
1592
|
+
CREATE INDEX idx_flows_client ON flows(tenant_id, client_id);
|
|
1593
|
+
|
|
1594
|
+
CREATE INDEX idx_flows_lookup ON flows(tenant_id, client_id, profile_id, is_active);
|
|
1595
|
+
|
|
1596
|
+
CREATE INDEX idx_flows_profile ON flows(tenant_id, profile_id);
|
|
1597
|
+
|
|
1598
|
+
CREATE INDEX idx_flows_tenant ON flows(tenant_id, is_active);
|
|
1599
|
+
|
|
1600
|
+
CREATE INDEX idx_idempotency_keys_expires
|
|
1601
|
+
ON idempotency_keys(expires_at);
|
|
1602
|
+
|
|
1603
|
+
CREATE INDEX idx_idempotency_keys_lookup
|
|
1604
|
+
ON idempotency_keys(tenant_id, actor_id, idempotency_key);
|
|
1605
|
+
|
|
1606
|
+
CREATE INDEX idx_identity_providers_type ON identity_providers(provider_type);
|
|
1607
|
+
|
|
1608
|
+
CREATE INDEX idx_issued_credentials_status ON issued_credentials(status);
|
|
1609
|
+
|
|
1610
|
+
CREATE INDEX idx_issued_credentials_type ON issued_credentials(credential_type);
|
|
1611
|
+
|
|
1612
|
+
CREATE INDEX idx_issued_credentials_user ON issued_credentials(tenant_id, user_id);
|
|
1613
|
+
|
|
1614
|
+
CREATE INDEX idx_linked_identities_provider ON linked_identities(provider_id);
|
|
1615
|
+
|
|
1616
|
+
CREATE INDEX idx_linked_identities_user ON linked_identities(user_id);
|
|
1617
|
+
|
|
1618
|
+
CREATE INDEX idx_membership_org ON subject_org_membership(org_id);
|
|
1619
|
+
|
|
1620
|
+
CREATE INDEX idx_membership_subject ON subject_org_membership(subject_id);
|
|
1621
|
+
|
|
1622
|
+
CREATE INDEX idx_oauth_clients_tenant_id ON oauth_clients(tenant_id);
|
|
1623
|
+
|
|
1624
|
+
CREATE INDEX idx_odm_lookup ON org_domain_mappings(
|
|
1625
|
+
tenant_id,
|
|
1626
|
+
domain_hash,
|
|
1627
|
+
is_active,
|
|
1628
|
+
verified DESC,
|
|
1629
|
+
priority DESC
|
|
1630
|
+
);
|
|
1631
|
+
|
|
1632
|
+
CREATE INDEX idx_odm_org ON org_domain_mappings(org_id);
|
|
1633
|
+
|
|
1634
|
+
CREATE INDEX idx_odm_verification_status ON org_domain_mappings(
|
|
1635
|
+
verification_status,
|
|
1636
|
+
verification_expires_at
|
|
1637
|
+
);
|
|
1638
|
+
|
|
1639
|
+
CREATE INDEX idx_odm_version ON org_domain_mappings(domain_hash_version);
|
|
1640
|
+
|
|
1641
|
+
CREATE INDEX idx_operational_logs_actor
|
|
1642
|
+
ON operational_logs(actor_id);
|
|
1643
|
+
|
|
1644
|
+
CREATE INDEX idx_operational_logs_expires
|
|
1645
|
+
ON operational_logs(expires_at);
|
|
1646
|
+
|
|
1647
|
+
CREATE INDEX idx_operational_logs_subject
|
|
1648
|
+
ON operational_logs(subject_type, subject_id);
|
|
1649
|
+
|
|
1650
|
+
CREATE INDEX idx_operational_logs_tenant_created
|
|
1651
|
+
ON operational_logs(tenant_id, created_at DESC);
|
|
1652
|
+
|
|
1653
|
+
CREATE INDEX idx_organizations_is_active ON organizations(is_active);
|
|
1654
|
+
|
|
1655
|
+
CREATE INDEX idx_organizations_org_type ON organizations(org_type);
|
|
1656
|
+
|
|
1657
|
+
CREATE INDEX idx_organizations_parent_org_id ON organizations(parent_org_id);
|
|
1658
|
+
|
|
1659
|
+
CREATE INDEX idx_organizations_tenant_id ON organizations(tenant_id);
|
|
1660
|
+
|
|
1661
|
+
CREATE UNIQUE INDEX idx_organizations_tenant_name ON organizations(tenant_id, name);
|
|
1662
|
+
|
|
1663
|
+
CREATE INDEX idx_passkeys_tenant ON passkeys(tenant_id);
|
|
1664
|
+
|
|
1665
|
+
CREATE INDEX idx_passkeys_user ON passkeys(user_id);
|
|
1666
|
+
|
|
1667
|
+
CREATE INDEX idx_password_reset_user ON password_reset_tokens(user_id);
|
|
1668
|
+
|
|
1669
|
+
CREATE INDEX idx_pca_api_key
|
|
1670
|
+
ON permission_check_audit(api_key_id)
|
|
1671
|
+
WHERE api_key_id IS NOT NULL;
|
|
1672
|
+
|
|
1673
|
+
CREATE INDEX idx_pca_checked_at
|
|
1674
|
+
ON permission_check_audit(checked_at);
|
|
1675
|
+
|
|
1676
|
+
CREATE INDEX idx_pca_denied
|
|
1677
|
+
ON permission_check_audit(tenant_id, final_decision)
|
|
1678
|
+
WHERE final_decision = 'deny';
|
|
1679
|
+
|
|
1680
|
+
CREATE INDEX idx_pca_tenant_subject
|
|
1681
|
+
ON permission_check_audit(tenant_id, subject_id);
|
|
1682
|
+
|
|
1683
|
+
CREATE INDEX idx_pcaudit_event_type
|
|
1684
|
+
ON permission_change_audit(tenant_id, event_type);
|
|
1685
|
+
|
|
1686
|
+
CREATE INDEX idx_pcaudit_tenant_subject
|
|
1687
|
+
ON permission_change_audit(tenant_id, subject_id);
|
|
1688
|
+
|
|
1689
|
+
CREATE INDEX idx_pcaudit_timestamp
|
|
1690
|
+
ON permission_change_audit(timestamp);
|
|
1691
|
+
|
|
1692
|
+
CREATE INDEX idx_policy_rules_priority ON policy_rules(tenant_id, priority DESC);
|
|
1693
|
+
|
|
1694
|
+
CREATE INDEX idx_policy_rules_tenant ON policy_rules(tenant_id, enabled);
|
|
1695
|
+
|
|
1696
|
+
CREATE INDEX idx_policy_simulations_tenant ON policy_simulations(tenant_id, simulated_at DESC);
|
|
1697
|
+
|
|
1698
|
+
CREATE INDEX idx_presentation_definitions_tenant ON presentation_definitions(tenant_id);
|
|
1699
|
+
|
|
1700
|
+
CREATE INDEX idx_rar_evaluation ON role_assignment_rules(
|
|
1701
|
+
tenant_id,
|
|
1702
|
+
is_active,
|
|
1703
|
+
priority DESC
|
|
1704
|
+
);
|
|
1705
|
+
|
|
1706
|
+
CREATE INDEX idx_rar_role ON role_assignment_rules(role_id);
|
|
1707
|
+
|
|
1708
|
+
CREATE INDEX idx_relation_defs_active
|
|
1709
|
+
ON relation_definitions(tenant_id, is_active);
|
|
1710
|
+
|
|
1711
|
+
CREATE INDEX idx_relation_defs_lookup
|
|
1712
|
+
ON relation_definitions(tenant_id, object_type, relation_name);
|
|
1713
|
+
|
|
1714
|
+
CREATE INDEX idx_relation_defs_tenant_object
|
|
1715
|
+
ON relation_definitions(tenant_id, object_type);
|
|
1716
|
+
|
|
1717
|
+
CREATE UNIQUE INDEX idx_relation_defs_unique
|
|
1718
|
+
ON relation_definitions(tenant_id, object_type, relation_name);
|
|
1719
|
+
|
|
1720
|
+
CREATE INDEX idx_relationships_evidence_type
|
|
1721
|
+
ON relationships(tenant_id, evidence_type);
|
|
1722
|
+
|
|
1723
|
+
CREATE INDEX idx_relationships_expires_at ON relationships(expires_at);
|
|
1724
|
+
|
|
1725
|
+
CREATE INDEX idx_relationships_from ON relationships(from_type, from_id);
|
|
1726
|
+
|
|
1727
|
+
CREATE INDEX idx_relationships_tenant_id ON relationships(tenant_id);
|
|
1728
|
+
|
|
1729
|
+
CREATE INDEX idx_relationships_to ON relationships(to_type, to_id);
|
|
1730
|
+
|
|
1731
|
+
CREATE INDEX idx_relationships_type ON relationships(relationship_type);
|
|
1732
|
+
|
|
1733
|
+
CREATE UNIQUE INDEX idx_relationships_unique
|
|
1734
|
+
ON relationships(tenant_id, relationship_type, from_type, from_id, to_type, to_id);
|
|
1735
|
+
|
|
1736
|
+
CREATE INDEX idx_role_assignments_role ON role_assignments(role_id);
|
|
1737
|
+
|
|
1738
|
+
CREATE INDEX idx_role_assignments_subject ON role_assignments(subject_id);
|
|
1739
|
+
|
|
1740
|
+
CREATE INDEX idx_roles_hierarchy_level ON roles(hierarchy_level);
|
|
1741
|
+
|
|
1742
|
+
CREATE INDEX idx_roles_name ON roles(name);
|
|
1743
|
+
|
|
1744
|
+
CREATE INDEX idx_roles_parent_role_id ON roles(parent_role_id);
|
|
1745
|
+
|
|
1746
|
+
CREATE INDEX idx_roles_role_type ON roles(role_type);
|
|
1747
|
+
|
|
1748
|
+
CREATE INDEX idx_roles_tenant_id ON roles(tenant_id);
|
|
1749
|
+
|
|
1750
|
+
CREATE INDEX idx_rp_expires ON resource_permissions(expires_at)
|
|
1751
|
+
WHERE expires_at IS NOT NULL;
|
|
1752
|
+
|
|
1753
|
+
CREATE INDEX idx_rp_lookup ON resource_permissions(
|
|
1754
|
+
tenant_id,
|
|
1755
|
+
subject_type,
|
|
1756
|
+
subject_id,
|
|
1757
|
+
resource_type,
|
|
1758
|
+
is_active
|
|
1759
|
+
);
|
|
1760
|
+
|
|
1761
|
+
CREATE INDEX idx_rp_resource ON resource_permissions(
|
|
1762
|
+
tenant_id,
|
|
1763
|
+
resource_type,
|
|
1764
|
+
resource_id,
|
|
1765
|
+
is_active
|
|
1766
|
+
);
|
|
1767
|
+
|
|
1768
|
+
CREATE INDEX idx_rtsc_activated_at
|
|
1769
|
+
ON refresh_token_shard_configs(activated_at);
|
|
1770
|
+
|
|
1771
|
+
CREATE INDEX idx_rtsc_generation
|
|
1772
|
+
ON refresh_token_shard_configs(generation);
|
|
1773
|
+
|
|
1774
|
+
CREATE INDEX idx_rtsc_tenant_client
|
|
1775
|
+
ON refresh_token_shard_configs(tenant_id, client_id);
|
|
1776
|
+
|
|
1777
|
+
CREATE INDEX idx_schema_migrations_applied_at ON schema_migrations(applied_at DESC);
|
|
1778
|
+
|
|
1779
|
+
CREATE INDEX idx_schema_migrations_checksum ON schema_migrations(checksum);
|
|
1780
|
+
|
|
1781
|
+
CREATE INDEX idx_scope_mappings_scope ON scope_mappings(scope);
|
|
1782
|
+
|
|
1783
|
+
CREATE INDEX idx_security_alerts_tenant_created
|
|
1784
|
+
ON security_alerts(tenant_id, created_at DESC);
|
|
1785
|
+
|
|
1786
|
+
CREATE INDEX idx_security_alerts_tenant_severity
|
|
1787
|
+
ON security_alerts(tenant_id, severity);
|
|
1788
|
+
|
|
1789
|
+
CREATE INDEX idx_security_alerts_tenant_status
|
|
1790
|
+
ON security_alerts(tenant_id, status);
|
|
1791
|
+
|
|
1792
|
+
CREATE INDEX idx_security_alerts_tenant_type
|
|
1793
|
+
ON security_alerts(tenant_id, type);
|
|
1794
|
+
|
|
1795
|
+
CREATE INDEX idx_security_alerts_user
|
|
1796
|
+
ON security_alerts(user_id);
|
|
1797
|
+
|
|
1798
|
+
CREATE INDEX idx_security_threats_detected ON security_threats(tenant_id, detected_at);
|
|
1799
|
+
|
|
1800
|
+
CREATE INDEX idx_security_threats_severity ON security_threats(tenant_id, severity);
|
|
1801
|
+
|
|
1802
|
+
CREATE INDEX idx_security_threats_status ON security_threats(tenant_id, status);
|
|
1803
|
+
|
|
1804
|
+
CREATE INDEX idx_security_threats_tenant ON security_threats(tenant_id);
|
|
1805
|
+
|
|
1806
|
+
CREATE INDEX idx_security_threats_type ON security_threats(tenant_id, type);
|
|
1807
|
+
|
|
1808
|
+
CREATE INDEX idx_session_clients_client_id ON session_clients(client_id);
|
|
1809
|
+
|
|
1810
|
+
CREATE INDEX idx_session_clients_last_seen_at ON session_clients(last_seen_at);
|
|
1811
|
+
|
|
1812
|
+
CREATE INDEX idx_session_clients_session_id ON session_clients(session_id);
|
|
1813
|
+
|
|
1814
|
+
CREATE INDEX idx_sessions_expires ON sessions(expires_at);
|
|
1815
|
+
|
|
1816
|
+
CREATE INDEX idx_sessions_tenant ON sessions(tenant_id);
|
|
1817
|
+
|
|
1818
|
+
CREATE INDEX idx_sessions_user ON sessions(user_id);
|
|
1819
|
+
|
|
1820
|
+
CREATE INDEX idx_settings_history_actor ON settings_history(
|
|
1821
|
+
actor_id,
|
|
1822
|
+
created_at DESC
|
|
1823
|
+
);
|
|
1824
|
+
|
|
1825
|
+
CREATE INDEX idx_settings_history_category ON settings_history(
|
|
1826
|
+
tenant_id,
|
|
1827
|
+
category,
|
|
1828
|
+
version DESC
|
|
1829
|
+
);
|
|
1830
|
+
|
|
1831
|
+
CREATE INDEX idx_settings_history_cleanup ON settings_history(
|
|
1832
|
+
tenant_id,
|
|
1833
|
+
category,
|
|
1834
|
+
created_at
|
|
1835
|
+
);
|
|
1836
|
+
|
|
1837
|
+
CREATE INDEX idx_status_lists_tenant ON status_lists(tenant_id);
|
|
1838
|
+
|
|
1839
|
+
CREATE INDEX idx_subject_identifiers_lookup
|
|
1840
|
+
ON subject_identifiers(tenant_id, identifier_type, identifier_value);
|
|
1841
|
+
|
|
1842
|
+
CREATE INDEX idx_subject_identifiers_primary
|
|
1843
|
+
ON subject_identifiers(tenant_id, subject_id, is_primary);
|
|
1844
|
+
|
|
1845
|
+
CREATE INDEX idx_subject_identifiers_tenant_subject
|
|
1846
|
+
ON subject_identifiers(tenant_id, subject_id);
|
|
1847
|
+
|
|
1848
|
+
CREATE UNIQUE INDEX idx_subject_identifiers_unique
|
|
1849
|
+
ON subject_identifiers(tenant_id, identifier_type, identifier_value);
|
|
1850
|
+
|
|
1851
|
+
CREATE INDEX idx_suspicious_activities_created ON suspicious_activities(tenant_id, created_at);
|
|
1852
|
+
|
|
1853
|
+
CREATE INDEX idx_suspicious_activities_severity ON suspicious_activities(tenant_id, severity);
|
|
1854
|
+
|
|
1855
|
+
CREATE INDEX idx_suspicious_activities_tenant ON suspicious_activities(tenant_id);
|
|
1856
|
+
|
|
1857
|
+
CREATE INDEX idx_suspicious_activities_type ON suspicious_activities(tenant_id, type);
|
|
1858
|
+
|
|
1859
|
+
CREATE INDEX idx_suspicious_activities_user ON suspicious_activities(tenant_id, user_id);
|
|
1860
|
+
|
|
1861
|
+
CREATE INDEX idx_tcr_evaluation ON token_claim_rules(
|
|
1862
|
+
tenant_id,
|
|
1863
|
+
token_type,
|
|
1864
|
+
is_active,
|
|
1865
|
+
priority DESC,
|
|
1866
|
+
created_at ASC
|
|
1867
|
+
);
|
|
1868
|
+
|
|
1869
|
+
CREATE INDEX idx_token_families_client ON user_token_families(client_id);
|
|
1870
|
+
|
|
1871
|
+
CREATE INDEX idx_token_families_user ON user_token_families(user_id);
|
|
1872
|
+
|
|
1873
|
+
CREATE INDEX idx_trusted_issuers_did ON trusted_issuers(issuer_did);
|
|
1874
|
+
|
|
1875
|
+
CREATE INDEX idx_trusted_issuers_tenant ON trusted_issuers(tenant_id);
|
|
1876
|
+
|
|
1877
|
+
CREATE INDEX idx_upstream_providers_enabled
|
|
1878
|
+
ON upstream_providers(tenant_id, enabled);
|
|
1879
|
+
|
|
1880
|
+
CREATE INDEX idx_upstream_providers_tenant_id
|
|
1881
|
+
ON upstream_providers(tenant_id);
|
|
1882
|
+
|
|
1883
|
+
CREATE UNIQUE INDEX idx_upstream_providers_tenant_name
|
|
1884
|
+
ON upstream_providers(tenant_id, name);
|
|
1885
|
+
|
|
1886
|
+
CREATE UNIQUE INDEX idx_upstream_providers_tenant_slug
|
|
1887
|
+
ON upstream_providers(tenant_id, slug)
|
|
1888
|
+
WHERE slug IS NOT NULL;
|
|
1889
|
+
|
|
1890
|
+
CREATE INDEX idx_user_verified_attributes_name ON user_verified_attributes(tenant_id, attribute_name);
|
|
1891
|
+
|
|
1892
|
+
CREATE INDEX idx_user_verified_attributes_user ON user_verified_attributes(tenant_id, user_id);
|
|
1893
|
+
|
|
1894
|
+
CREATE INDEX idx_users_core_active ON users_core(is_active);
|
|
1895
|
+
|
|
1896
|
+
CREATE INDEX idx_users_core_email_domain ON users_core(email_domain_hash);
|
|
1897
|
+
|
|
1898
|
+
CREATE INDEX idx_users_core_hash_version ON users_core(email_domain_hash_version);
|
|
1899
|
+
|
|
1900
|
+
CREATE INDEX idx_users_core_partition ON users_core(pii_partition);
|
|
1901
|
+
|
|
1902
|
+
CREATE INDEX idx_users_core_pii_status ON users_core(pii_status);
|
|
1903
|
+
|
|
1904
|
+
CREATE INDEX idx_users_core_status ON users_core(tenant_id, status);
|
|
1905
|
+
|
|
1906
|
+
CREATE INDEX idx_users_core_tenant ON users_core(tenant_id);
|
|
1907
|
+
|
|
1908
|
+
CREATE INDEX idx_users_core_tenant_external_id ON users_core(tenant_id, external_id);
|
|
1909
|
+
|
|
1910
|
+
CREATE INDEX idx_users_core_type ON users_core(tenant_id, user_type);
|
|
1911
|
+
|
|
1912
|
+
CREATE INDEX idx_users_created_at ON users(created_at);
|
|
1913
|
+
|
|
1914
|
+
CREATE UNIQUE INDEX idx_users_tenant_email ON users(tenant_id, email);
|
|
1915
|
+
|
|
1916
|
+
CREATE INDEX idx_users_tenant_id ON users(tenant_id);
|
|
1917
|
+
|
|
1918
|
+
CREATE INDEX idx_users_tenant_status ON users(tenant_id, status);
|
|
1919
|
+
|
|
1920
|
+
CREATE INDEX idx_users_user_type ON users(user_type);
|
|
1921
|
+
|
|
1922
|
+
CREATE INDEX idx_verified_attributes_expires
|
|
1923
|
+
ON verified_attributes(tenant_id, expires_at);
|
|
1924
|
+
|
|
1925
|
+
CREATE INDEX idx_verified_attributes_lookup
|
|
1926
|
+
ON verified_attributes(tenant_id, subject_id, attribute_name);
|
|
1927
|
+
|
|
1928
|
+
CREATE INDEX idx_verified_attributes_source
|
|
1929
|
+
ON verified_attributes(tenant_id, source);
|
|
1930
|
+
|
|
1931
|
+
CREATE INDEX idx_verified_attributes_tenant_subject
|
|
1932
|
+
ON verified_attributes(tenant_id, subject_id);
|
|
1933
|
+
|
|
1934
|
+
CREATE INDEX idx_verified_attributes_unique_check
|
|
1935
|
+
ON verified_attributes(tenant_id, subject_id, attribute_name, source);
|
|
1936
|
+
|
|
1937
|
+
CREATE INDEX idx_vp_requests_nonce ON vp_requests(nonce);
|
|
1938
|
+
|
|
1939
|
+
CREATE INDEX idx_vp_requests_tenant_status ON vp_requests(tenant_id, status);
|
|
1940
|
+
|
|
1941
|
+
CREATE INDEX idx_webhook_configs_active ON webhook_configs(tenant_id, active) WHERE active = 1;
|
|
1942
|
+
|
|
1943
|
+
CREATE INDEX idx_webhook_configs_client ON webhook_configs(tenant_id, client_id);
|
|
1944
|
+
|
|
1945
|
+
CREATE INDEX idx_webhook_configs_scope ON webhook_configs(tenant_id, scope);
|
|
1946
|
+
|
|
1947
|
+
CREATE INDEX idx_webhook_configs_tenant ON webhook_configs(tenant_id);
|
|
1948
|
+
|
|
1949
|
+
CREATE INDEX idx_webhook_delivery_logs_created ON webhook_delivery_logs(created_at);
|
|
1950
|
+
|
|
1951
|
+
CREATE INDEX idx_webhook_delivery_logs_event ON webhook_delivery_logs(event_id);
|
|
1952
|
+
|
|
1953
|
+
CREATE INDEX idx_webhook_delivery_logs_tenant ON webhook_delivery_logs(tenant_id);
|
|
1954
|
+
|
|
1955
|
+
CREATE INDEX idx_webhook_delivery_logs_webhook ON webhook_delivery_logs(webhook_id);
|
|
1956
|
+
|
|
1957
|
+
CREATE INDEX idx_ws_subs_active
|
|
1958
|
+
ON websocket_subscriptions(is_active)
|
|
1959
|
+
WHERE is_active = 1;
|
|
1960
|
+
|
|
1961
|
+
CREATE INDEX idx_ws_subs_connection
|
|
1962
|
+
ON websocket_subscriptions(connection_id);
|
|
1963
|
+
|
|
1964
|
+
CREATE INDEX idx_ws_subs_subject
|
|
1965
|
+
ON websocket_subscriptions(subject_id, is_active);
|
|
1966
|
+
|