@the-ai-company/cbio-node-runtime 0.31.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/LICENSE +21 -0
- package/README.md +46 -0
- package/dist/agent/agent.d.ts +234 -0
- package/dist/agent/agent.js +565 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/audit/ActivityLog.d.ts +25 -0
- package/dist/audit/ActivityLog.js +66 -0
- package/dist/audit/ActivityLog.js.map +1 -0
- package/dist/errors.d.ts +28 -0
- package/dist/errors.js +37 -0
- package/dist/errors.js.map +1 -0
- package/dist/http/authClient.d.ts +26 -0
- package/dist/http/authClient.js +132 -0
- package/dist/http/authClient.js.map +1 -0
- package/dist/http/localAuthProxy.d.ts +33 -0
- package/dist/http/localAuthProxy.js +93 -0
- package/dist/http/localAuthProxy.js.map +1 -0
- package/dist/http/secretAcquisition.d.ts +54 -0
- package/dist/http/secretAcquisition.js +177 -0
- package/dist/http/secretAcquisition.js.map +1 -0
- package/dist/protocol/childSecretNaming.d.ts +7 -0
- package/dist/protocol/childSecretNaming.js +12 -0
- package/dist/protocol/childSecretNaming.js.map +1 -0
- package/dist/protocol/crypto.d.ts +23 -0
- package/dist/protocol/crypto.js +37 -0
- package/dist/protocol/crypto.js.map +1 -0
- package/dist/protocol/identity.d.ts +8 -0
- package/dist/protocol/identity.js +16 -0
- package/dist/protocol/identity.js.map +1 -0
- package/dist/runtime/index.d.ts +14 -0
- package/dist/runtime/index.js +11 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/sealed/index.d.ts +6 -0
- package/dist/sealed/index.js +6 -0
- package/dist/sealed/index.js.map +1 -0
- package/dist/sealed/seal.d.ts +19 -0
- package/dist/sealed/seal.js +56 -0
- package/dist/sealed/seal.js.map +1 -0
- package/dist/storage/fs.d.ts +16 -0
- package/dist/storage/fs.js +68 -0
- package/dist/storage/fs.js.map +1 -0
- package/dist/storage/memory.d.ts +11 -0
- package/dist/storage/memory.js +19 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/provider.d.ts +12 -0
- package/dist/storage/provider.js +6 -0
- package/dist/storage/provider.js.map +1 -0
- package/dist/vault/secretPolicy.d.ts +3 -0
- package/dist/vault/secretPolicy.js +14 -0
- package/dist/vault/secretPolicy.js.map +1 -0
- package/dist/vault/vault.d.ts +91 -0
- package/dist/vault/vault.js +534 -0
- package/dist/vault/vault.js.map +1 -0
- package/docs/ARCHITECTURE.md +100 -0
- package/docs/REFERENCE.md +184 -0
- package/docs/TODO-multi-vault.md +29 -0
- package/docs/WORKS_WITH_CUSTOM_FETCH.md +196 -0
- package/docs/es/README.md +27 -0
- package/docs/fr/README.md +27 -0
- package/docs/ja/README.md +27 -0
- package/docs/ko/README.md +27 -0
- package/docs/pt/README.md +27 -0
- package/docs/spec/runtime/README.md +27 -0
- package/docs/spec/runtime/activity-log.md +67 -0
- package/docs/spec/runtime/managed-agent-record.md +52 -0
- package/docs/spec/runtime/merge-rules.md +52 -0
- package/docs/spec/runtime/secret-origin-policy.md +46 -0
- package/docs/zh/README.md +27 -0
- package/examples/minimal.ts +13 -0
- package/package.json +57 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SecretAcquisition
|
|
3
|
+
*
|
|
4
|
+
* Fetches secrets from remote JSON endpoints and stores them in vault.
|
|
5
|
+
* Secret never leaves this module; fetch + extract + store is atomic.
|
|
6
|
+
*/
|
|
7
|
+
import { IdentityError } from '../errors.js';
|
|
8
|
+
import { isAllowedSecretUrl } from '../vault/secretPolicy.js';
|
|
9
|
+
function sanitize(obj, secret) {
|
|
10
|
+
if (typeof obj !== 'object' || obj === null)
|
|
11
|
+
return obj;
|
|
12
|
+
const newObj = Array.isArray(obj) ? [] : {};
|
|
13
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
14
|
+
if (typeof value === 'string' && value === secret) {
|
|
15
|
+
newObj[key] = '***';
|
|
16
|
+
}
|
|
17
|
+
else if (typeof value === 'object') {
|
|
18
|
+
newObj[key] = sanitize(value, secret);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
newObj[key] = value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return newObj;
|
|
25
|
+
}
|
|
26
|
+
function serializeJsonBody(body) {
|
|
27
|
+
return body === undefined ? undefined : JSON.stringify(body);
|
|
28
|
+
}
|
|
29
|
+
export class SecretAcquisition {
|
|
30
|
+
_vault;
|
|
31
|
+
_appendActivityLog;
|
|
32
|
+
constructor(_vault, _appendActivityLog) {
|
|
33
|
+
this._vault = _vault;
|
|
34
|
+
this._appendActivityLog = _appendActivityLog;
|
|
35
|
+
}
|
|
36
|
+
hasSecret(secretName) {
|
|
37
|
+
return this._vault.hasSecret(secretName);
|
|
38
|
+
}
|
|
39
|
+
listSecretNames() {
|
|
40
|
+
return this._vault.listSecretNames();
|
|
41
|
+
}
|
|
42
|
+
async fetchJsonAndAddSecret(options) {
|
|
43
|
+
const { url, method = 'POST', secretName } = options;
|
|
44
|
+
const fail = async (error, code) => {
|
|
45
|
+
try {
|
|
46
|
+
await this._appendActivityLog({
|
|
47
|
+
ts: Date.now(),
|
|
48
|
+
action: 'fetchJsonAndAddSecret',
|
|
49
|
+
secretName,
|
|
50
|
+
url,
|
|
51
|
+
method,
|
|
52
|
+
success: false,
|
|
53
|
+
error,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return { success: false, error, code, activityLogWriteFailed: true };
|
|
58
|
+
}
|
|
59
|
+
return { success: false, error, code };
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
const { headers = {}, body, extractKey, allowedOrigins } = options;
|
|
63
|
+
const sourceUrl = new URL(url);
|
|
64
|
+
if (!isAllowedSecretUrl(sourceUrl)) {
|
|
65
|
+
return fail(`Secret fetch requires HTTPS or loopback HTTP for local development. Received: ${url}`);
|
|
66
|
+
}
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
method,
|
|
69
|
+
headers: {
|
|
70
|
+
'Content-Type': 'application/json',
|
|
71
|
+
...headers
|
|
72
|
+
},
|
|
73
|
+
body: serializeJsonBody(body)
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
return fail(`HTTP Error: ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
const data = await response.json();
|
|
79
|
+
const key = extractKey(data);
|
|
80
|
+
if (!key) {
|
|
81
|
+
return fail("Failed to extract key from response");
|
|
82
|
+
}
|
|
83
|
+
let resolvedSecretName = secretName;
|
|
84
|
+
let suffix = 0;
|
|
85
|
+
while (this._vault.hasSecret(resolvedSecretName)) {
|
|
86
|
+
suffix++;
|
|
87
|
+
resolvedSecretName = `${secretName}_${suffix}`;
|
|
88
|
+
}
|
|
89
|
+
await this._vault.addSecret(resolvedSecretName, key, { allowedOrigins: allowedOrigins ?? [sourceUrl.origin] });
|
|
90
|
+
try {
|
|
91
|
+
await this._appendActivityLog({
|
|
92
|
+
ts: Date.now(),
|
|
93
|
+
action: 'fetchJsonAndAddSecret',
|
|
94
|
+
secretName: resolvedSecretName,
|
|
95
|
+
url,
|
|
96
|
+
method,
|
|
97
|
+
success: true,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
const sanitizedData = sanitize(data, key);
|
|
102
|
+
return { success: true, data: sanitizedData, secretName: resolvedSecretName, activityLogWriteFailed: true };
|
|
103
|
+
}
|
|
104
|
+
const sanitizedData = sanitize(data, key);
|
|
105
|
+
return { success: true, data: sanitizedData, secretName: resolvedSecretName };
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
const code = IdentityError.isIdentityError(e) ? e.code : undefined;
|
|
109
|
+
return fail(e.message ?? String(e), code);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async fetchJsonAndUpdateSecret(options) {
|
|
113
|
+
const { url, method = 'POST', secretName } = options;
|
|
114
|
+
const fail = async (error, code) => {
|
|
115
|
+
try {
|
|
116
|
+
await this._appendActivityLog({
|
|
117
|
+
ts: Date.now(),
|
|
118
|
+
action: 'fetchJsonAndUpdateSecret',
|
|
119
|
+
secretName,
|
|
120
|
+
url,
|
|
121
|
+
method,
|
|
122
|
+
success: false,
|
|
123
|
+
error,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return { success: false, error, code, activityLogWriteFailed: true };
|
|
128
|
+
}
|
|
129
|
+
return { success: false, error, code };
|
|
130
|
+
};
|
|
131
|
+
try {
|
|
132
|
+
const { headers = {}, body, extractKey } = options;
|
|
133
|
+
const sourceUrl = new URL(url);
|
|
134
|
+
if (!isAllowedSecretUrl(sourceUrl)) {
|
|
135
|
+
return fail(`Secret rotation requires HTTPS or loopback HTTP for local development. Received: ${url}`);
|
|
136
|
+
}
|
|
137
|
+
const response = await fetch(url, {
|
|
138
|
+
method,
|
|
139
|
+
headers: {
|
|
140
|
+
'Content-Type': 'application/json',
|
|
141
|
+
...headers
|
|
142
|
+
},
|
|
143
|
+
body: serializeJsonBody(body)
|
|
144
|
+
});
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
return fail(`HTTP Error: ${response.status}`);
|
|
147
|
+
}
|
|
148
|
+
const data = await response.json();
|
|
149
|
+
const key = extractKey(data);
|
|
150
|
+
if (!key) {
|
|
151
|
+
return fail("Failed to extract key from response");
|
|
152
|
+
}
|
|
153
|
+
await this._vault.rotateSecret(secretName, key, sourceUrl.origin);
|
|
154
|
+
try {
|
|
155
|
+
await this._appendActivityLog({
|
|
156
|
+
ts: Date.now(),
|
|
157
|
+
action: 'fetchJsonAndUpdateSecret',
|
|
158
|
+
secretName,
|
|
159
|
+
url,
|
|
160
|
+
method,
|
|
161
|
+
success: true,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
const sanitizedData = sanitize(data, key);
|
|
166
|
+
return { success: true, data: sanitizedData, secretName, activityLogWriteFailed: true };
|
|
167
|
+
}
|
|
168
|
+
const sanitizedData = sanitize(data, key);
|
|
169
|
+
return { success: true, data: sanitizedData, secretName };
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
const code = IdentityError.isIdentityError(e) ? e.code : undefined;
|
|
173
|
+
return fail(e.message ?? String(e), code);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=secretAcquisition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secretAcquisition.js","sourceRoot":"","sources":["../../src/http/secretAcquisition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault secret naming for child identities. CHILD_KEY_PREFIX, getChildIdentitySecretName.
|
|
3
|
+
* Not protocol objects. Protocol talks about public identities and signatures,
|
|
4
|
+
* not local secret names or internal storage prefixes.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CHILD_KEY_PREFIX: "cbio:child:";
|
|
7
|
+
export declare function getChildIdentitySecretName(publicKey: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault secret naming for child identities. CHILD_KEY_PREFIX, getChildIdentitySecretName.
|
|
3
|
+
* Not protocol objects. Protocol talks about public identities and signatures,
|
|
4
|
+
* not local secret names or internal storage prefixes.
|
|
5
|
+
*/
|
|
6
|
+
import * as crypto from 'node:crypto';
|
|
7
|
+
export const CHILD_KEY_PREFIX = 'cbio:child:';
|
|
8
|
+
export function getChildIdentitySecretName(publicKey) {
|
|
9
|
+
const hash = crypto.createHash('sha256').update(publicKey).digest('hex').substring(0, 12);
|
|
10
|
+
return CHILD_KEY_PREFIX + hash;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=childSecretNaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"childSecretNaming.js","sourceRoot":"","sources":["../../src/protocol/childSecretNaming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAsB,CAAC;AAEvD,MAAM,UAAU,0BAA0B,CAAC,SAAiB;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,gBAAgB,GAAG,IAAI,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claw-biometric Core Crypto. Runtime wrappers over protocol primitives.
|
|
3
|
+
* LocalSigner, Signer. Re-exports protocol for consumers.
|
|
4
|
+
*/
|
|
5
|
+
import { generateIdentityKeys, derivePublicKey, verifySignature, generateNonce, type KeyPair } from '@the-ai-company/cbio-protocol';
|
|
6
|
+
export type { KeyPair };
|
|
7
|
+
export { generateIdentityKeys, derivePublicKey, verifySignature, generateNonce };
|
|
8
|
+
export interface Signer {
|
|
9
|
+
getPublicKey(): Promise<string>;
|
|
10
|
+
sign(nonce: string): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
export declare class LocalSigner implements Signer {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(keyPair: KeyPair);
|
|
15
|
+
getPublicKey(): Promise<string>;
|
|
16
|
+
sign(nonce: string): Promise<string>;
|
|
17
|
+
/** @internal For exportIdentity only. Admin operation. */
|
|
18
|
+
exportPrivateKey(): string;
|
|
19
|
+
}
|
|
20
|
+
/** @internal Alias for protocol signPayload. */
|
|
21
|
+
export declare function signPayload(privateKey: string, payload: string): string;
|
|
22
|
+
/** @internal Use signPayload for protocol-level signing. */
|
|
23
|
+
export declare function signChallenge(privateKey: string, nonce: string): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claw-biometric Core Crypto. Runtime wrappers over protocol primitives.
|
|
3
|
+
* LocalSigner, Signer. Re-exports protocol for consumers.
|
|
4
|
+
*/
|
|
5
|
+
import { IdentityError, IdentityErrorCode } from '../errors.js';
|
|
6
|
+
import { signPayload as protocolSignPayload, generateIdentityKeys, derivePublicKey, verifySignature, generateNonce, } from '@the-ai-company/cbio-protocol';
|
|
7
|
+
export { generateIdentityKeys, derivePublicKey, verifySignature, generateNonce };
|
|
8
|
+
export class LocalSigner {
|
|
9
|
+
#privateKey;
|
|
10
|
+
#publicKey;
|
|
11
|
+
constructor(keyPair) {
|
|
12
|
+
if (!keyPair.publicKey) {
|
|
13
|
+
throw new IdentityError(IdentityErrorCode.SIGNER_REQUIRES_PUBLIC_KEY, "LocalSigner requires a publicKey. Use derivePublicKey() if you only have a privateKey.");
|
|
14
|
+
}
|
|
15
|
+
this.#privateKey = keyPair.privateKey;
|
|
16
|
+
this.#publicKey = keyPair.publicKey;
|
|
17
|
+
}
|
|
18
|
+
async getPublicKey() {
|
|
19
|
+
return this.#publicKey;
|
|
20
|
+
}
|
|
21
|
+
async sign(nonce) {
|
|
22
|
+
return protocolSignPayload(this.#privateKey, nonce);
|
|
23
|
+
}
|
|
24
|
+
/** @internal For exportIdentity only. Admin operation. */
|
|
25
|
+
exportPrivateKey() {
|
|
26
|
+
return this.#privateKey;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** @internal Alias for protocol signPayload. */
|
|
30
|
+
export function signPayload(privateKey, payload) {
|
|
31
|
+
return protocolSignPayload(privateKey, payload);
|
|
32
|
+
}
|
|
33
|
+
/** @internal Use signPayload for protocol-level signing. */
|
|
34
|
+
export function signChallenge(privateKey, nonce) {
|
|
35
|
+
return protocolSignPayload(privateKey, nonce);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/protocol/crypto.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EACH,WAAW,IAAI,mBAAmB,EAClC,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,aAAa,GAEhB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAOjF,MAAM,OAAO,WAAW;IACpB,WAAW,CAAS;IACpB,UAAU,CAAS;IAEnB,YAAY,OAAgB;QACxB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,aAAa,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,wFAAwF,CAAC,CAAC;QACpK,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,YAAY;QACd,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACpB,OAAO,mBAAmB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAED,0DAA0D;IAC1D,gBAAgB;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;CACJ;AAED,gDAAgD;AAChD,MAAM,UAAU,WAAW,CAAC,UAAkB,EAAE,OAAe;IAC3D,OAAO,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,KAAa;IAC3D,OAAO,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claw-biometric Core Identity. Runtime utilities over protocol primitives.
|
|
3
|
+
* getVaultPath (runtime). Re-exports protocol for consumers.
|
|
4
|
+
*/
|
|
5
|
+
import { deriveRootAgentId } from '@the-ai-company/cbio-protocol';
|
|
6
|
+
import { getChildIdentitySecretName, CHILD_KEY_PREFIX } from './childSecretNaming.js';
|
|
7
|
+
export { deriveRootAgentId, getChildIdentitySecretName, CHILD_KEY_PREFIX };
|
|
8
|
+
export declare function getVaultPath(publicKey: string): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claw-biometric Core Identity. Runtime utilities over protocol primitives.
|
|
3
|
+
* getVaultPath (runtime). Re-exports protocol for consumers.
|
|
4
|
+
*/
|
|
5
|
+
import * as os from 'node:os';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import * as crypto from 'node:crypto';
|
|
8
|
+
import { deriveRootAgentId } from '@the-ai-company/cbio-protocol';
|
|
9
|
+
import { getChildIdentitySecretName, CHILD_KEY_PREFIX } from './childSecretNaming.js';
|
|
10
|
+
export { deriveRootAgentId, getChildIdentitySecretName, CHILD_KEY_PREFIX };
|
|
11
|
+
export function getVaultPath(publicKey) {
|
|
12
|
+
const hash = crypto.createHash('sha256').update(publicKey).digest('hex').substring(0, 12);
|
|
13
|
+
const baseDir = process.env.C_BIO_VAULT_DIR || path.join(os.homedir(), '.c-bio');
|
|
14
|
+
return path.join(baseDir, `vault_${hash}.enc`);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/protocol/identity.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,CAAC;AAE3E,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IACjF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,IAAI,MAAM,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime export. For agent developers.
|
|
3
|
+
* Owner, Agent, storage, errors. Consumer surface only.
|
|
4
|
+
*/
|
|
5
|
+
export { CbioIdentity, CbioAgent } from "../agent/agent.js";
|
|
6
|
+
export type { ActivityLogConfig, GetAgentOptions, IssuedCapabilityName, ManagedAgentHandleConfig, ManagedAgentCapabilityInfo, ManagedAgentCapabilityStatus, ManagedAgentContext, ManagedAgentIssueConfig, ManagedAgentIssueOptions, ManagedAgentLoadOptions, ManagedAgentStorageConfig, RegisterChildIdentityOptions, RegisterChildIdentityResult, IdentityLoadKeys, IdentityLoadOptions, RuntimePermissionName, RuntimePermissions, } from "../agent/agent.js";
|
|
7
|
+
export type { MergeResult } from "../vault/vault.js";
|
|
8
|
+
export type { FetchFailure, FetchJsonAndAddSecretOptions, FetchJsonAndUpdateSecretOptions, FetchResult, FetchSuccess, } from "../http/secretAcquisition.js";
|
|
9
|
+
export { generateIdentityKeys } from "../protocol/crypto.js";
|
|
10
|
+
export { IdentityError, IdentityErrorCode } from "../errors.js";
|
|
11
|
+
export type { IStorageProvider } from "../storage/provider.js";
|
|
12
|
+
export { FsStorageProvider } from "../storage/fs.js";
|
|
13
|
+
export { MemoryStorageProvider } from "../storage/memory.js";
|
|
14
|
+
export { startLocalAuthProxy, type FetchWithAuthLike, type LocalAuthProxyOptions, type LocalAuthProxyHandle, } from "../http/localAuthProxy.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime export. For agent developers.
|
|
3
|
+
* Owner, Agent, storage, errors. Consumer surface only.
|
|
4
|
+
*/
|
|
5
|
+
export { CbioIdentity, CbioAgent } from "../agent/agent.js";
|
|
6
|
+
export { generateIdentityKeys } from "../protocol/crypto.js";
|
|
7
|
+
export { IdentityError, IdentityErrorCode } from "../errors.js";
|
|
8
|
+
export { FsStorageProvider } from "../storage/fs.js";
|
|
9
|
+
export { MemoryStorageProvider } from "../storage/memory.js";
|
|
10
|
+
export { startLocalAuthProxy, } from "../http/localAuthProxy.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA4B5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EACL,mBAAmB,GAIpB,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sealed/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sealed blob primitives. Single source of truth for sealed blob format.
|
|
3
|
+
* Used by vault and by Cloud for custody transfer. Do not depend on runtime.
|
|
4
|
+
*/
|
|
5
|
+
export declare const SEALED_BLOB_VERSION: "v1.0";
|
|
6
|
+
export interface SealedBlobPayload {
|
|
7
|
+
version: string;
|
|
8
|
+
secrets: Record<string, string>;
|
|
9
|
+
secretMetadata: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Seal secrets with external key (AES-256-GCM). For custody transfer.
|
|
13
|
+
* kdk: 32 bytes, base64url-encoded.
|
|
14
|
+
*/
|
|
15
|
+
export declare function sealBlob(payload: SealedBlobPayload, kdk: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Unseal blob encrypted with kdk. Returns payload for custody import.
|
|
18
|
+
*/
|
|
19
|
+
export declare function unsealBlob(sealedBlob: string, kdk: string): SealedBlobPayload;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sealed blob primitives. Single source of truth for sealed blob format.
|
|
3
|
+
* Used by vault and by Cloud for custody transfer. Do not depend on runtime.
|
|
4
|
+
*/
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
6
|
+
import * as crypto from 'node:crypto';
|
|
7
|
+
import { IdentityError, IdentityErrorCode } from '../errors.js';
|
|
8
|
+
export const SEALED_BLOB_VERSION = 'v1.0';
|
|
9
|
+
/**
|
|
10
|
+
* Seal secrets with external key (AES-256-GCM). For custody transfer.
|
|
11
|
+
* kdk: 32 bytes, base64url-encoded.
|
|
12
|
+
*/
|
|
13
|
+
export function sealBlob(payload, kdk) {
|
|
14
|
+
const key = Buffer.from(kdk, 'base64url');
|
|
15
|
+
if (key.length !== 32) {
|
|
16
|
+
throw new IdentityError(IdentityErrorCode.INVALID_KDK, 'seal: kdk must be 32 bytes (base64url decoded)');
|
|
17
|
+
}
|
|
18
|
+
const plainText = JSON.stringify(payload);
|
|
19
|
+
const iv = crypto.randomBytes(12);
|
|
20
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
21
|
+
const encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);
|
|
22
|
+
const tag = cipher.getAuthTag();
|
|
23
|
+
return Buffer.concat([iv, tag, encrypted]).toString('base64url');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Unseal blob encrypted with kdk. Returns payload for custody import.
|
|
27
|
+
*/
|
|
28
|
+
export function unsealBlob(sealedBlob, kdk) {
|
|
29
|
+
const key = Buffer.from(kdk, 'base64url');
|
|
30
|
+
if (key.length !== 32) {
|
|
31
|
+
throw new IdentityError(IdentityErrorCode.INVALID_KDK, 'unseal: kdk must be 32 bytes (base64url decoded)');
|
|
32
|
+
}
|
|
33
|
+
const bundle = Buffer.from(sealedBlob, 'base64url');
|
|
34
|
+
const iv = bundle.subarray(0, 12);
|
|
35
|
+
const tag = bundle.subarray(12, 28);
|
|
36
|
+
const encrypted = bundle.subarray(28);
|
|
37
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
38
|
+
decipher.setAuthTag(tag);
|
|
39
|
+
const plainText = decipher.update(encrypted, undefined, 'utf8') + decipher.final('utf8');
|
|
40
|
+
const data = JSON.parse(plainText);
|
|
41
|
+
if (data.version === undefined || data.version === null) {
|
|
42
|
+
throw new IdentityError(IdentityErrorCode.INVALID_KDK, 'Sealed blob missing version. Legacy format is no longer supported.');
|
|
43
|
+
}
|
|
44
|
+
if (typeof data.secrets !== 'object' || data.secrets === null) {
|
|
45
|
+
throw new IdentityError(IdentityErrorCode.INVALID_KDK, 'Sealed blob must have a secrets object. Legacy format is no longer supported.');
|
|
46
|
+
}
|
|
47
|
+
if (typeof data.secretMetadata !== 'object' || data.secretMetadata === null) {
|
|
48
|
+
throw new IdentityError(IdentityErrorCode.INVALID_KDK, 'Sealed blob must have a secretMetadata object. Legacy format is no longer supported.');
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
version: data.version,
|
|
52
|
+
secrets: data.secrets,
|
|
53
|
+
secretMetadata: data.secretMetadata,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=seal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seal.js","sourceRoot":"","sources":["../../src/sealed/seal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default file-system storage provider. Uses node:fs with atomic write.
|
|
3
|
+
*/
|
|
4
|
+
import type { IStorageProvider } from './provider.js';
|
|
5
|
+
export declare class FsStorageProvider implements IStorageProvider {
|
|
6
|
+
private baseDir?;
|
|
7
|
+
constructor(baseDir?: string | undefined);
|
|
8
|
+
private static readonly DIRECTORY_MODE;
|
|
9
|
+
private static readonly FILE_MODE;
|
|
10
|
+
private resolve;
|
|
11
|
+
read(key: string): Promise<Buffer | null>;
|
|
12
|
+
write(key: string, data: Buffer): Promise<void>;
|
|
13
|
+
delete(key: string): Promise<void>;
|
|
14
|
+
has(key: string): Promise<boolean>;
|
|
15
|
+
rename(fromKey: string, toKey: string): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default file-system storage provider. Uses node:fs with atomic write.
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
export class FsStorageProvider {
|
|
7
|
+
baseDir;
|
|
8
|
+
constructor(baseDir) {
|
|
9
|
+
this.baseDir = baseDir;
|
|
10
|
+
}
|
|
11
|
+
static DIRECTORY_MODE = 0o700;
|
|
12
|
+
static FILE_MODE = 0o600;
|
|
13
|
+
resolve(key) {
|
|
14
|
+
if (this.baseDir) {
|
|
15
|
+
return path.join(this.baseDir, key);
|
|
16
|
+
}
|
|
17
|
+
const dir = path.dirname(key);
|
|
18
|
+
if (dir && dir !== '.') {
|
|
19
|
+
return key;
|
|
20
|
+
}
|
|
21
|
+
return key;
|
|
22
|
+
}
|
|
23
|
+
async read(key) {
|
|
24
|
+
try {
|
|
25
|
+
return await fs.readFile(this.resolve(key));
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
if (e.code === 'ENOENT')
|
|
29
|
+
return null;
|
|
30
|
+
throw e;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async write(key, data) {
|
|
34
|
+
const fullPath = this.resolve(key);
|
|
35
|
+
await fs.mkdir(path.dirname(fullPath), { recursive: true, mode: FsStorageProvider.DIRECTORY_MODE });
|
|
36
|
+
await fs.writeFile(fullPath, data, { mode: FsStorageProvider.FILE_MODE });
|
|
37
|
+
await fs.chmod(fullPath, FsStorageProvider.FILE_MODE);
|
|
38
|
+
const fh = await fs.open(fullPath, 'r+');
|
|
39
|
+
try {
|
|
40
|
+
await fh.sync();
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
await fh.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async delete(key) {
|
|
47
|
+
try {
|
|
48
|
+
await fs.unlink(this.resolve(key));
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
if (e.code !== 'ENOENT')
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async has(key) {
|
|
56
|
+
try {
|
|
57
|
+
await fs.access(this.resolve(key));
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async rename(fromKey, toKey) {
|
|
65
|
+
await fs.rename(this.resolve(fromKey), this.resolve(toKey));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/storage/fs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,MAAM,OAAO,iBAAiB;IACN;IAApB,YAAoB,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;IAEhC,MAAM,CAAU,cAAc,GAAG,KAAK,CAAC;IACvC,MAAM,CAAU,SAAS,GAAG,KAAK,CAAC;IAElC,OAAO,CAAC,GAAW;QACvB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,GAAG,CAAC;QACf,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QAClB,IAAI,CAAC;YACD,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YACd,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACrC,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,IAAY;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,CAAC,cAAc,EAAE,CAAC,CAAC;QACpG,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACP,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YACd,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACjB,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,KAAa;QACvC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory storage provider. For testing and environments without persistent storage.
|
|
3
|
+
*/
|
|
4
|
+
import type { IStorageProvider } from './provider.js';
|
|
5
|
+
export declare class MemoryStorageProvider implements IStorageProvider {
|
|
6
|
+
#private;
|
|
7
|
+
read(key: string): Promise<Buffer | null>;
|
|
8
|
+
write(key: string, data: Buffer): Promise<void>;
|
|
9
|
+
delete(key: string): Promise<void>;
|
|
10
|
+
has(key: string): Promise<boolean>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory storage provider. For testing and environments without persistent storage.
|
|
3
|
+
*/
|
|
4
|
+
export class MemoryStorageProvider {
|
|
5
|
+
#store = new Map();
|
|
6
|
+
async read(key) {
|
|
7
|
+
return this.#store.get(key) ?? null;
|
|
8
|
+
}
|
|
9
|
+
async write(key, data) {
|
|
10
|
+
this.#store.set(key, data);
|
|
11
|
+
}
|
|
12
|
+
async delete(key) {
|
|
13
|
+
this.#store.delete(key);
|
|
14
|
+
}
|
|
15
|
+
async has(key) {
|
|
16
|
+
return this.#store.has(key);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,OAAO,qBAAqB;IAC9B,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEnC,KAAK,CAAC,IAAI,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,IAAY;QACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;CACJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pluggable storage layer for vault persistence.
|
|
3
|
+
* Enables Cloud, Mobile, and Edge runtimes to use custom storage.
|
|
4
|
+
*/
|
|
5
|
+
export interface IStorageProvider {
|
|
6
|
+
read(key: string): Promise<Buffer | null>;
|
|
7
|
+
write(key: string, data: Buffer): Promise<void>;
|
|
8
|
+
delete(key: string): Promise<void>;
|
|
9
|
+
has(key: string): Promise<boolean>;
|
|
10
|
+
/** Optional. If present, used for atomic save. Otherwise vault does write+delete. */
|
|
11
|
+
rename?(fromKey: string, toKey: string): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/storage/provider.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function isLoopbackHost(hostname) {
|
|
2
|
+
return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';
|
|
3
|
+
}
|
|
4
|
+
export function isAllowedSecretUrl(url) {
|
|
5
|
+
return url.protocol === 'https:' || (url.protocol === 'http:' && isLoopbackHost(url.hostname));
|
|
6
|
+
}
|
|
7
|
+
export function normalizeSecretPolicyOrigin(origin) {
|
|
8
|
+
const url = new URL(origin);
|
|
9
|
+
if (!isAllowedSecretUrl(url)) {
|
|
10
|
+
throw new Error(`Secret policy requires HTTPS origin or loopback HTTP for local development. Received: ${origin}`);
|
|
11
|
+
}
|
|
12
|
+
return url.origin;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=secretPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secretPolicy.js","sourceRoot":"","sources":["../../src/vault/secretPolicy.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC3C,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,KAAK,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAQ;IACvC,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,MAAc;IACtD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yFAAyF,MAAM,EAAE,CAAC,CAAC;IACvH,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,CAAC;AACtB,CAAC"}
|