---
title: Avoid hardcoded JWT signing secrets
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Static Code Analysis (SAST) > SAST
  Rules > Avoid hardcoded JWT signing secrets
---

# Avoid hardcoded JWT signing secrets

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**ID:** `rust-security/jwt-hardcoded-secret`

**Language:** Rust

**Severity:** Warning

**Category:** Security

**CWE**: [321](https://cwe.mitre.org/data/definitions/321.html)

## Description{% #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{% #learn-more %}

- [CWE-321: Use of Hard-coded Cryptographic Key](https://cwe.mitre.org/data/definitions/321.html)

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```rust
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{% #compliant-code-examples %}

```rust
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(())
}
```
  Seamless integrations. Try Datadog Code SecurityDatadog Code Security 
{% icon name="icon-external-link" /%}
 