mirror of
https://github.com/openai/codex.git
synced 2026-10-21 17:48:44 +00:00
Enforce managed auth across bootstrap and app-server
This commit is contained in:
@@ -372,6 +372,7 @@ pub async fn start(args: InProcessStartArgs) -> IoResult<InProcessClientHandle>
|
||||
}
|
||||
|
||||
async fn start_uninitialized(args: InProcessStartArgs) -> IoResult<InProcessClientHandle> {
|
||||
crate::enforce_auth_restrictions(&args.config).await;
|
||||
let channel_capacity = args.channel_capacity.max(1);
|
||||
let installation_id = resolve_installation_id(&args.config.codex_home).await?;
|
||||
let (client_tx, mut client_rx) = mpsc::channel::<InProcessClientMessage>(channel_capacity);
|
||||
|
||||
@@ -739,6 +739,7 @@ pub async fn run_main_with_transport_options(
|
||||
}
|
||||
drop(unix_socket_startup_lock);
|
||||
|
||||
enforce_auth_restrictions(&config).await;
|
||||
let auth_manager =
|
||||
AuthManager::shared_from_config(&config, /*enable_codex_api_key_env*/ false).await;
|
||||
|
||||
@@ -1171,6 +1172,12 @@ pub async fn run_main_with_transport_options(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn enforce_auth_restrictions(config: &Config) {
|
||||
if let Err(err) = codex_login::enforce_login_restrictions(&config.auth_config()).await {
|
||||
tracing::warn!("applied auth restrictions after logging out: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
struct SqliteRecoveryNotice {
|
||||
details: String,
|
||||
}
|
||||
|
||||
@@ -509,6 +509,7 @@ impl MessageProcessor {
|
||||
outgoing.clone(),
|
||||
config_manager.clone(),
|
||||
thread_manager.clone(),
|
||||
account_processor.clone(),
|
||||
analytics_events_client,
|
||||
);
|
||||
let external_agent_config_processor = ExternalAgentConfigRequestProcessor::new(
|
||||
|
||||
@@ -365,6 +365,7 @@ use codex_login::ServerOptions as LoginServerOptions;
|
||||
use codex_login::ShutdownHandle;
|
||||
use codex_login::auth::login_with_chatgpt_auth_tokens;
|
||||
use codex_login::complete_device_code_login;
|
||||
use codex_login::enforce_login_restrictions;
|
||||
use codex_login::login_with_api_key;
|
||||
use codex_login::oauth_client_id;
|
||||
use codex_login::request_device_code;
|
||||
|
||||
@@ -84,6 +84,21 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
async fn load_latest_config(&self) -> Result<Config, JSONRPCErrorError> {
|
||||
self.config_manager
|
||||
.load_latest_config(/*fallback_cwd*/ None)
|
||||
.await
|
||||
.map_err(|err| internal_error(format!("failed to reload auth configuration: {err}")))
|
||||
}
|
||||
|
||||
pub(crate) async fn refresh_auth_restrictions(&self, config: &Config) -> std::io::Result<()> {
|
||||
let result = enforce_login_restrictions(&config.auth_config()).await;
|
||||
self.auth_manager
|
||||
.set_forced_chatgpt_workspace_id(config.forced_chatgpt_workspace_id.clone());
|
||||
self.auth_manager.reload().await;
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) async fn login_account(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
@@ -270,14 +285,12 @@ impl AccountRequestProcessor {
|
||||
&self,
|
||||
params: &LoginApiKeyParams,
|
||||
) -> std::result::Result<(), JSONRPCErrorError> {
|
||||
let config = self.load_latest_config().await?;
|
||||
if self.auth_manager.is_external_chatgpt_auth_active() {
|
||||
return Err(self.external_auth_active_error());
|
||||
}
|
||||
|
||||
if matches!(
|
||||
self.config.forced_login_method,
|
||||
Some(ForcedLoginMethod::Chatgpt)
|
||||
) {
|
||||
if matches!(config.forced_login_method, Some(ForcedLoginMethod::Chatgpt)) {
|
||||
return Err(invalid_request(
|
||||
"API key login is disabled. Use ChatGPT login instead.",
|
||||
));
|
||||
@@ -292,10 +305,10 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
|
||||
match login_with_api_key(
|
||||
&self.config.codex_home,
|
||||
&config.codex_home,
|
||||
¶ms.api_key,
|
||||
self.config.cli_auth_credentials_store_mode,
|
||||
self.config.auth_keyring_backend_kind(),
|
||||
config.cli_auth_credentials_store_mode,
|
||||
config.auth_keyring_backend_kind(),
|
||||
) {
|
||||
Ok(()) => {
|
||||
self.auth_manager.reload().await;
|
||||
@@ -323,8 +336,8 @@ impl AccountRequestProcessor {
|
||||
async fn login_chatgpt_common(
|
||||
&self,
|
||||
codex_streamlined_login: bool,
|
||||
) -> std::result::Result<LoginServerOptions, JSONRPCErrorError> {
|
||||
let config = self.config.as_ref();
|
||||
) -> std::result::Result<(LoginServerOptions, String), JSONRPCErrorError> {
|
||||
let config = self.load_latest_config().await?;
|
||||
|
||||
if self.auth_manager.is_external_chatgpt_auth_active() {
|
||||
return Err(self.external_auth_active_error());
|
||||
@@ -358,7 +371,7 @@ impl AccountRequestProcessor {
|
||||
opts
|
||||
};
|
||||
|
||||
Ok(opts)
|
||||
Ok((opts, config.chatgpt_base_url.clone()))
|
||||
}
|
||||
|
||||
fn login_chatgpt_device_code_start_error(err: IoError) -> JSONRPCErrorError {
|
||||
@@ -383,7 +396,7 @@ impl AccountRequestProcessor {
|
||||
&self,
|
||||
codex_streamlined_login: bool,
|
||||
) -> Result<LoginAccountResponse, JSONRPCErrorError> {
|
||||
let opts = self.login_chatgpt_common(codex_streamlined_login).await?;
|
||||
let (opts, chatgpt_base_url) = self.login_chatgpt_common(codex_streamlined_login).await?;
|
||||
let server = run_login_server(opts)
|
||||
.map_err(|err| internal_error(format!("failed to start login server: {err}")))?;
|
||||
let login_id = Uuid::new_v4();
|
||||
@@ -404,7 +417,6 @@ impl AccountRequestProcessor {
|
||||
let outgoing_clone = self.outgoing.clone();
|
||||
let config_manager = self.config_manager.clone();
|
||||
let thread_manager = Arc::clone(&self.thread_manager);
|
||||
let chatgpt_base_url = self.config.chatgpt_base_url.clone();
|
||||
let active_login = self.active_login.clone();
|
||||
let auth_url = server.auth_url.clone();
|
||||
tokio::spawn(async move {
|
||||
@@ -454,7 +466,7 @@ impl AccountRequestProcessor {
|
||||
async fn login_chatgpt_device_code_response(
|
||||
&self,
|
||||
) -> Result<LoginAccountResponse, JSONRPCErrorError> {
|
||||
let opts = self
|
||||
let (opts, chatgpt_base_url) = self
|
||||
.login_chatgpt_common(/*codex_streamlined_login*/ false)
|
||||
.await?;
|
||||
let device_code = request_device_code(&opts)
|
||||
@@ -480,7 +492,6 @@ impl AccountRequestProcessor {
|
||||
let outgoing_clone = self.outgoing.clone();
|
||||
let config_manager = self.config_manager.clone();
|
||||
let thread_manager = Arc::clone(&self.thread_manager);
|
||||
let chatgpt_base_url = self.config.chatgpt_base_url.clone();
|
||||
let active_login = self.active_login.clone();
|
||||
tokio::spawn(async move {
|
||||
let (success, error_msg) = tokio::select! {
|
||||
@@ -573,10 +584,8 @@ impl AccountRequestProcessor {
|
||||
chatgpt_account_id: String,
|
||||
chatgpt_plan_type: Option<String>,
|
||||
) -> Result<LoginAccountResponse, JSONRPCErrorError> {
|
||||
if matches!(
|
||||
self.config.forced_login_method,
|
||||
Some(ForcedLoginMethod::Api)
|
||||
) {
|
||||
let config = self.load_latest_config().await?;
|
||||
if matches!(config.forced_login_method, Some(ForcedLoginMethod::Api)) {
|
||||
return Err(invalid_request(
|
||||
"External ChatGPT auth is disabled. Use API key login instead.",
|
||||
));
|
||||
@@ -590,7 +599,7 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(expected_workspaces) = self.config.forced_chatgpt_workspace_id.as_deref()
|
||||
if let Some(expected_workspaces) = config.forced_chatgpt_workspace_id.as_deref()
|
||||
&& !expected_workspaces.contains(&chatgpt_account_id)
|
||||
{
|
||||
return Err(invalid_request(format!(
|
||||
@@ -599,7 +608,7 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
|
||||
login_with_chatgpt_auth_tokens(
|
||||
&self.config.codex_home,
|
||||
&config.codex_home,
|
||||
&access_token,
|
||||
&chatgpt_account_id,
|
||||
chatgpt_plan_type.as_deref(),
|
||||
@@ -608,7 +617,7 @@ impl AccountRequestProcessor {
|
||||
self.auth_manager.reload().await;
|
||||
self.config_manager.replace_cloud_config_bundle_loader(
|
||||
self.auth_manager.clone(),
|
||||
self.config.chatgpt_base_url.clone(),
|
||||
config.chatgpt_base_url.clone(),
|
||||
);
|
||||
self.config_manager
|
||||
.sync_default_client_residency_requirement()
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::error_code::internal_error;
|
||||
use crate::error_code::invalid_request;
|
||||
use crate::outgoing_message::ConnectionRequestId;
|
||||
use crate::outgoing_message::OutgoingMessageSender;
|
||||
use crate::request_processors::AccountRequestProcessor;
|
||||
use codex_analytics::AnalyticsEventsClient;
|
||||
use codex_app_server_protocol::ClientResponsePayload;
|
||||
use codex_app_server_protocol::ComputerUseRequirements;
|
||||
@@ -59,6 +60,7 @@ pub(crate) struct ConfigRequestProcessor {
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
config_manager: ConfigManager,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
account_processor: AccountRequestProcessor,
|
||||
analytics_events_client: AnalyticsEventsClient,
|
||||
}
|
||||
|
||||
@@ -67,12 +69,14 @@ impl ConfigRequestProcessor {
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
config_manager: ConfigManager,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
account_processor: AccountRequestProcessor,
|
||||
analytics_events_client: AnalyticsEventsClient,
|
||||
) -> Self {
|
||||
Self {
|
||||
outgoing,
|
||||
config_manager,
|
||||
thread_manager,
|
||||
account_processor,
|
||||
analytics_events_client,
|
||||
}
|
||||
}
|
||||
@@ -282,6 +286,13 @@ impl ConfigRequestProcessor {
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Err(err) = self
|
||||
.account_processor
|
||||
.refresh_auth_restrictions(&next_config)
|
||||
.await
|
||||
{
|
||||
tracing::warn!("applied updated auth restrictions after logging out: {err}");
|
||||
}
|
||||
let thread_ids = self.thread_manager.list_thread_ids().await;
|
||||
for thread_id in thread_ids {
|
||||
let Ok(thread) = self.thread_manager.get_thread(thread_id).await else {
|
||||
|
||||
@@ -17,6 +17,9 @@ use codex_app_server_protocol::CancelLoginAccountResponse;
|
||||
use codex_app_server_protocol::CancelLoginAccountStatus;
|
||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshReason;
|
||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshResponse;
|
||||
use codex_app_server_protocol::ConfigBatchWriteParams;
|
||||
use codex_app_server_protocol::ConfigEdit;
|
||||
use codex_app_server_protocol::ConfigWriteResponse;
|
||||
use codex_app_server_protocol::GetAccountParams;
|
||||
use codex_app_server_protocol::GetAccountResponse;
|
||||
use codex_app_server_protocol::GetAuthStatusParams;
|
||||
@@ -27,11 +30,13 @@ use codex_app_server_protocol::JSONRPCNotification;
|
||||
use codex_app_server_protocol::JSONRPCResponse;
|
||||
use codex_app_server_protocol::LoginAccountResponse;
|
||||
use codex_app_server_protocol::LogoutAccountResponse;
|
||||
use codex_app_server_protocol::MergeStrategy;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::ServerRequest;
|
||||
use codex_app_server_protocol::TurnCompletedNotification;
|
||||
use codex_app_server_protocol::TurnStatus;
|
||||
use codex_app_server_protocol::WriteStatus;
|
||||
use codex_config::types::AuthCredentialsStoreMode;
|
||||
use codex_login::AuthKeyringBackendKind;
|
||||
use codex_login::CLIENT_ID_OVERRIDE_ENV_VAR;
|
||||
@@ -251,6 +256,97 @@ async fn logout_account_removes_auth_and_notifies() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn startup_removes_disallowed_stored_auth() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(
|
||||
codex_home.path(),
|
||||
CreateConfigTomlParams {
|
||||
forced_method: Some("chatgpt".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
login_with_api_key(
|
||||
codex_home.path(),
|
||||
"sk-test-key",
|
||||
AuthCredentialsStoreMode::File,
|
||||
AuthKeyringBackendKind::default(),
|
||||
)?;
|
||||
|
||||
let mut mcp =
|
||||
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
assert!(!codex_home.path().join("auth.json").exists());
|
||||
|
||||
let request_id = mcp
|
||||
.send_get_account_request(GetAccountParams {
|
||||
refresh_token: false,
|
||||
})
|
||||
.await?;
|
||||
let response = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(request_id)),
|
||||
)
|
||||
.await??;
|
||||
let response: GetAccountResponse = to_response(response)?;
|
||||
assert_eq!(response.account, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn config_reload_removes_newly_disallowed_auth() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(codex_home.path(), CreateConfigTomlParams::default())?;
|
||||
login_with_api_key(
|
||||
codex_home.path(),
|
||||
"sk-test-key",
|
||||
AuthCredentialsStoreMode::File,
|
||||
AuthKeyringBackendKind::default(),
|
||||
)?;
|
||||
|
||||
let mut mcp =
|
||||
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let request_id = mcp
|
||||
.send_config_batch_write_request(ConfigBatchWriteParams {
|
||||
file_path: None,
|
||||
edits: vec![ConfigEdit {
|
||||
key_path: "forced_login_method".to_string(),
|
||||
value: json!("chatgpt"),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
}],
|
||||
expected_version: None,
|
||||
reload_user_config: true,
|
||||
})
|
||||
.await?;
|
||||
let response = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(request_id)),
|
||||
)
|
||||
.await??;
|
||||
let response: ConfigWriteResponse = to_response(response)?;
|
||||
assert_eq!(response.status, WriteStatus::Ok);
|
||||
assert!(!codex_home.path().join("auth.json").exists());
|
||||
|
||||
let request_id = mcp
|
||||
.send_get_account_request(GetAccountParams {
|
||||
refresh_token: false,
|
||||
})
|
||||
.await?;
|
||||
let response = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(request_id)),
|
||||
)
|
||||
.await??;
|
||||
let response: GetAccountResponse = to_response(response)?;
|
||||
assert_eq!(response.account, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn set_auth_token_updates_account_and_notifies() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
use super::Config;
|
||||
use super::ConfigTomlLoadResult;
|
||||
use super::ManagedFeatures;
|
||||
use codex_config::config_toml::ForcedChatgptWorkspaceIds;
|
||||
use codex_config::types::AuthKeyringBackendKind;
|
||||
use codex_features::Feature;
|
||||
use codex_features::FeatureConfigSource;
|
||||
use codex_features::FeatureOverrides;
|
||||
use codex_features::Features;
|
||||
use codex_login::AuthConfig;
|
||||
use std::path::Path;
|
||||
|
||||
impl Config {
|
||||
pub fn auth_keyring_backend_kind(&self) -> AuthKeyringBackendKind {
|
||||
@@ -13,6 +16,35 @@ impl Config {
|
||||
self.features.enabled(Feature::SecretAuthStorage),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn auth_config(&self) -> AuthConfig {
|
||||
AuthConfig {
|
||||
codex_home: self.codex_home.to_path_buf(),
|
||||
auth_credentials_store_mode: self.cli_auth_credentials_store_mode,
|
||||
keyring_backend_kind: self.auth_keyring_backend_kind(),
|
||||
forced_login_method: self.forced_login_method,
|
||||
chatgpt_base_url: Some(self.chatgpt_base_url.clone()),
|
||||
forced_chatgpt_workspace_id: self.forced_chatgpt_workspace_id.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bootstrap_auth_config(
|
||||
codex_home: &Path,
|
||||
bootstrap_config: &ConfigTomlLoadResult,
|
||||
) -> std::io::Result<AuthConfig> {
|
||||
let config = &bootstrap_config.config_toml;
|
||||
Ok(AuthConfig {
|
||||
codex_home: codex_home.to_path_buf(),
|
||||
auth_credentials_store_mode: config.cli_auth_credentials_store.unwrap_or_default(),
|
||||
keyring_backend_kind: resolve_bootstrap_auth_keyring_backend_kind(bootstrap_config)?,
|
||||
forced_login_method: config.forced_login_method,
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
forced_chatgpt_workspace_id: config
|
||||
.forced_chatgpt_workspace_id
|
||||
.clone()
|
||||
.map(ForcedChatgptWorkspaceIds::into_vec),
|
||||
})
|
||||
}
|
||||
|
||||
/// Resolve the auth keyring backend from a partially loaded bootstrap config.
|
||||
|
||||
@@ -11001,6 +11001,13 @@ chatgpt_base_url = "https://user.example/backend-api"
|
||||
cli_auth_credentials_store = "keyring"
|
||||
chatgpt_base_url = "https://managed.example/backend-api"
|
||||
|
||||
[allowed_login_methods]
|
||||
chatgpt = true
|
||||
api = false
|
||||
|
||||
[allowed_chatgpt_workspaces]
|
||||
"123e4567-e89b-42d3-a456-426614174000" = true
|
||||
|
||||
[features]
|
||||
secret_auth_storage = true
|
||||
"#,
|
||||
@@ -11024,11 +11031,18 @@ secret_auth_storage = true
|
||||
(
|
||||
bootstrap_config.config_toml.cli_auth_credentials_store,
|
||||
bootstrap_config.config_toml.chatgpt_base_url,
|
||||
bootstrap_config.config_toml.forced_login_method,
|
||||
bootstrap_config
|
||||
.config_toml
|
||||
.forced_chatgpt_workspace_id
|
||||
.map(codex_config::config_toml::ForcedChatgptWorkspaceIds::into_vec),
|
||||
auth_keyring_backend_kind,
|
||||
),
|
||||
(
|
||||
Some(AuthCredentialsStoreMode::Keyring),
|
||||
Some("https://managed.example/backend-api".to_string()),
|
||||
Some(ForcedLoginMethod::Chatgpt),
|
||||
Some(vec!["123e4567-e89b-42d3-a456-426614174000".to_string()]),
|
||||
AuthKeyringBackendKind::Secrets,
|
||||
)
|
||||
);
|
||||
|
||||
@@ -25,6 +25,7 @@ use codex_config::ThreadConfigLoader;
|
||||
use codex_config::config_toml::ConfigLockfileToml;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
use codex_config::config_toml::DEFAULT_PROJECT_DOC_MAX_BYTES;
|
||||
use codex_config::config_toml::ForcedChatgptWorkspaceIds;
|
||||
use codex_config::config_toml::ProjectConfig;
|
||||
use codex_config::config_toml::RealtimeAudioConfig;
|
||||
use codex_config::config_toml::RealtimeConfig;
|
||||
@@ -149,6 +150,7 @@ mod requirements;
|
||||
mod resolved_permission_profile;
|
||||
#[cfg(test)]
|
||||
mod schema;
|
||||
pub use auth_keyring::bootstrap_auth_config;
|
||||
pub use auth_keyring::resolve_bootstrap_auth_keyring_backend_kind;
|
||||
pub use codex_config::ConfigLoadOptions;
|
||||
pub use codex_config::Constrained;
|
||||
@@ -1755,6 +1757,14 @@ pub async fn load_bootstrap_config_toml_with_layer_stack(
|
||||
if let Some(required) = requirements.chatgpt_base_url.as_ref() {
|
||||
result.config_toml.chatgpt_base_url = Some(required.clone());
|
||||
}
|
||||
let (forced_login_method, forced_chatgpt_workspace_id) =
|
||||
requirements::resolve_auth_restrictions(
|
||||
&result.config_toml,
|
||||
result.config_layer_stack.requirements(),
|
||||
)?;
|
||||
result.config_toml.forced_login_method = forced_login_method;
|
||||
result.config_toml.forced_chatgpt_workspace_id =
|
||||
forced_chatgpt_workspace_id.map(ForcedChatgptWorkspaceIds::Multiple);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ pub(super) fn push_structured_requirement_override_warning(
|
||||
));
|
||||
}
|
||||
|
||||
fn resolve_auth_restrictions(
|
||||
pub(super) fn resolve_auth_restrictions(
|
||||
config: &ConfigToml,
|
||||
requirements: &ConfigRequirements,
|
||||
) -> std::io::Result<(Option<ForcedLoginMethod>, Option<Vec<String>>)> {
|
||||
|
||||
@@ -63,6 +63,7 @@ use codex_core::config::Config;
|
||||
use codex_core::config::ConfigBuilder;
|
||||
use codex_core::config::ConfigOverrides;
|
||||
use codex_core::config::ConfigTomlLoadResult;
|
||||
use codex_core::config::bootstrap_auth_config;
|
||||
use codex_core::config::find_codex_home;
|
||||
use codex_core::config::load_bootstrap_config_toml_with_layer_stack;
|
||||
use codex_core::config::resolve_bootstrap_auth_keyring_backend_kind;
|
||||
@@ -344,6 +345,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
|
||||
)
|
||||
.await;
|
||||
let bootstrap_config_toml = &bootstrap_config.config_toml;
|
||||
enforce_login_restrictions(&bootstrap_auth_config(&codex_home, &bootstrap_config)?).await?;
|
||||
|
||||
let chatgpt_base_url = bootstrap_config_toml
|
||||
.chatgpt_base_url
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::legacy_core::config::Config;
|
||||
use crate::legacy_core::config::ConfigBuilder;
|
||||
use crate::legacy_core::config::ConfigOverrides;
|
||||
use crate::legacy_core::config::ConfigTomlLoadResult;
|
||||
use crate::legacy_core::config::bootstrap_auth_config;
|
||||
use crate::legacy_core::config::load_bootstrap_config_toml_with_layer_stack;
|
||||
use crate::legacy_core::config::resolve_bootstrap_auth_keyring_backend_kind;
|
||||
use crate::legacy_core::config::resolve_oss_provider;
|
||||
@@ -951,6 +952,7 @@ pub async fn run_main(
|
||||
)
|
||||
.await;
|
||||
let bootstrap_config_toml = &bootstrap_config.config_toml;
|
||||
enforce_login_restrictions(&bootstrap_auth_config(&codex_home, &bootstrap_config)?).await?;
|
||||
|
||||
let chatgpt_base_url = bootstrap_config_toml
|
||||
.chatgpt_base_url
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::Cli;
|
||||
use crate::app_server_session::AppServerSession;
|
||||
use crate::legacy_core::config::ConfigBuilder;
|
||||
use crate::legacy_core::config::ConfigOverrides;
|
||||
use crate::legacy_core::config::bootstrap_auth_config;
|
||||
use crate::legacy_core::config::load_bootstrap_config_toml_with_layer_stack;
|
||||
use crate::legacy_core::config::resolve_bootstrap_auth_keyring_backend_kind;
|
||||
use crate::legacy_core::config::resolve_oss_provider;
|
||||
@@ -25,6 +26,7 @@ use codex_config::ConfigLoadOptions;
|
||||
use codex_config::LoaderOverrides;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_exec_server::ExecServerRuntimePaths;
|
||||
use codex_login::enforce_login_restrictions;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_utils_cli::CliConfigOverrides;
|
||||
use codex_utils_home_dir::find_codex_home;
|
||||
@@ -324,6 +326,11 @@ async fn start_app_server_for_archive_command(
|
||||
)
|
||||
.await
|
||||
.wrap_err("failed to load config.toml")?;
|
||||
enforce_login_restrictions(&bootstrap_auth_config(
|
||||
codex_home.as_path(),
|
||||
&bootstrap_config,
|
||||
)?)
|
||||
.await?;
|
||||
let config_toml = &bootstrap_config.config_toml;
|
||||
let chatgpt_base_url = config_toml
|
||||
.chatgpt_base_url
|
||||
|
||||
Reference in New Issue
Block a user