Follow Gemini native authentication inference

Recognize native gateway and cloud overrides and infer the selected auth mode from the same environment priorities as the CLI.

Checks: 129 environment and readiness tests; desktop packaging; git diff --check.
This commit is contained in:
Ryder Sun committed 2026-11-07 20:13:46 +08:00
1 parent 96aebb1d6c
commit ac78959842
3 files changed
+25 -2

No files matched your search

@@ -103,7 +103,7 @@ const RUNTIME_ENV_KEYS = Object.freeze({
'GEMINI_CLI_TRUSTED_FOLDERS_PATH'],
gemini: [
'GEMINI_API_KEY', 'GOOGLE_API_KEY', 'GEMINI_MODEL', 'GEMINI_CLI_HOME',
'GEMINI_DEFAULT_AUTH_TYPE', 'GEMINI_CLI_AUTH_OVERRIDE', 'GEMINI_CLI_USE_COMPUTE_ADC',
'GEMINI_DEFAULT_AUTH_TYPE', 'GEMINI_CLI_AUTH_OVERRIDE', 'GEMINI_CLI_USE_COMPUTE_ADC', 'CLOUD_SHELL',
'GEMINI_CLI_SYSTEM_SETTINGS_PATH', 'GEMINI_CLI_SYSTEM_DEFAULTS_PATH',
'GEMINI_CLI_TRUSTED_FOLDERS_PATH', 'GEMINI_CLI_TRUST_WORKSPACE', 'GEMINI_RESTRICTED_MODE',
'GOOGLE_GEMINI_BASE_URL', 'GOOGLE_VERTEX_BASE_URL', 'GOOGLE_GENAI_API_VERSION',
@@ -30,7 +30,7 @@ function geminiNativeAuth(options = {}) {
try {
const layers = [readSettings(defaults), readSettings(path.join(root, 'settings.json'))]
const systemSettings = readSettings(system)
const validOverrides = ['oauth-personal', 'gemini-api-key', 'vertex-ai', 'compute-default-credentials']
const validOverrides = ['oauth-personal', 'gemini-api-key', 'vertex-ai', 'cloud-shell', 'compute-default-credentials', 'gateway']
const override = validOverrides.includes(env.GEMINI_CLI_AUTH_OVERRIDE) ? env.GEMINI_CLI_AUTH_OVERRIDE : ''
let authType = override || (layers[1].security?.auth?.selectedType ?? layers[0].security?.auth?.selectedType ?? '')
const workdir = typeof options.workdir === 'string' && path.isAbsolute(options.workdir) ? options.workdir : ''
@@ -63,6 +63,13 @@ function geminiNativeAuth(options = {}) {
if (trusted) authType = readSettings(path.join(workdir, '.gemini', 'settings.json')).security?.auth?.selectedType ?? authType
}
authType = systemSettings.security?.auth?.selectedType ?? authType
if (!authType) {
if (env.GOOGLE_GENAI_USE_GCA === 'true') authType = 'oauth-personal'
else if (env.GOOGLE_GENAI_USE_VERTEXAI === 'true') authType = 'vertex-ai'
else if (env.GOOGLE_GEMINI_BASE_URL) authType = 'gateway'
else if (env.GEMINI_API_KEY) authType = 'gemini-api-key'
else if (env.CLOUD_SHELL === 'true' || env.GEMINI_CLI_USE_COMPUTE_ADC === 'true') authType = 'compute-default-credentials'
}
return { authType: typeof authType === 'string' ? authType : '', root }
} catch { return { uncertain: true } }
}
@@ -46,3 +46,19 @@ test('Gemini readiness checks credentials for its selected auth mode', t => {
delete env.GEMINI_API_KEY
assert.deepEqual(nativeCredentialState('gemini', { home, env }), { state: 'unknown', source: 'unverified' })
})
test('Gemini auth inference and overrides follow native CLI precedence', t => {
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-gemini-inferred-'))
t.after(() => fs.rmSync(home, { recursive: true, force: true }))
const env = { GEMINI_CLI_SYSTEM_SETTINGS_PATH: path.join(home, 'missing.json'), GEMINI_API_KEY: 'unrelated' }
assert.equal(geminiNativeAuth({ home, env }).authType, 'gemini-api-key')
assert.equal(geminiNativeAuth({ home, env: { GEMINI_CLI_SYSTEM_SETTINGS_PATH: env.GEMINI_CLI_SYSTEM_SETTINGS_PATH,
CLOUD_SHELL: 'true' } }).authType, 'compute-default-credentials')
for (const [extra, expected] of [[{ GOOGLE_GENAI_USE_GCA: 'true' }, 'oauth-personal'],
[{ GOOGLE_GENAI_USE_VERTEXAI: 'true' }, 'vertex-ai'], [{ GOOGLE_GEMINI_BASE_URL: 'https://example.test' }, 'gateway'],
[{ GEMINI_CLI_AUTH_OVERRIDE: 'cloud-shell' }, 'cloud-shell'], [{ GEMINI_CLI_AUTH_OVERRIDE: 'gateway' }, 'gateway']]) {
const selected = { ...env, ...extra }
assert.equal(geminiNativeAuth({ home, env: selected }).authType, expected)
assert.deepEqual(nativeCredentialState('gemini', { home, env: selected }), { state: 'unknown', source: 'unverified' })
}
})