-
Notifications
You must be signed in to change notification settings - Fork 12
features provider authentication
Active contributors: Nik, Ran
DroidProxy uses your existing provider subscriptions instead of API keys. Auth tokens live as JSON files in ~/.cli-proxy-api/. Most providers authenticate through a browser OAuth flow driven by the bundled cli-proxy-api binary; Cursor is API-key based. Multiple accounts per provider are supported, with round-robin load balancing and per-account enable/disable.
| Provider | ServiceType |
Login flag | Auth mechanism |
|---|---|---|---|
| Claude Code | claude |
-claude-login |
Browser OAuth → token JSON |
| Codex | codex |
-codex-login |
Browser OAuth → token JSON |
| Antigravity | antigravity |
-antigravity-login |
Browser OAuth (requires Google Antigravity installed) → token JSON |
| Kimi | kimi |
-kimi-login |
Browser OAuth → token JSON |
| Cursor | cursor |
none | API key written to cursor.json (beta-gated) |
ServiceType(authFileType:) in src/Sources/AuthStatus.swift also maps the legacy gemini / gemini-cli type strings onto antigravity.
| Type | Role |
|---|---|
AuthCommand |
Enum (claudeLogin, codexLogin, antigravityLogin, kimiLogin) with a loginFlag computed property passed to cli-proxy-api. |
ServerManager.runAuthCommand |
Launches cli-proxy-api --config <bundled config> <loginFlag>, captures output, and posts authDirectoryChanged on clean exit. |
AuthManager |
Scans ~/.cli-proxy-api/, parses each JSON into AuthAccount, and publishes serviceAccounts keyed by ServiceType. |
AuthAccount |
One account: id (filename), email/login, type, expired, filePath, isDisabled. |
AuthDirectoryMonitor |
Debounced DispatchSource watcher on ~/.cli-proxy-api that fires onChange when files are written, deleted, or renamed. |
ServiceRow / AccountRowView
|
SwiftUI rows for a provider and its accounts, with Add Account, Enable/Disable, and Remove controls. |
sequenceDiagram
participant U as User
participant SV as SettingsView
participant SM as ServerManager
participant CLI as cli-proxy-api
participant B as Browser
participant FS as ~/.cli-proxy-api
participant M as AuthDirectoryMonitor
participant AM as AuthManager
U->>SV: Click Add Account
SV->>SV: connectService(serviceType)
SV->>SM: runAuthCommand(.claudeLogin / .codexLogin / ...)
SM->>CLI: launch with -<provider>-login
CLI->>B: open OAuth URL
U->>B: complete login
B->>CLI: redirect / callback
CLI->>FS: write token JSON
CLI-->>SM: exit 0
SM->>M: post authDirectoryChanged
FS-->>M: filesystem write event
M->>AM: onChange (debounced)
AM->>AM: checkAuthStatus()
AM-->>SV: publish serviceAccounts (UI refresh)
connectService short-circuits for Cursor: it shows an alert and calls saveCursorApiKey, which writes cursor.json (with type: "cursor", the key, and disabled: false) and sets 0o600 permissions. For Codex, runAuthCommand writes a newline to the process after ~12s so the login keeps waiting on its callback instead of blocking on the manual prompt.
Each provider may hold several account files. The backend config (src/Sources/Resources/config.yaml) sets routing.strategy: round-robin with session-affinity: true (TTL 2h), so a session pins to one upstream auth while new sessions spread across accounts. disable-cooling: true keeps a single transient failure from blacking out an auth.
-
AuthManager.toggleAccountDisabledflips thedisabledfield in the account's JSON, but refuses to disable the last enabled account for a provider. -
disconnectAccount(inSettingsView) stops the server, deletes the file viaAuthManager.deleteAccount, then restarts the server if it was running. - The
ServiceRow"connected accounts" summary shows "Round-robin w/ auto-failover" when more than one account is enabled, and expands to show per-account Enable/Disable and Remove controls.
Separate from per-account flags, the provider toggle calls ServerManager.setProviderEnabled, which writes oauth-excluded-models into ~/.cli-proxy-api/merged-config.yaml. CLIProxyAPI hot-reloads, so no restart is needed. See Server manager.
-
src/Sources/ServerManager.swiftownsrunAuthCommand, the provider-enable config writing, and the merged-config generation. -
src/Sources/AuthDirectoryMonitor.swiftis used by bothAppDelegateandSettingsViewto refresh on auth changes. -
src/Sources/OAuthUsageTracker.swiftreads Codex/Claude OAuth quota windows for the usage dashboard.
- Add a provider: extend
ServiceTypeandServiceType(authFileType:)insrc/Sources/AuthStatus.swift, add a case +loginFlagtoAuthCommandinsrc/Sources/ServerManager.swift, map it inoauthProviderKeys, and wire aproviderServiceRowinsrc/Sources/SettingsView.swift. - Change the auth directory: edit
src/Sources/AuthPaths.swift(single source of truth). - Adjust login timing/quirks: see
runAuthCommandinsrc/Sources/ServerManager.swift.
| File | Role |
|---|---|
src/Sources/ServerManager.swift |
runAuthCommand, AuthCommand, provider enable/disable, merged config. |
src/Sources/AuthStatus.swift |
ServiceType, AuthAccount, AuthManager scanning and account mutations. |
src/Sources/SettingsView.swift |
connectService, saveCursorApiKey, successMessage, ServiceRow, AccountRowView. |
src/Sources/AuthDirectoryMonitor.swift |
Debounced filesystem watcher on ~/.cli-proxy-api. |
src/Sources/AuthPaths.swift |
Auth directory location. |