Skip to main content

sync_auth/providers/
codex.rs

1//! OpenAI Codex CLI auth provider.
2
3use crate::{AuthProvider, CredentialFile, ValidationResult};
4use std::path::PathBuf;
5
6/// Provider for OpenAI Codex CLI credentials.
7///
8/// Codex CLI stores auth in `~/.codex/` (controlled by `CODEX_HOME` env var).
9/// Key files: `auth.json` (tokens), `config.toml` (settings).
10#[derive(Debug, Clone, Default)]
11pub struct CodexProvider;
12
13#[async_trait::async_trait]
14impl AuthProvider for CodexProvider {
15    fn name(&self) -> &str {
16        "codex"
17    }
18
19    fn display_name(&self) -> &str {
20        "OpenAI Codex CLI"
21    }
22
23    fn credential_files(&self) -> Vec<CredentialFile> {
24        let codex_home = std::env::var("CODEX_HOME").map_or_else(
25            |_| {
26                dirs::home_dir()
27                    .unwrap_or_else(|| PathBuf::from("~"))
28                    .join(".codex")
29            },
30            PathBuf::from,
31        );
32        vec![CredentialFile {
33            relative_path: "codex/dot-codex".to_string(),
34            local_path: codex_home,
35            is_dir: true,
36        }]
37    }
38
39    async fn validate(&self) -> ValidationResult {
40        let codex_home = std::env::var("CODEX_HOME").map_or_else(
41            |_| {
42                dirs::home_dir()
43                    .unwrap_or_else(|| PathBuf::from("~"))
44                    .join(".codex")
45            },
46            PathBuf::from,
47        );
48        if codex_home.join("auth.json").exists() {
49            ValidationResult::Valid
50        } else {
51            ValidationResult::Missing
52        }
53    }
54}