mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: add sanitizer to redact secrets (#11600)
Adding a sanitizer crate that can redact API keys and other secret with known pattern from a String
This commit is contained in:
committed by
GitHub
Unverified
parent
d8b130d9a4
commit
cf4ef84b52
Generated
+7
@@ -2485,6 +2485,13 @@ dependencies = [
|
||||
"pretty_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-utils-sanitizer"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-utils-string"
|
||||
version = "0.0.0"
|
||||
|
||||
@@ -53,6 +53,7 @@ members = [
|
||||
"utils/cli",
|
||||
"utils/elapsed",
|
||||
"utils/sandbox-summary",
|
||||
"utils/sanitizer",
|
||||
"utils/approval-presets",
|
||||
"utils/oss",
|
||||
"utils/fuzzy-match",
|
||||
@@ -129,6 +130,7 @@ codex-utils-pty = { path = "utils/pty" }
|
||||
codex-utils-readiness = { path = "utils/readiness" }
|
||||
codex-utils-rustls-provider = { path = "utils/rustls-provider" }
|
||||
codex-utils-sandbox-summary = { path = "utils/sandbox-summary" }
|
||||
codex-utils-sanitizer = { path = "utils/sanitizer" }
|
||||
codex-utils-string = { path = "utils/string" }
|
||||
codex-windows-sandbox = { path = "windows-sandbox-rs" }
|
||||
core_test_support = { path = "core/tests/common" }
|
||||
@@ -338,6 +340,7 @@ ignored = [
|
||||
"icu_provider",
|
||||
"openssl-sys",
|
||||
"codex-utils-readiness",
|
||||
"codex-utils-sanitizer",
|
||||
"codex-secrets",
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "codex-utils-sanitizer"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
regex = "1.12.3"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1,41 @@
|
||||
use regex::Regex;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static OPENAI_KEY_REGEX: LazyLock<Regex> = LazyLock::new(|| compile_regex(r"sk-[A-Za-z0-9]{20,}"));
|
||||
static AWS_ACCESS_KEY_ID_REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| compile_regex(r"\bAKIA[0-9A-Z]{16}\b"));
|
||||
static BEARER_TOKEN_REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| compile_regex(r"(?i)\bBearer\s+[A-Za-z0-9._\-]{16,}\b"));
|
||||
static SECRET_ASSIGNMENT_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
compile_regex(r#"(?i)\b(api[_-]?key|token|secret|password)\b(\s*[:=]\s*)(["']?)[^\s"']{8,}"#)
|
||||
});
|
||||
|
||||
/// Remove secret and keys from a String. This is done on best effort basis following some
|
||||
/// well-known REGEX.
|
||||
pub fn redact_secrets(input: String) -> String {
|
||||
let redacted = OPENAI_KEY_REGEX.replace_all(&input, "[REDACTED_SECRET]");
|
||||
let redacted = AWS_ACCESS_KEY_ID_REGEX.replace_all(&redacted, "[REDACTED_SECRET]");
|
||||
let redacted = BEARER_TOKEN_REGEX.replace_all(&redacted, "Bearer [REDACTED_SECRET]");
|
||||
let redacted = SECRET_ASSIGNMENT_REGEX.replace_all(&redacted, "$1$2$3[REDACTED_SECRET]");
|
||||
|
||||
redacted.to_string()
|
||||
}
|
||||
|
||||
fn compile_regex(pattern: &str) -> Regex {
|
||||
match Regex::new(pattern) {
|
||||
Ok(regex) => regex,
|
||||
// Panic is ok thanks to `load_regex` test.
|
||||
Err(err) => panic!("invalid regex pattern `{pattern}`: {err}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn load_regex() {
|
||||
// The goal of this test is just to compile all the regex to prevent the panic
|
||||
let _ = redact_secrets("secret".to_string());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user