For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/static_analysis/static_analysis_rules/rust-security/jwt-hardcoded-secret.md. A documentation index is available at /llms.txt.

Avoid hardcoded JWT signing secrets

This product is not supported for your selected Datadog site. ().

Metadata

ID: rust-security/jwt-hardcoded-secret

Language: Rust

Severity: Warning

Category: Security

CWE: 321

Description

Passing a literal (direct or coerced via .as_bytes() / .as_ref() / .as_str()) to EncodingKey::from_secret(), EncodingKey::from_base64_secret(), or their DecodingKey counterparts from the jsonwebtoken crate hardcodes the JWT signing key in source code. For HMAC algorithms the same secret signs and verifies, so a hardcoded DecodingKey lets attackers forge tokens. Every deployment shares the same key, rotation requires a code change, and the secret is visible to anyone who can read the repository (or its history) which includes past contributors and anyone who clones a leaked archive. Load the key from an environment variable, configuration file, or a secret store at runtime instead.

Learn More

Non-Compliant Code Examples

use jsonwebtoken::EncodingKey;

fn invalid() -> Result<(), Box<dyn std::error::Error>> {
    // Byte string literal — classic hardcoded secret
    let _ = EncodingKey::from_secret(b"my-jwt-secret");

    // Fully qualified path
    let _ = jsonwebtoken::EncodingKey::from_secret(b"another-secret");

    // Raw byte string literal
    let _ = EncodingKey::from_secret(br"raw-byte-secret");

    // Hardcoded base64 string
    let _ = EncodingKey::from_base64_secret("aGFyZGNvZGVk")?;

    // DecodingKey 
    let _ = jsonwebtoken::DecodingKey::from_secret(b"verify-secret");

    // Coerced literal
    let _ = EncodingKey::from_secret("via-as-ref".as_ref());

    Ok(())
}

Compliant Code Examples

use jsonwebtoken::EncodingKey;

fn valid() -> Result<(), Box<dyn std::error::Error>> {
    // Loaded from the environment at runtime
    let secret = std::env::var("JWT_SECRET")?;
    let _ = EncodingKey::from_secret(secret.as_bytes());

    // From a function call
    fn get_secret() -> Vec<u8> { vec![] }
    let _ = EncodingKey::from_secret(&get_secret());

    // Variable holding the bytes
    let key_bytes: &[u8] = &[1, 2, 3];
    let _ = EncodingKey::from_secret(key_bytes);

    // .as_bytes() on a variable — not a literal so must not flag
    let name = String::from("runtime");
    let _ = EncodingKey::from_secret(name.as_bytes());

    Ok(())
}
https://static.datadoghq.com/static/images/logos/github_avatar.svg https://static.datadoghq.com/static/images/logos/vscode_avatar.svg jetbrains

Seamless integrations. Try Datadog Code Security