Skip to content

Per-project API key management — system env leak across projects #305

@yodakrkids

Description

@yodakrkids

Summary

GEMINI_API_KEY / ANTHROPIC_API_KEY / OPENAI_API_KEY 등 SDK API key 가 process env 만 참조하는 구조. 시스템 (Windows User scope, macOS launchctl, Linux ~/.profile 등) 에 한 번 박히면 모든 tunaFlow 프로젝트 + 다른 앱에 공유됨. 프로젝트별 다른 키를 쓸 수 없고, 다른 프로젝트에서 박힌 키가 tunaFlow 동작에 영향.

Repro (실 사례)

  1. 사용자가 과거 다른 프로젝트 작업 중 setx GEMINI_API_KEY ... 로 User scope 에 영구 저장 (본인도 정확한 시점 기억 못함)
  2. 이후 tunaFlow 실행 시 gemini_sdk::is_available() 가 true → SDK 경로로 라우팅
  3. RT 에서 gemini 참가자 호출 → Google API key 의 prepay credits 초과 → 429 RESOURCE_EXHAUSTED
  4. 키 회수하려면 시스템 env 자체를 제거해야 → 다른 앱들도 영향

Existing infrastructure

commands/secrets.rs 에 OS keychain 백엔드 이미 존재:

  • Windows Credential Vault / macOS Keychain / Linux Secret Service
  • Service prefix com.tunaflow.<key>, Account "default" 하드코딩
  • 주석에 명시: "If per-project secrets become a need, caller can namespace the key itself (e.g. anthropic_api_key:project_foo)"

그러나 SDK 코드는 이 store 를 안 씀 — 모두 std::env::var() 만 참조.

Proposed: 3-tier resolution

우선순위 순:

  1. Project-scoped keychainget_secret(format!("{key}:{project_key}"))
  2. Global tunaFlow keychainget_secret(key)
  3. Process env (현 동작 유지, 호환성)

env 가 없어도 keychain 에서 발견되면 동작. 시스템 env 가 박혀 있어도 project-scoped 가 우선이라 override 가능.

Affected SDK paths

파일 env var
gemini_sdk.rs:17, 30 GEMINI_API_KEY
anthropic_sdk.rs:22, 35 ANTHROPIC_API_KEY
openai_sdk.rs:17, 30 OPENAI_API_KEY
openai_compat.rs:125, 203-204, 288-289 VLLM_API_KEY, LMSTUDIO_API_KEY
agent_detect.rs:280 VLLM_API_KEY (probe)

Settings UI

Settings → Agents 또는 신규 Settings → Secrets 섹션에 project-scoped + global API key 입력란 (마스킹 + 토글 표시). 입력값은 keychain 저장.

Out of scope

  • env var 지원 제거 (CI / 헤드리스 환경에서 유효)
  • Multi-account 지원 (Account "default" 하드코딩 유지 가능)
  • .env 파일 자동 로딩 (별도 논의)

Related

본 이슈 발견 경위: PR #305 (또는 fix branch fix/gemini-sdk-auto-model) 작업 중 — SDK 의 model="auto" 가 그대로 models/auto:streamGenerateContent URL 로 전달되어 404 가 났고, 그걸 추적하던 중 env-only 라우팅이 본 issue 의 원인임을 확인.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions