@the-ai-company/cbio-node-runtime 1.25.0 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -103,9 +103,9 @@ const createdVault = await createVault(storage, {
103
103
  });
104
104
  ```
105
105
 
106
- The workspace root can contain many vaults. Each vault is physically divided into `vault/sealed/` (encrypted) and `vault/public/` (plaintext discovery).
106
+ The workspace root can contain many vaults. Each vault is physically divided into `vault/sealed/` (encrypted) and `vault/public/` (signed discovery).
107
107
 
108
- Each identity also has its own private namespace under `identities/<identityId>/sealed/...` for encrypted metadata such as `profile.sealed` and `children.sealed`.
108
+ Every identity also has its own private namespace under `identities/<identityId>/sealed/...` for encrypted metadata, and a companion `public/profile.json` for verified discovery.
109
109
 
110
110
  ## Architecture
111
111
 
@@ -5,7 +5,6 @@ import type { CreatedIdentity } from "./identity.js";
5
5
  export interface CreateVaultOptions extends Omit<CreatePersistentVaultCoreDependenciesOptions, "vaultWorkingKey" | "vaultId"> {
6
6
  vaultId?: string;
7
7
  nickname?: string;
8
- exposeNickname?: boolean;
9
8
  publicMetadata?: Record<string, any>;
10
9
  ownerIdentity: CreatedIdentity;
11
10
  vault?: {
@@ -3,8 +3,9 @@ import { createVaultCore } from "../vault-core/core.js";
3
3
  import { createPersistentVaultCoreDependencies, } from "../vault-core/index.js";
4
4
  import { wrapVaultCoreAsVaultService, } from "../vault-ingress/index.js";
5
5
  import { createPrefixedStorage } from "../storage/prefix.js";
6
- import { readVaultProfile, writeVaultProfile, readVaultPublicMetadata } from "./vault-metadata.js";
6
+ import { readVaultProfile, writeVaultProfile } from "./vault-metadata.js";
7
7
  import { createWorkspaceStorage } from "./workspace-storage.js";
8
+ import { writeVerifiableMetadata, readVerifiableMetadata } from "./verifiable-metadata.js";
8
9
  function deriveVaultWorkingKey(privateKey, vaultId) {
9
10
  return crypto
10
11
  .createHash("sha256")
@@ -48,17 +49,20 @@ export async function createVault(storageOrOptions, maybeOptions) {
48
49
  };
49
50
  await core.bootstrapOwnerIdentity(bootstrapOwner);
50
51
  const nickname = options.nickname?.trim() ? options.nickname.trim() : undefined;
51
- const publicMetadata = { ...(options.publicMetadata || {}) };
52
- if (options.exposeNickname && nickname) {
53
- publicMetadata.nickname = nickname;
54
- }
52
+ // Nickname is public-by-design for discovery
53
+ const publicMetadata = {
54
+ ...(options.publicMetadata || {}),
55
+ ...(nickname ? { nickname } : {})
56
+ };
55
57
  await writeVaultProfile(storage, {
56
58
  sealed: {
57
59
  vaultId,
58
- nickname,
60
+ // nickname removed from sealed area
59
61
  },
60
- public: publicMetadata,
62
+ public: {}, // Sealed profile no longer carries public mirror
61
63
  }, vaultWorkingKey);
64
+ // Write Signed Public Profile for Discovery
65
+ await writeVerifiableMetadata(storage, "vault/public/profile.json", publicMetadata, options.ownerIdentity.privateKey);
62
66
  return {
63
67
  core,
64
68
  vault: wrapVaultCoreAsVaultService(core, options.vault),
@@ -77,10 +81,11 @@ export async function recoverVault(storageOrOptions, maybeOptions) {
77
81
  });
78
82
  const core = createVaultCore(deps);
79
83
  const profile = await readVaultProfile(storage, vaultWorkingKey);
84
+ const publicMeta = await readVerifiableMetadata(storage, "vault/public/profile.json", options.ownerIdentity.publicKey).catch(() => null);
80
85
  return {
81
86
  core,
82
87
  vault: wrapVaultCoreAsVaultService(core, options.vault),
83
- nickname: profile?.sealed.nickname,
88
+ nickname: publicMeta?.nickname,
84
89
  storage,
85
90
  };
86
91
  }
@@ -95,10 +100,10 @@ export async function listVaults(storage) {
95
100
  const results = [];
96
101
  for (const id of ids) {
97
102
  const vaultStorage = createPrefixedStorage(storage, vaultStoragePrefix(id));
98
- const publicData = await readVaultPublicMetadata(vaultStorage).catch(() => ({}));
103
+ const publicData = await readVerifiableMetadata(vaultStorage, "vault/public/profile.json").catch(() => ({}));
99
104
  results.push({
100
105
  vaultId: id,
101
- public: publicData,
106
+ public: publicData || {},
102
107
  });
103
108
  }
104
109
  return results;
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,6 @@ import type { IStorageProvider } from "../storage/provider.js";
2
2
  import { type CreatedIdentity } from "./identity.js";
3
3
  export interface IdentityPrivateVaultProfile {
4
4
  identityId: string;
5
- nickname?: string;
6
5
  publicKey: string;
7
6
  parentIdentityId?: string;
8
7
  childIndex?: number;
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { SealedJsonRepository } from "../sealed/index.js";
3
3
  import { restoreIdentity } from "./identity.js";
4
+ import { writeVerifiableMetadata, readVerifiableMetadata } from "./verifiable-metadata.js";
4
5
  const PRIVATE_VAULT_PREFIX = "identities";
5
6
  const PRIVATE_VAULT_LOCK_SUFFIX = ".lock";
6
7
  export function identityPrivateVaultPrefix(identityId) {
@@ -37,27 +38,26 @@ export async function ensureIdentityPrivateVault(storage, identity) {
37
38
  const profileKey = identityPrivateVaultProfileKey(identity.identityId);
38
39
  const profileRepo = new SealedJsonRepository(storage, profileKey, deriveIdentityPrivateVaultKey(identity));
39
40
  const existingProfile = await profileRepo.read(null);
41
+ // Read current public profile to preserve nickname if needed
42
+ const publicPath = identityPrivateVaultPublicProfileKey(identity.identityId);
43
+ const publicRaw = await storage.read(publicPath);
44
+ const existingPublic = publicRaw ? JSON.parse(publicRaw.toString()) : {};
40
45
  const profile = {
41
46
  identityId: identity.identityId,
42
- nickname: identity.nickname || existingProfile?.nickname,
43
47
  publicKey: identity.publicKey,
44
48
  parentIdentityId: identity.parentIdentityId || existingProfile?.parentIdentityId,
45
49
  childIndex: identity.childIndex ?? existingProfile?.childIndex,
46
50
  };
47
- // Only write if new profile differs or doesn't exist
48
- if (!existingProfile ||
49
- profile.nickname !== existingProfile.nickname ||
50
- profile.parentIdentityId !== existingProfile.parentIdentityId) {
51
- await profileRepo.write(profile, "identity_private_vault_profile");
52
- // Sync public profile mirror (Plaintext)
53
- const publicProfile = {
54
- identityId: profile.identityId,
55
- publicKey: profile.publicKey,
56
- nickname: profile.nickname,
57
- parentIdentityId: profile.parentIdentityId,
58
- };
59
- await storage.write(identityPrivateVaultPublicProfileKey(identity.identityId), Buffer.from(JSON.stringify(publicProfile, null, 2)));
60
- }
51
+ // Profile data in sealed area (excluding nickname)
52
+ await profileRepo.write(profile, "identity_private_vault_profile");
53
+ // Write Signed Public Profile for Discovery
54
+ const publicProfile = {
55
+ identityId: profile.identityId,
56
+ publicKey: profile.publicKey,
57
+ nickname: identity.nickname || existingPublic?.nickname,
58
+ parentIdentityId: profile.parentIdentityId,
59
+ };
60
+ await writeVerifiableMetadata(storage, publicPath, publicProfile, identity.privateKey);
61
61
  const childrenKey = identityPrivateVaultChildrenKey(identity.identityId);
62
62
  if (!(await storage.has(childrenKey))) {
63
63
  const emptyState = {
@@ -78,31 +78,29 @@ export async function readIdentityPrivateVaultProfile(storage, identityOrPrivate
78
78
  * Handles both open discovery (identityId only) and authorized read (privateKey).
79
79
  */
80
80
  export async function readIdentityMetadata(storage, identityId, privateKey) {
81
- // If private key is provided, we prefer the full sealed profile
81
+ const publicPath = identityPrivateVaultPublicProfileKey(identityId);
82
+ const publicProfile = await readVerifiableMetadata(storage, publicPath).catch(() => null);
83
+ // If private key is provided, try to read and merge the full sealed profile
82
84
  if (privateKey) {
83
85
  try {
84
86
  const identity = restoreIdentity(privateKey);
85
87
  if (identity.identityId !== identityId) {
86
88
  throw new Error("identityId mismatch");
87
89
  }
88
- return await readIdentityPrivateVaultProfile(storage, identity);
89
- }
90
- catch {
91
- // Fallback to public if privateKey is invalid or decryption fails
92
- }
93
- }
94
- // Otherwise, read the public discovery profile
95
- const publicPath = identityPrivateVaultPublicProfileKey(identityId);
96
- const publicData = await storage.read(publicPath);
97
- if (publicData) {
98
- try {
99
- return JSON.parse(publicData.toString());
90
+ const sealed = await readIdentityPrivateVaultProfile(storage, identity);
91
+ if (sealed) {
92
+ return {
93
+ ...publicProfile, // Spread public profile (contains nickname)
94
+ ...sealed, // Spread sealed profile (contains keys/metadata)
95
+ };
96
+ }
100
97
  }
101
- catch {
102
- return null;
98
+ catch (e) {
99
+ // Fallback to public if decryption fails
100
+ console.warn(`[IdentityMetadata] Decryption failed for ${identityId}:`, e);
103
101
  }
104
102
  }
105
- return null;
103
+ return publicProfile;
106
104
  }
107
105
  export async function readIdentityPrivateVaultChildrenState(storage, identityOrPrivateKey) {
108
106
  const identity = normalizeIdentityAccess(identityOrPrivateKey);
@@ -1 +1 @@
1
- {"version":3,"file":"private-vault.js","sourceRoot":"","sources":["../../src/runtime/private-vault.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"private-vault.js","sourceRoot":"","sources":["../../src/runtime/private-vault.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAwB,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAE3F,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAC1C,MAAM,yBAAyB,GAAG,OAAO,CAAC;AA+B1C,MAAM,UAAU,0BAA0B,CAAC,UAAkB;IAC3D,OAAO,GAAG,oBAAoB,IAAI,UAAU,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,UAAkB;IAC/D,OAAO,GAAG,0BAA0B,CAAC,UAAU,CAAC,wBAAwB,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,UAAkB;IAChE,OAAO,GAAG,0BAA0B,CAAC,UAAU,CAAC,yBAAyB,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,oCAAoC,CAAC,UAAkB;IACrE,OAAO,GAAG,0BAA0B,CAAC,UAAU,CAAC,sBAAsB,CAAC;AACzE,CAAC;AAED,SAAS,OAAO,CAAC,UAAkB;IACjC,OAAO,GAAG,0BAA0B,CAAC,UAAU,CAAC,sBAAsB,yBAAyB,EAAE,CAAC;AACpG,CAAC;AAED,SAAS,uBAAuB,CAAC,oBAAgD;IAC/E,IAAI,OAAO,oBAAoB,KAAK,QAAQ,EAAE,CAAC;QAC7C,OAAO,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED,SAAS,6BAA6B,CAAC,QAAyB;IAC9D,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,gCAAgC,CAAC;SACxC,MAAM,CAAC,IAAI,CAAC;SACZ,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;SAC3B,MAAM,CAAC,IAAI,CAAC;SACZ,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;SAC3B,MAAM,CAAC,WAAW,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAAyB,EACzB,QAAyB;IAEzB,MAAM,UAAU,GAAG,8BAA8B,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAC1C,OAAO,EACP,UAAU,EACV,6BAA6B,CAAC,QAAQ,CAAC,CACxC,CAAC;IAEF,MAAM,eAAe,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,IAAW,CAAC,CAAC;IAE5D,6DAA6D;IAC7D,MAAM,UAAU,GAAG,oCAAoC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEzE,MAAM,OAAO,GAAgC;QAC3C,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,IAAI,eAAe,EAAE,gBAAgB;QAChF,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,eAAe,EAAE,UAAU;KAC/D,CAAC;IAEF,mDAAmD;IACnD,MAAM,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,gCAAgC,CAAC,CAAC;IAEnE,4CAA4C;IAC5C,MAAM,aAAa,GAA0B;QAC3C,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,cAAc,EAAE,QAAQ;QACvD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;KAC3C,CAAC;IACF,MAAM,uBAAuB,CAC3B,OAAO,EACP,UAAU,EACV,aAAa,EACb,QAAQ,CAAC,UAAU,CACpB,CAAC;IAEF,MAAM,WAAW,GAAG,+BAA+B,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACzE,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,UAAU,GAAsC;YACpD,cAAc,EAAE,CAAC;YACjB,QAAQ,EAAE,EAAE;SACb,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,oBAAoB,CAC3C,OAAO,EACP,WAAW,EACX,6BAA6B,CAAC,QAAQ,CAAC,CACxC,CAAC;QACF,MAAM,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,iCAAiC,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,OAAyB,EACzB,oBAAgD;IAEhD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,IAAI,oBAAoB,CACnC,OAAO,EACP,8BAA8B,CAAC,QAAQ,CAAC,UAAU,CAAC,EACnD,6BAA6B,CAAC,QAAQ,CAAC,CACxC,CAAC;IACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAW,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAyB,EACzB,UAAkB,EAClB,UAAmB;IAEnB,MAAM,UAAU,GAAG,oCAAoC,CAAC,UAAU,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAChD,OAAO,EACP,UAAU,CACX,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAEpB,4EAA4E;IAC5E,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,+BAA+B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACxE,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO;oBACL,GAAG,aAAa,EAAE,4CAA4C;oBAC9D,GAAG,MAAM,EAAS,iDAAiD;iBAC7D,CAAC;YACX,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,yCAAyC;YACzC,OAAO,CAAC,IAAI,CAAC,4CAA4C,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qCAAqC,CACzD,OAAyB,EACzB,oBAAgD;IAEhD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,IAAI,oBAAoB,CACnC,OAAO,EACP,+BAA+B,CAAC,QAAQ,CAAC,UAAU,CAAC,EACpD,6BAA6B,CAAC,QAAQ,CAAC,CACxC,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACpE,OAAO;QACL,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC/D,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAC1D,OAAyB,EACzB,oBAAgD,EAChD,KAAwC;IAExC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,IAAI,oBAAoB,CACnC,OAAO,EACP,+BAA+B,CAAC,QAAQ,CAAC,UAAU,CAAC,EACpD,6BAA6B,CAAC,QAAQ,CAAC,CACxC,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,iCAAiC,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAAyB,EACzB,oBAAgD,EAChD,IAAsB;IAEtB,MAAM,QAAQ,GAAG,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAyB;IAC5D,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACrD,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,qDAAqD;QACrD,IAAI,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAAE,SAAS;QAErD,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,OAAgC,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,7 +1,9 @@
1
1
  import type { IStorageProvider } from "../storage/provider.js";
2
2
  export interface VaultProfile {
3
3
  sealed: Record<string, any>;
4
- public: Record<string, any>;
4
+ public: Record<string, any> & {
5
+ nickname?: string;
6
+ };
5
7
  }
6
8
  export declare const VAULT_PUBLIC_PROFILE_KEY = "vault/public/profile.json";
7
9
  /**
@@ -1,27 +1,20 @@
1
- import { Buffer } from "node:buffer";
2
1
  import { SealedJsonRepository } from "../sealed/index.js";
3
2
  const VAULT_SEALED_PROFILE_KEY = "vault/sealed/profile.sealed";
4
3
  export const VAULT_PUBLIC_PROFILE_KEY = "vault/public/profile.json";
4
+ import { readVerifiableMetadata } from "./verifiable-metadata.js";
5
5
  /**
6
6
  * Reads only the public (plaintext) metadata of a vault. No key required.
7
7
  */
8
8
  export async function readVaultPublicMetadata(storage) {
9
- const publicRaw = await storage.read(VAULT_PUBLIC_PROFILE_KEY);
10
- return publicRaw ? JSON.parse(publicRaw.toString("utf8")) : {};
9
+ const data = await readVerifiableMetadata(storage, VAULT_PUBLIC_PROFILE_KEY).catch(() => null);
10
+ return data || {};
11
11
  }
12
12
  export async function writeVaultProfile(storage, profile, vaultWorkingKey) {
13
13
  // 1. Write Sealed Profile
14
14
  const repo = new SealedJsonRepository(storage, VAULT_SEALED_PROFILE_KEY, vaultWorkingKey);
15
15
  await repo.write(profile.sealed, "vault_profile_sealed");
16
- // 2. Write Public Profile
17
- if (profile.public && Object.keys(profile.public).length > 0) {
18
- await storage.write(VAULT_PUBLIC_PROFILE_KEY, Buffer.from(JSON.stringify(profile.public, null, 2), "utf8"));
19
- }
20
- else {
21
- if (await storage.has(VAULT_PUBLIC_PROFILE_KEY)) {
22
- await storage.delete(VAULT_PUBLIC_PROFILE_KEY);
23
- }
24
- }
16
+ // NOTE: Public profile writing is handled separately via writeVerifiableMetadata
17
+ // by the component that holds the owner's private key (e.g., bootstrap.ts).
25
18
  }
26
19
  export async function readVaultProfile(storage, vaultWorkingKey) {
27
20
  const repo = new SealedJsonRepository(storage, VAULT_SEALED_PROFILE_KEY, vaultWorkingKey);
@@ -29,8 +22,7 @@ export async function readVaultProfile(storage, vaultWorkingKey) {
29
22
  if (!sealed) {
30
23
  return null;
31
24
  }
32
- const publicRaw = await storage.read(VAULT_PUBLIC_PROFILE_KEY);
33
- const publicData = publicRaw ? JSON.parse(publicRaw.toString("utf8")) : {};
25
+ const publicData = await readVaultPublicMetadata(storage);
34
26
  return {
35
27
  sealed,
36
28
  public: publicData,
@@ -1 +1 @@
1
- {"version":3,"file":"vault-metadata.js","sourceRoot":"","sources":["../../src/runtime/vault-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAO1D,MAAM,wBAAwB,GAAG,6BAA6B,CAAC;AAC/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,2BAA2B,CAAC;AAEpE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAyB;IAEzB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC/D,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAyB,EACzB,OAAqB,EACrB,eAAuB;IAEvB,0BAA0B;IAC1B,MAAM,IAAI,GAAG,IAAI,oBAAoB,CAAsB,OAAO,EAAE,wBAAwB,EAAE,eAAe,CAAC,CAAC;IAC/G,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAEzD,0BAA0B;IAC1B,IAAI,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9G,CAAC;SAAM,CAAC;QACN,IAAI,MAAM,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC;YAChD,MAAM,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAyB,EACzB,eAAuB;IAEvB,MAAM,IAAI,GAAG,IAAI,oBAAoB,CAAsB,OAAO,EAAE,wBAAwB,EAAE,eAAe,CAAC,CAAC;IAC/G,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAW,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3E,OAAO;QACL,MAAM;QACN,MAAM,EAAE,UAAU;KACnB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"vault-metadata.js","sourceRoot":"","sources":["../../src/runtime/vault-metadata.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAO1D,MAAM,wBAAwB,GAAG,6BAA6B,CAAC;AAC/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,2BAA2B,CAAC;AAEpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAyB;IAEzB,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAsB,OAAO,EAAE,wBAAwB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACpH,OAAO,IAAI,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAyB,EACzB,OAAqB,EACrB,eAAuB;IAEvB,0BAA0B;IAC1B,MAAM,IAAI,GAAG,IAAI,oBAAoB,CAAsB,OAAO,EAAE,wBAAwB,EAAE,eAAe,CAAC,CAAC;IAC/G,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAEzD,iFAAiF;IACjF,4EAA4E;AAC9E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAyB,EACzB,eAAuB;IAEvB,MAAM,IAAI,GAAG,IAAI,oBAAoB,CAAsB,OAAO,EAAE,wBAAwB,EAAE,eAAe,CAAC,CAAC;IAC/G,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAW,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAE1D,OAAO;QACL,MAAM;QACN,MAAM,EAAE,UAAU;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { IStorageProvider } from "../storage/provider.js";
2
+ /**
3
+ * A verifiable envelope for public metadata.
4
+ * Proves that the data was signed by the rightful owner.
5
+ */
6
+ export interface VerifiableMetadata<T> {
7
+ payload: T;
8
+ signature: string;
9
+ signer: string;
10
+ }
11
+ /**
12
+ * Signs and writes a payload to storage as a verifiable metadata envelope.
13
+ */
14
+ export declare function writeVerifiableMetadata<T>(storage: IStorageProvider, path: string, payload: T, privateKey: string): Promise<void>;
15
+ /**
16
+ * Reads and optionally verifies a verifiable metadata envelope from storage.
17
+ */
18
+ export declare function readVerifiableMetadata<T>(storage: IStorageProvider, path: string, expectedSigner?: string): Promise<T | null>;
@@ -0,0 +1,41 @@
1
+ import { signPayload, verifySignature } from "../protocol/crypto.js";
2
+ /**
3
+ * Signs and writes a payload to storage as a verifiable metadata envelope.
4
+ */
5
+ export async function writeVerifiableMetadata(storage, path, payload, privateKey) {
6
+ const payloadStr = JSON.stringify(payload);
7
+ const signature = await signPayload(privateKey, payloadStr);
8
+ const signer = await import("../protocol/crypto.js").then(m => m.derivePublicKey(privateKey));
9
+ const envelope = {
10
+ payload,
11
+ signature,
12
+ signer,
13
+ };
14
+ await storage.write(path, Buffer.from(JSON.stringify(envelope, null, 2)));
15
+ }
16
+ /**
17
+ * Reads and optionally verifies a verifiable metadata envelope from storage.
18
+ */
19
+ export async function readVerifiableMetadata(storage, path, expectedSigner) {
20
+ const raw = await storage.read(path);
21
+ if (!raw)
22
+ return null;
23
+ try {
24
+ const envelope = JSON.parse(raw.toString());
25
+ // If expectedSigner is provided, we MUST verify
26
+ if (expectedSigner && envelope.signer !== expectedSigner) {
27
+ return null; // Signer mismatch
28
+ }
29
+ const payloadStr = JSON.stringify(envelope.payload);
30
+ const isValid = await verifySignature(envelope.signer, payloadStr, envelope.signature);
31
+ if (!isValid) {
32
+ console.warn(`[VerifiableMetadata] Invalid signature at ${path}`);
33
+ return null;
34
+ }
35
+ return envelope.payload;
36
+ }
37
+ catch (e) {
38
+ return null;
39
+ }
40
+ }
41
+ //# sourceMappingURL=verifiable-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifiable-metadata.js","sourceRoot":"","sources":["../../src/runtime/verifiable-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAarE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAyB,EACzB,IAAY,EACZ,OAAU,EACV,UAAkB;IAElB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9F,MAAM,QAAQ,GAA0B;QACtC,OAAO;QACP,SAAS;QACT,MAAM;KACP,CAAC;IAEF,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAyB,EACzB,IAAY,EACZ,cAAuB;IAEvB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAA0B,CAAC;QAErE,gDAAgD;QAChD,IAAI,cAAc,IAAI,QAAQ,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACzD,OAAO,IAAI,CAAC,CAAC,kBAAkB;QACjC,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QAEvF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC1B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -55,9 +55,10 @@ The vault is physically divided into two partitions to balance security and disc
55
55
  - **Auditing**: Every access is tracked and logged in the append-only audit trail.
56
56
 
57
57
  - **Public Area (`vault/public/`)**
58
- - **Security**: Plaintext JSON (`.json`).
59
- - **Access**: Identity is required for **writing** (authorized update), but **reading is open**.
60
- - **Auditing**: Reading from the public area is **untracked**, reducing audit noise for discovery / identity resolution.
58
+ - **Security**: Verifiable JSON Envelopes (`.json`).
59
+ - **Integrity**: Every public file is **digitally signed** by the vault owner's private key.
60
+ - **Access**: Reading is open and anonymous; however, the SDK automatically verifies signatures to prevent unauthorized tampering.
61
+ - **Auditing**: Anonymous reading is untracked to reduce noise. Writing requires proving identity through a valid signature.
61
62
 
62
63
  ## Core Rules
63
64
 
@@ -65,7 +66,7 @@ The vault is physically divided into two partitions to balance security and disc
65
66
  2. Only owner and trusted issuer paths may write secrets.
66
67
  3. Agent can only request dispatch through capability + proof.
67
68
  4. Vault validates and audits every dispatch.
68
- 5. Public data (e.g., nicknames, public keys) is explicitly mirrored to the Public Area for discovery.
69
+ 5. Public metadata (e.g., nicknames, discovery profile) is stored **exclusively** in the Public Area and is digitally signed.
69
70
  6. Identity-specific private data is stored in `identities/`, separate from named `vaults/`.
70
71
 
71
72
  ## Current HTTP Secret Flows
package/docs/REFERENCE.md CHANGED
@@ -40,7 +40,7 @@ Recommended persistent-vault entrypoints:
40
40
 
41
41
  `createVault(storage, { ownerIdentity, nickname, publicMetadata })` overrides the workspace storage explicitly.
42
42
 
43
- `recoverVault({ vaultId, ownerIdentity })` reopens a vault and returns the `nickname` from the sealed profile.
43
+ `recoverVault({ vaultId, ownerIdentity })` reopens a vault and returns metadata (including `nickname`) from the **public signed profile**.
44
44
 
45
45
  `recoverVault(storage, { vaultId, ownerIdentity })` overrides the workspace storage explicitly.
46
46
 
@@ -87,6 +87,8 @@ Role rules:
87
87
 
88
88
  Those files are encrypted at rest in the `sealed/` sub-directory and are not readable as plain JSON on disk.
89
89
 
90
+ Identities also maintain a **public discovery area** at `public/profile.json`. This file is readable without authentication but is **digitally signed** by the identity's private key to prevent anonymous tampering.
91
+
90
92
  `restoreIdentity(privateKey)` returns the same shape for an existing private key.
91
93
 
92
94
  `readIdentityPrivateVaultProfile(storage, identityOrPrivateKey)` decrypts and returns the current identity profile for the supplied identity or private key.
@@ -97,9 +99,9 @@ Those files are encrypted at rest in the `sealed/` sub-directory and are not rea
97
99
  If `privateKey` is provided, it returns the full sealed profile.
98
100
  If `privateKey` is missing, it returns the public discovery profile (nickname, publicKey, parentIdentityId).
99
101
 
100
- `listIdentities(storage)` returns all identity discovery profiles in the workspace.
102
+ `listIdentities(storage)` returns all identity discovery profiles. These profiles are automatically verified for signature integrity.
101
103
 
102
- `listVaults(storage)` returns all vault metadata summaries in the workspace.
104
+ `listVaults(storage)` returns all vault metadata summaries. These summaries are pulled from the public signed profiles and verified.
103
105
 
104
106
  Typical relationship lookup flow when you already have a private key:
105
107
 
@@ -360,6 +362,21 @@ If the custom flow mode includes secret acquisition, the owner also defines a re
360
362
  }
361
363
  ```
