From 161ba76f6576448635c99a4034325970d99990f2 Mon Sep 17 00:00:00 2001 From: galz10 Date: Tue, 24 Feb 2026 13:33:06 -0800 Subject: [PATCH] fix(core): remove filesystem binding for secret storage stability Removes Inode and Birthtime from the Master Key derivation shards. These identifiers were too volatile for atomic write operations (which change inodes) and did not survive extension re-installs or file moves. Master Key security remains extremely high, relying on: - OS Keychain Shard (Tier 1) - Physical Shard (~/.gemini_id) (Tier 2) - Deep Hardware Binding (Motherboard, Disk, MAC) (Tier 3) - Cryptographic Pepper (Tier 4) --- .../mcp/token-storage/file-secret-storage.test.ts | 8 ++++---- .../src/mcp/token-storage/file-secret-storage.ts | 14 ++------------ 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/packages/core/src/mcp/token-storage/file-secret-storage.test.ts b/packages/core/src/mcp/token-storage/file-secret-storage.test.ts index 4abf18b79c..fd0f98df38 100644 --- a/packages/core/src/mcp/token-storage/file-secret-storage.test.ts +++ b/packages/core/src/mcp/token-storage/file-secret-storage.test.ts @@ -21,10 +21,10 @@ vi.mock('node:fs', () => { mkdir: vi.fn(), rename: vi.fn(), }, - statsSync: vi.fn((_p: string) => ({ - ino: 12345, - birthtimeMs: 67890, - })), + statSync: vi.fn(() => ({ + ino: 12345, + birthtimeMs: 67890, + })), }; }); diff --git a/packages/core/src/mcp/token-storage/file-secret-storage.ts b/packages/core/src/mcp/token-storage/file-secret-storage.ts index 09be6c6edb..0ab1a69ba4 100644 --- a/packages/core/src/mcp/token-storage/file-secret-storage.ts +++ b/packages/core/src/mcp/token-storage/file-secret-storage.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { promises as fs, statSync } from 'node:fs'; +import { promises as fs } from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; import * as crypto from 'node:crypto'; @@ -193,16 +193,6 @@ export class FileSecretStorage implements SecretStorage { const userSecret = process.env['GEMINI_MASTER_KEY'] || ''; - let fsBinding = ''; - if (version === 'v2') { - try { - const stats = statSync(this.secretFilePath); - fsBinding = `${stats.ino}-${stats.birthtimeMs}`; - } catch { - // File doesn't exist yet - } - } - let systemSecret = ''; if (version === 'v2') { systemSecret = (await this.getPersistentSystemSecret()) || ''; @@ -217,7 +207,7 @@ export class FileSecretStorage implements SecretStorage { const password = version === 'v2' - ? `${FileSecretStorage.PEPPER}-v2-${this.serviceName}-${machineIdentifier}-${fsBinding}-${systemSecret}-${installationId}-${userSecret}` + ? `${FileSecretStorage.PEPPER}-v3-${this.serviceName}-${machineIdentifier}-${systemSecret}-${installationId}-${userSecret}` : `gemini-cli-secret-v1-${this.serviceName}-${userSecret}`; let salt: Buffer;