From 99f6912307db7a1243f0a3462d3e195502959bd5 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Fri, 2 Oct 2026 17:52:11 -0400 Subject: [PATCH 1/2] fix(server): Codex auth tokens are an omitted key, never undefined Signed-off-by: Yordis Prieto --- apps/server/src/telemetry/Identify.test.ts | 99 +++++++++++++--------- apps/server/src/telemetry/Identify.ts | 8 +- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/apps/server/src/telemetry/Identify.test.ts b/apps/server/src/telemetry/Identify.test.ts index a8c107b57389..c02e8cf93f86 100644 --- a/apps/server/src/telemetry/Identify.test.ts +++ b/apps/server/src/telemetry/Identify.test.ts @@ -57,48 +57,65 @@ it.layer(NodeServices.layer)("telemetry identity", (it) => { ), ); - it.effect("falls back quietly when Codex authenticates with an API key", () => { - const logs: CapturedLog[] = []; - const logger = makeCaptureLogger(logs); - - return Effect.gen(function* () { - const config = yield* ServerConfig.ServerConfig; - const fileSystem = yield* FileSystem.FileSystem; - const path = yield* Path.Path; - const homeDirectory = path.join(config.baseDir, "home"); - const codexAuthPath = path.join(homeDirectory, ".codex", "auth.json"); - const anonymousId = "api-key-fallback-anonymous-id"; - const privateApiKey = "sk-private-openai-api-key"; - - yield* fileSystem.makeDirectory(path.dirname(codexAuthPath), { recursive: true }); - yield* fileSystem.writeFileString( - codexAuthPath, - `{"auth_mode":"apikey","OPENAI_API_KEY":"${privateApiKey}"}`, - ); - yield* fileSystem.writeFileString(config.anonymousIdPath, anonymousId); - - const identifier = yield* Identify.getTelemetryIdentifierForHome(homeDirectory); - - assert.equal(identifier, sha256(anonymousId)); - assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityDecodeError")); - assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityReadError")); - const allLogs = logs - .map((log) => - [String(log.message), ...Object.values(log.annotations).map(String)].join("\n"), - ) - .join("\n"); - assert.notInclude(allLogs, privateApiKey); - }).pipe( - Effect.provide( - Layer.merge( - ServerConfig.layerTest(process.cwd(), { - prefix: "t3-telemetry-identify-apikey-", - }), - Logger.layer([logger], { mergeWithExisting: false }), + const codexLoginsWithoutTokens = [ + { + login: "an API key", + secret: "sk-private-openai-api-key", + authJson: (secret: string) => `{"auth_mode":"apikey","OPENAI_API_KEY":"${secret}"}`, + }, + { + login: "an agent identity", + secret: "private-agent-identity-jwt", + authJson: (secret: string) => + `{"auth_mode":"agentIdentity","OPENAI_API_KEY":null,"agent_identity":"${secret}"}`, + }, + { + login: "a personal access token", + secret: "private-personal-access-token", + authJson: (secret: string) => `{"OPENAI_API_KEY":null,"personal_access_token":"${secret}"}`, + }, + ]; + + for (const { login, secret, authJson } of codexLoginsWithoutTokens) { + it.effect(`falls back quietly when Codex authenticates with ${login}`, () => { + const logs: CapturedLog[] = []; + const logger = makeCaptureLogger(logs); + + return Effect.gen(function* () { + const config = yield* ServerConfig.ServerConfig; + const fileSystem = yield* FileSystem.FileSystem; + const path = yield* Path.Path; + const homeDirectory = path.join(config.baseDir, "home"); + const codexAuthPath = path.join(homeDirectory, ".codex", "auth.json"); + const anonymousId = "tokenless-codex-anonymous-id"; + + yield* fileSystem.makeDirectory(path.dirname(codexAuthPath), { recursive: true }); + yield* fileSystem.writeFileString(codexAuthPath, authJson(secret)); + yield* fileSystem.writeFileString(config.anonymousIdPath, anonymousId); + + const identifier = yield* Identify.getTelemetryIdentifierForHome(homeDirectory); + + assert.equal(identifier, sha256(anonymousId)); + assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityDecodeError")); + assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityReadError")); + const allLogs = logs + .map((log) => + [String(log.message), ...Object.values(log.annotations).map(String)].join("\n"), + ) + .join("\n"); + assert.notInclude(allLogs, secret); + }).pipe( + Effect.provide( + Layer.merge( + ServerConfig.layerTest(process.cwd(), { + prefix: "t3-telemetry-identify-tokenless-", + }), + Logger.layer([logger], { mergeWithExisting: false }), + ), ), - ), - ); - }); + ); + }); + } it.effect("logs structured decode context and falls back from malformed Codex auth", () => { const logs: CapturedLog[] = []; diff --git a/apps/server/src/telemetry/Identify.ts b/apps/server/src/telemetry/Identify.ts index 1a658a1b5043..b593ab224913 100644 --- a/apps/server/src/telemetry/Identify.ts +++ b/apps/server/src/telemetry/Identify.ts @@ -11,12 +11,12 @@ import * as Schema from "effect/Schema"; import * as ServerConfig from "../config.ts"; /** - * Codex omits `tokens` entirely when the install authenticates with an API key - * rather than a ChatGPT account, so an absent `tokens` is a supported install - * and not a malformed file. + * Codex writes `tokens` only for ChatGPT logins and omits the key for API-key, + * agent-identity, and personal-access-token logins, so its absence is a + * supported install and not a malformed file. */ const CodexAuthJsonSchema = Schema.Struct({ - tokens: Schema.optional( + tokens: Schema.optionalKey( Schema.Struct({ account_id: Schema.String, }), From 539b7ec73056c6ec3e8075a402abfbaf63a3b062 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Fri, 2 Oct 2026 18:44:17 -0400 Subject: [PATCH 2/2] test(server): table-drive tokenless Codex login cases Signed-off-by: Yordis Prieto --- apps/server/src/telemetry/Identify.test.ts | 80 ++++++++++------------ 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/apps/server/src/telemetry/Identify.test.ts b/apps/server/src/telemetry/Identify.test.ts index c02e8cf93f86..c4240be18345 100644 --- a/apps/server/src/telemetry/Identify.test.ts +++ b/apps/server/src/telemetry/Identify.test.ts @@ -57,7 +57,7 @@ it.layer(NodeServices.layer)("telemetry identity", (it) => { ), ); - const codexLoginsWithoutTokens = [ + it.effect.each([ { login: "an API key", secret: "sk-private-openai-api-key", @@ -74,48 +74,44 @@ it.layer(NodeServices.layer)("telemetry identity", (it) => { secret: "private-personal-access-token", authJson: (secret: string) => `{"OPENAI_API_KEY":null,"personal_access_token":"${secret}"}`, }, - ]; - - for (const { login, secret, authJson } of codexLoginsWithoutTokens) { - it.effect(`falls back quietly when Codex authenticates with ${login}`, () => { - const logs: CapturedLog[] = []; - const logger = makeCaptureLogger(logs); - - return Effect.gen(function* () { - const config = yield* ServerConfig.ServerConfig; - const fileSystem = yield* FileSystem.FileSystem; - const path = yield* Path.Path; - const homeDirectory = path.join(config.baseDir, "home"); - const codexAuthPath = path.join(homeDirectory, ".codex", "auth.json"); - const anonymousId = "tokenless-codex-anonymous-id"; - - yield* fileSystem.makeDirectory(path.dirname(codexAuthPath), { recursive: true }); - yield* fileSystem.writeFileString(codexAuthPath, authJson(secret)); - yield* fileSystem.writeFileString(config.anonymousIdPath, anonymousId); - - const identifier = yield* Identify.getTelemetryIdentifierForHome(homeDirectory); - - assert.equal(identifier, sha256(anonymousId)); - assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityDecodeError")); - assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityReadError")); - const allLogs = logs - .map((log) => - [String(log.message), ...Object.values(log.annotations).map(String)].join("\n"), - ) - .join("\n"); - assert.notInclude(allLogs, secret); - }).pipe( - Effect.provide( - Layer.merge( - ServerConfig.layerTest(process.cwd(), { - prefix: "t3-telemetry-identify-tokenless-", - }), - Logger.layer([logger], { mergeWithExisting: false }), - ), + ])("falls back quietly when Codex authenticates with $login", ({ secret, authJson }) => { + const logs: CapturedLog[] = []; + const logger = makeCaptureLogger(logs); + + return Effect.gen(function* () { + const config = yield* ServerConfig.ServerConfig; + const fileSystem = yield* FileSystem.FileSystem; + const path = yield* Path.Path; + const homeDirectory = path.join(config.baseDir, "home"); + const codexAuthPath = path.join(homeDirectory, ".codex", "auth.json"); + const anonymousId = "tokenless-codex-anonymous-id"; + + yield* fileSystem.makeDirectory(path.dirname(codexAuthPath), { recursive: true }); + yield* fileSystem.writeFileString(codexAuthPath, authJson(secret)); + yield* fileSystem.writeFileString(config.anonymousIdPath, anonymousId); + + const identifier = yield* Identify.getTelemetryIdentifierForHome(homeDirectory); + + assert.equal(identifier, sha256(anonymousId)); + assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityDecodeError")); + assert.isUndefined(findIdentityLog(logs, "codex", "TelemetryIdentityReadError")); + const allLogs = logs + .map((log) => + [String(log.message), ...Object.values(log.annotations).map(String)].join("\n"), + ) + .join("\n"); + assert.notInclude(allLogs, secret); + }).pipe( + Effect.provide( + Layer.merge( + ServerConfig.layerTest(process.cwd(), { + prefix: "t3-telemetry-identify-tokenless-", + }), + Logger.layer([logger], { mergeWithExisting: false }), ), - ); - }); - } + ), + ); + }); it.effect("logs structured decode context and falls back from malformed Codex auth", () => { const logs: CapturedLog[] = [];