362
364
 
365
+ ## Verifiable Discovery (Signed Content)
366
+
367
+ The CBIO Node Runtime implements a **Public-Read, Owner-Write (Signed)** protection for discovery metadata.
368
+
369
+ - **Storage**: `vault/public/profile.json` and `identities/{id}/public/profile.json`.
370
+ - **Integrity**: These files are wrapped in a verifiable envelope:
371
+ ```json
372
+ {
373
+ "payload": { "nickname": "...", ... },
374
+ "signature": "...",
375
+ "signer": "publicKey"
376
+ }
377
+ ```
378
+ - **Verification**: The SDK automatically verifies signatures during `listVaults`, `listIdentities`, and retrieval. Corrupted or tampered files are ignored to prevent phishing or metadata poisoning.
379
+
363
380
  ## Persistent Dependencies
364
381
 
365
382
  `createPersistentVaultCoreDependencies(...)` builds a file-backed single-node profile under `vault/sealed/` with:
package/docs/es/README.md CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  readIdentityMetadata,
24
24
  createVault,
25
25
  listIdentities,
26
- + listVaults,
27
- recoverVault,
26
+ listVaults,
27
+ recoverVault,
28
28
  LocalVaultTransport,
29
29
  createVaultClient,
30
30
  createAgentClient,
