@coffre/db 0.3.0 → 0.4.0
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/connect.d.ts +1 -1
- package/dist/{database-Cq_52uUo.d.ts → database-edkMkG02.d.ts} +1 -1
- package/dist/dialect.d.ts +10 -2
- package/dist/dialect.js +34 -1
- package/dist/grants.d.ts +32 -0
- package/dist/grants.js +27 -0
- package/dist/hyperdrive.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/log.d.ts +1 -1
- package/dist/migrate.js +6 -1
- package/dist/migrations/postgres/0000_baseline.sql +174 -46
- package/dist/migrations/postgres/0001_mcp_approvals.sql +24 -0
- package/dist/migrations/postgres/meta/0000_snapshot.json +963 -185
- package/dist/migrations/postgres/meta/0001_snapshot.json +1171 -30
- package/dist/migrations/postgres/meta/_journal.json +3 -24
- package/dist/migrations/sqlite/0000_baseline.sql +142 -35
- package/dist/migrations/sqlite/0001_mcp_approvals.sql +19 -0
- package/dist/migrations/sqlite/meta/0000_snapshot.json +878 -235
- package/dist/migrations/sqlite/meta/0001_snapshot.json +1062 -57
- package/dist/migrations/sqlite/meta/_journal.json +3 -24
- package/dist/portable.d.ts +2 -2
- package/dist/{schema-Wt-p8AOh.d.ts → schema-BqCB3XFm.d.ts} +1153 -83
- package/dist/schema-sqlite.d.ts +1171 -60
- package/dist/schema-sqlite.js +173 -11
- package/dist/schema-version.d.ts +9 -13
- package/dist/schema-version.js +38 -90
- package/dist/schema.d.ts +2 -2
- package/dist/schema.js +208 -15
- package/package.json +7 -2
- package/src/baseline/postgres.sql +46 -10
- package/src/baseline/sqlite.sql +15 -0
- package/src/baseline.ts +7 -3
- package/src/dialect.ts +25 -1
- package/src/grants.ts +51 -0
- package/src/migrate.ts +5 -0
- package/src/migrations/postgres/0000_baseline.sql +174 -46
- package/src/migrations/postgres/0001_mcp_approvals.sql +24 -0
- package/src/migrations/postgres/meta/0000_snapshot.json +963 -185
- package/src/migrations/postgres/meta/0001_snapshot.json +1171 -30
- package/src/migrations/postgres/meta/_journal.json +3 -24
- package/src/migrations/sqlite/0000_baseline.sql +142 -35
- package/src/migrations/sqlite/0001_mcp_approvals.sql +19 -0
- package/src/migrations/sqlite/meta/0000_snapshot.json +878 -235
- package/src/migrations/sqlite/meta/0001_snapshot.json +1062 -57
- package/src/migrations/sqlite/meta/_journal.json +3 -24
- package/src/schema-version.ts +26 -18
- package/src/schema.sqlite.ts +223 -8
- package/src/schema.ts +263 -11
- package/dist/migrations/postgres/0001_remove_syncs.sql +0 -13
- package/dist/migrations/postgres/0002_service_bindings.sql +0 -28
- package/dist/migrations/postgres/0003_exchanges.sql +0 -10
- package/dist/migrations/postgres/0004_live_indexes.sql +0 -3
- package/dist/migrations/postgres/meta/0002_snapshot.json +0 -1870
- package/dist/migrations/postgres/meta/0003_snapshot.json +0 -1917
- package/dist/migrations/postgres/meta/0004_snapshot.json +0 -2006
- package/dist/migrations/sqlite/0001_remove_syncs.sql +0 -13
- package/dist/migrations/sqlite/0002_service_bindings.sql +0 -23
- package/dist/migrations/sqlite/0003_exchanges.sql +0 -7
- package/dist/migrations/sqlite/0004_live_indexes.sql +0 -3
- package/dist/migrations/sqlite/meta/0002_snapshot.json +0 -1736
- package/dist/migrations/sqlite/meta/0003_snapshot.json +0 -1781
- package/dist/migrations/sqlite/meta/0004_snapshot.json +0 -1811
- package/src/migrations/postgres/0001_remove_syncs.sql +0 -13
- package/src/migrations/postgres/0002_service_bindings.sql +0 -28
- package/src/migrations/postgres/0003_exchanges.sql +0 -10
- package/src/migrations/postgres/0004_live_indexes.sql +0 -3
- package/src/migrations/postgres/meta/0002_snapshot.json +0 -1870
- package/src/migrations/postgres/meta/0003_snapshot.json +0 -1917
- package/src/migrations/postgres/meta/0004_snapshot.json +0 -2006
- package/src/migrations/sqlite/0001_remove_syncs.sql +0 -13
- package/src/migrations/sqlite/0002_service_bindings.sql +0 -23
- package/src/migrations/sqlite/0003_exchanges.sql +0 -7
- package/src/migrations/sqlite/0004_live_indexes.sql +0 -3
- package/src/migrations/sqlite/meta/0002_snapshot.json +0 -1736
- package/src/migrations/sqlite/meta/0003_snapshot.json +0 -1781
- package/src/migrations/sqlite/meta/0004_snapshot.json +0 -1811
|
@@ -5,36 +5,15 @@
|
|
|
5
5
|
{
|
|
6
6
|
"idx": 0,
|
|
7
7
|
"version": "7",
|
|
8
|
-
"when":
|
|
8
|
+
"when": 1791237720902,
|
|
9
9
|
"tag": "0000_baseline",
|
|
10
10
|
"breakpoints": true
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"idx": 1,
|
|
14
14
|
"version": "7",
|
|
15
|
-
"when":
|
|
16
|
-
"tag": "
|
|
17
|
-
"breakpoints": true
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"idx": 2,
|
|
21
|
-
"version": "7",
|
|
22
|
-
"when": 1791069304538,
|
|
23
|
-
"tag": "0002_service_bindings",
|
|
24
|
-
"breakpoints": true
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"idx": 3,
|
|
28
|
-
"version": "7",
|
|
29
|
-
"when": 1791072336889,
|
|
30
|
-
"tag": "0003_exchanges",
|
|
31
|
-
"breakpoints": true
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
"idx": 4,
|
|
35
|
-
"version": "7",
|
|
36
|
-
"when": 1791084354462,
|
|
37
|
-
"tag": "0004_live_indexes",
|
|
15
|
+
"when": 1791242674488,
|
|
16
|
+
"tag": "0001_mcp_approvals",
|
|
38
17
|
"breakpoints": true
|
|
39
18
|
}
|
|
40
19
|
]
|
|
@@ -38,7 +38,7 @@ CREATE TABLE `audit_log` (
|
|
|
38
38
|
FOREIGN KEY (`secret_version_id`) REFERENCES `secret_versions`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
39
39
|
FOREIGN KEY (`related_seq`) REFERENCES `audit_log`(`seq`) ON UPDATE no action ON DELETE restrict,
|
|
40
40
|
CONSTRAINT "audit_log_author_check" CHECK("audit_log"."author" IN ('app', 'vault')),
|
|
41
|
-
CONSTRAINT "audit_log_actor_check" CHECK("audit_log"."actor" GLOB 'user:?*' OR "audit_log"."actor" GLOB 'token:?*' OR "audit_log"."actor" GLOB '
|
|
41
|
+
CONSTRAINT "audit_log_actor_check" CHECK("audit_log"."actor" GLOB 'user:?*' OR "audit_log"."actor" GLOB 'token:?*' OR "audit_log"."actor" GLOB 'system:?*'),
|
|
42
42
|
CONSTRAINT "audit_log_decision_check" CHECK("audit_log"."decision" IN ('allow', 'deny')),
|
|
43
43
|
CONSTRAINT "audit_log_metadata_check" CHECK(json_valid("audit_log"."metadata")),
|
|
44
44
|
CONSTRAINT "audit_log_prev_hash_check" CHECK(octet_length("audit_log"."prev_hash") = 32),
|
|
@@ -54,6 +54,18 @@ CREATE INDEX `audit_log_operation_idx` ON `audit_log` (`operation_id`,`seq`);-->
|
|
|
54
54
|
CREATE INDEX `audit_log_action_idx` ON `audit_log` (`author`,`action`,`seq`);--> statement-breakpoint
|
|
55
55
|
CREATE INDEX `audit_log_releases_idx` ON `audit_log` (`author`,`actor`,`action`,`decision`,`occurred_at`);--> statement-breakpoint
|
|
56
56
|
CREATE INDEX `audit_log_subject_idx` ON `audit_log` (`author`,`subject_principal`,`seq`);--> statement-breakpoint
|
|
57
|
+
CREATE INDEX `audit_log_unbind_idx` ON `audit_log` (json_extract("metadata", '$.bindingId')) WHERE "audit_log"."author" = 'app' AND "audit_log"."action" = 'token.unbind' AND "audit_log"."decision" = 'allow';--> statement-breakpoint
|
|
58
|
+
CREATE INDEX `audit_log_exchange_idx` ON `audit_log` (json_extract("metadata", '$.credentialId')) WHERE "audit_log"."author" = 'app' AND "audit_log"."action" = 'token.exchange' AND "audit_log"."decision" = 'allow';--> statement-breakpoint
|
|
59
|
+
CREATE INDEX `audit_log_reference_end_idx` ON `audit_log` (`related_seq`) WHERE "audit_log"."author" = 'vault' AND "audit_log"."action" = 'reference.end' AND "audit_log"."decision" = 'allow';--> statement-breakpoint
|
|
60
|
+
CREATE INDEX `audit_log_also_project_idx` ON `audit_log` (json_extract("metadata", '$.also.projectId'),`seq`) WHERE json_extract("audit_log"."metadata", '$.also') IS NOT NULL;--> statement-breakpoint
|
|
61
|
+
CREATE INDEX `audit_log_also_environment_idx` ON `audit_log` (json_extract("metadata", '$.also.environmentId'),`seq`) WHERE json_extract("audit_log"."metadata", '$.also') IS NOT NULL;--> statement-breakpoint
|
|
62
|
+
CREATE INDEX `audit_log_also_secret_idx` ON `audit_log` (json_extract("metadata", '$.also.secretId'),`seq`) WHERE json_extract("audit_log"."metadata", '$.also') IS NOT NULL;--> statement-breakpoint
|
|
63
|
+
CREATE TABLE `consumed_tokens` (
|
|
64
|
+
`hash` blob PRIMARY KEY NOT NULL,
|
|
65
|
+
`consumed_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
66
|
+
CONSTRAINT "consumed_tokens_hash_check" CHECK(octet_length("consumed_tokens"."hash") = 32)
|
|
67
|
+
);
|
|
68
|
+
--> statement-breakpoint
|
|
57
69
|
CREATE TABLE `credentials` (
|
|
58
70
|
`id` text PRIMARY KEY NOT NULL,
|
|
59
71
|
`kind` text NOT NULL,
|
|
@@ -81,6 +93,8 @@ CREATE TABLE `credentials` (
|
|
|
81
93
|
);
|
|
82
94
|
--> statement-breakpoint
|
|
83
95
|
CREATE INDEX `credentials_principal_idx` ON `credentials` (`principal`,`generation`);--> statement-breakpoint
|
|
96
|
+
CREATE INDEX `credentials_live_idx` ON `credentials` (`principal`,`expires_at`) WHERE "credentials"."revoked_at" IS NULL;--> statement-breakpoint
|
|
97
|
+
CREATE INDEX `credentials_issued_by_idx` ON `credentials` (`principal`,`created_by`,`created_at`);--> statement-breakpoint
|
|
84
98
|
CREATE UNIQUE INDEX `credentials_token_hash_key` ON `credentials` (`token_hash`);--> statement-breakpoint
|
|
85
99
|
CREATE TABLE `device_authorizations` (
|
|
86
100
|
`id` text PRIMARY KEY NOT NULL,
|
|
@@ -108,6 +122,18 @@ CREATE TABLE `device_authorizations` (
|
|
|
108
122
|
--> statement-breakpoint
|
|
109
123
|
CREATE UNIQUE INDEX `device_authorizations_device_code_hash_key` ON `device_authorizations` (`device_code_hash`);--> statement-breakpoint
|
|
110
124
|
CREATE UNIQUE INDEX `device_authorizations_user_code_key` ON `device_authorizations` (`user_code`);--> statement-breakpoint
|
|
125
|
+
CREATE TABLE `dismissed_keys` (
|
|
126
|
+
`environment_id` text NOT NULL,
|
|
127
|
+
`key` text NOT NULL,
|
|
128
|
+
`dismissed_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
129
|
+
`dismissed_by` text NOT NULL,
|
|
130
|
+
`restored_at` integer,
|
|
131
|
+
`restored_by` text,
|
|
132
|
+
PRIMARY KEY(`environment_id`, `key`),
|
|
133
|
+
FOREIGN KEY (`environment_id`) REFERENCES `environments`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
134
|
+
CONSTRAINT "dismissed_keys_key_check" CHECK(length("dismissed_keys"."key") BETWEEN 1 AND 128 AND "dismissed_keys"."key" GLOB '[A-Za-z_]*' AND "dismissed_keys"."key" NOT GLOB '*[^A-Za-z0-9_]*')
|
|
135
|
+
);
|
|
136
|
+
--> statement-breakpoint
|
|
111
137
|
CREATE TABLE `environments` (
|
|
112
138
|
`id` text PRIMARY KEY NOT NULL,
|
|
113
139
|
`project_id` text NOT NULL,
|
|
@@ -116,7 +142,7 @@ CREATE TABLE `environments` (
|
|
|
116
142
|
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
117
143
|
`archived_at` integer,
|
|
118
144
|
FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
119
|
-
CONSTRAINT "environments_slug_check" CHECK(length("environments"."slug") BETWEEN 1 AND 63 AND "environments"."slug" GLOB '[a-z0-9]*' AND "environments"."slug" NOT GLOB '*[^a-z0-9-]*')
|
|
145
|
+
CONSTRAINT "environments_slug_check" CHECK((length("environments"."slug") BETWEEN 1 AND 63 AND "environments"."slug" GLOB '[a-z0-9]*' AND "environments"."slug" NOT GLOB '*[^a-z0-9-]*') OR (instr("environments"."slug", '~') BETWEEN 2 AND 64 AND substr("environments"."slug", 1, instr("environments"."slug", '~') - 1) GLOB '[a-z0-9]*' AND substr("environments"."slug", 1, instr("environments"."slug", '~') - 1) NOT GLOB '*[^a-z0-9-]*' AND length(substr("environments"."slug", instr("environments"."slug", '~') + 1)) BETWEEN 1 AND 40 AND substr("environments"."slug", instr("environments"."slug", '~') + 1) NOT GLOB '*[^a-z0-9-]*'))
|
|
120
146
|
);
|
|
121
147
|
--> statement-breakpoint
|
|
122
148
|
CREATE UNIQUE INDEX `environments_project_id_slug_key` ON `environments` (`project_id`,`slug`);--> statement-breakpoint
|
|
@@ -145,16 +171,86 @@ CREATE TABLE `identities` (
|
|
|
145
171
|
CREATE UNIQUE INDEX `identities_active_subject` ON `identities` (`provider`,`issuer_hash`,`active_subject`);--> statement-breakpoint
|
|
146
172
|
CREATE INDEX `identities_principal_idx` ON `identities` (`principal`,`generation`);--> statement-breakpoint
|
|
147
173
|
CREATE UNIQUE INDEX `identities_member_generation_key` ON `identities` (`id`,`principal`,`generation`);--> statement-breakpoint
|
|
174
|
+
CREATE TABLE `mcp_connections` (
|
|
175
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
176
|
+
`auth_mac` blob NOT NULL,
|
|
177
|
+
`principal` text NOT NULL,
|
|
178
|
+
`generation` integer NOT NULL,
|
|
179
|
+
`client_id` text NOT NULL,
|
|
180
|
+
`client_name` text NOT NULL,
|
|
181
|
+
`client_host` text,
|
|
182
|
+
`registration` text NOT NULL,
|
|
183
|
+
`scopes` text NOT NULL,
|
|
184
|
+
`redirect_uri` text NOT NULL,
|
|
185
|
+
`code_hash` blob,
|
|
186
|
+
`code_challenge` text,
|
|
187
|
+
`code_expires_at` integer,
|
|
188
|
+
`refresh_hash` blob,
|
|
189
|
+
`refresh_previous_hash` blob,
|
|
190
|
+
`expires_at` integer NOT NULL,
|
|
191
|
+
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
192
|
+
`last_used_at` integer,
|
|
193
|
+
`last_used_ip` text,
|
|
194
|
+
`revoked_at` integer,
|
|
195
|
+
`revoked_by` text,
|
|
196
|
+
FOREIGN KEY (`principal`) REFERENCES `vault_members`(`principal`) ON UPDATE no action ON DELETE restrict,
|
|
197
|
+
CONSTRAINT "mcp_connections_principal_check" CHECK("mcp_connections"."principal" LIKE 'user:%'),
|
|
198
|
+
CONSTRAINT "mcp_connections_registration_check" CHECK("mcp_connections"."registration" IN ('cimd', 'dcr')),
|
|
199
|
+
CONSTRAINT "mcp_connections_auth_mac_check" CHECK(octet_length("mcp_connections"."auth_mac") = 32),
|
|
200
|
+
CONSTRAINT "mcp_connections_code_hash_check" CHECK("mcp_connections"."code_hash" IS NULL OR octet_length("mcp_connections"."code_hash") = 32),
|
|
201
|
+
CONSTRAINT "mcp_connections_refresh_hash_check" CHECK("mcp_connections"."refresh_hash" IS NULL OR octet_length("mcp_connections"."refresh_hash") = 32)
|
|
202
|
+
);
|
|
203
|
+
--> statement-breakpoint
|
|
204
|
+
CREATE INDEX `mcp_connections_refresh_previous_idx` ON `mcp_connections` (`refresh_previous_hash`);--> statement-breakpoint
|
|
205
|
+
CREATE INDEX `mcp_connections_live_idx` ON `mcp_connections` (`principal`,`expires_at`) WHERE "mcp_connections"."revoked_at" IS NULL;--> statement-breakpoint
|
|
206
|
+
CREATE UNIQUE INDEX `mcp_connections_code_hash_key` ON `mcp_connections` (`code_hash`);--> statement-breakpoint
|
|
207
|
+
CREATE UNIQUE INDEX `mcp_connections_refresh_hash_key` ON `mcp_connections` (`refresh_hash`);--> statement-breakpoint
|
|
208
|
+
CREATE TABLE `oauth_clients` (
|
|
209
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
210
|
+
`auth_mac` blob NOT NULL,
|
|
211
|
+
`name` text NOT NULL,
|
|
212
|
+
`redirect_uris` text NOT NULL,
|
|
213
|
+
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
214
|
+
`created_ip` text,
|
|
215
|
+
`revoked_at` integer,
|
|
216
|
+
CONSTRAINT "oauth_clients_auth_mac_check" CHECK(octet_length("oauth_clients"."auth_mac") = 32),
|
|
217
|
+
CONSTRAINT "oauth_clients_redirect_uris_check" CHECK(json_valid("oauth_clients"."redirect_uris"))
|
|
218
|
+
);
|
|
219
|
+
--> statement-breakpoint
|
|
148
220
|
CREATE TABLE `projects` (
|
|
149
221
|
`id` text PRIMARY KEY NOT NULL,
|
|
150
222
|
`slug` text NOT NULL,
|
|
151
223
|
`name` text NOT NULL,
|
|
152
224
|
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
153
225
|
`archived_at` integer,
|
|
154
|
-
|
|
226
|
+
`folder` text,
|
|
227
|
+
CONSTRAINT "projects_slug_check" CHECK((length("projects"."slug") BETWEEN 1 AND 63 AND "projects"."slug" GLOB '[a-z0-9]*' AND "projects"."slug" NOT GLOB '*[^a-z0-9-]*') OR (instr("projects"."slug", '~') BETWEEN 2 AND 64 AND substr("projects"."slug", 1, instr("projects"."slug", '~') - 1) GLOB '[a-z0-9]*' AND substr("projects"."slug", 1, instr("projects"."slug", '~') - 1) NOT GLOB '*[^a-z0-9-]*' AND length(substr("projects"."slug", instr("projects"."slug", '~') + 1)) BETWEEN 1 AND 40 AND substr("projects"."slug", instr("projects"."slug", '~') + 1) NOT GLOB '*[^a-z0-9-]*')),
|
|
228
|
+
CONSTRAINT "projects_folder_check" CHECK("projects"."folder" IS NULL OR (length("projects"."folder") BETWEEN 1 AND 64 AND "projects"."folder" NOT GLOB '*/*' AND "projects"."folder" = trim("projects"."folder")))
|
|
155
229
|
);
|
|
156
230
|
--> statement-breakpoint
|
|
157
231
|
CREATE UNIQUE INDEX `projects_slug_key` ON `projects` (`slug`);--> statement-breakpoint
|
|
232
|
+
CREATE TABLE `secret_references` (
|
|
233
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
234
|
+
`project_id` text NOT NULL,
|
|
235
|
+
`environment_id` text NOT NULL,
|
|
236
|
+
`secret_id` text NOT NULL,
|
|
237
|
+
`source_project_id` text NOT NULL,
|
|
238
|
+
`source_environment_id` text NOT NULL,
|
|
239
|
+
`source_secret_id` text NOT NULL,
|
|
240
|
+
`created_seq` integer NOT NULL,
|
|
241
|
+
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
242
|
+
`created_by` text NOT NULL,
|
|
243
|
+
FOREIGN KEY (`secret_id`) REFERENCES `secrets`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
244
|
+
FOREIGN KEY (`source_secret_id`) REFERENCES `secrets`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
245
|
+
FOREIGN KEY (`created_seq`) REFERENCES `audit_log`(`seq`) ON UPDATE no action ON DELETE restrict
|
|
246
|
+
);
|
|
247
|
+
--> statement-breakpoint
|
|
248
|
+
CREATE INDEX `secret_references_holder_idx` ON `secret_references` (`secret_id`,`created_seq`);--> statement-breakpoint
|
|
249
|
+
CREATE INDEX `secret_references_source_idx` ON `secret_references` (`source_secret_id`);--> statement-breakpoint
|
|
250
|
+
CREATE INDEX `secret_references_project_idx` ON `secret_references` (`project_id`);--> statement-breakpoint
|
|
251
|
+
CREATE INDEX `secret_references_source_project_idx` ON `secret_references` (`source_project_id`);--> statement-breakpoint
|
|
252
|
+
CREATE INDEX `secret_references_created_by_idx` ON `secret_references` (`created_by`);--> statement-breakpoint
|
|
253
|
+
CREATE UNIQUE INDEX `secret_references_created_seq_key` ON `secret_references` (`created_seq`);--> statement-breakpoint
|
|
158
254
|
CREATE TABLE `secret_versions` (
|
|
159
255
|
`id` text PRIMARY KEY NOT NULL,
|
|
160
256
|
`secret_id` text NOT NULL,
|
|
@@ -187,52 +283,45 @@ CREATE TABLE `secrets` (
|
|
|
187
283
|
`current_version_id` text,
|
|
188
284
|
`current_version` integer DEFAULT 0 NOT NULL,
|
|
189
285
|
`archived_at` integer,
|
|
286
|
+
`folder` text,
|
|
190
287
|
FOREIGN KEY (`current_version_id`) REFERENCES `secret_versions`(`id`) ON UPDATE no action ON DELETE no action,
|
|
191
288
|
FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
192
289
|
FOREIGN KEY (`environment_id`) REFERENCES `environments`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
193
290
|
FOREIGN KEY (`environment_id`,`project_id`) REFERENCES `environments`(`id`,`project_id`) ON UPDATE no action ON DELETE no action,
|
|
194
|
-
CONSTRAINT "secrets_key_check" CHECK(length("secrets"."key") BETWEEN 1 AND 128 AND "secrets"."key" GLOB '[A-Za-z_]*' AND "secrets"."key" NOT GLOB '*[^A-Za-z0-9_]*')
|
|
291
|
+
CONSTRAINT "secrets_key_check" CHECK(length("secrets"."key") BETWEEN 1 AND 128 AND "secrets"."key" GLOB '[A-Za-z_]*' AND "secrets"."key" NOT GLOB '*[^A-Za-z0-9_]*'),
|
|
292
|
+
CONSTRAINT "secrets_folder_check" CHECK("secrets"."folder" IS NULL OR (length("secrets"."folder") BETWEEN 1 AND 64 AND "secrets"."folder" NOT GLOB '*/*' AND "secrets"."folder" = trim("secrets"."folder")))
|
|
195
293
|
);
|
|
196
294
|
--> statement-breakpoint
|
|
197
295
|
CREATE INDEX `secrets_lookup_idx` ON `secrets` (`project_id`,`environment_id`,`key`);--> statement-breakpoint
|
|
198
296
|
CREATE UNIQUE INDEX `secrets_project_id_environment_id_key_key` ON `secrets` (`project_id`,`environment_id`,`key`);--> statement-breakpoint
|
|
199
|
-
CREATE TABLE `
|
|
200
|
-
`sync_id` text NOT NULL,
|
|
201
|
-
`key` text NOT NULL,
|
|
202
|
-
`secret_version_id` text,
|
|
203
|
-
`pushed_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
204
|
-
`removed_at` integer,
|
|
205
|
-
PRIMARY KEY(`sync_id`, `key`),
|
|
206
|
-
FOREIGN KEY (`sync_id`) REFERENCES `syncs`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
207
|
-
FOREIGN KEY (`secret_version_id`) REFERENCES `secret_versions`(`id`) ON UPDATE no action ON DELETE restrict
|
|
208
|
-
);
|
|
209
|
-
--> statement-breakpoint
|
|
210
|
-
CREATE TABLE `syncs` (
|
|
297
|
+
CREATE TABLE `service_bindings` (
|
|
211
298
|
`id` text PRIMARY KEY NOT NULL,
|
|
212
|
-
`
|
|
213
|
-
`
|
|
214
|
-
`
|
|
215
|
-
`
|
|
216
|
-
`
|
|
299
|
+
`auth_mac` blob NOT NULL,
|
|
300
|
+
`principal` text NOT NULL,
|
|
301
|
+
`generation` integer NOT NULL,
|
|
302
|
+
`profile` text NOT NULL,
|
|
303
|
+
`issuer` text NOT NULL,
|
|
304
|
+
`jwks_uri` text NOT NULL,
|
|
305
|
+
`claims` text NOT NULL,
|
|
306
|
+
`label` text,
|
|
217
307
|
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
218
308
|
`created_by` text NOT NULL,
|
|
219
|
-
`
|
|
220
|
-
`
|
|
221
|
-
`
|
|
222
|
-
`
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
FOREIGN KEY (`credential_secret_id`) REFERENCES `secrets`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
227
|
-
CONSTRAINT "syncs_config_check" CHECK(json_valid("syncs"."config")),
|
|
228
|
-
CONSTRAINT "syncs_last_status_check" CHECK("syncs"."last_status" IS NULL OR "syncs"."last_status" IN ('ok', 'partial', 'failed'))
|
|
309
|
+
`last_used_at` integer,
|
|
310
|
+
`revoked_at` integer,
|
|
311
|
+
`revoked_by` text,
|
|
312
|
+
FOREIGN KEY (`principal`) REFERENCES `vault_members`(`principal`) ON UPDATE no action ON DELETE restrict,
|
|
313
|
+
CONSTRAINT "service_bindings_principal_check" CHECK("service_bindings"."principal" LIKE 'token:%'),
|
|
314
|
+
CONSTRAINT "service_bindings_auth_mac_check" CHECK(octet_length("service_bindings"."auth_mac") = 32),
|
|
315
|
+
CONSTRAINT "service_bindings_claims_check" CHECK(json_valid("service_bindings"."claims"))
|
|
229
316
|
);
|
|
230
317
|
--> statement-breakpoint
|
|
231
|
-
CREATE INDEX `
|
|
318
|
+
CREATE INDEX `service_bindings_principal_idx` ON `service_bindings` (`principal`,`issuer`);--> statement-breakpoint
|
|
319
|
+
CREATE INDEX `service_bindings_live_idx` ON `service_bindings` (`principal`,`issuer`,`generation`,`created_at`,`id`) WHERE "service_bindings"."revoked_at" IS NULL;--> statement-breakpoint
|
|
232
320
|
CREATE TABLE `vault_grants` (
|
|
233
321
|
`principal` text NOT NULL,
|
|
234
322
|
`project_id` text,
|
|
235
323
|
`environment_id` text,
|
|
324
|
+
`environment_slug` text,
|
|
236
325
|
`role` text NOT NULL,
|
|
237
326
|
`expires_at` integer,
|
|
238
327
|
`granted_at` integer NOT NULL,
|
|
@@ -240,13 +329,16 @@ CREATE TABLE `vault_grants` (
|
|
|
240
329
|
FOREIGN KEY (`principal`) REFERENCES `vault_members`(`principal`) ON UPDATE no action ON DELETE restrict,
|
|
241
330
|
FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
242
331
|
FOREIGN KEY (`environment_id`) REFERENCES `environments`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
243
|
-
CONSTRAINT "vault_grants_one_place" CHECK(("vault_grants"."project_id" IS NULL) <> ("vault_grants"."environment_id" IS NULL)),
|
|
332
|
+
CONSTRAINT "vault_grants_one_place" CHECK((("vault_grants"."project_id" IS NULL) <> ("vault_grants"."environment_id" IS NULL) AND "vault_grants"."environment_slug" IS NULL) OR ("vault_grants"."project_id" IS NULL AND "vault_grants"."environment_id" IS NULL)),
|
|
333
|
+
CONSTRAINT "vault_grants_environment_slug_check" CHECK("vault_grants"."environment_slug" IS NULL OR (length("vault_grants"."environment_slug") BETWEEN 1 AND 63 AND "vault_grants"."environment_slug" GLOB '[a-z0-9]*' AND "vault_grants"."environment_slug" NOT GLOB '*[^a-z0-9-]*')),
|
|
244
334
|
CONSTRAINT "vault_grants_role_check" CHECK("vault_grants"."role" IN ('viewer', 'developer', 'maintainer', 'access-manager', 'auditor', 'owner')),
|
|
245
|
-
CONSTRAINT "vault_grants_environment_role_check" CHECK("vault_grants"."environment_id" IS NULL OR "vault_grants"."role" IN ('viewer', 'developer', 'auditor'))
|
|
335
|
+
CONSTRAINT "vault_grants_environment_role_check" CHECK(("vault_grants"."environment_id" IS NULL AND "vault_grants"."environment_slug" IS NULL) OR "vault_grants"."role" IN ('viewer', 'developer', 'auditor'))
|
|
246
336
|
);
|
|
247
337
|
--> statement-breakpoint
|
|
338
|
+
CREATE UNIQUE INDEX `vault_grants_on_every_project` ON `vault_grants` (`principal`) WHERE "vault_grants"."project_id" IS NULL AND "vault_grants"."environment_id" IS NULL AND "vault_grants"."environment_slug" IS NULL;--> statement-breakpoint
|
|
248
339
|
CREATE UNIQUE INDEX `vault_grants_on_project` ON `vault_grants` (`principal`,`project_id`);--> statement-breakpoint
|
|
249
340
|
CREATE UNIQUE INDEX `vault_grants_on_environment` ON `vault_grants` (`principal`,`environment_id`);--> statement-breakpoint
|
|
341
|
+
CREATE UNIQUE INDEX `vault_grants_on_environment_slug` ON `vault_grants` (`principal`,`environment_slug`);--> statement-breakpoint
|
|
250
342
|
CREATE TABLE `vault_members` (
|
|
251
343
|
`principal` text PRIMARY KEY NOT NULL,
|
|
252
344
|
`status` text NOT NULL,
|
|
@@ -259,7 +351,7 @@ CREATE TABLE `vault_members` (
|
|
|
259
351
|
`access_seq` integer NOT NULL,
|
|
260
352
|
`mac` blob NOT NULL,
|
|
261
353
|
CONSTRAINT "vault_members_mac_check" CHECK(octet_length("vault_members"."mac") = 32),
|
|
262
|
-
CONSTRAINT "vault_members_principal_check" CHECK(("vault_members"."principal" GLOB 'user:?*' OR "vault_members"."principal" GLOB 'token:?*'
|
|
354
|
+
CONSTRAINT "vault_members_principal_check" CHECK(("vault_members"."principal" GLOB 'user:?*' OR "vault_members"."principal" GLOB 'token:?*')
|
|
263
355
|
AND substr("vault_members"."principal", instr("vault_members"."principal", ':') + 1, 1) <> ':'
|
|
264
356
|
AND instr("vault_members"."principal", ' ') = 0 AND instr("vault_members"."principal", char(9)) = 0
|
|
265
357
|
AND instr("vault_members"."principal", char(10)) = 0 AND instr("vault_members"."principal", char(13)) = 0),
|
|
@@ -291,3 +383,18 @@ CREATE TRIGGER `audit_log_no_delete` BEFORE DELETE ON `audit_log`
|
|
|
291
383
|
BEGIN
|
|
292
384
|
SELECT RAISE(ABORT, 'audit_log is append-only');
|
|
293
385
|
END;
|
|
386
|
+
--> statement-breakpoint
|
|
387
|
+
|
|
388
|
+
-- A secret version is never rewritten in place, only erased: a deleted
|
|
389
|
+
-- project or environment stays as a tombstone the log's entries name, and
|
|
390
|
+
-- its versions with it, their ciphertext and wrapped data key emptied. That
|
|
391
|
+
-- is the one change a version takes.
|
|
392
|
+
CREATE TRIGGER `secret_versions_erase_only` BEFORE UPDATE ON `secret_versions`
|
|
393
|
+
WHEN length(NEW.`ciphertext`) <> 0 OR length(NEW.`wrapped_dek`) <> 0
|
|
394
|
+
OR NEW.`id` IS NOT OLD.`id` OR NEW.`secret_id` IS NOT OLD.`secret_id` OR NEW.`version` IS NOT OLD.`version`
|
|
395
|
+
OR NEW.`envelope_version` IS NOT OLD.`envelope_version` OR NEW.`iv` IS NOT OLD.`iv` OR NEW.`auth_tag` IS NOT OLD.`auth_tag`
|
|
396
|
+
OR NEW.`kek_provider` IS NOT OLD.`kek_provider` OR NEW.`kek_id` IS NOT OLD.`kek_id` OR NEW.`kek_version` IS NOT OLD.`kek_version`
|
|
397
|
+
OR NEW.`created_at` IS NOT OLD.`created_at` OR NEW.`created_by` IS NOT OLD.`created_by`
|
|
398
|
+
BEGIN
|
|
399
|
+
SELECT RAISE(ABORT, 'a secret version is only ever erased');
|
|
400
|
+
END;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
CREATE TABLE `mcp_approvals` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`connection_id` text NOT NULL,
|
|
4
|
+
`tool` text NOT NULL,
|
|
5
|
+
`arguments` text NOT NULL,
|
|
6
|
+
`digest` blob NOT NULL,
|
|
7
|
+
`status` text DEFAULT 'pending' NOT NULL,
|
|
8
|
+
`outcome` text,
|
|
9
|
+
`created_at` integer DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER)) NOT NULL,
|
|
10
|
+
`expires_at` integer NOT NULL,
|
|
11
|
+
`decided_at` integer,
|
|
12
|
+
`reported_at` integer,
|
|
13
|
+
FOREIGN KEY (`connection_id`) REFERENCES `mcp_connections`(`id`) ON UPDATE no action ON DELETE restrict,
|
|
14
|
+
CONSTRAINT "mcp_approvals_status_check" CHECK("mcp_approvals"."status" IN ('pending', 'approved', 'denied', 'cancelled', 'failed')),
|
|
15
|
+
CONSTRAINT "mcp_approvals_digest_check" CHECK(octet_length("mcp_approvals"."digest") = 32),
|
|
16
|
+
CONSTRAINT "mcp_approvals_arguments_check" CHECK(json_valid("mcp_approvals"."arguments"))
|
|
17
|
+
);
|
|
18
|
+
--> statement-breakpoint
|
|
19
|
+
CREATE INDEX `mcp_approvals_open_idx` ON `mcp_approvals` (`connection_id`,`digest`) WHERE "mcp_approvals"."reported_at" IS NULL;
|