Docs

secret-formats

Source: crates/lvcs/src/secrets/formats.rs.

/// The characters a token's body may hold, all ASCII.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Body {
    /// `A-Z a-z 0-9`.
    Alnum,
    /// `A-Z 0-9`.
    UpperAlnum,
    /// `0-9 a-f`.
    LowerHex,
    /// `A-Z a-z 0-9 _`.
    AlnumUnderscore,
    /// `A-Z a-z 0-9 -`.
    AlnumDash,
    /// `A-Z a-z 0-9 _ -` (base64url).
    Base64Url,
    /// `A-Z a-z 0-9 /`.
    AlnumSlash,
}

/// How many code points a token's body holds.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Len {
    Exactly(usize),
    AtLeast(usize),
}

/// How a known token format is recognized. A token starts only where the
/// code point before it is not an ASCII letter, digit, `_`, or `-`, so a
/// prefix inside a longer word (`task_live_`) is not a token.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Shape {
    /// One of `prefixes`, then the longest run of `body` characters, whose
    /// length must fit `len`, followed by no ASCII letter or digit. With
    /// `mixed`, the run must also hold an uppercase letter, a lowercase
    /// letter, and a digit, as a random token does and a word does not.
    Prefixed {
        prefixes: &'static [&'static str],
        body: Body,
        len: Len,
        mixed: bool,
    },
    /// A JSON Web Token: three base64url segments of at least
    /// [`JWT_SEGMENT_MIN`] code points joined by `.`, the first two
    /// starting `eyJ` (a base64url-encoded JSON object).
    Jwt,
}

/// A known token format; `rule` names it in `SecretHit::rule` and the
/// API's `SecretData.rule`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct TokenFormat {
    rule: &'static str,
    shape: Shape,
}

/// The rule of a PEM private key: `-----BEGIN <label>-----` whose label
/// ends in `PRIVATE KEY` or `PRIVATE KEY BLOCK`, through the first
/// `-----END ` after it when that closes the same label, with at least
/// [`PEM_BODY_MIN`] code points between them. A header with no body, as
/// code that parses PEM names it, is not a hit; a body written without
/// its footer is left to the high-entropy heuristic, line by line. A PEM
/// block with any other label (`CERTIFICATE`, `PUBLIC KEY`) is public
/// data: the heuristic skips it.
const PEM_PRIVATE_KEY_RULE: &str = "private-key";

/// Fewest code points between a PEM private key's header and footer.
const PEM_BODY_MIN: usize = 64;

/// Fewest code points in each segment of a JSON Web Token.
const JWT_SEGMENT_MIN: usize = 10;

/// The known token formats, tried in this order at each position: the
/// first that matches names the hit, so a format comes before a more
/// general one sharing its prefix (`anthropic-key` before `sk-key`).
const TOKEN_FORMATS: &[TokenFormat] = &[
    TokenFormat {
        rule: "aws-access-key-id",
        shape: Shape::Prefixed {
            prefixes: &["AKIA", "ASIA", "ABIA", "ACCA"],
            body: Body::UpperAlnum,
            len: Len::Exactly(16),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "github-token",
        shape: Shape::Prefixed {
            prefixes: &["ghp_", "gho_", "ghu_", "ghs_", "ghr_"],
            body: Body::Alnum,
            len: Len::AtLeast(36),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "github-pat",
        shape: Shape::Prefixed {
            prefixes: &["github_pat_"],
            body: Body::AlnumUnderscore,
            len: Len::AtLeast(40),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "gitlab-token",
        shape: Shape::Prefixed {
            prefixes: &["glpat-"],
            body: Body::Base64Url,
            len: Len::AtLeast(20),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "slack-token",
        shape: Shape::Prefixed {
            prefixes: &["xoxa-", "xoxb-", "xoxe-", "xoxp-", "xoxr-", "xoxs-"],
            body: Body::AlnumDash,
            len: Len::AtLeast(10),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "slack-webhook",
        shape: Shape::Prefixed {
            prefixes: &["https://hooks.slack.com/services/"],
            body: Body::AlnumSlash,
            len: Len::AtLeast(20),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "stripe-key",
        shape: Shape::Prefixed {
            prefixes: &["sk_live_", "rk_live_", "sk_test_", "rk_test_"],
            body: Body::Alnum,
            len: Len::AtLeast(16),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "anthropic-key",
        shape: Shape::Prefixed {
            prefixes: &["sk-ant-"],
            body: Body::Base64Url,
            len: Len::AtLeast(32),
            mixed: true,
        },
    },
    TokenFormat {
        rule: "sk-key",
        shape: Shape::Prefixed {
            prefixes: &["sk-"],
            body: Body::Base64Url,
            len: Len::AtLeast(32),
            mixed: true,
        },
    },
    TokenFormat {
        rule: "google-api-key",
        shape: Shape::Prefixed {
            prefixes: &["AIza"],
            body: Body::Base64Url,
            len: Len::Exactly(35),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "huggingface-token",
        shape: Shape::Prefixed {
            prefixes: &["hf_"],
            body: Body::Alnum,
            len: Len::AtLeast(34),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "npm-token",
        shape: Shape::Prefixed {
            prefixes: &["npm_"],
            body: Body::Alnum,
            len: Len::AtLeast(36),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "pypi-token",
        shape: Shape::Prefixed {
            prefixes: &["pypi-AgEIcHlwaS5vcmc"],
            body: Body::Base64Url,
            len: Len::AtLeast(50),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "digitalocean-token",
        shape: Shape::Prefixed {
            prefixes: &["dop_v1_", "doo_v1_", "dor_v1_"],
            body: Body::LowerHex,
            len: Len::Exactly(64),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "age-secret-key",
        shape: Shape::Prefixed {
            prefixes: &["AGE-SECRET-KEY-1"],
            body: Body::UpperAlnum,
            len: Len::Exactly(58),
            mixed: false,
        },
    },
    TokenFormat {
        rule: "jwt",
        shape: Shape::Jwt,
    },
];