@@ -44,6 +44,9 @@ Ruta principal recomendada para vault persistente:
44
44
  - crear el vault persistente con `createVault(...)` (soporta `publicMetadata` para el descubrimiento de información pública)
45
45
  - recuperar el vault persistente con `recoverVault(...)` usando la identidad del owner
46
46
  - Capas de almacenamiento divididas: `vaults/` (Bóvedas con nombre) e `identities/` (Espacio de identidad personal)
47
+ - **Descubrimiento Verificable (Verifiable Discovery)**:
48
+ - El área pública (`public/`) utiliza el modelo **“Lectura Anónima, Escritura del Propietario”**.
49
+ - Todos los metadatos públicos (como el apodo) incluyen una **firma digital**, la cual el SDK verifica automáticamente para prevenir manipulaciones anónimas.
47
50
 
48
51
  La API antigua centrada en `CbioIdentity` ya no es la superficie principal del producto.
49
52
 
package/docs/fr/README.md CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  readIdentityMetadata,
24
24
  createVault,
25
25
  listIdentities,
26
- + listVaults,
27
- recoverVault,
26
+ listVaults,
27
+ recoverVault,
28
28
  LocalVaultTransport,
29
29
  createVaultClient,
30
30
  createAgentClient,
package/docs/ja/README.md CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  readIdentityMetadata,
24
24
  createVault,
