Skip to content
4 changes: 4 additions & 0 deletions .Jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2025-02-14 - Prevent clap from leaking secrets in help menus
**Vulnerability:** The CLI exposed sensitive environment variables (e.g., `KEYCLOAK_PASSWORD`, `VAULT_TOKEN`) in the `--help` output because `clap` natively prints the current values of `env` fallback arguments when they are populated.
**Learning:** `clap` parses and caches environment variable values dynamically. If an argument uses `env = "SECRET_NAME"` without explicit configuration, running `--help` will print `[env: SECRET_NAME=actual_secret_value]` directly to standard output, risking exposure in CI logs or terminal scrollback.
**Prevention:** Always use `hide_env_values = true` (e.g., `#[arg(env = "SECRET_NAME", hide_env_values = true)]`) when binding sensitive environment variables to `clap` structs to suppress value rendering in help menus while retaining native parsing.
6 changes: 3 additions & 3 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ pub struct Cli {
pub user: Option<String>,

/// Keycloak Admin Password
#[arg(skip)]
#[arg(long, env = "KEYCLOAK_PASSWORD", hide_env_values = true)]
pub password: Option<String>,

/// Keycloak Client ID (for client credentials grant)
#[arg(long, env = "KEYCLOAK_CLIENT_ID")]
pub client_id: Option<String>,

/// Keycloak Client Secret (for client credentials grant)
#[arg(skip)]
#[arg(long, env = "KEYCLOAK_CLIENT_SECRET", hide_env_values = true)]
pub client_secret: Option<String>,

/// Profile name to load from profiles/ directory
Expand All @@ -43,7 +43,7 @@ pub struct Cli {
pub vault_addr: Option<String>,

/// HashiCorp Vault Token
#[arg(long, env = "VAULT_TOKEN")]
#[arg(long, env = "VAULT_TOKEN", hide_env_values = true)]
pub vault_token: Option<String>,

/// Path to a custom TOML configuration file
Expand Down
10 changes: 1 addition & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,7 @@ async fn main() -> Result<()> {
dotenvy::from_filename(".secrets").ok();
env_logger::init();

let mut cli = Cli::parse();

// Load skipped fields from environment if not provided
if cli.password.is_none() {
cli.password = std::env::var("KEYCLOAK_PASSWORD").ok();
}
if cli.client_secret.is_none() {
cli.client_secret = std::env::var("KEYCLOAK_CLIENT_SECRET").ok();
}
let cli = Cli::parse();

kaji::run_app(cli).await
}