fix(fxt): read JWT secret from config.toml for gateway auth
The fxt client was using a hardcoded dev fallback secret for JWT signing, causing InvalidSignature errors against the API gateway. Now reads jwt_secret from ~/.foxhunt/config.toml with fallback chain: env var > config file > dev secret. Also updates default api_gateway_url to https://api.fxhnt.ai. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,15 +47,20 @@ pub struct JwtConfig {
|
||||
|
||||
impl Default for JwtConfig {
|
||||
fn default() -> Self {
|
||||
// Precedence: env var > config file > dev fallback
|
||||
let resolved_secret = std::env::var("JWT_SECRET")
|
||||
.ok()
|
||||
.or_else(|| {
|
||||
crate::config::TliConfig::load()
|
||||
.ok()
|
||||
.and_then(|c| c.jwt_secret)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
tracing::warn!("JWT_SECRET not set and no jwt_secret in config.toml - using development fallback");
|
||||
"test-secret-must-be-at-least-64-characters-long-for-security-validation-ok-1234567890".to_owned()
|
||||
});
|
||||
Self {
|
||||
// Read JWT_SECRET from environment to match API Gateway configuration
|
||||
// Falls back to test secret for development without .env
|
||||
// Note: Production systems should use Vault via the API Gateway
|
||||
secret: std::env::var("JWT_SECRET")
|
||||
.unwrap_or_else(|_| {
|
||||
tracing::warn!("JWT_SECRET not set - using development fallback secret");
|
||||
"test-secret-must-be-at-least-64-characters-long-for-security-validation-ok-1234567890".to_owned()
|
||||
}),
|
||||
secret: resolved_secret,
|
||||
issuer: std::env::var("JWT_ISSUER")
|
||||
.unwrap_or_else(|_| "foxhunt-api-gateway".to_owned()),
|
||||
audience: std::env::var("JWT_AUDIENCE")
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//! ## Example Config File
|
||||
//! ```toml
|
||||
//! # ~/.foxhunt/config.toml
|
||||
//! api_gateway_url = "http://localhost:50051"
|
||||
//! api_gateway_url = "https://api.fxhnt.ai"
|
||||
//! log_level = "info"
|
||||
//! token_storage = "keyring"
|
||||
//! ```
|
||||
@@ -96,13 +96,17 @@ pub struct TliConfig {
|
||||
#[serde(default = "default_token_storage")]
|
||||
pub token_storage: String,
|
||||
|
||||
/// JWT secret for token signing (must match API Gateway's JWT_SECRET)
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub jwt_secret: Option<String>,
|
||||
|
||||
/// Broker connectivity settings
|
||||
#[serde(default)]
|
||||
pub broker: BrokerConfig,
|
||||
}
|
||||
|
||||
fn default_api_gateway_url() -> String {
|
||||
"http://localhost:50051".to_owned()
|
||||
"https://api.fxhnt.ai".to_owned()
|
||||
}
|
||||
|
||||
fn default_log_level() -> String {
|
||||
@@ -119,6 +123,7 @@ impl Default for TliConfig {
|
||||
api_gateway_url: default_api_gateway_url(),
|
||||
log_level: default_log_level(),
|
||||
token_storage: default_token_storage(),
|
||||
jwt_secret: None,
|
||||
broker: BrokerConfig::default(),
|
||||
}
|
||||
}
|
||||
@@ -165,6 +170,7 @@ impl TliConfig {
|
||||
/// api_gateway_url: "http://localhost:50051".to_string(),
|
||||
/// log_level: "debug".to_string(),
|
||||
/// token_storage: "keyring".to_string(),
|
||||
/// jwt_secret: None,
|
||||
/// broker: BrokerConfig::default(),
|
||||
/// };
|
||||
/// config.save().unwrap();
|
||||
@@ -203,7 +209,7 @@ mod tests {
|
||||
fn test_default_config() {
|
||||
// Test that Default trait provides correct values
|
||||
let config = TliConfig::default();
|
||||
assert_eq!(config.api_gateway_url, "http://localhost:50051");
|
||||
assert_eq!(config.api_gateway_url, "https://api.fxhnt.ai");
|
||||
assert_eq!(config.log_level, "info");
|
||||
assert_eq!(config.token_storage, "keyring");
|
||||
}
|
||||
@@ -214,6 +220,7 @@ mod tests {
|
||||
api_gateway_url: "http://example.com:50051".to_owned(),
|
||||
log_level: "debug".to_owned(),
|
||||
token_storage: "file".to_owned(),
|
||||
jwt_secret: None,
|
||||
broker: BrokerConfig::default(),
|
||||
};
|
||||
|
||||
@@ -238,7 +245,7 @@ mod tests {
|
||||
// Test that empty TOML string deserializes to defaults
|
||||
let empty_toml = "";
|
||||
let config: TliConfig = toml::from_str(empty_toml).unwrap();
|
||||
assert_eq!(config.api_gateway_url, "http://localhost:50051");
|
||||
assert_eq!(config.api_gateway_url, "https://api.fxhnt.ai");
|
||||
assert_eq!(config.log_level, "info");
|
||||
assert_eq!(config.token_storage, "keyring");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user