@happyvertical/smrt-secrets 0.30.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/AGENTS.md +66 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +144 -0
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/chunks/SecretService-C91H6WJK.js +1275 -0
- package/dist/chunks/SecretService-C91H6WJK.js.map +1 -0
- package/dist/chunks/TenantKey-DzglnpAV.js +377 -0
- package/dist/chunks/TenantKey-DzglnpAV.js.map +1 -0
- package/dist/collections/SecretAuditLogCollection.d.ts +71 -0
- package/dist/collections/SecretAuditLogCollection.d.ts.map +1 -0
- package/dist/collections/SecretCollection.d.ts +63 -0
- package/dist/collections/SecretCollection.d.ts.map +1 -0
- package/dist/collections/TenantKeyCollection.d.ts +42 -0
- package/dist/collections/TenantKeyCollection.d.ts.map +1 -0
- package/dist/collections/index.d.ts +8 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +1272 -0
- package/dist/models/Secret.d.ts +104 -0
- package/dist/models/Secret.d.ts.map +1 -0
- package/dist/models/SecretAuditLog.d.ts +123 -0
- package/dist/models/SecretAuditLog.d.ts.map +1 -0
- package/dist/models/TenantKey.d.ts +101 -0
- package/dist/models/TenantKey.d.ts.map +1 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +8 -0
- package/dist/models/index.js.map +1 -0
- package/dist/services/SecretService.d.ts +266 -0
- package/dist/services/SecretService.d.ts.map +1 -0
- package/dist/services/SecretService.js +9 -0
- package/dist/services/SecretService.js.map +1 -0
- package/dist/smrt-knowledge.json +447 -0
- package/package.json +71 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
/**
|
|
3
|
+
* Secret status values
|
|
4
|
+
*/
|
|
5
|
+
export type SecretStatus = 'active' | 'disabled' | 'expired';
|
|
6
|
+
/**
|
|
7
|
+
* Secret represents an encrypted value stored per-tenant.
|
|
8
|
+
*
|
|
9
|
+
* Secrets are tenant-scoped and use envelope encryption:
|
|
10
|
+
* - Each tenant has their own Data Encryption Key (TDEK)
|
|
11
|
+
* - The TDEK is wrapped by the Application Master Key (AMK)
|
|
12
|
+
* - Secret values are encrypted by the unwrapped TDEK
|
|
13
|
+
*
|
|
14
|
+
* **Security**: This model deliberately excludes API and MCP exposure
|
|
15
|
+
* to prevent accidental secret leakage. Secrets are only accessible
|
|
16
|
+
* via CLI commands or direct service calls.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { SecretService } from '@happyvertical/smrt-secrets';
|
|
21
|
+
*
|
|
22
|
+
* const service = await SecretService.create({ db });
|
|
23
|
+
*
|
|
24
|
+
* await withTenant({ tenantId: 'tenant-123' }, async () => {
|
|
25
|
+
* // Store a secret
|
|
26
|
+
* await service.store('api-key', 'sk_live_xxx', { category: 'stripe' });
|
|
27
|
+
*
|
|
28
|
+
* // Retrieve (auto-decrypts)
|
|
29
|
+
* const apiKey = await service.retrieve('api-key');
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class Secret extends SmrtObject {
|
|
34
|
+
/**
|
|
35
|
+
* Tenant that owns this secret. Also stored in context for per-tenant name uniqueness.
|
|
36
|
+
*/
|
|
37
|
+
tenantId: string;
|
|
38
|
+
/**
|
|
39
|
+
* Unique name for the secret within the tenant
|
|
40
|
+
*/
|
|
41
|
+
name: string;
|
|
42
|
+
/**
|
|
43
|
+
* Human-readable description
|
|
44
|
+
*/
|
|
45
|
+
description: string;
|
|
46
|
+
/**
|
|
47
|
+
* Category for organization (e.g., 'database', 'api-key', 'oauth')
|
|
48
|
+
*/
|
|
49
|
+
category: string;
|
|
50
|
+
/**
|
|
51
|
+
* JSON-encoded EncryptedEnvelope from @happyvertical/secrets
|
|
52
|
+
*/
|
|
53
|
+
encryptedValue: string;
|
|
54
|
+
/**
|
|
55
|
+
* Version of the tenant key used to encrypt this secret
|
|
56
|
+
*/
|
|
57
|
+
keyVersion: number;
|
|
58
|
+
/**
|
|
59
|
+
* Current status of the secret
|
|
60
|
+
*/
|
|
61
|
+
status: SecretStatus;
|
|
62
|
+
/**
|
|
63
|
+
* Optional expiration date
|
|
64
|
+
*/
|
|
65
|
+
expiresAt: Date | null;
|
|
66
|
+
/**
|
|
67
|
+
* Last time this secret was accessed (decrypted)
|
|
68
|
+
*/
|
|
69
|
+
lastAccessedAt: Date | null;
|
|
70
|
+
/**
|
|
71
|
+
* Number of times this secret has been accessed
|
|
72
|
+
*/
|
|
73
|
+
accessCount: number;
|
|
74
|
+
/**
|
|
75
|
+
* Additional metadata stored with the secret
|
|
76
|
+
*/
|
|
77
|
+
metadata: Record<string, unknown>;
|
|
78
|
+
constructor(options?: any);
|
|
79
|
+
/**
|
|
80
|
+
* Check if the secret is currently active
|
|
81
|
+
*/
|
|
82
|
+
isActive(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Check if the secret has expired
|
|
85
|
+
*/
|
|
86
|
+
isExpired(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Check if the secret can be used (active and not expired)
|
|
89
|
+
*/
|
|
90
|
+
isUsable(): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Record an access to this secret
|
|
93
|
+
*/
|
|
94
|
+
recordAccess(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Disable the secret
|
|
97
|
+
*/
|
|
98
|
+
disable(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Enable the secret
|
|
101
|
+
*/
|
|
102
|
+
enable(): void;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=Secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Secret.d.ts","sourceRoot":"","sources":["../../src/models/Secret.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,qBASa,MAAO,SAAQ,UAAU;IACpC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAM;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAM;IAE5B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAK;IAEvB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAY;IAEhC;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B;;OAEG;IACH,cAAc,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEnC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAK;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;gBAE3B,OAAO,GAAE,GAAQ;IAgC7B;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,SAAS,IAAI,OAAO;IAKpB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,YAAY,IAAI,IAAI;IAKpB;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { SmrtCreateInput, SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
/**
|
|
3
|
+
* Secret audit action types
|
|
4
|
+
*/
|
|
5
|
+
export type SecretAuditAction = 'create' | 'read' | 'update' | 'delete' | 'rotate_key' | 'disable' | 'enable' | 'expire';
|
|
6
|
+
/**
|
|
7
|
+
* Audit result types
|
|
8
|
+
*/
|
|
9
|
+
export type SecretAuditResult = 'success' | 'failure' | 'denied';
|
|
10
|
+
/**
|
|
11
|
+
* SecretAuditLog records all operations on secrets for compliance
|
|
12
|
+
* and security monitoring.
|
|
13
|
+
*
|
|
14
|
+
* Every secret operation (create, read, update, delete, key rotation)
|
|
15
|
+
* is logged with the user, action, result, and relevant details.
|
|
16
|
+
*
|
|
17
|
+
* **Retention**: Audit logs should be retained according to your
|
|
18
|
+
* compliance requirements (typically 1-7 years).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Query recent audit logs
|
|
23
|
+
* const logs = await auditLogs.list({
|
|
24
|
+
* where: { tenantId: 'tenant-123' },
|
|
25
|
+
* orderBy: 'created_at DESC',
|
|
26
|
+
* limit: 100
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Filter by action
|
|
30
|
+
* const reads = await auditLogs.list({
|
|
31
|
+
* where: {
|
|
32
|
+
* tenantId: 'tenant-123',
|
|
33
|
+
* action: 'read'
|
|
34
|
+
* }
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Filter by secret name
|
|
38
|
+
* const apiKeyLogs = await auditLogs.list({
|
|
39
|
+
* where: {
|
|
40
|
+
* tenantId: 'tenant-123',
|
|
41
|
+
* secretName: 'stripe-api-key'
|
|
42
|
+
* }
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare class SecretAuditLog extends SmrtObject {
|
|
47
|
+
/**
|
|
48
|
+
* Tenant associated with the audited secret operation.
|
|
49
|
+
*/
|
|
50
|
+
tenantId: string | null;
|
|
51
|
+
/**
|
|
52
|
+
* ID of the secret (may be null for deleted secrets)
|
|
53
|
+
*/
|
|
54
|
+
secretId: string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Name of the secret at the time of the operation
|
|
57
|
+
*/
|
|
58
|
+
secretName: string;
|
|
59
|
+
/**
|
|
60
|
+
* ID of the user who performed the action
|
|
61
|
+
*/
|
|
62
|
+
userId: string;
|
|
63
|
+
/**
|
|
64
|
+
* The action that was performed
|
|
65
|
+
*/
|
|
66
|
+
action: SecretAuditAction;
|
|
67
|
+
/**
|
|
68
|
+
* Result of the operation
|
|
69
|
+
*/
|
|
70
|
+
result: SecretAuditResult;
|
|
71
|
+
/**
|
|
72
|
+
* IP address of the client (if available)
|
|
73
|
+
*/
|
|
74
|
+
ipAddress: string;
|
|
75
|
+
/**
|
|
76
|
+
* User agent string (if available)
|
|
77
|
+
*/
|
|
78
|
+
userAgent: string;
|
|
79
|
+
/**
|
|
80
|
+
* Additional context about the operation
|
|
81
|
+
*/
|
|
82
|
+
details: Record<string, unknown>;
|
|
83
|
+
constructor(options?: any);
|
|
84
|
+
/**
|
|
85
|
+
* Check if this was a successful operation
|
|
86
|
+
*/
|
|
87
|
+
isSuccess(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Check if this was a failed operation
|
|
90
|
+
*/
|
|
91
|
+
isFailure(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Check if this was a denied operation (permission denied)
|
|
94
|
+
*/
|
|
95
|
+
isDenied(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Check if this is a read operation
|
|
98
|
+
*/
|
|
99
|
+
isReadAction(): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Check if this is a write operation (create, update, delete)
|
|
102
|
+
*/
|
|
103
|
+
isWriteAction(): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Check if this is a key operation
|
|
106
|
+
*/
|
|
107
|
+
isKeyOperation(): boolean;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create an audit log entry for a secret operation
|
|
111
|
+
*/
|
|
112
|
+
export declare function createAuditEntry(params: {
|
|
113
|
+
secretId?: string | null;
|
|
114
|
+
secretName: string;
|
|
115
|
+
tenantId?: string | null;
|
|
116
|
+
userId: string;
|
|
117
|
+
action: SecretAuditAction;
|
|
118
|
+
result: SecretAuditResult;
|
|
119
|
+
ipAddress?: string;
|
|
120
|
+
userAgent?: string;
|
|
121
|
+
details?: Record<string, unknown>;
|
|
122
|
+
}): SmrtCreateInput<SecretAuditLog>;
|
|
123
|
+
//# sourceMappingURL=SecretAuditLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecretAuditLog.d.ts","sourceRoot":"","sources":["../../src/models/SecretAuditLog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,QAAQ,GACR,QAAQ,CAAC;AAEb;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAUH,qBAQa,cAAe,SAAQ,UAAU;IAC5C;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IAEH,MAAM,EAAE,MAAM,CAAM;IAEpB;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAAU;IAEnC;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAAa;IAEtC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;gBAE1B,OAAO,GAAE,GAAQ;IAe7B;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,cAAc,IAAI,OAAO;CAG1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,GAAG,eAAe,CAAC,cAAc,CAAC,CAkBlC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
/**
|
|
3
|
+
* Key status values
|
|
4
|
+
*/
|
|
5
|
+
export type TenantKeyStatus = 'active' | 'rotating' | 'retired' | 'compromised';
|
|
6
|
+
/**
|
|
7
|
+
* TenantKey tracks the per-tenant Data Encryption Keys (TDEKs).
|
|
8
|
+
*
|
|
9
|
+
* Each tenant has one or more TDEKs stored in wrapped form. The wrapped key
|
|
10
|
+
* can only be decrypted using the Application Master Key (AMK).
|
|
11
|
+
*
|
|
12
|
+
* **Key Lifecycle**:
|
|
13
|
+
* 1. `active` - Current key used for encryption
|
|
14
|
+
* 2. `rotating` - Transitional state during rotation
|
|
15
|
+
* 3. `retired` - Old key kept for decryption of existing secrets
|
|
16
|
+
* 4. `compromised` - Key marked as compromised, should not be used
|
|
17
|
+
*
|
|
18
|
+
* **Note**: This model is NOT tenant-scoped itself because it tracks
|
|
19
|
+
* keys FOR tenants, not secrets owned BY tenants.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Get active key for a tenant
|
|
24
|
+
* const key = await tenantKeys.get({
|
|
25
|
+
* tenantId: 'tenant-123',
|
|
26
|
+
* status: 'active'
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // List all key versions for a tenant
|
|
30
|
+
* const versions = await tenantKeys.list({
|
|
31
|
+
* where: { tenantId: 'tenant-123' },
|
|
32
|
+
* orderBy: 'version DESC'
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class TenantKey extends SmrtObject {
|
|
37
|
+
/**
|
|
38
|
+
* Tenant ID this key belongs to
|
|
39
|
+
*/
|
|
40
|
+
tenantId: string;
|
|
41
|
+
/**
|
|
42
|
+
* Wrapped key data (format: wrappedKey:iv:authTag)
|
|
43
|
+
*/
|
|
44
|
+
wrappedKey: string;
|
|
45
|
+
/**
|
|
46
|
+
* ID of the AMK used to wrap this key
|
|
47
|
+
*/
|
|
48
|
+
amkKeyId: string;
|
|
49
|
+
/**
|
|
50
|
+
* Current status of the key
|
|
51
|
+
*/
|
|
52
|
+
status: TenantKeyStatus;
|
|
53
|
+
/**
|
|
54
|
+
* Version number (increments on rotation)
|
|
55
|
+
*/
|
|
56
|
+
version: number;
|
|
57
|
+
/**
|
|
58
|
+
* Recommended rotation date
|
|
59
|
+
*/
|
|
60
|
+
rotateAfter: Date | null;
|
|
61
|
+
/**
|
|
62
|
+
* When the key was retired (if applicable)
|
|
63
|
+
*/
|
|
64
|
+
retiredAt: Date | null;
|
|
65
|
+
constructor(options?: any);
|
|
66
|
+
/**
|
|
67
|
+
* Check if this key is currently active
|
|
68
|
+
*/
|
|
69
|
+
isActive(): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Check if this key needs rotation
|
|
72
|
+
*/
|
|
73
|
+
needsRotation(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Check if this key is retired
|
|
76
|
+
*/
|
|
77
|
+
isRetired(): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Check if this key is compromised
|
|
80
|
+
*/
|
|
81
|
+
isCompromised(): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Check if this key can be used for decryption
|
|
84
|
+
* (active or retired keys can decrypt)
|
|
85
|
+
*/
|
|
86
|
+
canDecrypt(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Check if this key can be used for encryption
|
|
89
|
+
* (only active keys should encrypt)
|
|
90
|
+
*/
|
|
91
|
+
canEncrypt(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Mark this key as retired
|
|
94
|
+
*/
|
|
95
|
+
retire(): void;
|
|
96
|
+
/**
|
|
97
|
+
* Mark this key as compromised
|
|
98
|
+
*/
|
|
99
|
+
markCompromised(): void;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=TenantKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TenantKey.d.ts","sourceRoot":"","sources":["../../src/models/TenantKey.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AASH,qBAQa,SAAU,SAAQ,UAAU;IACvC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,MAAM,EAAE,eAAe,CAAY;IAEnC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAK;IAEpB;;OAEG;IACH,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;gBAElB,OAAO,GAAE,GAAQ;IAyB7B;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,aAAa,IAAI,OAAO;IAKxB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,UAAU,IAAI,OAAO;IAIrB;;;OAGG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,MAAM,IAAI,IAAI;IAKd;;OAEG;IACH,eAAe,IAAI,IAAI;CAGxB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Secret, type SecretStatus } from './Secret.js';
|
|
2
|
+
export { createAuditEntry, type SecretAuditAction, SecretAuditLog, type SecretAuditResult, } from './SecretAuditLog.js';
|
|
3
|
+
export { TenantKey, type TenantKeyStatus } from './TenantKey.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,yBAAyB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,cAAc,EACd,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import { Secret } from '../models/Secret.js';
|
|
3
|
+
import { SecretAuditLog } from '../models/SecretAuditLog.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating a SecretService
|
|
6
|
+
*/
|
|
7
|
+
export interface SecretServiceOptions {
|
|
8
|
+
/** Database connection */
|
|
9
|
+
db: DatabaseInterface;
|
|
10
|
+
/** Environment variable containing the AMK (64 hex chars) */
|
|
11
|
+
amkEnvVar?: string;
|
|
12
|
+
/** AMK key identifier */
|
|
13
|
+
amkKeyId?: string;
|
|
14
|
+
/** Enable audit logging (default: true) */
|
|
15
|
+
auditEnabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Options for storing a secret
|
|
19
|
+
*/
|
|
20
|
+
export interface StoreSecretOptions {
|
|
21
|
+
/** Human-readable description */
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Category for organization */
|
|
24
|
+
category?: string;
|
|
25
|
+
/** Optional expiration date */
|
|
26
|
+
expiresAt?: Date;
|
|
27
|
+
/** Additional metadata */
|
|
28
|
+
metadata?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Result of retrieving a secret
|
|
32
|
+
*/
|
|
33
|
+
export interface RetrievedSecret {
|
|
34
|
+
/** The decrypted secret value */
|
|
35
|
+
value: string;
|
|
36
|
+
/** Secret metadata */
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
category: string;
|
|
40
|
+
expiresAt: Date | null;
|
|
41
|
+
createdAt: Date;
|
|
42
|
+
lastAccessedAt: Date | null;
|
|
43
|
+
accessCount: number;
|
|
44
|
+
metadata: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
export type SecretKeyDriftIssueSeverity = 'info' | 'warning' | 'error';
|
|
47
|
+
export type SecretKeyDriftIssueCode = 'amk_unavailable' | 'active_secrets_without_usable_active_key' | 'missing_active_tenant_encryption_key' | 'multiple_active_tenant_encryption_keys' | 'active_tenant_encryption_key_amk_mismatch' | 'active_tenant_encryption_key_unwrap_failed' | 'secret_envelope_invalid_json' | 'secret_envelope_invalid_wrapped_key' | 'secret_envelope_missing_tenant_encryption_key' | 'secret_envelope_unwrap_failed' | 'smrt_tenant_keys_query_failed' | 'smrt_tenant_keys_not_mirrored';
|
|
48
|
+
export type SecretKeyDriftRepairAction = 'delete-unrecoverable-secret' | 'delete-unusable-tenant-encryption-key' | 'store-fresh-secret-value' | 'none';
|
|
49
|
+
export interface SecretKeyDriftIssue {
|
|
50
|
+
code: SecretKeyDriftIssueCode;
|
|
51
|
+
severity: SecretKeyDriftIssueSeverity;
|
|
52
|
+
message: string;
|
|
53
|
+
repairAction: SecretKeyDriftRepairAction;
|
|
54
|
+
secretId?: string;
|
|
55
|
+
secretName?: string;
|
|
56
|
+
keyId?: string;
|
|
57
|
+
sourceTable?: 'secrets' | 'tenant_encryption_keys' | 'tenant_keys';
|
|
58
|
+
details?: Record<string, string | number | boolean | null>;
|
|
59
|
+
}
|
|
60
|
+
export interface DiagnoseTenantSecretKeyDriftOptions {
|
|
61
|
+
/**
|
|
62
|
+
* Limit secret-envelope checks to these names. Tenant key checks still run.
|
|
63
|
+
*/
|
|
64
|
+
secretNames?: string[];
|
|
65
|
+
}
|
|
66
|
+
export interface SecretKeyDriftReport {
|
|
67
|
+
tenantId: string;
|
|
68
|
+
checkedAt: Date;
|
|
69
|
+
ok: boolean;
|
|
70
|
+
summary: {
|
|
71
|
+
activeSecretCount: number;
|
|
72
|
+
tenantEncryptionKeyCount: number;
|
|
73
|
+
activeTenantEncryptionKeyCount: number;
|
|
74
|
+
usableActiveTenantEncryptionKeyCount: number;
|
|
75
|
+
smrtTenantKeyCount: number;
|
|
76
|
+
activeSmrtTenantKeyCount: number;
|
|
77
|
+
};
|
|
78
|
+
issues: SecretKeyDriftIssue[];
|
|
79
|
+
}
|
|
80
|
+
export interface RepairTenantSecretKeyDriftOptions extends DiagnoseTenantSecretKeyDriftOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Preview affected rows without deleting anything.
|
|
83
|
+
*/
|
|
84
|
+
dryRun?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Required for destructive repair. This deletes encrypted values/key rows
|
|
87
|
+
* that cannot be used with the currently configured AMK.
|
|
88
|
+
*/
|
|
89
|
+
confirmDeleteUnrecoverableData?: boolean;
|
|
90
|
+
}
|
|
91
|
+
export interface SecretKeyDriftRepairResult {
|
|
92
|
+
tenantId: string;
|
|
93
|
+
dryRun: boolean;
|
|
94
|
+
issuesBefore: SecretKeyDriftIssue[];
|
|
95
|
+
remainingIssues: SecretKeyDriftIssue[];
|
|
96
|
+
wouldDeleteSecrets: number;
|
|
97
|
+
wouldDeleteTenantEncryptionKeys: number;
|
|
98
|
+
deletedSecrets: number;
|
|
99
|
+
deletedTenantEncryptionKeys: number;
|
|
100
|
+
secretNames: string[];
|
|
101
|
+
tenantEncryptionKeyIds: string[];
|
|
102
|
+
}
|
|
103
|
+
export declare class SecretKeyDriftError extends Error {
|
|
104
|
+
readonly code = "SECRET_KEY_DRIFT";
|
|
105
|
+
readonly tenantId: string;
|
|
106
|
+
readonly report: SecretKeyDriftReport;
|
|
107
|
+
readonly cause?: Error;
|
|
108
|
+
constructor(message: string, tenantId: string, report: SecretKeyDriftReport, cause?: Error);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* SecretService provides high-level operations for managing per-tenant secrets.
|
|
112
|
+
*
|
|
113
|
+
* It integrates with:
|
|
114
|
+
* - `@happyvertical/secrets` for envelope encryption
|
|
115
|
+
* - `@happyvertical/smrt-tenancy` for tenant context
|
|
116
|
+
* - Audit logging for compliance
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* import { SecretService } from '@happyvertical/smrt-secrets';
|
|
121
|
+
* import { withTenant } from '@happyvertical/smrt-tenancy';
|
|
122
|
+
*
|
|
123
|
+
* const service = await SecretService.create({ db });
|
|
124
|
+
*
|
|
125
|
+
* await withTenant({ tenantId: 'tenant-123' }, async () => {
|
|
126
|
+
* // Store a secret
|
|
127
|
+
* await service.store('stripe-api-key', 'sk_live_xxx', {
|
|
128
|
+
* category: 'api-keys',
|
|
129
|
+
* description: 'Stripe production API key'
|
|
130
|
+
* });
|
|
131
|
+
*
|
|
132
|
+
* // Retrieve the secret
|
|
133
|
+
* const secret = await service.retrieve('stripe-api-key');
|
|
134
|
+
* console.log(secret.value); // 'sk_live_xxx'
|
|
135
|
+
*
|
|
136
|
+
* // List secret names (without values)
|
|
137
|
+
* const secrets = await service.list();
|
|
138
|
+
*
|
|
139
|
+
* // Rotate tenant's encryption key
|
|
140
|
+
* await service.rotateKey();
|
|
141
|
+
*
|
|
142
|
+
* // Delete a secret
|
|
143
|
+
* await service.delete('stripe-api-key');
|
|
144
|
+
* });
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare class SecretService {
|
|
148
|
+
private db;
|
|
149
|
+
private secretStore;
|
|
150
|
+
private secrets;
|
|
151
|
+
private tenantKeys;
|
|
152
|
+
private auditLogs;
|
|
153
|
+
private auditEnabled;
|
|
154
|
+
private amkEnvVar;
|
|
155
|
+
private amkKeyId;
|
|
156
|
+
private constructor();
|
|
157
|
+
/**
|
|
158
|
+
* Create a new SecretService instance
|
|
159
|
+
*/
|
|
160
|
+
static create(options: SecretServiceOptions): Promise<SecretService>;
|
|
161
|
+
/**
|
|
162
|
+
* Store a secret for the current tenant
|
|
163
|
+
*/
|
|
164
|
+
store(name: string, value: string, options?: StoreSecretOptions): Promise<Secret>;
|
|
165
|
+
/**
|
|
166
|
+
* Store a secret for a specific tenant.
|
|
167
|
+
*
|
|
168
|
+
* This is useful for integrations that already resolved tenant ownership but
|
|
169
|
+
* may be running outside the application's ambient tenant context.
|
|
170
|
+
*/
|
|
171
|
+
storeForTenant(tenantId: string, name: string, value: string, options?: StoreSecretOptions): Promise<Secret>;
|
|
172
|
+
/**
|
|
173
|
+
* Retrieve a secret for the current tenant
|
|
174
|
+
*/
|
|
175
|
+
retrieve(name: string): Promise<RetrievedSecret>;
|
|
176
|
+
/**
|
|
177
|
+
* Retrieve a secret for a specific tenant.
|
|
178
|
+
*/
|
|
179
|
+
retrieveForTenant(tenantId: string, name: string): Promise<RetrievedSecret>;
|
|
180
|
+
/**
|
|
181
|
+
* Diagnose tenant secret/key drift without exposing decrypted values.
|
|
182
|
+
*/
|
|
183
|
+
diagnoseTenantSecretKeyDrift(tenantId: string, options?: DiagnoseTenantSecretKeyDriftOptions): Promise<SecretKeyDriftReport>;
|
|
184
|
+
/**
|
|
185
|
+
* Diagnose drift for the current tenant context.
|
|
186
|
+
*/
|
|
187
|
+
diagnoseCurrentTenantSecretKeyDrift(options?: DiagnoseTenantSecretKeyDriftOptions): Promise<SecretKeyDriftReport>;
|
|
188
|
+
/**
|
|
189
|
+
* Delete unrecoverable secret/key rows identified by diagnosis.
|
|
190
|
+
*
|
|
191
|
+
* This never attempts to recover or expose secret values. Use dryRun first
|
|
192
|
+
* to preview destructive changes.
|
|
193
|
+
*/
|
|
194
|
+
repairTenantSecretKeyDrift(tenantId: string, options?: RepairTenantSecretKeyDriftOptions): Promise<SecretKeyDriftRepairResult>;
|
|
195
|
+
/**
|
|
196
|
+
* List secrets for the current tenant (names only, not values)
|
|
197
|
+
*/
|
|
198
|
+
list(options?: {
|
|
199
|
+
category?: string;
|
|
200
|
+
}): Promise<Secret[]>;
|
|
201
|
+
/**
|
|
202
|
+
* Delete a secret
|
|
203
|
+
*/
|
|
204
|
+
delete(name: string): Promise<boolean>;
|
|
205
|
+
/**
|
|
206
|
+
* Disable a secret (soft delete)
|
|
207
|
+
*/
|
|
208
|
+
disable(name: string): Promise<boolean>;
|
|
209
|
+
/**
|
|
210
|
+
* Enable a disabled secret
|
|
211
|
+
*/
|
|
212
|
+
enable(name: string): Promise<boolean>;
|
|
213
|
+
/**
|
|
214
|
+
* Rotate the tenant's encryption key
|
|
215
|
+
*
|
|
216
|
+
* This creates a new TDEK and marks the old one as retired.
|
|
217
|
+
* Existing secrets remain encrypted with the old key and can still
|
|
218
|
+
* be decrypted (the old key is kept in retired state).
|
|
219
|
+
*
|
|
220
|
+
* For full re-encryption, call reencryptAll() after rotation.
|
|
221
|
+
*/
|
|
222
|
+
rotateKey(): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Re-encrypt all secrets with the current active key
|
|
225
|
+
*
|
|
226
|
+
* Call this after key rotation to ensure all secrets use the new key.
|
|
227
|
+
* This is optional but recommended for security.
|
|
228
|
+
*/
|
|
229
|
+
reencryptAll(): Promise<{
|
|
230
|
+
success: number;
|
|
231
|
+
failed: number;
|
|
232
|
+
}>;
|
|
233
|
+
/**
|
|
234
|
+
* Get audit logs for the current tenant
|
|
235
|
+
*/
|
|
236
|
+
getAuditLogs(options?: {
|
|
237
|
+
secretName?: string;
|
|
238
|
+
limit?: number;
|
|
239
|
+
}): Promise<SecretAuditLog[]>;
|
|
240
|
+
/**
|
|
241
|
+
* Get secret categories for the current tenant
|
|
242
|
+
*/
|
|
243
|
+
getCategories(): Promise<string[]>;
|
|
244
|
+
/**
|
|
245
|
+
* Check if a secret exists for the current tenant
|
|
246
|
+
*/
|
|
247
|
+
exists(name: string): Promise<boolean>;
|
|
248
|
+
private listActiveSecretRowsForDiagnosis;
|
|
249
|
+
private listTenantEncryptionKeyRows;
|
|
250
|
+
private listSmrtTenantKeysForDiagnosis;
|
|
251
|
+
private getConfiguredAmkForDiagnosis;
|
|
252
|
+
private checkWrappedKey;
|
|
253
|
+
private getWrappedKeyFingerprint;
|
|
254
|
+
private parseSecretEnvelopeForDiagnosis;
|
|
255
|
+
private deleteRowsByIds;
|
|
256
|
+
private auditSecretDriftRepairDeletes;
|
|
257
|
+
private rowsFromResult;
|
|
258
|
+
private classifyTenantKeyFailure;
|
|
259
|
+
private shouldClassifyTenantKeyFailure;
|
|
260
|
+
private getSecretErrorCode;
|
|
261
|
+
private toError;
|
|
262
|
+
private getCurrentUserId;
|
|
263
|
+
private audit;
|
|
264
|
+
private serializeMetadata;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=SecretService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecretService.d.ts","sourceRoot":"","sources":["../../src/services/SecretService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "../chunks/TenantKey-DzglnpAV.js";
|
|
2
|
+
import { b, c } from "../chunks/SecretService-C91H6WJK.js";
|
|
3
|
+
import "@happyvertical/secrets";
|
|
4
|
+
import "@happyvertical/smrt-tenancy";
|
|
5
|
+
export {
|
|
6
|
+
b as SecretKeyDriftError,
|
|
7
|
+
c as SecretService
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=SecretService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecretService.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|