@viewportai/daemon 0.5.3 → 0.6.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/cli/commands.d.ts +1 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +1 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/context-access-command.d.ts +0 -6
- package/dist/cli/context-access-command.d.ts.map +1 -1
- package/dist/cli/context-access-command.js +1 -71
- package/dist/cli/context-access-command.js.map +1 -1
- package/dist/cli/context-command.d.ts.map +1 -1
- package/dist/cli/context-command.js +526 -38
- package/dist/cli/context-command.js.map +1 -1
- package/dist/cli/context-vault-metadata-command.d.ts.map +1 -1
- package/dist/cli/context-vault-metadata-command.js +6 -1
- package/dist/cli/context-vault-metadata-command.js.map +1 -1
- package/dist/cli/lifecycle-commands.d.ts.map +1 -1
- package/dist/cli/lifecycle-commands.js +2 -8
- package/dist/cli/lifecycle-commands.js.map +1 -1
- package/dist/cli/unlock-command.d.ts +2 -0
- package/dist/cli/unlock-command.d.ts.map +1 -0
- package/dist/cli/unlock-command.js +35 -0
- package/dist/cli/unlock-command.js.map +1 -0
- package/dist/context/local-edge-store.d.ts +11 -0
- package/dist/context/local-edge-store.d.ts.map +1 -1
- package/dist/context/local-edge-store.js +25 -0
- package/dist/context/local-edge-store.js.map +1 -1
- package/dist/context/local-edge-sync.d.ts +2 -15
- package/dist/context/local-edge-sync.d.ts.map +1 -1
- package/dist/context/local-edge-sync.js +244 -85
- package/dist/context/local-edge-sync.js.map +1 -1
- package/dist/context/local-edge-types.d.ts +12 -0
- package/dist/context/local-edge-types.d.ts.map +1 -1
- package/dist/hooks/trusted-edge-plan-artifacts.d.ts +30 -27
- package/dist/hooks/trusted-edge-plan-artifacts.d.ts.map +1 -1
- package/dist/hooks/trusted-edge-plan-artifacts.js +71 -89
- package/dist/hooks/trusted-edge-plan-artifacts.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/security/epoch-enrollment.d.ts +48 -0
- package/dist/security/epoch-enrollment.d.ts.map +1 -0
- package/dist/security/epoch-enrollment.js +290 -0
- package/dist/security/epoch-enrollment.js.map +1 -0
- package/dist/security/epoch-protocol.d.ts +181 -0
- package/dist/security/epoch-protocol.d.ts.map +1 -0
- package/dist/security/epoch-protocol.js +285 -0
- package/dist/security/epoch-protocol.js.map +1 -0
- package/dist/security/epoch-public-pins.d.ts +19 -0
- package/dist/security/epoch-public-pins.d.ts.map +1 -0
- package/dist/security/epoch-public-pins.js +129 -0
- package/dist/security/epoch-public-pins.js.map +1 -0
- package/dist/security/epoch-recovery.d.ts +56 -0
- package/dist/security/epoch-recovery.d.ts.map +1 -0
- package/dist/security/epoch-recovery.js +314 -0
- package/dist/security/epoch-recovery.js.map +1 -0
- package/dist/security/epoch-store.d.ts +111 -0
- package/dist/security/epoch-store.d.ts.map +1 -0
- package/dist/security/epoch-store.js +224 -0
- package/dist/security/epoch-store.js.map +1 -0
- package/dist/security/epoch-sync.d.ts +47 -0
- package/dist/security/epoch-sync.d.ts.map +1 -0
- package/dist/security/epoch-sync.js +371 -0
- package/dist/security/epoch-sync.js.map +1 -0
- package/dist/security/team-epoch-grants.d.ts +28 -0
- package/dist/security/team-epoch-grants.d.ts.map +1 -0
- package/dist/security/team-epoch-grants.js +256 -0
- package/dist/security/team-epoch-grants.js.map +1 -0
- package/dist/server/http-context-routes.d.ts +2 -1
- package/dist/server/http-context-routes.d.ts.map +1 -1
- package/dist/server/http-context-routes.js +46 -15
- package/dist/server/http-context-routes.js.map +1 -1
- package/dist/server/http-server.js +1 -1
- package/dist/server/http-server.js.map +1 -1
- package/dist/server/rate-limiter.d.ts.map +1 -1
- package/dist/server/rate-limiter.js +2 -1
- package/dist/server/rate-limiter.js.map +1 -1
- package/dist/server/trusted-edge-command-capability.d.ts +1 -1
- package/dist/server/trusted-edge-command-capability.d.ts.map +1 -1
- package/dist/server/trusted-edge-command-capability.js +11 -0
- package/dist/server/trusted-edge-command-capability.js.map +1 -1
- package/dist/server/ws-command-handlers.d.ts.map +1 -1
- package/dist/server/ws-command-handlers.js +124 -28
- package/dist/server/ws-command-handlers.js.map +1 -1
- package/dist/server/ws-protocol.d.ts +268 -44
- package/dist/server/ws-protocol.d.ts.map +1 -1
- package/dist/server/ws-protocol.js +81 -19
- package/dist/server/ws-protocol.js.map +1 -1
- package/dist/startup.d.ts.map +1 -1
- package/dist/startup.js +0 -17
- package/dist/startup.js.map +1 -1
- package/docs/protocol-matrix.json +40 -8
- package/node_modules/@viewportai/context-engine/src/repo/materializer.js +20 -5
- package/node_modules/@viewportai/context-engine/src/repo/membership.js +15 -0
- package/node_modules/@viewportai/context-engine/src/repo/sync.js +4 -4
- package/node_modules/@viewportai/context-engine/src/repo/vault.js +8 -3
- package/package.json +1 -1
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
export const USER_EPOCH_SCHEMA = 'viewport.user_crypto_epoch/v1';
|
|
3
|
+
export const TEAM_EPOCH_SCHEMA = 'viewport.team_crypto_epoch/v1';
|
|
4
|
+
export const DEVICE_ENROLLMENT_SCHEMA = 'viewport.device_enrollment/v1';
|
|
5
|
+
export const RESOURCE_GRANT_SCHEMA = 'viewport.resource_key_grant/v1';
|
|
6
|
+
export const WRAPPED_KEY_ENVELOPE_SCHEMA = 'viewport.wrapped_key_envelope/v1';
|
|
7
|
+
export const TRUSTED_EDGE_CRYPTO_PROTOCOL_HEADER = 'X-Viewport-Crypto-Protocol';
|
|
8
|
+
export const TRUSTED_EDGE_CRYPTO_PROTOCOL_VERSION = 'viewport.trusted_edge_crypto/v2';
|
|
9
|
+
const PRIVATE_JWK_FIELDS = new Set([
|
|
10
|
+
'd',
|
|
11
|
+
'p',
|
|
12
|
+
'q',
|
|
13
|
+
'dp',
|
|
14
|
+
'dq',
|
|
15
|
+
'qi',
|
|
16
|
+
'oth',
|
|
17
|
+
'k',
|
|
18
|
+
'x5c_private',
|
|
19
|
+
'hpkePrivateKey',
|
|
20
|
+
'privateKey',
|
|
21
|
+
'secretKey',
|
|
22
|
+
]);
|
|
23
|
+
export function canonicalJson(value) {
|
|
24
|
+
return JSON.stringify(canonicalize(value));
|
|
25
|
+
}
|
|
26
|
+
export function sha256Base64Url(value) {
|
|
27
|
+
return crypto.createHash('sha256').update(value).digest('base64url');
|
|
28
|
+
}
|
|
29
|
+
export function fingerprintPayload(value) {
|
|
30
|
+
return `sha256:${sha256Base64Url(canonicalJson(value))}`;
|
|
31
|
+
}
|
|
32
|
+
export function epochFingerprint(epoch) {
|
|
33
|
+
return fingerprintPayload({
|
|
34
|
+
schema: epoch.schema,
|
|
35
|
+
workspaceId: epoch.workspaceId,
|
|
36
|
+
subjectType: epoch.subjectType,
|
|
37
|
+
subjectId: epoch.subjectId,
|
|
38
|
+
epoch: epoch.epoch,
|
|
39
|
+
encryptionPublicKeyJwk: epoch.encryptionPublicKeyJwk,
|
|
40
|
+
signingPublicKeyJwk: epoch.signingPublicKeyJwk,
|
|
41
|
+
previousEpochFingerprint: epoch.previousEpochFingerprint ?? null,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function deviceEnrollmentFingerprint(request) {
|
|
45
|
+
assertNoPrivateKeyMaterial(request.encryptionPublicKeyJwk);
|
|
46
|
+
assertNoPrivateKeyMaterial(request.signingPublicKeyJwk);
|
|
47
|
+
return fingerprintPayload({
|
|
48
|
+
schema: request.schema,
|
|
49
|
+
workspaceId: request.workspaceId,
|
|
50
|
+
deviceId: request.deviceId,
|
|
51
|
+
deviceLabel: request.deviceLabel,
|
|
52
|
+
encryptionPublicKeyJwk: request.encryptionPublicKeyJwk,
|
|
53
|
+
signingPublicKeyJwk: request.signingPublicKeyJwk,
|
|
54
|
+
nonce: request.nonce,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export function signDeviceEnrollmentRequest(input) {
|
|
58
|
+
const key = crypto.createPrivateKey({
|
|
59
|
+
key: input.signingPrivateKeyJwk,
|
|
60
|
+
format: 'jwk',
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
payload: input.payload,
|
|
64
|
+
signature: crypto
|
|
65
|
+
.sign(null, Buffer.from(canonicalJson(input.payload)), key)
|
|
66
|
+
.toString('base64url'),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export function userEpochDeviceMaterializationPayload(input) {
|
|
70
|
+
return {
|
|
71
|
+
schema: 'viewport.user_epoch_device_materialization/v1',
|
|
72
|
+
workspaceId: input.workspaceId,
|
|
73
|
+
userId: input.userId,
|
|
74
|
+
enrollmentId: input.enrollmentId,
|
|
75
|
+
grantId: input.grantId,
|
|
76
|
+
userCryptoEpochId: input.userCryptoEpochId,
|
|
77
|
+
userEpochFingerprint: input.userEpochFingerprint,
|
|
78
|
+
recipientFingerprint: input.recipientFingerprint,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function signUserEpochDeviceMaterialization(input) {
|
|
82
|
+
const key = crypto.createPrivateKey({
|
|
83
|
+
key: input.signingPrivateKeyJwk,
|
|
84
|
+
format: 'jwk',
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
payload: input.payload,
|
|
88
|
+
signature: crypto
|
|
89
|
+
.sign(null, Buffer.from(canonicalJson(input.payload)), key)
|
|
90
|
+
.toString('base64url'),
|
|
91
|
+
signedByUserEpochFingerprint: input.signedByUserEpochFingerprint,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export function teamEpochMemberMaterializationPayload(input) {
|
|
95
|
+
return {
|
|
96
|
+
schema: 'viewport.team_epoch_member_materialization/v1',
|
|
97
|
+
workspaceId: input.workspaceId,
|
|
98
|
+
grantId: input.grantId,
|
|
99
|
+
teamCryptoEpochId: input.teamCryptoEpochId,
|
|
100
|
+
teamEpochFingerprint: input.teamEpochFingerprint,
|
|
101
|
+
recipientUserCryptoEpochId: input.recipientUserCryptoEpochId,
|
|
102
|
+
recipientUserEpochFingerprint: input.recipientUserEpochFingerprint,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function signTeamEpochMemberMaterialization(input) {
|
|
106
|
+
const key = crypto.createPrivateKey({
|
|
107
|
+
key: input.signingPrivateKeyJwk,
|
|
108
|
+
format: 'jwk',
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
payload: input.payload,
|
|
112
|
+
signature: crypto
|
|
113
|
+
.sign(null, Buffer.from(canonicalJson(input.payload)), key)
|
|
114
|
+
.toString('base64url'),
|
|
115
|
+
signedByTeamEpochFingerprint: input.signedByTeamEpochFingerprint,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function contextGrantMaterializationPayload(input) {
|
|
119
|
+
return {
|
|
120
|
+
schema: 'viewport.context_vault_grant_materialization/v1',
|
|
121
|
+
workspaceId: input.workspaceId,
|
|
122
|
+
contextResourceId: input.contextResourceId,
|
|
123
|
+
grantEventId: input.grantEventId,
|
|
124
|
+
recipientName: input.recipientName,
|
|
125
|
+
keyEpoch: input.keyEpoch,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export function signContextGrantMaterialization(input) {
|
|
129
|
+
const key = crypto.createPrivateKey({
|
|
130
|
+
key: input.signingPrivateKeyJwk,
|
|
131
|
+
format: 'jwk',
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
payload: input.payload,
|
|
135
|
+
signature: crypto
|
|
136
|
+
.sign(null, Buffer.from(canonicalJson(input.payload)), key)
|
|
137
|
+
.toString('base64url'),
|
|
138
|
+
signedByEpochFingerprint: input.signedByEpochFingerprint,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
export function epochTransitionPayload(input) {
|
|
142
|
+
if (input.from.workspaceId !== input.to.workspaceId) {
|
|
143
|
+
throw new Error('Epoch transition workspace mismatch.');
|
|
144
|
+
}
|
|
145
|
+
if (input.from.subjectType !== input.to.subjectType ||
|
|
146
|
+
input.from.subjectId !== input.to.subjectId) {
|
|
147
|
+
throw new Error('Epoch transition subject mismatch.');
|
|
148
|
+
}
|
|
149
|
+
if (input.to.epoch !== input.from.epoch + 1) {
|
|
150
|
+
throw new Error('Epoch transition must advance by exactly one epoch.');
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
schema: 'viewport.epoch_transition/v1',
|
|
154
|
+
workspaceId: input.from.workspaceId,
|
|
155
|
+
subjectType: input.from.subjectType,
|
|
156
|
+
subjectId: input.from.subjectId,
|
|
157
|
+
fromEpoch: input.from.epoch,
|
|
158
|
+
fromEpochFingerprint: epochFingerprint(input.from),
|
|
159
|
+
toEpoch: input.to.epoch,
|
|
160
|
+
toEpochFingerprint: epochFingerprint(input.to),
|
|
161
|
+
reason: input.reason,
|
|
162
|
+
createdAt: input.createdAt,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export function signEpochTransition(input) {
|
|
166
|
+
const key = crypto.createPrivateKey({
|
|
167
|
+
key: input.signingPrivateKeyJwk,
|
|
168
|
+
format: 'jwk',
|
|
169
|
+
});
|
|
170
|
+
const signature = crypto
|
|
171
|
+
.sign(null, Buffer.from(canonicalJson(input.payload)), key)
|
|
172
|
+
.toString('base64url');
|
|
173
|
+
return {
|
|
174
|
+
payload: input.payload,
|
|
175
|
+
signature,
|
|
176
|
+
signedByEpochFingerprint: input.signedByEpochFingerprint,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
export function verifyEpochTransition(input) {
|
|
180
|
+
if (input.signed.signedByEpochFingerprint !== input.expectedFromEpochFingerprint)
|
|
181
|
+
return false;
|
|
182
|
+
if (input.signed.payload.fromEpochFingerprint !== input.expectedFromEpochFingerprint)
|
|
183
|
+
return false;
|
|
184
|
+
if (input.signed.payload.toEpochFingerprint !== input.expectedToEpochFingerprint)
|
|
185
|
+
return false;
|
|
186
|
+
const key = crypto.createPublicKey({
|
|
187
|
+
key: input.signingPublicKeyJwk,
|
|
188
|
+
format: 'jwk',
|
|
189
|
+
});
|
|
190
|
+
return crypto.verify(null, Buffer.from(canonicalJson(input.signed.payload)), key, Buffer.from(input.signed.signature, 'base64url'));
|
|
191
|
+
}
|
|
192
|
+
export function wrapJsonForX25519Recipient(input) {
|
|
193
|
+
assertNoPrivateKeyMaterial(input.recipientPublicKeyJwk);
|
|
194
|
+
const ephemeral = crypto.generateKeyPairSync('x25519');
|
|
195
|
+
const recipientPublicKey = crypto.createPublicKey({
|
|
196
|
+
key: input.recipientPublicKeyJwk,
|
|
197
|
+
format: 'jwk',
|
|
198
|
+
});
|
|
199
|
+
const sharedSecret = crypto.diffieHellman({
|
|
200
|
+
privateKey: ephemeral.privateKey,
|
|
201
|
+
publicKey: recipientPublicKey,
|
|
202
|
+
});
|
|
203
|
+
const aad = Buffer.from(canonicalJson(input.aad));
|
|
204
|
+
const iv = crypto.randomBytes(12);
|
|
205
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', deriveWrapKey(sharedSecret), iv);
|
|
206
|
+
cipher.setAAD(aad);
|
|
207
|
+
const ciphertext = Buffer.concat([
|
|
208
|
+
cipher.update(Buffer.from(canonicalJson(input.payload))),
|
|
209
|
+
cipher.final(),
|
|
210
|
+
]);
|
|
211
|
+
return {
|
|
212
|
+
schema: WRAPPED_KEY_ENVELOPE_SCHEMA,
|
|
213
|
+
alg: 'x25519-hkdf-sha256-aes-256-gcm',
|
|
214
|
+
ephemeralPublicKeyJwk: ephemeral.publicKey.export({ format: 'jwk' }),
|
|
215
|
+
iv: iv.toString('base64url'),
|
|
216
|
+
ciphertext: ciphertext.toString('base64url'),
|
|
217
|
+
tag: cipher.getAuthTag().toString('base64url'),
|
|
218
|
+
aadDigest: fingerprintPayload(input.aad),
|
|
219
|
+
createdAt: input.createdAt ?? new Date().toISOString(),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
export function unwrapJsonFromX25519Envelope(input) {
|
|
223
|
+
if (input.envelope.schema !== WRAPPED_KEY_ENVELOPE_SCHEMA) {
|
|
224
|
+
throw new Error('Unsupported wrapped key envelope schema.');
|
|
225
|
+
}
|
|
226
|
+
if (input.envelope.alg !== 'x25519-hkdf-sha256-aes-256-gcm') {
|
|
227
|
+
throw new Error('Unsupported wrapped key envelope algorithm.');
|
|
228
|
+
}
|
|
229
|
+
const expectedAadDigest = fingerprintPayload(input.aad);
|
|
230
|
+
if (input.envelope.aadDigest !== expectedAadDigest) {
|
|
231
|
+
throw new Error('Wrapped key envelope AAD mismatch.');
|
|
232
|
+
}
|
|
233
|
+
const recipientPrivateKey = crypto.createPrivateKey({
|
|
234
|
+
key: input.recipientPrivateKeyJwk,
|
|
235
|
+
format: 'jwk',
|
|
236
|
+
});
|
|
237
|
+
const ephemeralPublicKey = crypto.createPublicKey({
|
|
238
|
+
key: input.envelope.ephemeralPublicKeyJwk,
|
|
239
|
+
format: 'jwk',
|
|
240
|
+
});
|
|
241
|
+
const sharedSecret = crypto.diffieHellman({
|
|
242
|
+
privateKey: recipientPrivateKey,
|
|
243
|
+
publicKey: ephemeralPublicKey,
|
|
244
|
+
});
|
|
245
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', deriveWrapKey(sharedSecret), Buffer.from(input.envelope.iv, 'base64url'));
|
|
246
|
+
decipher.setAAD(Buffer.from(canonicalJson(input.aad)));
|
|
247
|
+
decipher.setAuthTag(Buffer.from(input.envelope.tag, 'base64url'));
|
|
248
|
+
const plaintext = Buffer.concat([
|
|
249
|
+
decipher.update(Buffer.from(input.envelope.ciphertext, 'base64url')),
|
|
250
|
+
decipher.final(),
|
|
251
|
+
]);
|
|
252
|
+
return JSON.parse(plaintext.toString('utf8'));
|
|
253
|
+
}
|
|
254
|
+
export function assertNoPrivateKeyMaterial(value, path = '$') {
|
|
255
|
+
if (Array.isArray(value)) {
|
|
256
|
+
value.forEach((item, index) => assertNoPrivateKeyMaterial(item, `${path}[${index}]`));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (!value || typeof value !== 'object')
|
|
260
|
+
return;
|
|
261
|
+
for (const [key, child] of Object.entries(value)) {
|
|
262
|
+
if (PRIVATE_JWK_FIELDS.has(key)) {
|
|
263
|
+
throw new Error(`Private key material is not allowed at ${path}.${key}.`);
|
|
264
|
+
}
|
|
265
|
+
assertNoPrivateKeyMaterial(child, `${path}.${key}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function deriveWrapKey(sharedSecret) {
|
|
269
|
+
return Buffer.from(crypto.hkdfSync('sha256', sharedSecret, Buffer.from('viewport-wrapped-key-envelope-salt-v1'), Buffer.from('viewport-wrapped-key-envelope/v1'), 32));
|
|
270
|
+
}
|
|
271
|
+
function canonicalize(value) {
|
|
272
|
+
if (Array.isArray(value))
|
|
273
|
+
return value.map((item) => canonicalize(item));
|
|
274
|
+
if (!value || typeof value !== 'object')
|
|
275
|
+
return value;
|
|
276
|
+
return Object.keys(value)
|
|
277
|
+
.sort()
|
|
278
|
+
.reduce((acc, key) => {
|
|
279
|
+
const child = value[key];
|
|
280
|
+
if (child !== undefined)
|
|
281
|
+
acc[key] = canonicalize(child);
|
|
282
|
+
return acc;
|
|
283
|
+
}, {});
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=epoch-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epoch-protocol.js","sourceRoot":"","sources":["../../src/security/epoch-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type JsonValue } from './epoch-protocol.js';
|
|
2
|
+
import { type LocalPublicEpochPin } from './epoch-store.js';
|
|
3
|
+
export interface PublicEpochForPinning {
|
|
4
|
+
platformEpochId: string;
|
|
5
|
+
workspaceId: string;
|
|
6
|
+
subjectType: 'user' | 'team';
|
|
7
|
+
subjectId: string;
|
|
8
|
+
epoch: number;
|
|
9
|
+
schema: 'viewport.user_crypto_epoch/v1' | 'viewport.team_crypto_epoch/v1';
|
|
10
|
+
fingerprint: string;
|
|
11
|
+
encryptionPublicKeyJwk: JsonValue;
|
|
12
|
+
signingPublicKeyJwk: JsonValue;
|
|
13
|
+
previousEpochFingerprint?: string | null;
|
|
14
|
+
continuityPayload?: JsonValue | null;
|
|
15
|
+
continuitySignature?: string | null;
|
|
16
|
+
signedByEpochFingerprint?: string | null;
|
|
17
|
+
}
|
|
18
|
+
export declare function validateAndPinPublicEpoch(epoch: PublicEpochForPinning, home?: string): Promise<LocalPublicEpochPin>;
|
|
19
|
+
//# sourceMappingURL=epoch-public-pins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epoch-public-pins.d.ts","sourceRoot":"","sources":["../../src/security/epoch-public-pins.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,+BAA+B,GAAG,+BAA+B,CAAC;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,SAAS,CAAC;IAClC,mBAAmB,EAAE,SAAS,CAAC;IAC/B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,iBAAiB,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,qBAAqB,EAC5B,IAAI,SAAc,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { configDir } from '../core/config.js';
|
|
2
|
+
import { epochFingerprint, verifyEpochTransition, } from './epoch-protocol.js';
|
|
3
|
+
import { getLocalPublicEpochPin, upsertLocalPublicEpochPin, } from './epoch-store.js';
|
|
4
|
+
export async function validateAndPinPublicEpoch(epoch, home = configDir()) {
|
|
5
|
+
const descriptor = publicEpochDescriptor(epoch);
|
|
6
|
+
const computedFingerprint = epochFingerprint(descriptor);
|
|
7
|
+
if (computedFingerprint !== epoch.fingerprint) {
|
|
8
|
+
throw new Error(`Fetched ${epoch.subjectType} epoch fingerprint mismatch for ${epoch.subjectId}.`);
|
|
9
|
+
}
|
|
10
|
+
const previous = await getLocalPublicEpochPin({
|
|
11
|
+
workspaceId: epoch.workspaceId,
|
|
12
|
+
subjectType: epoch.subjectType,
|
|
13
|
+
subjectId: epoch.subjectId,
|
|
14
|
+
}, home);
|
|
15
|
+
if (previous) {
|
|
16
|
+
if (epoch.epoch < previous.epoch) {
|
|
17
|
+
throw new Error(`Fetched ${epoch.subjectType} epoch rollback for ${epoch.subjectId}: ${epoch.epoch} < ${previous.epoch}.`);
|
|
18
|
+
}
|
|
19
|
+
if (epoch.epoch === previous.epoch && epoch.fingerprint !== previous.fingerprint) {
|
|
20
|
+
throw new Error(`Fetched ${epoch.subjectType} epoch replacement for ${epoch.subjectId} requires signed continuity.`);
|
|
21
|
+
}
|
|
22
|
+
if (epoch.epoch > previous.epoch) {
|
|
23
|
+
assertSignedContinuity({ previous, next: epoch });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return upsertLocalPublicEpochPin({
|
|
27
|
+
workspaceId: epoch.workspaceId,
|
|
28
|
+
subjectType: epoch.subjectType,
|
|
29
|
+
subjectId: epoch.subjectId,
|
|
30
|
+
platformEpochId: epoch.platformEpochId,
|
|
31
|
+
epoch: epoch.epoch,
|
|
32
|
+
schema: epoch.schema,
|
|
33
|
+
fingerprint: epoch.fingerprint,
|
|
34
|
+
encryptionPublicKeyJwk: epoch.encryptionPublicKeyJwk,
|
|
35
|
+
signingPublicKeyJwk: epoch.signingPublicKeyJwk,
|
|
36
|
+
previousEpochFingerprint: epoch.previousEpochFingerprint ?? null,
|
|
37
|
+
continuityPayload: epoch.continuityPayload ?? null,
|
|
38
|
+
continuitySignature: epoch.continuitySignature ?? null,
|
|
39
|
+
signedByEpochFingerprint: epoch.signedByEpochFingerprint ?? null,
|
|
40
|
+
}, home);
|
|
41
|
+
}
|
|
42
|
+
function assertSignedContinuity(input) {
|
|
43
|
+
if (input.next.previousEpochFingerprint !== input.previous.fingerprint) {
|
|
44
|
+
throw new Error(`Fetched ${input.next.subjectType} epoch ${input.next.epoch} does not continue from pinned epoch ${input.previous.epoch}.`);
|
|
45
|
+
}
|
|
46
|
+
if (!input.next.continuityPayload || !input.next.continuitySignature) {
|
|
47
|
+
throw new Error(`Fetched ${input.next.subjectType} epoch ${input.next.epoch} is missing signed continuity.`);
|
|
48
|
+
}
|
|
49
|
+
const signed = {
|
|
50
|
+
payload: epochTransitionPayload(input.next.continuityPayload),
|
|
51
|
+
signature: input.next.continuitySignature,
|
|
52
|
+
signedByEpochFingerprint: input.next.signedByEpochFingerprint ?? input.next.previousEpochFingerprint ?? '',
|
|
53
|
+
};
|
|
54
|
+
const ok = verifyEpochTransition({
|
|
55
|
+
signed,
|
|
56
|
+
signingPublicKeyJwk: input.previous.signingPublicKeyJwk,
|
|
57
|
+
expectedFromEpochFingerprint: input.previous.fingerprint,
|
|
58
|
+
expectedToEpochFingerprint: input.next.fingerprint,
|
|
59
|
+
});
|
|
60
|
+
if (!ok) {
|
|
61
|
+
throw new Error(`Fetched ${input.next.subjectType} epoch ${input.next.epoch} continuity signature is invalid.`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function publicEpochDescriptor(epoch) {
|
|
65
|
+
return {
|
|
66
|
+
schema: epoch.schema,
|
|
67
|
+
workspaceId: epoch.workspaceId,
|
|
68
|
+
subjectType: epoch.subjectType,
|
|
69
|
+
subjectId: epoch.subjectId,
|
|
70
|
+
epoch: epoch.epoch,
|
|
71
|
+
encryptionPublicKeyJwk: epoch.encryptionPublicKeyJwk,
|
|
72
|
+
signingPublicKeyJwk: epoch.signingPublicKeyJwk,
|
|
73
|
+
previousEpochFingerprint: epoch.previousEpochFingerprint ?? null,
|
|
74
|
+
createdAt: 'pinning-fingerprint-input',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function epochTransitionPayload(value) {
|
|
78
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
79
|
+
throw new Error('Epoch continuity payload must be an object.');
|
|
80
|
+
}
|
|
81
|
+
const data = value;
|
|
82
|
+
return {
|
|
83
|
+
schema: 'viewport.epoch_transition/v1',
|
|
84
|
+
workspaceId: stringField(data, 'workspaceId'),
|
|
85
|
+
subjectType: subjectTypeField(data, 'subjectType'),
|
|
86
|
+
subjectId: stringField(data, 'subjectId'),
|
|
87
|
+
fromEpoch: numberField(data, 'fromEpoch'),
|
|
88
|
+
fromEpochFingerprint: stringField(data, 'fromEpochFingerprint'),
|
|
89
|
+
toEpoch: numberField(data, 'toEpoch'),
|
|
90
|
+
toEpochFingerprint: stringField(data, 'toEpochFingerprint'),
|
|
91
|
+
reason: reasonField(data, 'reason'),
|
|
92
|
+
createdAt: stringField(data, 'createdAt'),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function stringField(value, field) {
|
|
96
|
+
const child = value[field];
|
|
97
|
+
if (typeof child !== 'string' || child.trim() === '') {
|
|
98
|
+
throw new Error(`Epoch continuity payload missing ${field}.`);
|
|
99
|
+
}
|
|
100
|
+
return child;
|
|
101
|
+
}
|
|
102
|
+
function numberField(value, field) {
|
|
103
|
+
const child = value[field];
|
|
104
|
+
if (typeof child !== 'number') {
|
|
105
|
+
throw new Error(`Epoch continuity payload missing numeric ${field}.`);
|
|
106
|
+
}
|
|
107
|
+
return child;
|
|
108
|
+
}
|
|
109
|
+
function subjectTypeField(value, field) {
|
|
110
|
+
const child = stringField(value, field);
|
|
111
|
+
if (child !== 'user' && child !== 'team') {
|
|
112
|
+
throw new Error(`Epoch continuity payload has unsupported ${field}.`);
|
|
113
|
+
}
|
|
114
|
+
return child;
|
|
115
|
+
}
|
|
116
|
+
function reasonField(value, field) {
|
|
117
|
+
const child = stringField(value, field);
|
|
118
|
+
if (child === 'initial' ||
|
|
119
|
+
child === 'device_enrolled' ||
|
|
120
|
+
child === 'device_revoked' ||
|
|
121
|
+
child === 'member_added' ||
|
|
122
|
+
child === 'member_revoked' ||
|
|
123
|
+
child === 'manual_rotation' ||
|
|
124
|
+
child === 'recovery') {
|
|
125
|
+
return child;
|
|
126
|
+
}
|
|
127
|
+
throw new Error(`Epoch continuity payload has unsupported ${field}.`);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=epoch-public-pins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epoch-public-pins.js","sourceRoot":"","sources":["../../src/security/epoch-public-pins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { transportFetch } from '../cli/network.js';
|
|
2
|
+
import { type LocalUserCryptoEpoch } from './epoch-store.js';
|
|
3
|
+
import { type JsonValue } from './epoch-protocol.js';
|
|
4
|
+
import { type CryptoEpochSyncTarget } from './epoch-sync.js';
|
|
5
|
+
export declare const USER_EPOCH_RECOVERY_BACKUP_SCHEMA = "viewport.user_epoch_recovery_backup/v1";
|
|
6
|
+
declare const USER_EPOCH_RECOVERY_ENVELOPE_SCHEMA = "viewport.user_epoch_recovery_envelope/v1";
|
|
7
|
+
declare const RECOVERY_KDF = "scrypt-sha256/v1";
|
|
8
|
+
interface UserKeyBackupResponse {
|
|
9
|
+
id: string;
|
|
10
|
+
workspace_id: string;
|
|
11
|
+
user_id: number | string;
|
|
12
|
+
user_crypto_epoch_id: string;
|
|
13
|
+
schema: typeof USER_EPOCH_RECOVERY_BACKUP_SCHEMA;
|
|
14
|
+
status: string;
|
|
15
|
+
kdf: typeof RECOVERY_KDF;
|
|
16
|
+
kdf_params: RecoveryKdfParams;
|
|
17
|
+
encrypted_payload: RecoveryEnvelope;
|
|
18
|
+
created_at?: string | null;
|
|
19
|
+
}
|
|
20
|
+
interface RecoveryKdfParams {
|
|
21
|
+
salt: string;
|
|
22
|
+
keyLength: number;
|
|
23
|
+
N: number;
|
|
24
|
+
r: number;
|
|
25
|
+
p: number;
|
|
26
|
+
}
|
|
27
|
+
interface RecoveryEnvelope {
|
|
28
|
+
schema: typeof USER_EPOCH_RECOVERY_ENVELOPE_SCHEMA;
|
|
29
|
+
alg: 'aes-256-gcm';
|
|
30
|
+
aad: JsonValue;
|
|
31
|
+
iv: string;
|
|
32
|
+
ciphertext: string;
|
|
33
|
+
tag: string;
|
|
34
|
+
aadDigest: string;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function generateUserEpochRecoveryKey(): string;
|
|
38
|
+
export declare function createUserEpochRecoveryBackup(options: {
|
|
39
|
+
target: CryptoEpochSyncTarget;
|
|
40
|
+
recoveryKey: string;
|
|
41
|
+
home?: string;
|
|
42
|
+
fetchImpl?: typeof transportFetch;
|
|
43
|
+
}): Promise<UserKeyBackupResponse>;
|
|
44
|
+
export declare function restoreUserEpochFromRecoveryBackup(options: {
|
|
45
|
+
target: CryptoEpochSyncTarget;
|
|
46
|
+
recoveryKey: string;
|
|
47
|
+
home?: string;
|
|
48
|
+
fetchImpl?: typeof transportFetch;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
backup: UserKeyBackupResponse;
|
|
51
|
+
restoredEpoch: LocalUserCryptoEpoch;
|
|
52
|
+
rotatedEpoch: LocalUserCryptoEpoch;
|
|
53
|
+
rotatedBackup: UserKeyBackupResponse;
|
|
54
|
+
}>;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=epoch-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epoch-recovery.d.ts","sourceRoot":"","sources":["../../src/security/epoch-recovery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAyB,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,eAAO,MAAM,iCAAiC,2CAA2C,CAAC;AAE1F,QAAA,MAAM,mCAAmC,6CAA6C,CAAC;AACvF,QAAA,MAAM,YAAY,qBAAqB,CAAC;AAWxC,UAAU,qBAAqB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,OAAO,iCAAiC,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,YAAY,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,OAAO,mCAAmC,CAAC;IACnD,GAAG,EAAE,aAAa,CAAC;IACnB,GAAG,EAAE,SAAS,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAsB,6BAA6B,CAAC,OAAO,EAAE;IAC3D,MAAM,EAAE,qBAAqB,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,cAAc,CAAC;CACnC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAkDjC;AAED,wBAAsB,kCAAkC,CAAC,OAAO,EAAE;IAChE,MAAM,EAAE,qBAAqB,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,cAAc,CAAC;CACnC,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,oBAAoB,CAAC;IACpC,YAAY,EAAE,oBAAoB,CAAC;IACnC,aAAa,EAAE,qBAAqB,CAAC;CACtC,CAAC,CAqCD"}
|