Skip to content

Commit f5a6f2e

Browse files
committed
fix(auth): ignore blank environment tokens
1 parent 7954d02 commit f5a6f2e

7 files changed

Lines changed: 37 additions & 17 deletions

File tree

src/cortex-cli/src/cli/handlers.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,15 +530,15 @@ fn install_completions(shell: Shell) -> Result<()> {
530530

531531
/// Show current logged-in user.
532532
pub async fn run_whoami() -> Result<()> {
533-
use cortex_login::{AuthMode, load_auth_with_fallback, safe_format_key};
533+
use cortex_login::{AuthMode, has_non_blank_token, load_auth_with_fallback, safe_format_key};
534534

535535
let cortex_home = dirs::home_dir()
536536
.map(|h| h.join(".cortex"))
537537
.unwrap_or_else(|| std::path::PathBuf::from(".cortex"));
538538

539539
// Check environment variables first
540540
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN")
541-
&& !token.is_empty()
541+
&& has_non_blank_token(&token)
542542
{
543543
println!(
544544
"Authenticated via CORTEX_AUTH_TOKEN: {}",
@@ -548,7 +548,7 @@ pub async fn run_whoami() -> Result<()> {
548548
}
549549

550550
if let Ok(token) = std::env::var("CORTEX_API_KEY")
551-
&& !token.is_empty()
551+
&& has_non_blank_token(&token)
552552
{
553553
println!(
554554
"Authenticated via CORTEX_API_KEY: {}",

src/cortex-cli/src/login.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
use crate::styled_output::{print_dim, print_error, print_info, print_success, print_warning};
44
use cortex_common::CliConfigOverrides;
55
use cortex_login::{
6-
AuthMode, CredentialsStoreMode, SecureAuthData, load_auth_with_fallback, logout_with_fallback,
7-
safe_format_key, save_auth_with_fallback,
6+
AuthMode, CredentialsStoreMode, SecureAuthData, has_non_blank_token, load_auth_with_fallback,
7+
logout_with_fallback, safe_format_key, save_auth_with_fallback,
88
};
99
use std::collections::HashSet;
1010
use std::io::{IsTerminal, Read};
@@ -132,7 +132,7 @@ pub async fn run_login_status(config_overrides: CliConfigOverrides) -> ! {
132132

133133
// Check environment variables first (CORTEX_AUTH_TOKEN and CORTEX_API_KEY)
134134
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN")
135-
&& !token.is_empty()
135+
&& has_non_blank_token(&token)
136136
{
137137
print_success(&format!(
138138
"Authenticated via CORTEX_AUTH_TOKEN environment variable: {}",
@@ -142,7 +142,7 @@ pub async fn run_login_status(config_overrides: CliConfigOverrides) -> ! {
142142
}
143143

144144
if let Ok(token) = std::env::var("CORTEX_API_KEY")
145-
&& !token.is_empty()
145+
&& has_non_blank_token(&token)
146146
{
147147
print_success(&format!(
148148
"Authenticated via CORTEX_API_KEY environment variable: {}",

src/cortex-engine/src/auth_token.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ use crate::error::{CortexError, Result};
4444
pub fn get_auth_token(instance_token: Option<&str>) -> Result<String> {
4545
// Priority 1: Instance token (if provided and non-empty)
4646
if let Some(token) = instance_token {
47-
if !token.is_empty() {
47+
if cortex_login::has_non_blank_token(token) {
4848
tracing::debug!(source = "instance", "Using auth token from client instance");
4949
return Ok(token.to_string());
5050
}
5151
}
5252

5353
// Priority 2: CORTEX_AUTH_TOKEN environment variable
5454
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN") {
55-
if !token.is_empty() {
55+
if cortex_login::has_non_blank_token(&token) {
5656
tracing::debug!(
5757
source = "env_var",
5858
"Using auth token from CORTEX_AUTH_TOKEN"
@@ -63,7 +63,7 @@ pub fn get_auth_token(instance_token: Option<&str>) -> Result<String> {
6363

6464
// Priority 3: CORTEX_API_KEY environment variable (alias for GitHub Actions workflow)
6565
if let Ok(token) = std::env::var("CORTEX_API_KEY") {
66-
if !token.is_empty() {
66+
if cortex_login::has_non_blank_token(&token) {
6767
tracing::debug!(source = "env_var", "Using auth token from CORTEX_API_KEY");
6868
return Ok(token);
6969
}
@@ -95,17 +95,20 @@ pub fn get_auth_token_optional(instance_token: Option<&str>) -> Option<String> {
9595
/// Useful for fast availability checks in UI.
9696
pub fn is_authenticated(instance_token: Option<&str>) -> bool {
9797
// Check instance token
98-
if instance_token.map_or(false, |t| !t.is_empty()) {
98+
if instance_token.is_some_and(cortex_login::has_non_blank_token) {
9999
return true;
100100
}
101101

102102
// Check CORTEX_AUTH_TOKEN env var
103-
if std::env::var("CORTEX_AUTH_TOKEN").map_or(false, |t| !t.is_empty()) {
103+
if std::env::var("CORTEX_AUTH_TOKEN")
104+
.is_ok_and(|token| cortex_login::has_non_blank_token(&token))
105+
{
104106
return true;
105107
}
106108

107109
// Check CORTEX_API_KEY env var (alias)
108-
if std::env::var("CORTEX_API_KEY").map_or(false, |t| !t.is_empty()) {
110+
if std::env::var("CORTEX_API_KEY").is_ok_and(|token| cortex_login::has_non_blank_token(&token))
111+
{
109112
return true;
110113
}
111114

@@ -142,6 +145,7 @@ mod tests {
142145
fn test_is_authenticated_with_instance() {
143146
assert!(is_authenticated(Some("token")));
144147
assert!(!is_authenticated(Some("")));
148+
assert!(!is_authenticated(Some(" ")));
145149
assert!(!is_authenticated(None));
146150
}
147151

src/cortex-engine/src/client/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ pub trait ModelClient: Send + Sync {
5050
fn get_auth_token() -> Result<String> {
5151
// First check environment variable
5252
if let Ok(token) = std::env::var("CORTEX_AUTH_TOKEN") {
53-
return Ok(token);
53+
if cortex_login::has_non_blank_token(&token) {
54+
return Ok(token);
55+
}
5456
}
5557

5658
// Try to load from cortex-login keyring storage
@@ -78,7 +80,7 @@ pub fn create_client(
7880
_base_url: Option<&str>,
7981
) -> Result<Box<dyn ModelClient>> {
8082
// Use provided api_key as auth token, or try to get from environment/keyring
81-
let auth_token = if !api_key.is_empty() {
83+
let auth_token = if cortex_login::has_non_blank_token(api_key) {
8284
api_key.to_string()
8385
} else {
8486
get_auth_token()?

src/cortex-login/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub use keyring::{delete_from_keyring, load_from_keyring, save_to_keyring};
5353
pub use token::get_auth_token;
5454

5555
// Re-exports from utils
56-
pub use utils::safe_format_key;
56+
pub use utils::{has_non_blank_token, safe_format_key};
5757

5858
// Re-exports from device_code_auth
5959
pub use device_code_auth::run_device_code_login;

src/cortex-login/src/token.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::constants::{API_BASE_URL, USER_AGENT};
77
use crate::keyring::save_to_keyring;
88
use crate::storage::load_auth_with_fallback;
99
use crate::types::{AuthMode, SecureAuthData};
10+
use crate::utils::has_non_blank_token;
1011

1112
/// Refresh an expired access token using the refresh token.
1213
///
@@ -71,7 +72,7 @@ fn refresh_token_sync(refresh_token: &str) -> Option<SecureAuthData> {
7172
pub fn get_auth_token() -> Option<String> {
7273
// Check environment variable first (highest priority for CI/CD)
7374
if let Ok(token) = std::env::var("CORTEX_API_KEY") {
74-
if !token.is_empty() {
75+
if has_non_blank_token(&token) {
7576
tracing::debug!("Using API key from CORTEX_API_KEY environment variable");
7677
return Some(token);
7778
}

src/cortex-login/src/utils.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ pub fn safe_format_key(key: &str) -> String {
1313
format!("{prefix}***{suffix}")
1414
}
1515

16+
/// Return true when a token contains at least one non-whitespace character.
17+
pub fn has_non_blank_token(token: &str) -> bool {
18+
!token.trim().is_empty()
19+
}
20+
1621
/// Set restrictive file permissions (0600 on Unix).
1722
pub fn set_file_permissions(path: &Path) -> Result<()> {
1823
#[cfg(unix)]
@@ -46,4 +51,12 @@ mod tests {
4651
let key = "sk-proj-12345";
4752
assert_eq!(safe_format_key(key), "***");
4853
}
54+
55+
#[test]
56+
fn test_has_non_blank_token() {
57+
assert!(has_non_blank_token("ctx-token"));
58+
assert!(has_non_blank_token(" ctx-token "));
59+
assert!(!has_non_blank_token(""));
60+
assert!(!has_non_blank_token(" \t\n"));
61+
}
4962
}

0 commit comments

Comments
 (0)