25
25
  listIdentities,
26
- + listVaults,
27
- recoverVault,
26
+ listVaults,
27
+ recoverVault,
28
28
  LocalVaultTransport,
29
29
  createVaultClient,
30
30
  createAgentClient,
@@ -44,6 +44,9 @@ import {
44
44
  - `createVault(...)` で persistent vault を作成する (`publicMetadata` による公開情報のディスカバリをサポート)
45
45
  - `recoverVault(...)` で owner identity を使って persistent vault を復旧する
46
46
  - 分離されたストレージ層: `vaults/` (具名 Vault) と `identities/` (個人 ID スペース)
47
+ - **検証可能なディスカバリ (Verifiable Discovery)**:
48
+ - 公開エリア (`public/`) は **「匿名読み取り、所有者書き込み」** モデルを採用しています。
49
+ - ニックネームなどのすべての公開メタデータには **電子署名** が付与されており、SDK がその正当性を自動的に検証することで、匿名による改ざんを防止します。
47
50
 
48
51
  旧 `CbioIdentity` 中心 API は、もはや主要な公開面ではありません。
49
52
 
package/docs/ko/README.md CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  readIdentityMetadata,
24
24
  createVault,
25
25
  listIdentities,
26
- + listVaults,
27
- recoverVault,
26
+ listVaults,
27
+ recoverVault,
28
28
  LocalVaultTransport,
29
29
  createVaultClient,
30
30
  createAgentClient,
@@ -44,6 +44,9 @@ import {
44
44
  - `createVault(...)` 로 persistent vault 를 생성합니다 (`publicMetadata` 를 통한 공개 정보 검색 지원)
45
45
  - `recoverVault(...)` 로 owner identity 를 사용해 persistent vault 를 복구합니다
46
46
  - 분리된 스토리지 계층: `vaults/` (기명 Vault) 및 `identities/` (개인 ID 공간)
47
+ - **검증 가능한 디스커버리 (Verifiable Discovery)**:
48
+ - 공개 영역 (`public/`)은 **"익명 읽기, 소유자 쓰기"** 모델을 채택하고 있습니다.
49
+ - 닉네임과 같은 모든 공개 메타데이터에는 **디지털 서명**이 포함되어 있으며, SDK가 그 정당성을 자동으로 검증하여 익명에 의한 변조를 방지합니다.
47
50
 
48
51
  이전 `CbioIdentity` 중심 API 는 더 이상 주요 제품 표면이 아닙니다.
49
52
 
package/docs/pt/README.md CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  readIdentityMetadata,
24
24
  createVault,
25
25
  listIdentities,
26
- + listVaults,
27
- recoverVault,
26
+ listVaults,
27
+ recoverVault,
28
28
  LocalVaultTransport,
29
29
  createVaultClient,
30
30
  createAgentClient,
@@ -44,6 +44,9 @@ Caminho principal recomendado para vault persistente:
44
44
  - criar o cofre persistente com `createVault(...)` (suporta `publicMetadata` para a descoberta de informações públicas)
45
45
  - recuperar o cofre persistente com `recoverVault(...)` usando a identidade do owner
46
46
  - Camadas de armazenamento divididas: `vaults/` (Cofres nomeados) e `identities/` (Espaço de identidade pessoal)
47
+ - **Descoberta Verificável (Verifiable Discovery)**:
48
+ - A área pública (`public/`) utiliza o modelo **“Leitura Anônima, Escrita do Proprietário”**.
49
+ - Todos os metadados públicos (como o apelido) incluem uma **assinatura digital**, que o SDK verifica automaticamente para evitar adulterações anônimas.
47
50
 
48
51
  A antiga API centrada em `CbioIdentity` nao e mais a superficie principal do produto.
49
52
 
package/docs/zh/README.md CHANGED
@@ -45,6 +45,9 @@ import {
45
45
  - 通过 `createVault(...)` 创建持久化 vault (支持 `publicMetadata` 用于公开发现)
46
46
  - 通过 `recoverVault(...)` 用 owner 身份恢复持久化 vault
47
47
  - 分区存储:`vaults/` (具名保险箱) 与 `identities/` (身份私有空间)
48
+ - **可验证发现 (Verifiable Discovery)**:
49
+ - 公开区 (`public/`) 采用 **“匿名读、所有者写”** 模式。
50
+ - 所有公开元数据(如昵称)均附带**数字签名**,SDK 会自动验证其真实性,防止匿名篡改。
48
51
 
49
52
  ## 构建
50
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@the-ai-company/cbio-node-runtime",
3
- "version": "1.25.0",
3
+ "version": "1.26.0",
4
4
  "description": "Node.js runtime for cbio identity and credential vault. Library only, no CLI or TUI.",
5
5
  "type": "module",
6
6
  "main": "./dist/runtime/index.js",