@vollcrypt/db-guard 0.1.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/README.md +271 -0
- package/compliance-config.json +39 -0
- package/dist/blind-index.d.ts +7 -0
- package/dist/blind-index.js +24 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +211 -0
- package/dist/compliance-report.html +562 -0
- package/dist/compliance.d.ts +40 -0
- package/dist/compliance.js +659 -0
- package/dist/drizzle.d.ts +65 -0
- package/dist/drizzle.js +118 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +44 -0
- package/dist/kms.d.ts +46 -0
- package/dist/kms.js +154 -0
- package/dist/mongoose.d.ts +30 -0
- package/dist/mongoose.js +317 -0
- package/dist/prisma.d.ts +54 -0
- package/dist/prisma.js +390 -0
- package/dist/provenance.json +222 -0
- package/dist/provenance.json.sig +1 -0
- package/dist/sbom.json +209 -0
- package/dist/sbom.json.sig +1 -0
- package/dist/security.d.ts +88 -0
- package/dist/security.js +547 -0
- package/dist/typeorm.d.ts +26 -0
- package/dist/typeorm.js +149 -0
- package/package.json +50 -0
package/dist/prisma.js
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prismaDbGuard = void 0;
|
|
4
|
+
exports.resolveKeys = resolveKeys;
|
|
5
|
+
exports.encryptValue = encryptValue;
|
|
6
|
+
exports.decryptValue = decryptValue;
|
|
7
|
+
exports.rewriteQueryWhere = rewriteQueryWhere;
|
|
8
|
+
exports.addBlindIndexes = addBlindIndexes;
|
|
9
|
+
const client_1 = require("@prisma/client");
|
|
10
|
+
const blind_index_1 = require("./blind-index");
|
|
11
|
+
const kms_1 = require("./kms");
|
|
12
|
+
const security_1 = require("./security");
|
|
13
|
+
/**
|
|
14
|
+
* Resolves the plaintext keys asynchronously from local config or KMS provider.
|
|
15
|
+
*/
|
|
16
|
+
async function resolveKeys(options) {
|
|
17
|
+
let rawKeys = {};
|
|
18
|
+
if (options.key) {
|
|
19
|
+
if (Buffer.isBuffer(options.key)) {
|
|
20
|
+
rawKeys = { '1': options.key };
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
rawKeys = { ...options.key };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (options.kms) {
|
|
27
|
+
const { provider, wrappedKey, wrappedKek } = options.kms;
|
|
28
|
+
if (Buffer.isBuffer(wrappedKey)) {
|
|
29
|
+
if (wrappedKek && Buffer.isBuffer(wrappedKek)) {
|
|
30
|
+
const unwrappedKek = await provider.decrypt(wrappedKek);
|
|
31
|
+
const dek = (0, kms_1.unwrapDekLocal)(wrappedKey, unwrappedKek);
|
|
32
|
+
unwrappedKek.fill(0); // RAM Security: zeroize KEK immediately
|
|
33
|
+
rawKeys = { '1': dek };
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const key = await provider.decrypt(wrappedKey);
|
|
37
|
+
rawKeys = { '1': key };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
for (const [ver, wrapped] of Object.entries(wrappedKey)) {
|
|
42
|
+
if (wrappedKek) {
|
|
43
|
+
const wKek = Buffer.isBuffer(wrappedKek) ? wrappedKek : wrappedKek[ver];
|
|
44
|
+
if (wKek) {
|
|
45
|
+
const unwrappedKek = await provider.decrypt(wKek);
|
|
46
|
+
const dek = (0, kms_1.unwrapDekLocal)(wrapped, unwrappedKek);
|
|
47
|
+
unwrappedKek.fill(0); // RAM Security: zeroize KEK immediately
|
|
48
|
+
rawKeys[ver] = dek;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
rawKeys[ver] = await provider.decrypt(wrapped);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
rawKeys[ver] = await provider.decrypt(wrapped);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new Error("Either 'key' or 'kms' configuration must be provided.");
|
|
62
|
+
}
|
|
63
|
+
return rawKeys;
|
|
64
|
+
}
|
|
65
|
+
function encryptValue(val, key, version) {
|
|
66
|
+
if (val === null || val === undefined)
|
|
67
|
+
return val;
|
|
68
|
+
const plaintext = typeof val === 'string' ? val : JSON.stringify(val);
|
|
69
|
+
const plaintextBuf = Buffer.from(plaintext, 'utf8');
|
|
70
|
+
const encrypted = security_1.CRYPTO_ALGORITHMS['1'].encrypt(plaintextBuf, key);
|
|
71
|
+
// RAM Security: Zeroize the plaintext buffer immediately
|
|
72
|
+
plaintextBuf.fill(0);
|
|
73
|
+
return `VOLLVALT:v${version}:${encrypted.toString('base64')}`;
|
|
74
|
+
}
|
|
75
|
+
function decryptValue(stored, keys) {
|
|
76
|
+
if (typeof stored !== 'string') {
|
|
77
|
+
return stored;
|
|
78
|
+
}
|
|
79
|
+
const parsed = (0, security_1.parseCiphertext)(stored);
|
|
80
|
+
if (!parsed) {
|
|
81
|
+
return stored;
|
|
82
|
+
}
|
|
83
|
+
const { algoId, version, base64Data } = parsed;
|
|
84
|
+
const key = keys[version];
|
|
85
|
+
if (!key) {
|
|
86
|
+
throw new Error(`Decryption key version "${version}" not found in registered keys`);
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const encryptedBuf = Buffer.from(base64Data, 'base64');
|
|
90
|
+
const decryptor = security_1.CRYPTO_ALGORITHMS[algoId];
|
|
91
|
+
if (!decryptor) {
|
|
92
|
+
throw new Error(`Unsupported decryption algorithm ID "${algoId}"`);
|
|
93
|
+
}
|
|
94
|
+
const decrypted = decryptor.decrypt(encryptedBuf, key);
|
|
95
|
+
const plaintext = decrypted.toString('utf8');
|
|
96
|
+
// RAM Security: Zeroize the decrypted buffer
|
|
97
|
+
decrypted.fill(0);
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(plaintext);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return plaintext;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
throw new Error(`Failed to decrypt field value: ${err.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Traverses query `where` arguments to rewrite exact match queries on encrypted fields
|
|
111
|
+
* to target shadow `_bidx` columns using dynamic HKDF-SHA256 blind indexing.
|
|
112
|
+
*/
|
|
113
|
+
function rewriteQueryWhere(where, fields, rootSalt, modelName) {
|
|
114
|
+
if (!where || typeof where !== 'object')
|
|
115
|
+
return;
|
|
116
|
+
for (const field of fields) {
|
|
117
|
+
if (where[field] !== undefined) {
|
|
118
|
+
const val = where[field];
|
|
119
|
+
const bidxField = `${field}_bidx`;
|
|
120
|
+
if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
|
|
121
|
+
where[bidxField] = (0, blind_index_1.computeBlindIndex)(val, rootSalt, `${modelName}.${field}`);
|
|
122
|
+
delete where[field];
|
|
123
|
+
}
|
|
124
|
+
else if (val && typeof val === 'object') {
|
|
125
|
+
if (val.equals !== undefined) {
|
|
126
|
+
where[bidxField] = {
|
|
127
|
+
equals: (0, blind_index_1.computeBlindIndex)(val.equals, rootSalt, `${modelName}.${field}`),
|
|
128
|
+
};
|
|
129
|
+
delete where[field];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Recurse into compound logical operators
|
|
135
|
+
const operators = ['AND', 'OR', 'NOT'];
|
|
136
|
+
for (const op of operators) {
|
|
137
|
+
if (Array.isArray(where[op])) {
|
|
138
|
+
where[op].forEach((item) => rewriteQueryWhere(item, fields, rootSalt, modelName));
|
|
139
|
+
}
|
|
140
|
+
else if (where[op] && typeof where[op] === 'object') {
|
|
141
|
+
rewriteQueryWhere(where[op], fields, rootSalt, modelName);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Appends calculated blind indexes to the write payload (create/update).
|
|
147
|
+
*/
|
|
148
|
+
function addBlindIndexes(data, fields, rootSalt, modelName) {
|
|
149
|
+
if (!data || typeof data !== 'object')
|
|
150
|
+
return;
|
|
151
|
+
if (Array.isArray(data)) {
|
|
152
|
+
data.forEach((item) => addBlindIndexes(item, fields, rootSalt, modelName));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
for (const field of fields) {
|
|
156
|
+
if (data[field] !== undefined && data[field] !== null) {
|
|
157
|
+
const bidxField = `${field}_bidx`;
|
|
158
|
+
data[bidxField] = (0, blind_index_1.computeBlindIndex)(data[field], rootSalt, `${modelName}.${field}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Prisma DbGuard Extension Factory
|
|
164
|
+
*
|
|
165
|
+
* Bootstraps client-level field encryption, query translation, and automatic decryption.
|
|
166
|
+
*/
|
|
167
|
+
const prismaDbGuard = (options, resolvedKeys) => {
|
|
168
|
+
let keys = resolvedKeys;
|
|
169
|
+
if (!keys) {
|
|
170
|
+
if (options.key) {
|
|
171
|
+
if (Buffer.isBuffer(options.key)) {
|
|
172
|
+
keys = { '1': options.key };
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
keys = { ...options.key };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (options.kms || options.multiTenant) {
|
|
179
|
+
// Keys might be resolved dynamically per tenant, or resolved later
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
throw new Error("Resolved keys must be provided as the second argument when using KMS.");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (keys) {
|
|
186
|
+
(0, security_1.registerKeysForZeroization)(keys);
|
|
187
|
+
}
|
|
188
|
+
const activeVersion = options.kms?.activeKeyVersion || '1';
|
|
189
|
+
const activeKey = keys ? keys[activeVersion] : undefined;
|
|
190
|
+
const resolveTenantKeysAndActiveKey = async (tenantId) => {
|
|
191
|
+
if ((0, security_1.isBreakGlassActive)()) {
|
|
192
|
+
const bgKey = (0, security_1.getBreakGlassKey)();
|
|
193
|
+
if (bgKey) {
|
|
194
|
+
return { keys: { '1': bgKey }, activeKey: bgKey, activeVersion: '1' };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (!tenantId || !options.multiTenant) {
|
|
198
|
+
if (!keys || !activeKey) {
|
|
199
|
+
throw new Error("Vollcrypt Security: Global keys are not resolved.");
|
|
200
|
+
}
|
|
201
|
+
return { keys, activeKey, activeVersion };
|
|
202
|
+
}
|
|
203
|
+
// Check Secure TTL Cache
|
|
204
|
+
const cachedActiveKey = (0, security_1.getCachedKey)(tenantId, activeVersion);
|
|
205
|
+
if (cachedActiveKey) {
|
|
206
|
+
return { keys: { [activeVersion]: cachedActiveKey }, activeKey: cachedActiveKey, activeVersion };
|
|
207
|
+
}
|
|
208
|
+
// Cache miss: resolve configuration
|
|
209
|
+
let tenantConfig;
|
|
210
|
+
if (options.multiTenant.tenants) {
|
|
211
|
+
tenantConfig = options.multiTenant.tenants[tenantId];
|
|
212
|
+
}
|
|
213
|
+
else if (options.multiTenant.getTenantConfig) {
|
|
214
|
+
tenantConfig = await options.multiTenant.getTenantConfig(tenantId);
|
|
215
|
+
}
|
|
216
|
+
if (!tenantConfig) {
|
|
217
|
+
throw new Error(`Vollcrypt Security: Configuration not found for tenantId "${tenantId}".`);
|
|
218
|
+
}
|
|
219
|
+
const resolvedTenantKeys = await resolveKeys({
|
|
220
|
+
...options,
|
|
221
|
+
key: tenantConfig.key,
|
|
222
|
+
kms: tenantConfig.kms
|
|
223
|
+
});
|
|
224
|
+
(0, security_1.registerKeysForZeroization)(resolvedTenantKeys);
|
|
225
|
+
const tActiveVersion = tenantConfig.kms?.activeKeyVersion || '1';
|
|
226
|
+
const tActiveKey = resolvedTenantKeys[tActiveVersion];
|
|
227
|
+
if (!tActiveKey) {
|
|
228
|
+
throw new Error(`Vollcrypt Security: Active key version "${tActiveVersion}" not found for tenantId "${tenantId}".`);
|
|
229
|
+
}
|
|
230
|
+
for (const [ver, keyBuf] of Object.entries(resolvedTenantKeys)) {
|
|
231
|
+
(0, security_1.setCachedKey)(tenantId, ver, keyBuf);
|
|
232
|
+
}
|
|
233
|
+
return { keys: resolvedTenantKeys, activeKey: tActiveKey, activeVersion: tActiveVersion };
|
|
234
|
+
};
|
|
235
|
+
const encryptPayload = (modelName, data, encKey, encVer) => {
|
|
236
|
+
const fieldsToEncrypt = options.models[modelName];
|
|
237
|
+
if (!fieldsToEncrypt || !data || typeof data !== 'object')
|
|
238
|
+
return data;
|
|
239
|
+
const cloned = { ...data };
|
|
240
|
+
for (const field of fieldsToEncrypt) {
|
|
241
|
+
if (cloned[field] !== undefined) {
|
|
242
|
+
cloned[field] = encryptValue(cloned[field], encKey, encVer);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return cloned;
|
|
246
|
+
};
|
|
247
|
+
const decryptResult = (modelName, result, decKeys) => {
|
|
248
|
+
const fieldsToEncrypt = options.models[modelName];
|
|
249
|
+
if (!fieldsToEncrypt || !result)
|
|
250
|
+
return result;
|
|
251
|
+
if (Array.isArray(result)) {
|
|
252
|
+
const pageSizeStatus = (0, security_1.checkPageSize)(result.length, options.rateLimiter);
|
|
253
|
+
if (pageSizeStatus === 'bypass') {
|
|
254
|
+
const currentCtx = security_1.dbGuardContextStore.getStore() || {};
|
|
255
|
+
return security_1.dbGuardContextStore.run({ ...currentCtx, bypassRateLimit: true }, () => {
|
|
256
|
+
return result.map((item) => decryptResult(modelName, item, decKeys));
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return result.map((item) => decryptResult(modelName, item, decKeys));
|
|
260
|
+
}
|
|
261
|
+
if (typeof result !== 'object')
|
|
262
|
+
return result;
|
|
263
|
+
const cloned = { ...result };
|
|
264
|
+
for (const field of fieldsToEncrypt) {
|
|
265
|
+
if (cloned[field] !== undefined) {
|
|
266
|
+
cloned[field] = (0, security_1.decryptWithSecurity)(cloned[field], (val) => decryptValue(val, decKeys), modelName, field, cloned.id || cloned._id, options);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return cloned;
|
|
270
|
+
};
|
|
271
|
+
const processWriteQuery = (modelName, args, encKey, encVer) => {
|
|
272
|
+
if (!args)
|
|
273
|
+
return;
|
|
274
|
+
// Encrypt write payload
|
|
275
|
+
if (args.data) {
|
|
276
|
+
args.data = encryptPayload(modelName, args.data, encKey, encVer);
|
|
277
|
+
}
|
|
278
|
+
if (args.create) {
|
|
279
|
+
args.create = encryptPayload(modelName, args.create, encKey, encVer);
|
|
280
|
+
}
|
|
281
|
+
if (args.update) {
|
|
282
|
+
args.update = encryptPayload(modelName, args.update, encKey, encVer);
|
|
283
|
+
}
|
|
284
|
+
// Add blind indexes if enabled
|
|
285
|
+
const bidxFields = options.blindIndexes?.models[modelName];
|
|
286
|
+
if (bidxFields && options.blindIndexes?.rootSalt) {
|
|
287
|
+
if (args.data) {
|
|
288
|
+
addBlindIndexes(args.data, bidxFields, options.blindIndexes.rootSalt, modelName);
|
|
289
|
+
}
|
|
290
|
+
if (args.create) {
|
|
291
|
+
addBlindIndexes(args.create, bidxFields, options.blindIndexes.rootSalt, modelName);
|
|
292
|
+
}
|
|
293
|
+
if (args.update) {
|
|
294
|
+
addBlindIndexes(args.update, bidxFields, options.blindIndexes.rootSalt, modelName);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
const processReadQuery = (modelName, args) => {
|
|
299
|
+
if (!args)
|
|
300
|
+
return;
|
|
301
|
+
// Rewrite queries targeting encrypted columns to use the blind index column
|
|
302
|
+
const bidxFields = options.blindIndexes?.models[modelName];
|
|
303
|
+
if (bidxFields && options.blindIndexes?.rootSalt && args.where) {
|
|
304
|
+
rewriteQueryWhere(args.where, bidxFields, options.blindIndexes.rootSalt, modelName);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
return client_1.Prisma.defineExtension((client) => {
|
|
308
|
+
return client.$extends({
|
|
309
|
+
name: 'vollcrypt-db-guard',
|
|
310
|
+
query: {
|
|
311
|
+
$allModels: {
|
|
312
|
+
async create({ model, args, query }) {
|
|
313
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
314
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
315
|
+
processWriteQuery(model, args, resolved.activeKey, resolved.activeVersion);
|
|
316
|
+
const result = await query(args);
|
|
317
|
+
return decryptResult(model, result, resolved.keys);
|
|
318
|
+
},
|
|
319
|
+
async createMany({ model, args, query }) {
|
|
320
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
321
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
322
|
+
if (args.data) {
|
|
323
|
+
if (Array.isArray(args.data)) {
|
|
324
|
+
args.data = args.data.map((item) => {
|
|
325
|
+
const encrypted = encryptPayload(model, item, resolved.activeKey, resolved.activeVersion);
|
|
326
|
+
const bidxFields = options.blindIndexes?.models[model];
|
|
327
|
+
if (bidxFields && options.blindIndexes?.rootSalt) {
|
|
328
|
+
addBlindIndexes(encrypted, bidxFields, options.blindIndexes.rootSalt, model);
|
|
329
|
+
}
|
|
330
|
+
return encrypted;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
processWriteQuery(model, args, resolved.activeKey, resolved.activeVersion);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const result = await query(args);
|
|
338
|
+
return decryptResult(model, result, resolved.keys);
|
|
339
|
+
},
|
|
340
|
+
async update({ model, args, query }) {
|
|
341
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
342
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
343
|
+
processWriteQuery(model, args, resolved.activeKey, resolved.activeVersion);
|
|
344
|
+
processReadQuery(model, args);
|
|
345
|
+
const result = await query(args);
|
|
346
|
+
return decryptResult(model, result, resolved.keys);
|
|
347
|
+
},
|
|
348
|
+
async updateMany({ model, args, query }) {
|
|
349
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
350
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
351
|
+
processWriteQuery(model, args, resolved.activeKey, resolved.activeVersion);
|
|
352
|
+
processReadQuery(model, args);
|
|
353
|
+
const result = await query(args);
|
|
354
|
+
return decryptResult(model, result, resolved.keys);
|
|
355
|
+
},
|
|
356
|
+
async upsert({ model, args, query }) {
|
|
357
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
358
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
359
|
+
processWriteQuery(model, args, resolved.activeKey, resolved.activeVersion);
|
|
360
|
+
processReadQuery(model, args);
|
|
361
|
+
const result = await query(args);
|
|
362
|
+
return decryptResult(model, result, resolved.keys);
|
|
363
|
+
},
|
|
364
|
+
async findFirst({ model, args, query }) {
|
|
365
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
366
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
367
|
+
processReadQuery(model, args);
|
|
368
|
+
const result = await query(args);
|
|
369
|
+
return decryptResult(model, result, resolved.keys);
|
|
370
|
+
},
|
|
371
|
+
async findUnique({ model, args, query }) {
|
|
372
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
373
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
374
|
+
processReadQuery(model, args);
|
|
375
|
+
const result = await query(args);
|
|
376
|
+
return decryptResult(model, result, resolved.keys);
|
|
377
|
+
},
|
|
378
|
+
async findMany({ model, args, query }) {
|
|
379
|
+
const context = security_1.dbGuardContextStore.getStore();
|
|
380
|
+
const resolved = await resolveTenantKeysAndActiveKey(context?.tenantId);
|
|
381
|
+
processReadQuery(model, args);
|
|
382
|
+
const result = await query(args);
|
|
383
|
+
return decryptResult(model, result, resolved.keys);
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
};
|
|
390
|
+
exports.prismaDbGuard = prismaDbGuard;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_type": "https://in-toto.io/Statement/v1",
|
|
3
|
+
"subject": [
|
|
4
|
+
{
|
|
5
|
+
"name": "dist/blind-index.d.ts",
|
|
6
|
+
"digest": {
|
|
7
|
+
"sha256": "7e613b58cf47bc14d647cfbfa2a9cc0f9e805dbab7562daa00ac679c30830ba7"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"name": "dist/blind-index.js",
|
|
12
|
+
"digest": {
|
|
13
|
+
"sha256": "fb28a7038cc818346aeb212ece2e5d4f1db4b72fd3ed9dda78a1a7f5744d7455"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "dist/cli.d.ts",
|
|
18
|
+
"digest": {
|
|
19
|
+
"sha256": "43e818adf60173644896298637f47b01d5819b17eda46eaa32d0c7d64724d012"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "dist/cli.js",
|
|
24
|
+
"digest": {
|
|
25
|
+
"sha256": "bf91d9b9d820796590d8b030e409031623d177e45cc487da8bcb66af13078ec0"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "dist/compliance.d.ts",
|
|
30
|
+
"digest": {
|
|
31
|
+
"sha256": "cfdccbe0a9cf27c428af69853b2a16f860dcdfc9ac2f2c65fe7305b7a5332d19"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "dist/compliance.js",
|
|
36
|
+
"digest": {
|
|
37
|
+
"sha256": "0b660e3eafcc27a78d5c97c7d34837a25c68295660a3d1c7da0ae8e0a676bfb6"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "dist/drizzle.d.ts",
|
|
42
|
+
"digest": {
|
|
43
|
+
"sha256": "cb43fec66c7da1e84b96a97e8a18b0d08606535c64236f66ff950250d0f23292"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "dist/drizzle.js",
|
|
48
|
+
"digest": {
|
|
49
|
+
"sha256": "aad49d4c9dd41f2e44175465da6ae7f4a7ae35337ce12f7b3a87113ec0f25424"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "dist/index.d.ts",
|
|
54
|
+
"digest": {
|
|
55
|
+
"sha256": "7f7c57559ed6b17bd5698a248c18d636c65f812406b685bb6b2fe243d6df59b8"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "dist/index.js",
|
|
60
|
+
"digest": {
|
|
61
|
+
"sha256": "9a6c591ff862cca301b2b45455b884c2c5ab7e994dd4a31df1235ebdcff8393c"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "dist/kms.d.ts",
|
|
66
|
+
"digest": {
|
|
67
|
+
"sha256": "822f37608176917f438febaaea06a3b65508c45474bd7e137c4df815c50b4854"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "dist/kms.js",
|
|
72
|
+
"digest": {
|
|
73
|
+
"sha256": "4b1a32b35545e2e7944ebba3f84272b7421ffedd1cc3c7eb569e1a6b2fcc4a02"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "dist/mongoose.d.ts",
|
|
78
|
+
"digest": {
|
|
79
|
+
"sha256": "a3bf00d62fecf9266325a9dd18c4ec272de9559355dbf3f9f43836a4688fe86b"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "dist/mongoose.js",
|
|
84
|
+
"digest": {
|
|
85
|
+
"sha256": "42b2177825713fa1c618b80af6cf7a5d9f4055399c8e95b67018a0410add2a3f"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "dist/prisma.d.ts",
|
|
90
|
+
"digest": {
|
|
91
|
+
"sha256": "f6b85a786a9bb964f0620df4bcad0787e5c972e853df35551cf8fc902bb79691"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "dist/prisma.js",
|
|
96
|
+
"digest": {
|
|
97
|
+
"sha256": "e2b7a8fa24c120f59ab48ebb508a18c01e3e24245e04c197b08ad0e327a2d9a8"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "dist/security.d.ts",
|
|
102
|
+
"digest": {
|
|
103
|
+
"sha256": "85bbbfdbf47b5ce72c29071004664aa8d4c872107a9f1826daaec53f3b40182b"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "dist/security.js",
|
|
108
|
+
"digest": {
|
|
109
|
+
"sha256": "8d3d398281d7d268e874f540c58371a4ba6410e19d5804d2cdde8fb7628531da"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "dist/typeorm.d.ts",
|
|
114
|
+
"digest": {
|
|
115
|
+
"sha256": "6cc82bbbe82e260abcc789495fe85f984138c5c8368901881edaece1ffa46d8c"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "dist/typeorm.js",
|
|
120
|
+
"digest": {
|
|
121
|
+
"sha256": "154827069a5496e043a9f69b3249bd5dddd62690783dfa8675d06d0f574ac76b"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
"predicateType": "https://slsa.dev/provenance/v1.0",
|
|
126
|
+
"predicate": {
|
|
127
|
+
"buildDefinition": {
|
|
128
|
+
"buildType": "https://vollcrypt.dev/builders/npm-typescript/v1",
|
|
129
|
+
"externalParameters": {
|
|
130
|
+
"packageJson": {
|
|
131
|
+
"name": "@vollcrypt/db-guard",
|
|
132
|
+
"version": "0.1.0",
|
|
133
|
+
"scripts": {
|
|
134
|
+
"build": "tsc && node scripts/generate-sbom.js",
|
|
135
|
+
"test": "node --import tsx --test tests/*.test.ts"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"internalParameters": {
|
|
140
|
+
"nodeVersion": "v22.15.0",
|
|
141
|
+
"platform": "win32",
|
|
142
|
+
"arch": "x64"
|
|
143
|
+
},
|
|
144
|
+
"resolvedDependencies": [
|
|
145
|
+
{
|
|
146
|
+
"uri": "pkg:npm/@prisma/client@4.7.0",
|
|
147
|
+
"digest": {}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"uri": "pkg:npm/mongoose@6.0.0",
|
|
151
|
+
"digest": {}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"uri": "pkg:npm/drizzle-orm@0.28.0",
|
|
155
|
+
"digest": {}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"uri": "pkg:npm/typeorm@0.3.0",
|
|
159
|
+
"digest": {}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"uri": "pkg:rust/aes-gcm",
|
|
163
|
+
"digest": {}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"uri": "pkg:rust/hkdf",
|
|
167
|
+
"digest": {}
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"uri": "pkg:rust/sha2",
|
|
171
|
+
"digest": {}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"uri": "pkg:rust/rand",
|
|
175
|
+
"digest": {}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"uri": "pkg:rust/diesel",
|
|
179
|
+
"digest": {}
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"uri": "pkg:rust/base64",
|
|
183
|
+
"digest": {}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"uri": "pkg:rust/once_cell",
|
|
187
|
+
"digest": {}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"uri": "pkg:rust/zeroize",
|
|
191
|
+
"digest": {}
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"uri": "pkg:rust/libsqlite3-sys",
|
|
195
|
+
"digest": {}
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"uri": "pkg:rust/sea-orm",
|
|
199
|
+
"digest": {}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"uri": "pkg:rust/cryptoki",
|
|
203
|
+
"digest": {}
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"uri": "pkg:rust/secrecy",
|
|
207
|
+
"digest": {}
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
"runDetails": {
|
|
212
|
+
"builder": {
|
|
213
|
+
"id": "https://vollcrypt.dev/builders/local-hermetic-env"
|
|
214
|
+
},
|
|
215
|
+
"metadata": {
|
|
216
|
+
"invocationId": "6a158baa8a336e407b4daf328603e46e",
|
|
217
|
+
"startedOn": "2026-06-11T12:43:47.573Z",
|
|
218
|
+
"finishedOn": "2026-06-11T12:43:47.574Z"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�]�B�����8٨�3�e�1�,���d2@jIo~�Ҧ��r�4Hp�/9b=�uy'�>�dӰ3
|