{"repo": "alphane-ai/zenari", "files": {"backend/internal/security/redact.go": {"b885b7ac1c75cad256d774a1fed82008eea4aecf": {"t": 1786068553.2301419, "n": 110939, "h": "9964ea48caebd059", "c": "package security\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n)\n\nconst Redacted = \"[REDACTED]\"\n\ntype SecretKind string\n\nconst (\n\tSecretKindSensitiveKey SecretKind = \"sensitive_key\"\n\tSecretKindPassword SecretKind = \"password\"\n\tSecretKindToken SecretKind = \"token\"\n\tSecretKindAPIKey SecretKind = \"api_key\"\n\tSecretKindAccessKey SecretKind = \"access_key\"\n\tSecretKindPrivateKey SecretKind = \"private_key\"\n\tSecretKindCredential SecretKind = \"credential\"\n\tSecretKindCookie SecretKind = \"cookie\"\n\tSecretKindAuthorization SecretKind = \"authorization\"\n\tSecretKindWebhookSecret SecretKind = \"webhook_secret\"\n\tSecretKindDSN SecretKind = \"dsn_credentials\"\n\tSecretKindProviderKey SecretKind = \"provider_key\"\n\tSecretKindCloudKey SecretKind = \"cloud_key\"\n\tSecretKindSignedURL SecretKind = \"signed_url_secret\"\n\tSecretKindServiceAcct SecretKind = \"service_account\"\n\tSecretKindRegistryAuth SecretKind = \"registry_auth\"\n\tSecretKindEncryptionKey SecretKind = \"encryption_key\"\n\tSecretKindSecretPayload SecretKind = \"secret_payload\"\n)\n\ntype SecretFinding struct {\n\tKind SecretKind `json:\"kind\"`\n\tSignal string `json:\"signal\"`\n\tLocation string `json:\"location,omitempty\"`\n}\n\nvar sensitiveKeyPattern = regexp.MustCompile(`(?i)(secret|token|password|passwd|pwd|passphrase|api[_-]?key|x[_-]?api[_-]?key|access[_-]?key|private[_-]?key|private[_-]?token|deploy[_-]?key|credential|signature|session|cookie|authorization|proxy[_-]?authorization|client[_-]?secret|client[_-]?token|client[_-]?assertion|refresh[_-]?token|id[_-]?token|personal[_-]?access[_-]?token|license[_-]?key|pat|jwt|oauth|webhook[_-]?(?:secret|url)|signing[_-]?key|routing[_-]?key|integration[_-]?key|shared[_-]?access[_-]?signature|sas|stripe|paddle|lemon[_-]?squeezy|lemonsqueezy|chargebee|recurly|braintree|paypal|adyen|taxjar|avalara|quickbooks|xero|openai|anthropic|deepseek|mistral|cohere|gemini|google[_-]?ai|openrouter|perplexity|xai|fireworks|fal|elevenlabs|provider[_-]?key|sentry|datadog|honeycomb|new[_-]?relic|splunk|grafana|otel|otlp|posthog|segment|amplitude|mixpanel|launchdarkly|langfuse|braintrust|helicone|openpipe|promptlayer|portkey|wandb|weights[_-]?biases|weave|arize[_-]?phoenix|better[_-]?(?:stack|uptime)|logtail|cronitor|healthchecks|uptimerobot|uptime[_-]?robot|honeybadger|rollbar|bugsnag|airbrake|scout[_-]?apm|lightstep|chronosphere|signoz|axiom|logflare|sematext|logz(?:io|_io)|papertrail|pagerduty|opsgenie|zendesk|intercom|resend|postmark|mailchimp|clerk|auth0|okta|supabase|firebase|rootly|firehydrant|statuspage|victorops|splunk[_-]?on[_-]?call|squadcast|redis[_-]?url|smtp[_-]?url|smtp[_-]?dsn|smtp[_-]?connection|elastic[_-]?cloud[_-]?auth|elasticsearch[_-]?url|opensearch[_-]?url|clickhouse[_-]?url|metabase[_-]?secret[_-]?key|metabase[_-]?api[_-]?key|metabase[_-]?session|terraform|snyk|circleci|buildkite|database[_-]?url|dsn|connection[_-]?string|connectionstring|service[_-]?account|storage[_-]?key|account[_-]?key|subscription[_-]?key|tenant[_-]?secret|object[_-]?storage[_-]?signing[_-]?key|object[_-]?storage[_-]?access[_-]?key|object[_-]?storage[_-]?secret[_-]?key|aws[_-]?secret[_-]?access[_-]?key|aws[_-]?session[_-]?token|s3[_-]?secret[_-]?key|minio[_-]?root[_-]?password|minio[_-]?secret[_-]?key|r2[_-]?(access|secret)|wasabi[_-]?(access|secret)|scw[_-]?(access|secret)|scaleway[_-]?(access|secret)|vultr[_-]?(access|secret)|linode[_-]?(access|secret)|oci[_-]?(access|secret|private)|oracle[_-]?(access|secret|private)|restic|kopia|borg|pgbackrest|wal[_-]?g|walg|litestream|backup[_-]?(?:repository|repo|password|passphrase|encryption|signing)|age[_-]?(?:identity|secret)|gpg[_-]?(?:private|passphrase)|pgp[_-]?(?:private|passphrase)|encryption[_-]?customer[_-]?key|customer[_-]?encryption[_-]?key|sse[_-]?customer[_-]?key|docker[_-]?auth|dockerconfigjson|dockercfg|image[_-]?pull[_-]?secret|registry[_-]?(auth|token|password))`)\n\nvar secretValuePatterns = []struct {\n\tkind SecretKind\n\tsignal string\n\tpattern *regexp.Regexp\n}{\n\t{SecretKindAuthorization, \"bearer_token\", regexp.MustCompile(`(?i)\\bBearer\\s+[A-Za-z0-9._~+/\\-=]{3,}`)},\n\t{SecretKindAuthorization, \"basic_authorization\", regexp.MustCompile(`(?i)\\bBasic\\s+[A-Za-z0-9+/=]{12,}`)},\n\t{SecretKindAuthorization, \"api_key_authorization\", regexp.MustCompile(`(?i)\\bApiKey\\s+[A-Za-z0-9._~+/\\-=]{12,}`)},\n\t{SecretKindPrivateKey, \"pem_private_key\", regexp.MustCompile(`(?s)-----BEGIN [A-Z ]*PRIVATE KEY-----.*?-----END [A-Z ]*PRIVATE KEY-----`)},\n\t{SecretKindProviderKey, \"openai_key\", regexp.MustCompile(`\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"stripe_key\", regexp.MustCompile(`\\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\\b`)},\n\t{SecretKindProviderKey, \"slack_token\", regexp.MustCompile(`\\bxox[abprs]-[A-Za-z0-9-]{10,}\\b`)},\n\t{SecretKindAccessKey, \"aws_access_key\", regexp.MustCompile(`\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b`)},\n\t{SecretKindAccessKey, \"s3_access_key_id\", regexp.MustCompile(`(?i)\\b(?:AWSAccessKeyId|AccessKeyId|access[_-]?key[_-]?id|object[_-]?storage[_-]?access[_-]?key)\\s*[=:]\\s*(\"[A-Za-z0-9][A-Za-z0-9._/-]{7,}\"|'[A-Za-z0-9][A-Za-z0-9._/-]{7,}'|[A-Za-z0-9][A-Za-z0-9._/-]{7,})`)},\n\t{SecretKindCloudKey, \"s3_secret_access_key\", regexp.MustCompile(`(?i)\\b(?:aws[_-]?)?(?:secret[_-]?access[_-]?key|object[_-]?storage[_-]?secret[_-]?key|s3[_-]?secret[_-]?key|minio[_-]?secret[_-]?key|minio[_-]?root[_-]?password)\\s*[=:]\\s*(\"[A-Za-z0-9/+=._-]{8,}\"|'[A-Za-z0-9/+=._-]{8,}'|[A-Za-z0-9/+=._-]{8,})`)},\n\t{SecretKindToken, \"aws_session_token\", regexp.MustCompile(`(?i)\\baws[_-]?session[_-]?token\\s*[=:]\\s*(\"[A-Za-z0-9/+=._-]{8,}\"|'[A-Za-z0-9/+=._-]{8,}'|[A-Za-z0-9/+=._-]{8,})`)},\n\t{SecretKindAuthorization, \"aws_sigv4_authorization\", regexp.MustCompile(`(?i)\\bAuthorization\\s*:\\s*AWS4-HMAC-SHA256\\s+[^\\r\\n]+`)},\n\t{SecretKindCloudKey, \"google_api_key\", regexp.MustCompile(`\\bAIza[0-9A-Za-z_-]{35}\\b`)},\n\t{SecretKindCloudKey, \"azure_storage_key\", regexp.MustCompile(`(?i)\\bDefaultEndpointsProtocol=https?;AccountName=[A-Za-z0-9]+;AccountKey=[A-Za-z0-9+/=]{20,}`)},\n\t{SecretKindToken, \"github_token\", regexp.MustCompile(`\\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\\b`)},\n\t{SecretKindToken, \"github_fine_grained_token\", regexp.MustCompile(`\\bgithub_pat_[A-Za-z0-9_]{20,}\\b`)},\n\t{SecretKindToken, \"gitlab_token\", regexp.MustCompile(`\\b(?:glpat|glrt|glcbt|glimt|glsoat|glagent)-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"jwt\", regexp.MustCompile(`\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b`)},\n\t{SecretKindToken, \"vercel_token\", regexp.MustCompile(`\\bvercel_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"npm_token\", regexp.MustCompile(`\\bnpm_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"pypi_token\", regexp.MustCompile(`\\bpypi-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"gitlab_deploy_token\", regexp.MustCompile(`\\bgldt-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindWebhookSecret, \"slack_webhook_url\", regexp.MustCompile(`https://hooks\\.slack\\.com/services/[A-Za-z0-9/_-]{20,}`)},\n\t{SecretKindWebhookSecret, \"discord_webhook_url\", regexp.MustCompile(`https://discord(?:app)?\\.com/api/webhooks/[0-9]+/[A-Za-z0-9._-]{20,}`)},\n\t{SecretKindProviderKey, \"anthropic_key\", regexp.MustCompile(`\\bsk-ant-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"linear_key\", regexp.MustCompile(`\\blin_api_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindProviderKey, \"huggingface_token\", regexp.MustCompile(`\\bhf_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindProviderKey, \"replicate_token\", regexp.MustCompile(`\\br8_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindProviderKey, \"stability_key\", regexp.MustCompile(`\\bsk-[A-Za-z0-9]{32,}\\b`)},\n\t{SecretKindProviderKey, \"groq_key\", regexp.MustCompile(`\\bgsk_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindProviderKey, \"together_key\", regexp.MustCompile(`\\btgp_v1_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"pinecone_key\", regexp.MustCompile(`\\bpcsk_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"openrouter_key\", regexp.MustCompile(`\\bsk-or-v1-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"perplexity_key\", regexp.MustCompile(`\\bpplx-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"xai_key\", regexp.MustCompile(`\\bxai-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"fireworks_key\", regexp.MustCompile(`\\bfw_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"fal_key\", regexp.MustCompile(`\\bfal-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"elevenlabs_key\", regexp.MustCompile(`\\bsk_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"figma_token\", regexp.MustCompile(`\\bfigd_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"notion_token\", regexp.MustCompile(`\\bsecret_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindProviderKey, \"langsmith_token\", regexp.MustCompile(`\\blsv2_pt_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"supabase_jwt\", regexp.MustCompile(`\\bsb_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"cloudflare_token\", regexp.MustCompile(`\\b(?:CFPAT|cfpat)_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"datadog_key\", regexp.MustCompile(`\\b(?:dd|datadog)_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"sentry_auth_token\", regexp.MustCompile(`\\bsntrys_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"posthog_key\", regexp.MustCompile(`\\bphx_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindProviderKey, \"resend_key\", regexp.MustCompile(`\\bre_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"sendgrid_key\", regexp.MustCompile(`\\bSG\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}\\b`)},\n\t{SecretKindToken, \"mailgun_key\", regexp.MustCompile(`\\bkey-[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindWebhookSecret, \"stripe_webhook_secret\", regexp.MustCompile(`\\bwhsec_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"shopify_access_token\", regexp.MustCompile(`\\bshp(?:at|ca|ss)_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindAccessKey, \"aws_secret_access_key_assignment\", regexp.MustCompile(`(?i)\\b(?:aws[_-]?)?secret[_-]?access[_-]?key\\s*[=:]\\s*(\"[A-Za-z0-9/+=]{32,}\"|'[A-Za-z0-9/+=]{32,}'|[A-Za-z0-9/+=]{32,})`)},\n\t{SecretKindToken, \"twilio_key\", regexp.MustCompile(`\\bSK[0-9a-fA-F]{32}\\b`)},\n\t{SecretKindToken, \"square_token\", regexp.MustCompile(`\\bEAAA[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindCloudKey, \"digitalocean_token\", regexp.MustCompile(`\\bdop_v1_[0-9a-f]{64}\\b`)},\n\t{SecretKindToken, \"netlify_token\", regexp.MustCompile(`\\bnfp_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"railway_token\", regexp.MustCompile(`\\brailway_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindCloudKey, \"google_oauth_token\", regexp.MustCompile(`\\bya29\\.[0-9A-Za-z_-]{20,}\\b`)},\n\t{SecretKindCloudKey, \"firebase_server_key\", regexp.MustCompile(`\\bAAAA[A-Za-z0-9_-]{7,}:APA91b[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindCloudKey, \"azure_devops_pat\", regexp.MustCompile(`\\bazdpat[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"grafana_service_account_token\", regexp.MustCompile(`\\bglsa_[A-Za-z0-9_]{20,}\\b`)},\n\t{SecretKindToken, \"grafana_cloud_token\", regexp.MustCompile(`\\bglc_[A-Za-z0-9_=-]{20,}\\b`)},\n\t{SecretKindToken, \"elasticsearch_encoded_api_key\", regexp.MustCompile(`(?i)\\b(?:elastic|elasticsearch|opensearch)[_-]?api[_-]?key\\s*[=:]\\s*(\"[A-Za-z0-9+/=]{20,}\"|'[A-Za-z0-9+/=]{20,}'|[A-Za-z0-9+/=]{20,})`)},\n\t{SecretKindToken, \"metabase_session\", regexp.MustCompile(`(?i)\\b(?:metabase|mb)[_-]?session(?:[_-]?cookie)?\\s*[=:]\\s*(\"[A-Za-z0-9._=-]{12,}\"|'[A-Za-z0-9._=-]{12,}'|[A-Za-z0-9._=-]{12,})`)},\n\t{SecretKindToken, \"new_relic_key\", regexp.MustCompile(`\\b(?:NRAK|NRII)-[A-Z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"terraform_cloud_token\", regexp.MustCompile(`\\b[A-Za-z0-9]{14}\\.atlasv1\\.[A-Za-z0-9_-]{40,}\\b`)},\n\t{SecretKindToken, \"snyk_token\", regexp.MustCompile(`\\bsnyk_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"pulumi_access_token\", regexp.MustCompile(`\\bpul-[A-Fa-f0-9]{40}\\b`)},\n\t{SecretKindToken, \"databricks_pat\", regexp.MustCompile(`\\bdapi[a-f0-9]{32}\\b`)},\n\t{SecretKindToken, \"fly_token\", regexp.MustCompile(`\\bFlyV1\\s+[A-Za-z0-9+/_=:-]{20,}\\b`)},\n\t{SecretKindWebhookSecret, \"healthchecks_ping_url\", regexp.MustCompile(`https://hc-ping\\.com/[A-Za-z0-9._~/-]{16,}`)},\n\t{SecretKindWebhookSecret, \"better_uptime_heartbeat_url\", regexp.MustCompile(`https://uptime\\.betterstack\\.com/api/v1/heartbeat/[A-Za-z0-9._~/-]{16,}`)},\n\t{SecretKindWebhookSecret, \"grafana_oncall_webhook_url\", regexp.MustCompile(`https://[^/\\s\"'<>]+/integrations/v1/[A-Za-z0-9._~/-]{16,}`)},\n\t{SecretKindToken, \"langfuse_secret_key\", regexp.MustCompile(`\\bsk-lf-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"langfuse_public_key\", regexp.MustCompile(`\\bpk-lf-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"helicone_key\", regexp.MustCompile(`\\bsk-helicone-[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"promptlayer_key\", regexp.MustCompile(`\\bpl_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"openpipe_key\", regexp.MustCompile(`\\bopk_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindToken, \"portkey_key\", regexp.MustCompile(`\\bptk_[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindRegistryAuth, \"docker_auth_token\", regexp.MustCompile(`(?i)\\b(?:docker|registry|container)[_-]?(?:auth|token|password)\\s*[=:]\\s*(\"[A-Za-z0-9+/=._-]{20,}\"|'[A-Za-z0-9+/=._-]{20,}'|[A-Za-z0-9+/=._-]{20,})`)},\n\t{SecretKindRegistryAuth, \"dockerconfigjson_auth\", regexp.MustCompile(`(?i)\"auth\"\\s*:\\s*\"[A-Za-z0-9+/=]{20,}\"`)},\n\t{SecretKindPrivateKey, \"private_key_block_literal\", regexp.MustCompile(`(?s)-----BEGIN [A-Z ]*PRIVATE KEY-----.*?-----END [A-Z ]*PRIVATE KEY-----`)},\n\t{SecretKindPrivateKey, \"github_app_private_key\", regexp.MustCompile(`(?i)\\bgithub[_-]?app[_-]?private[_-]?key\\s*[=:]\\s*(\"[A-Za-z0-9+/=\\\\n-]{20,}\"|'[A-Za-z0-9+/=\\\\n-]{20,}'|[A-Za-z0-9+/=\\\\n-]{20,})`)},\n\t{SecretKindToken, \"render_api_key\", regexp.MustCompile(`\\brnd_[A-Za-z0-9]{20,}\\b`)},\n\t{SecretKindToken, \"doppler_token\", regexp.MustCompile(`\\bdp\\.pt\\.[A-Za-z0-9._-]{20,}\\b`)},\n\t{SecretKindToken, \"vault_token\", regexp.MustCompile(`\\bhvs\\.[A-Za-z0-9_-]{20,}\\b`)},\n\t{SecretKindPrivateKey, \"age_secret_key\", regexp.MustCompile(`\\bAGE-SECRET-KEY-[A-Z0-9]{20,}\\b`)},\n\t{SecretKindEncryptionKey, \"sse_customer_key_assignment\", regexp.MustCompile(`(?i)\\b(?:x[_-]?amz[_-]?)?(?:server[_-]?side[_-]?encryption[_-]customer[_-]?key|sse[_-]?customer[_-]?key|customer[_-]?provided[_-]?key)\\s*[=:]\\s*(\"[A-Za-z0-9+/=]{20,}\"|'[A-Za-z0-9+/=]{20,}'|[A-Za-z0-9+/=]{20,})`)},\n\t{SecretKindRegistryAuth, \"kubernetes_pull_secret\", regexp.MustCompile(`(?i)\\b(?:image[_-]?pull[_-]?secret|dockerconfigjson|dockercfg)\\s*[=:]\\s*(\"[A-Za-z0-9+/=._-]{20,}\"|'[A-Za-z0-9+/=._-]{20,}'|[A-Za-z0-9+/=._-]{20,})`)},\n}\n\nvar assignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:secret|token|password|passwd|pwd|passphrase|api[_-]?key|x[_-]?api[_-]?key|access[_-]?key|private[_-]?key|private[_-]?token|deploy[_-]?key|credential|signature|session|cookie|authorization|proxy[_-]?authorization|client[_-]?secret|client[_-]?token|client[_-]?assertion|refresh[_-]?token|personal[_-]?access[_-]?token|license[_-]?key|webhook[_-]?secret|signing[_-]?key|shared[_-]?access[_-]?signature|database[_-]?url|redis[_-]?url|smtp[_-]?url|smtp[_-]?dsn|smtp[_-]?connection|elasticsearch[_-]?url|opensearch[_-]?url|elastic[_-]?cloud[_-]?auth|clickhouse[_-]?url|dsn|connection[_-]?string|connectionstring|service[_-]?account|storage[_-]?key|account[_-]?key|subscription[_-]?key|tenant[_-]?secret|object[_-]?storage[_-]?signing[_-]?key|object[_-]?storage[_-]?access[_-]?key|object[_-]?storage[_-]?secret[_-]?key|aws[_-]?secret[_-]?access[_-]?key|aws[_-]?session[_-]?token|s3[_-]?secret[_-]?key|minio[_-]?root[_-]?password|minio[_-]?secret[_-]?key|r2[_-]?access|r2[_-]?secret|wasabi[_-]?access|wasabi[_-]?secret|scw[_-]?access|scw[_-]?secret|scaleway[_-]?access|scaleway[_-]?secret|vultr[_-]?access|vultr[_-]?secret|linode[_-]?access|linode[_-]?secret|oci[_-]?access|oci[_-]?secret|oci[_-]?private|oracle[_-]?access|oracle[_-]?secret|oracle[_-]?private|encryption[_-]?customer[_-]?key|customer[_-]?encryption[_-]?key|sse[_-]?customer[_-]?key|dockerconfigjson|dockercfg|image[_-]?pull[_-]?secret)[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:honeycomb|new[_-]?relic|splunk|grafana|otel|otlp|terraform|snyk|circleci|buildkite|okta|langfuse|braintrust|helicone|openpipe|promptlayer|portkey|wandb|weights[_-]?biases|weave|arize[_-]?phoenix|x[_-]?honeycomb[_-]?team|x[_-]?sf[_-]?token)[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar signedDeliveryAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:cloudfront[_-]?(?:signature|policy|expires|key[_-]?pair[_-]?id)|key[_-]?pair[_-]?id|edge[_-]?auth|akamai[_-]?signature|hdnts|hdntl|__token__|cloud[_-]?cdn[_-]?(?:signature|policy|expires|key[_-]?name|url[_-]?prefix)|url[_-]?prefix|key[_-]?name|signed[_-]?(?:cookie|policy|signature)|cdn[_-]?(?:policy|signature|token)|cf[_-]?authorization|cloudflare[_-]?access[_-]?jwt[_-]?assertion|fastly[_-]?(?:api[_-]?key|service[_-]?token|edge[_-]?auth|signature)|imgix[_-]?(?:secure[_-]?url[_-]?token|signature|sign)|bunny(?:cdn|[_-]?cdn|[_-]?storage)?[_-]?(?:api[_-]?key|token|password|signature)|mux[_-]?(?:token[_-]?id|token[_-]?secret|signing[_-]?key|signature|policy)|vercel[_-]?(?:blob[_-]?)?(?:read[_-]?write[_-]?token|token|signature))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchSignedDeliverySecretKeyPattern = regexp.MustCompile(`(?i)(fastly[_-]?(?:api[_-]?key|service[_-]?token|edge[_-]?auth|signature)|imgix[_-]?(?:secure[_-]?url[_-]?token|signature|sign)|bunny(?:cdn|[_-]?cdn|[_-]?storage)?[_-]?(?:api[_-]?key|token|password|signature)|mux[_-]?(?:token[_-]?id|token[_-]?secret|signing[_-]?key|signature|policy)|vercel[_-]?(?:blob[_-]?)?(?:read[_-]?write[_-]?token|token|signature))`)\nvar launchDataSecretKeyPattern = regexp.MustCompile(`(?i)(snowflake[_-]?(?:password|private[_-]?key|token|url|uri|dsn|connection|credential|credentials)|bigquery[_-]?(?:service[_-]?account|credentials|private[_-]?key|client[_-]?email|token|key)|google[_-]?application[_-]?credentials|gcp[_-]?(?:service[_-]?account|credentials|private[_-]?key)|databricks[_-]?(?:token|pat|host|url|dsn|client[_-]?secret|client[_-]?id)|dbt[_-]?cloud[_-]?(?:token|api[_-]?key|account[_-]?id)|airbyte[_-]?(?:api[_-]?key|client[_-]?secret|client[_-]?id|refresh[_-]?token)|fivetran[_-]?(?:api[_-]?key|api[_-]?secret|token)|motherduck[_-]?(?:token|url|dsn)|duckdb[_-]?(?:token|url|dsn)|neon[_-]?(?:database[_-]?url|connection[_-]?string|api[_-]?key)|planetscale[_-]?(?:password|token|service[_-]?token|url|dsn)|pscale[_-]?(?:password|token)|turso[_-]?(?:auth[_-]?token|database[_-]?url|url|token)|libsql[_-]?(?:auth[_-]?token|url|token)|aiven[_-]?(?:api[_-]?token|service[_-]?uri|password|url|dsn)|cockroach[_-]?(?:url|dsn|password|connection)|mongodb?[_-]?(?:uri|url|password|connection)|postgres(?:ql)?[_-]?(?:url|dsn|password|connection)|mysql[_-]?(?:url|dsn|password|connection))`)\nvar launchDataSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:snowflake[_-]?(?:password|private[_-]?key|token|url|uri|dsn|connection|credential|credentials)|bigquery[_-]?(?:service[_-]?account|credentials|private[_-]?key|client[_-]?email|token|key)|google[_-]?application[_-]?credentials|gcp[_-]?(?:service[_-]?account|credentials|private[_-]?key)|databricks[_-]?(?:token|pat|host|url|dsn|client[_-]?secret|client[_-]?id)|dbt[_-]?cloud[_-]?(?:token|api[_-]?key|account[_-]?id)|airbyte[_-]?(?:api[_-]?key|client[_-]?secret|client[_-]?id|refresh[_-]?token)|fivetran[_-]?(?:api[_-]?key|api[_-]?secret|token)|motherduck[_-]?(?:token|url|dsn)|duckdb[_-]?(?:token|url|dsn)|neon[_-]?(?:database[_-]?url|connection[_-]?string|api[_-]?key)|planetscale[_-]?(?:password|token|service[_-]?token|url|dsn)|pscale[_-]?(?:password|token)|turso[_-]?(?:auth[_-]?token|database[_-]?url|url|token)|libsql[_-]?(?:auth[_-]?token|url|token)|aiven[_-]?(?:api[_-]?token|service[_-]?uri|password|url|dsn)|cockroach[_-]?(?:url|dsn|password|connection)|mongodb?[_-]?(?:uri|url|password|connection)|postgres(?:ql)?[_-]?(?:url|dsn|password|connection)|mysql[_-]?(?:url|dsn|password|connection))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchPackageRegistrySecretKeyPattern = regexp.MustCompile(`(?i)(node[_-]?auth[_-]?token|npm(?:rc)?[_-]?(?:auth[_-]?token|token|password)|yarn[_-]?npm[_-]?(?:auth[_-]?token|token)|pnpm[_-]?(?:auth[_-]?token|token)|pypi[_-]?(?:token|password|api[_-]?token)|twine[_-]?(?:password|token)|rubygems?[_-]?(?:api[_-]?key|token)|gem[_-]?(?:host[_-]?api[_-]?key|credentials)|cargo[_-]?(?:registry[_-]?token|token)|crates[_-]?io[_-]?token|composer[_-]?(?:auth|github[_-]?oauth|gitlab[_-]?token|http[_-]?basic)|packagist[_-]?(?:token|api[_-]?key)|nuget[_-]?(?:api[_-]?key|token)|maven[_-]?(?:password|token|server[_-]?password)|gradle[_-]?(?:password|token)|jfrog[_-]?(?:access[_-]?token|api[_-]?key|password)|artifactory[_-]?(?:access[_-]?token|api[_-]?key|password)|cloudsmith[_-]?(?:api[_-]?key|token|entitlement[_-]?token)|gitlab[_-]?deploy[_-]?token|gitea[_-]?(?:token|deploy[_-]?key)|bitbucket[_-]?(?:app[_-]?password|token)|sourcegraph[_-]?token|gerrit[_-]?(?:http[_-]?password|token))`)\nvar launchPackageRegistrySecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:node[_-]?auth[_-]?token|npm(?:rc)?[_-]?(?:auth[_-]?token|token|password)|yarn[_-]?npm[_-]?(?:auth[_-]?token|token)|pnpm[_-]?(?:auth[_-]?token|token)|pypi[_-]?(?:token|password|api[_-]?token)|twine[_-]?(?:password|token)|rubygems?[_-]?(?:api[_-]?key|token)|gem[_-]?(?:host[_-]?api[_-]?key|credentials)|cargo[_-]?(?:registry[_-]?token|token)|crates[_-]?io[_-]?token|composer[_-]?(?:auth|github[_-]?oauth|gitlab[_-]?token|http[_-]?basic)|packagist[_-]?(?:token|api[_-]?key)|nuget[_-]?(?:api[_-]?key|token)|maven[_-]?(?:password|token|server[_-]?password)|gradle[_-]?(?:password|token)|jfrog[_-]?(?:access[_-]?token|api[_-]?key|password)|artifactory[_-]?(?:access[_-]?token|api[_-]?key|password)|cloudsmith[_-]?(?:api[_-]?key|token|entitlement[_-]?token)|gitlab[_-]?deploy[_-]?token|gitea[_-]?(?:token|deploy[_-]?key)|bitbucket[_-]?(?:app[_-]?password|token)|sourcegraph[_-]?token|gerrit[_-]?(?:http[_-]?password|token))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchObservabilityWebhookSecretKeyPattern = regexp.MustCompile(`(?i)(better[_-]?(?:stack|uptime)[_-]?(?:api[_-]?key|heartbeat[_-]?url|webhook[_-]?url|token)|logtail[_-]?(?:source[_-]?token|ingest[_-]?token|api[_-]?key)|cronitor[_-]?(?:api[_-]?key|ping[_-]?url|telemetry[_-]?key)|healthchecks[_-]?(?:ping[_-]?url|api[_-]?key|uuid|token)|uptime[_-]?robot[_-]?(?:api[_-]?key|token)|uptimerobot[_-]?(?:api[_-]?key|token)|honeybadger[_-]?(?:api[_-]?key|deploy[_-]?token|personal[_-]?auth[_-]?token)|rollbar[_-]?(?:access[_-]?token|post[_-]?server[_-]?item[_-]?token)|bugsnag[_-]?(?:api[_-]?key|build[_-]?api[_-]?key)|airbrake[_-]?(?:project[_-]?key|api[_-]?key)|scout[_-]?apm[_-]?(?:key|api[_-]?key)|lightstep[_-]?(?:access[_-]?token|satellite[_-]?key)|chronosphere[_-]?(?:api[_-]?token|api[_-]?key)|signoz[_-]?(?:ingestion[_-]?key|api[_-]?key)|axiom[_-]?(?:api[_-]?token|api[_-]?key|ingest[_-]?token)|logflare[_-]?(?:api[_-]?key|source[_-]?token)|sematext[_-]?(?:logs[_-]?token|app[_-]?token|api[_-]?key)|logz(?:io|[_-]?io)[_-]?(?:shipping[_-]?token|listener[_-]?token|api[_-]?token|api[_-]?key)|papertrail[_-]?(?:api[_-]?token|token))`)\nvar launchObservabilityWebhookSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:better[_-]?(?:stack|uptime)[_-]?(?:api[_-]?key|heartbeat[_-]?url|webhook[_-]?url|token)|logtail[_-]?(?:source[_-]?token|ingest[_-]?token|api[_-]?key)|cronitor[_-]?(?:api[_-]?key|ping[_-]?url|telemetry[_-]?key)|healthchecks[_-]?(?:ping[_-]?url|api[_-]?key|uuid|token)|uptime[_-]?robot[_-]?(?:api[_-]?key|token)|uptimerobot[_-]?(?:api[_-]?key|token)|honeybadger[_-]?(?:api[_-]?key|deploy[_-]?token|personal[_-]?auth[_-]?token)|rollbar[_-]?(?:access[_-]?token|post[_-]?server[_-]?item[_-]?token)|bugsnag[_-]?(?:api[_-]?key|build[_-]?api[_-]?key)|airbrake[_-]?(?:project[_-]?key|api[_-]?key)|scout[_-]?apm[_-]?(?:key|api[_-]?key)|lightstep[_-]?(?:access[_-]?token|satellite[_-]?key)|chronosphere[_-]?(?:api[_-]?token|api[_-]?key)|signoz[_-]?(?:ingestion[_-]?key|api[_-]?key)|axiom[_-]?(?:api[_-]?token|api[_-]?key|ingest[_-]?token)|logflare[_-]?(?:api[_-]?key|source[_-]?token)|sematext[_-]?(?:logs[_-]?token|app[_-]?token|api[_-]?key)|logz(?:io|[_-]?io)[_-]?(?:shipping[_-]?token|listener[_-]?token|api[_-]?token|api[_-]?key)|papertrail[_-]?(?:api[_-]?token|token))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchBillingSecretKeyPattern = regexp.MustCompile(`(?i)(paddle[_-]?(?:api[_-]?key|client[_-]?secret|auth[_-]?code|vendor[_-]?auth[_-]?code|webhook[_-]?secret)|lemon[_-]?squeezy[_-]?(?:api[_-]?key|signing[_-]?secret|webhook[_-]?secret)|lemonsqueezy[_-]?(?:api[_-]?key|signing[_-]?secret|webhook[_-]?secret)|chargebee[_-]?(?:api[_-]?key|site[_-]?api[_-]?key|webhook[_-]?secret)|recurly[_-]?(?:api[_-]?key|private[_-]?api[_-]?key|webhook[_-]?secret)|braintree[_-]?(?:private[_-]?key|access[_-]?token|merchant[_-]?account[_-]?id)|paypal[_-]?(?:client[_-]?secret|access[_-]?token|webhook[_-]?id)|adyen[_-]?(?:api[_-]?key|hmac[_-]?key|merchant[_-]?account)|taxjar[_-]?(?:api[_-]?key|token)|avalara[_-]?(?:account[_-]?id|license[_-]?key|password)|quickbooks[_-]?(?:client[_-]?secret|refresh[_-]?token|access[_-]?token)|xero[_-]?(?:client[_-]?secret|refresh[_-]?token|access[_-]?token))`)\nvar launchBillingSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:paddle[_-]?(?:api[_-]?key|client[_-]?secret|auth[_-]?code|vendor[_-]?auth[_-]?code|webhook[_-]?secret)|lemon[_-]?squeezy[_-]?(?:api[_-]?key|signing[_-]?secret|webhook[_-]?secret)|lemonsqueezy[_-]?(?:api[_-]?key|signing[_-]?secret|webhook[_-]?secret)|chargebee[_-]?(?:api[_-]?key|site[_-]?api[_-]?key|webhook[_-]?secret)|recurly[_-]?(?:api[_-]?key|private[_-]?api[_-]?key|webhook[_-]?secret)|braintree[_-]?(?:private[_-]?key|access[_-]?token|merchant[_-]?account[_-]?id)|paypal[_-]?(?:client[_-]?secret|access[_-]?token|webhook[_-]?id)|adyen[_-]?(?:api[_-]?key|hmac[_-]?key|merchant[_-]?account)|taxjar[_-]?(?:api[_-]?key|token)|avalara[_-]?(?:account[_-]?id|license[_-]?key|password)|quickbooks[_-]?(?:client[_-]?secret|refresh[_-]?token|access[_-]?token)|xero[_-]?(?:client[_-]?secret|refresh[_-]?token|access[_-]?token))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchExportRenderSecretKeyPattern = regexp.MustCompile(`(?i)(cloudconvert[_-]?(?:api[_-]?key|api[_-]?secret|webhook[_-]?secret)|convertapi[_-]?(?:secret|api[_-]?key)|browserless[_-]?(?:api[_-]?key|token)|browserbase[_-]?(?:api[_-]?key|secret)|screenshotone[_-]?(?:access[_-]?key|api[_-]?key|secret[_-]?key)|urlbox[_-]?(?:api[_-]?key|api[_-]?secret|secret)|html(?:css)?toimage[_-]?(?:api[_-]?key|user[_-]?id|password)|hcti[_-]?(?:api[_-]?key|user[_-]?id)|docraptor[_-]?(?:api[_-]?key|token)|pdfshift[_-]?(?:api[_-]?key|token)|pdfco[_-]?(?:api[_-]?key|token)|aspose[_-]?(?:client[_-]?secret|access[_-]?token|api[_-]?key)|cloudinary[_-]?(?:api[_-]?secret|auth[_-]?token)|uploadcare[_-]?(?:secret[_-]?key|private[_-]?key)|imagekit[_-]?(?:private[_-]?key|api[_-]?key)|filestack[_-]?(?:api[_-]?key|security[_-]?secret|policy|signature)|shotstack[_-]?(?:api[_-]?key|owner[_-]?id)|bannerbear[_-]?(?:api[_-]?key|project[_-]?api[_-]?key)|renderform[_-]?(?:api[_-]?key|workspace[_-]?secret)|figma[_-]?(?:personal[_-]?access[_-]?token|oauth[_-]?token|file[_-]?token|client[_-]?secret))`)\nvar launchExportRenderSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:cloudconvert[_-]?(?:api[_-]?key|api[_-]?secret|webhook[_-]?secret)|convertapi[_-]?(?:secret|api[_-]?key)|browserless[_-]?(?:api[_-]?key|token)|browserbase[_-]?(?:api[_-]?key|secret)|screenshotone[_-]?(?:access[_-]?key|api[_-]?key|secret[_-]?key)|urlbox[_-]?(?:api[_-]?key|api[_-]?secret|secret)|html(?:css)?toimage[_-]?(?:api[_-]?key|user[_-]?id|password)|hcti[_-]?(?:api[_-]?key|user[_-]?id)|docraptor[_-]?(?:api[_-]?key|token)|pdfshift[_-]?(?:api[_-]?key|token)|pdfco[_-]?(?:api[_-]?key|token)|aspose[_-]?(?:client[_-]?secret|access[_-]?token|api[_-]?key)|cloudinary[_-]?(?:api[_-]?secret|auth[_-]?token)|uploadcare[_-]?(?:secret[_-]?key|private[_-]?key)|imagekit[_-]?(?:private[_-]?key|api[_-]?key)|filestack[_-]?(?:api[_-]?key|security[_-]?secret|policy|signature)|shotstack[_-]?(?:api[_-]?key|owner[_-]?id)|bannerbear[_-]?(?:api[_-]?key|project[_-]?api[_-]?key)|renderform[_-]?(?:api[_-]?key|workspace[_-]?secret)|figma[_-]?(?:personal[_-]?access[_-]?token|oauth[_-]?token|file[_-]?token|client[_-]?secret))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchCrawlerResearchSecretKeyPattern = regexp.MustCompile(`(?i)(firecrawl[_-]?(?:api[_-]?key|token|secret|webhook[_-]?secret)|tavily[_-]?(?:api[_-]?key|token|secret)|exa[_-]?(?:api[_-]?key|token|secret)|serpapi[_-]?(?:api[_-]?key|token|secret)|serper[_-]?(?:api[_-]?key|token|secret)|apify[_-]?(?:api[_-]?key|token|secret)|bright[_-]?data[_-]?(?:api[_-]?key|token|password|proxy[_-]?password|customer[_-]?id)|zyte[_-]?(?:api[_-]?key|token|password)|scrapingbee[_-]?(?:api[_-]?key|token)|scraperapi[_-]?(?:api[_-]?key|token)|crawlbase[_-]?(?:api[_-]?key|token)|diffbot[_-]?(?:api[_-]?key|token)|jina[_-]?(?:api[_-]?key|token)|searchapi[_-]?(?:api[_-]?key|token|secret)|crawler[_-]?(?:api[_-]?key|token|secret|proxy[_-]?password|proxy[_-]?authorization|webhook[_-]?secret)|web[_-]?research[_-]?(?:api[_-]?key|token|secret))`)\nvar launchCrawlerResearchSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:firecrawl[_-]?(?:api[_-]?key|token|secret|webhook[_-]?secret)|tavily[_-]?(?:api[_-]?key|token|secret)|exa[_-]?(?:api[_-]?key|token|secret)|serpapi[_-]?(?:api[_-]?key|token|secret)|serper[_-]?(?:api[_-]?key|token|secret)|apify[_-]?(?:api[_-]?key|token|secret)|bright[_-]?data[_-]?(?:api[_-]?key|token|password|proxy[_-]?password|customer[_-]?id)|zyte[_-]?(?:api[_-]?key|token|password)|scrapingbee[_-]?(?:api[_-]?key|token)|scraperapi[_-]?(?:api[_-]?key|token)|crawlbase[_-]?(?:api[_-]?key|token)|diffbot[_-]?(?:api[_-]?key|token)|jina[_-]?(?:api[_-]?key|token)|searchapi[_-]?(?:api[_-]?key|token|secret)|crawler[_-]?(?:api[_-]?key|token|secret|proxy[_-]?password|proxy[_-]?authorization|webhook[_-]?secret)|web[_-]?research[_-]?(?:api[_-]?key|token|secret))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchDeployPlatformSecretKeyPattern = regexp.MustCompile(`(?i)(vercel[_-]?(?:token|auth[_-]?token|access[_-]?token|team[_-]?token|deploy[_-]?hook|project[_-]?protection[_-]?bypass|deployment[_-]?protection[_-]?bypass|automation[_-]?bypass[_-]?secret)|netlify[_-]?(?:auth[_-]?token|access[_-]?token|deploy[_-]?hook|build[_-]?hook|hook[_-]?url|site[_-]?deploy[_-]?key)|render[_-]?(?:api[_-]?key|deploy[_-]?hook|deploy[_-]?hook[_-]?url|service[_-]?token)|railway[_-]?(?:token|api[_-]?token|project[_-]?token)|fly(?:io)?[_-]?(?:token|access[_-]?token|deploy[_-]?token)|cloudflare[_-]?(?:api[_-]?token|global[_-]?api[_-]?key|tunnel[_-]?token|access[_-]?client[_-]?secret|turnstile[_-]?secret(?:[_-]?key)?|pages[_-]?deploy[_-]?hook)|cf[_-]?(?:api[_-]?token|tunnel[_-]?token|turnstile[_-]?secret)|recaptcha[_-]?(?:secret|secret[_-]?key)|hcaptcha[_-]?(?:secret|secret[_-]?key)|doppler[_-]?(?:token|service[_-]?token|project[_-]?token)|infisical[_-]?(?:token|service[_-]?token|client[_-]?secret|universal[_-]?auth[_-]?secret)|onepassword[_-]?(?:service[_-]?account[_-]?token|connect[_-]?token)|op[_-]?(?:service[_-]?account[_-]?token|connect[_-]?token)|vault[_-]?(?:token|approle[_-]?secret[_-]?id|transit[_-]?key)|sops[_-]?(?:age[_-]?key|pgp[_-]?key|kms[_-]?key|key[_-]?file))`)\nvar launchDeployPlatformSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:vercel[_-]?(?:token|auth[_-]?token|access[_-]?token|team[_-]?token|deploy[_-]?hook|project[_-]?protection[_-]?bypass|deployment[_-]?protection[_-]?bypass|automation[_-]?bypass[_-]?secret)|netlify[_-]?(?:auth[_-]?token|access[_-]?token|deploy[_-]?hook|build[_-]?hook|hook[_-]?url|site[_-]?deploy[_-]?key)|render[_-]?(?:api[_-]?key|deploy[_-]?hook|deploy[_-]?hook[_-]?url|service[_-]?token)|railway[_-]?(?:token|api[_-]?token|project[_-]?token)|fly(?:io)?[_-]?(?:token|access[_-]?token|deploy[_-]?token)|cloudflare[_-]?(?:api[_-]?token|global[_-]?api[_-]?key|tunnel[_-]?token|access[_-]?client[_-]?secret|turnstile[_-]?secret(?:[_-]?key)?|pages[_-]?deploy[_-]?hook)|cf[_-]?(?:api[_-]?token|tunnel[_-]?token|turnstile[_-]?secret)|recaptcha[_-]?(?:secret|secret[_-]?key)|hcaptcha[_-]?(?:secret|secret[_-]?key)|doppler[_-]?(?:token|service[_-]?token|project[_-]?token)|infisical[_-]?(?:token|service[_-]?token|client[_-]?secret|universal[_-]?auth[_-]?secret)|onepassword[_-]?(?:service[_-]?account[_-]?token|connect[_-]?token)|op[_-]?(?:service[_-]?account[_-]?token|connect[_-]?token)|vault[_-]?(?:token|approle[_-]?secret[_-]?id|transit[_-]?key)|sops[_-]?(?:age[_-]?key|pgp[_-]?key|kms[_-]?key|key[_-]?file))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchBackupIncidentSecretKeyPattern = regexp.MustCompile(`(?i)(restic[_-]?(?:password|repository|repo|key|aws[_-]?access|aws[_-]?secret)|kopia[_-]?(?:password|repo(?:sitory)?|server[_-]?password|tls[_-]?key)|borg[_-]?(?:passphrase|repo(?:sitory)?|key)|pgbackrest[_-]?(?:repo|password|cipher[_-]?pass|s3[_-]?(?:key|secret)|gcs[_-]?key)|wal[_-]?g[_-]?(?:s3[_-]?(?:prefix|access|secret)|gcs[_-]?(?:prefix|key)|azure[_-]?(?:account|key)|compression[_-]?passphrase)|walg[_-]?(?:s3[_-]?(?:prefix|access|secret)|gcs[_-]?(?:prefix|key)|azure[_-]?(?:account|key)|compression[_-]?passphrase)|litestream[_-]?(?:replica[_-]?(?:url|access|secret|key)|s3[_-]?(?:access|secret)|gcs[_-]?key)|backup[_-]?(?:repository|repo|password|passphrase|encryption[_-]?key|signing[_-]?key)|age[_-]?(?:identity|secret[_-]?key)|gpg[_-]?(?:private[_-]?key|passphrase)|pgp[_-]?(?:private[_-]?key|passphrase)|rootly[_-]?(?:api[_-]?key|token)|firehydrant[_-]?(?:api[_-]?key|token)|statuspage[_-]?(?:api[_-]?key|token)|victorops[_-]?(?:api[_-]?key|routing[_-]?key)|splunk[_-]?on[_-]?call[_-]?(?:api[_-]?key|routing[_-]?key)|squadcast[_-]?(?:api[_-]?key|token|webhook[_-]?secret))`)\nvar launchBackupIncidentSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:restic[_-]?(?:password|repository|repo|key|aws[_-]?access|aws[_-]?secret)|kopia[_-]?(?:password|repo(?:sitory)?|server[_-]?password|tls[_-]?key)|borg[_-]?(?:passphrase|repo(?:sitory)?|key)|pgbackrest[_-]?(?:repo|password|cipher[_-]?pass|s3[_-]?(?:key|secret)|gcs[_-]?key)|wal[_-]?g[_-]?(?:s3[_-]?(?:prefix|access|secret)|gcs[_-]?(?:prefix|key)|azure[_-]?(?:account|key)|compression[_-]?passphrase)|walg[_-]?(?:s3[_-]?(?:prefix|access|secret)|gcs[_-]?(?:prefix|key)|azure[_-]?(?:account|key)|compression[_-]?passphrase)|litestream[_-]?(?:replica[_-]?(?:url|access|secret|key)|s3[_-]?(?:access|secret)|gcs[_-]?key)|backup[_-]?(?:repository|repo|password|passphrase|encryption[_-]?key|signing[_-]?key)|age[_-]?(?:identity|secret[_-]?key)|gpg[_-]?(?:private[_-]?key|passphrase)|pgp[_-]?(?:private[_-]?key|passphrase)|rootly[_-]?(?:api[_-]?key|token)|firehydrant[_-]?(?:api[_-]?key|token)|statuspage[_-]?(?:api[_-]?key|token)|victorops[_-]?(?:api[_-]?key|routing[_-]?key)|splunk[_-]?on[_-]?call[_-]?(?:api[_-]?key|routing[_-]?key)|squadcast[_-]?(?:api[_-]?key|token|webhook[_-]?secret))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar launchMalwareScannerSecretKeyPattern = regexp.MustCompile(`(?i)(malware[_-]?(?:scan|scanner)?[_-]?(?:api[_-]?key|key|token|secret|webhook[_-]?secret|hmac[_-]?secret|client[_-]?secret|auth|authorization)|antivirus[_-]?(?:api[_-]?key|key|token|secret|license)|av[_-]?(?:api[_-]?key|token|secret|license[_-]?key)|clamav[_-]?(?:password|token|auth|api[_-]?key|key)|icap[_-]?(?:password|token|auth|api[_-]?key)|yara[_-]?(?:signing[_-]?key|private[_-]?key|token|secret)|virustotal[_-]?(?:api[_-]?key|apikey|key|token)|vt[_-]?(?:api[_-]?key|key|token)|google[_-]?safe[_-]?browsing[_-]?(?:api[_-]?key|key)|safe[_-]?browsing[_-]?(?:api[_-]?key|key)|opswat[_-]?(?:api[_-]?key|key|token)|metadefender[_-]?(?:api[_-]?key|key|token)|crowdstrike[_-]?(?:api[_-]?key|client[_-]?secret|token)|sentinelone[_-]?(?:api[_-]?token|token|secret)|sophos[_-]?(?:client[_-]?secret|api[_-]?key|token)|defender[_-]?(?:client[_-]?secret|api[_-]?key|token)|microsoft[_-]?defender[_-]?(?:client[_-]?secret|api[_-]?key|token))`)\nvar launchMalwareScannerSecretAssignmentPattern = regexp.MustCompile(`(?i)\\b([A-Za-z0-9_.-]*(?:malware[_-]?(?:scan|scanner)?[_-]?(?:api[_-]?key|key|token|secret|webhook[_-]?secret|hmac[_-]?secret|client[_-]?secret|auth|authorization)|antivirus[_-]?(?:api[_-]?key|key|token|secret|license)|av[_-]?(?:api[_-]?key|token|secret|license[_-]?key)|clamav[_-]?(?:password|token|auth|api[_-]?key|key)|icap[_-]?(?:password|token|auth|api[_-]?key)|yara[_-]?(?:signing[_-]?key|private[_-]?key|token|secret)|virustotal[_-]?(?:api[_-]?key|apikey|key|token)|vt[_-]?(?:api[_-]?key|key|token)|google[_-]?safe[_-]?browsing[_-]?(?:api[_-]?key|key)|safe[_-]?browsing[_-]?(?:api[_-]?key|key)|opswat[_-]?(?:api[_-]?key|key|token)|metadefender[_-]?(?:api[_-]?key|key|token)|crowdstrike[_-]?(?:api[_-]?key|client[_-]?secret|token)|sentinelone[_-]?(?:api[_-]?token|token|secret)|sophos[_-]?(?:client[_-]?secret|api[_-]?key|token)|defender[_-]?(?:client[_-]?secret|api[_-]?key|token)|microsoft[_-]?defender[_-]?(?:client[_-]?secret|api[_-]?key|token))[A-Za-z0-9_.-]*)\\s*([=:])\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;&]+)`)\nvar embeddedURLPattern = regexp.MustCompile(`[A-Za-z][A-Za-z0-9+.-]*://[^\\s\"'<>]+`)\n\ntype MalwareScanStatus string\n\nconst (\n\tMalwareScanStatusClean MalwareScanStatus = \"clean\"\n\tMalwareScanStatusSuspicious MalwareScanStatus = \"suspicious\"\n\tMalwareScanStatusUnavailable MalwareScanStatus = \"unavailable\"\n\tMalwareScanStatusError MalwareScanStatus = \"error\"\n)\n\ntype MalwareScanTarget struct {\n\tTenantID string `json:\"tenant_id\"`\n\tObjectKey string `json:\"object_key\"`\n\tContentType string `json:\"content_type\"`\n\tByteSize int64 `json:\"byte_size\"`\n\tChecksum string `json:\"checksum,omitempty\"`\n\tMetadata map[string]string `json:\"metadata,omitempty\"`\n}\n\ntype MalwareScanResult struct {\n\tStatus MalwareScanStatus `json:\"status\"`\n\tProvider string `json:\"provider\"`\n\tSignature string `json:\"signature\"`\n\tRationale string `json:\"rationale\"`\n\tScannedAt time.Time `json:\"scanned_at\"`\n\tMetadata map[string]string `json:\"metadata,omitempty\"`\n}\n\ntype MalwareScanner interface {\n\tScan(ctx context.Context, target MalwareScanTarget) (MalwareScanResult, error)\n}\n\ntype HTTPMalwareScanner struct {\n\tEndpoint string\n\tAPIKey string\n\tProvider string\n\tClient *http.Client\n\tTimeout time.Duration\n\tDenyLocalEndpoints bool\n\tNow func() time.Time\n}\n\nfunc (s HTTPMalwareScanner) Scan(ctx context.Context, target MalwareScanTarget) (MalwareScanResult, error) {\n\tendpoint := strings.TrimSpace(s.Endpoint)\n\tif endpoint == \"\" {\n\t\treturn MalwareScanResult{}, errors.New(\"malware scan endpoint is required\")\n\t}\n\tif err := validateMalwareScanEndpoint(endpoint, s.DenyLocalEndpoints); err != nil {\n\t\treturn MalwareScanResult{}, err\n\t}\n\tif strings.TrimSpace(target.TenantID) == \"\" || strings.TrimSpace(target.ObjectKey) == \"\" {\n\t\treturn MalwareScanResult{}, errors.New(\"malware scan tenant_id and object_key are required\")\n\t}\n\ttarget.Metadata = RedactStringMap(target.Metadata)\n\tbody, err := json.Marshal(target)\n\tif err != nil {\n\t\treturn MalwareScanResult{}, err\n\t}\n\tif s.Timeout > 0 {\n\t\tvar cancel context.CancelFunc\n\t\tctx, cancel = context.WithTimeout(ctx, s.Timeout)\n\t\tdefer cancel()\n\t}\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn MalwareScanResult{}, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\tif strings.TrimSpace(s.APIKey) != \"\" {\n\t\treq.Header.Set(\"Authorization\", \"Bearer \"+strings.TrimSpace(s.APIKey))\n\t}\n\tclient := malwareScanHTTPClient(s.Client)\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tif resp != nil && resp.Body != nil {\n\t\t\t_ = resp.Body.Close()\n\t\t}\n\t\treturn MalwareScanResult{}, errors.New(RedactString(err.Error()))\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\tlimited, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))\n\t\treturn MalwareScanResult{}, fmt.Errorf(\"malware scan endpoint returned %d: %s\", resp.StatusCode, RedactString(strings.TrimSpace(string(limited))))\n\t}\n\tvar result MalwareScanResult\n\tif err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&result); err != nil {\n\t\treturn MalwareScanResult{}, err\n\t}\n\tstatus, ok := NormalizeMalwareScanStatus(result.Status)\n\tif !ok {\n\t\treturn MalwareScanResult{}, fmt.Errorf(\"malware scan endpoint returned unsupported status %q\", RedactString(string(result.Status)))\n\t}\n\tresult.Status = status\n\tresult.Provider = RedactString(strings.TrimSpace(result.Provider))\n\tif result.Provider == \"\" {\n\t\tresult.Provider = strings.TrimSpace(s.Provider)\n\t}\n\tif result.Provider == \"\" {\n\t\tresult.Provider = \"http\"\n\t}\n\tresult.Signature = RedactString(strings.TrimSpace(result.Signature))\n\tif result.Signature == \"\" {\n\t\tresult.Signature = \"http-v1\"\n\t}\n\tresult.Rationale = RedactString(result.Rationale)\n\tif result.ScannedAt.IsZero() {\n\t\tresult.ScannedAt = s.clock()\n\t}\n\tresult.Metadata = RedactStringMap(result.Metadata)\n\treturn result, nil\n}\n\nfunc validateMalwareScanEndpoint(endpoint string, denyLocalEndpoints bool) error {\n\tparsed, err := url.ParseRequestURI(endpoint)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"malware scan endpoint must be a URL: %v\", err)\n\t}\n\tif parsed.Scheme != \"http\" && parsed.Scheme != \"https\" {\n\t\treturn errors.New(\"malware scan endpoint must use http or https\")\n\t}\n\tif parsed.Host == \"\" {\n\t\treturn errors.New(\"malware scan endpoint must include host\")\n\t}\n\tif parsed.User != nil {\n\t\treturn errors.New(\"malware scan endpoint must not include credentials\")\n\t}\n\tif parsed.RawQuery != \"\" {\n\t\treturn errors.New(\"malware scan endpoint must not include query parameters\")\n\t}\n\tif parsed.Fragment != \"\" || strings.Contains(endpoint, \"#\") {\n\t\treturn errors.New(\"malware scan endpoint must not include a fragment\")\n\t}\n\tif denyLocalEndpoints && isLocalServiceHost(parsed.Hostname()) {\n\t\treturn errors.New(\"malware scan endpoint must not target localhost or private IP\")\n\t}\n\treturn nil\n}\n\nfunc isLocalServiceHost(host string) bool {\n\thost = strings.Trim(strings.ToLower(strings.TrimSpace(host)), \"[]\")\n\tswitch host {\n\tcase \"\", \"localhost\", \"localhost.localdomain\":\n\t\treturn true\n\t}\n\tip := net.ParseIP(host)\n\tif ip == nil {\n\t\treturn false\n\t}\n\treturn ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsUnspecified()\n}\n\nfunc malwareScanHTTPClient(base *http.Client) *http.Client {\n\tif base == nil {\n\t\tbase = http.DefaultClient\n\t}\n\tclient := *base\n\tclient.CheckRedirect = func(_ *http.Request, _ []*http.Request) error {\n\t\treturn errors.New(\"malware scan endpoint redirect denied\")\n\t}\n\treturn &client\n}\n\nfunc NormalizeMalwareScanStatus(status MalwareScanStatus) (MalwareScanStatus, bool) {\n\tswitch MalwareScanStatus(strings.ToLower(strings.TrimSpace(string(status)))) {\n\tcase MalwareScanStatusClean:\n\t\treturn MalwareScanStatusClean, true\n\tcase MalwareScanStatusSuspicious:\n\t\treturn MalwareScanStatusSuspicious, true\n\tcase MalwareScanStatusUnavailable, \"\":\n\t\treturn MalwareScanStatusUnavailable, true\n\tcase MalwareScanStatusError:\n\t\treturn MalwareScanStatusError, true\n\tdefault:\n\t\treturn \"\", false\n\t}\n}\n\nfunc (s HTTPMalwareScanner) clock() time.Time {\n\tif s.Now != nil {\n\t\treturn s.Now().UTC()\n\t}\n\treturn time.Now().UTC()\n}\n\ntype PlaceholderMalwareScanner struct {\n\tProvider string\n\tNow func() time.Time\n}\n\nfunc (s PlaceholderMalwareScanner) Scan(ctx context.Context, target MalwareScanTarget) (MalwareScanResult, error) {\n\tif err := ctx.Err(); err != nil {\n\t\treturn MalwareScanResult{}, err\n\t}\n\tstatus := MalwareScanStatusUnavailable\n\trationale := \"malware scanning interface is configured but no production scanner is connected\"\n\tif strings.EqualFold(strings.TrimSpace(target.Metadata[\"stage0_force_malware_status\"]), string(MalwareScanStatusSuspicious)) {\n\t\tstatus = MalwareScanStatusSuspicious\n\t\trationale = \"deterministic placeholder suspicious result requested by metadata\"\n\t}\n\tprovider := strings.TrimSpace(s.Provider)\n\tif provider == \"\" {\n\t\tprovider = \"stage0-placeholder\"\n\t}\n\tnow := time.Now().UTC()\n\tif s.Now != nil {\n\t\tnow = s.Now().UTC()\n\t}\n\treturn MalwareScanResult{\n\t\tStatus: status,\n\t\tProvider: provider,\n\t\tSignature: \"placeholder-v1\",\n\t\tRationale: rationale,\n\t\tScannedAt: now,\n\t}, nil\n}\n\nfunc ClassifyKey(key string) []SecretFinding {\n\tkey = strings.TrimSpace(key)\n\tnormalized := normalizeSecretKey(key)\n\tif normalized == \"path\" {\n\t\treturn nil\n\t}\n\tif isPublicIncidentMetadataKey(normalized) {\n\t\treturn nil\n\t}\n\tif key == \"\" ||\n\t\t(!sensitiveKeyPattern.MatchString(key) && !sensitiveKeyPattern.MatchString(normalized) &&\n\t\t\t!launchDataSecretKeyPattern.MatchString(key) && !launchDataSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchPackageRegistrySecretKeyPattern.MatchString(key) && !launchPackageRegistrySecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchObservabilityWebhookSecretKeyPattern.MatchString(key) && !launchObservabilityWebhookSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchBillingSecretKeyPattern.MatchString(key) && !launchBillingSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchExportRenderSecretKeyPattern.MatchString(key) && !launchExportRenderSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchCrawlerResearchSecretKeyPattern.MatchString(key) && !launchCrawlerResearchSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchDeployPlatformSecretKeyPattern.MatchString(key) && !launchDeployPlatformSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchBackupIncidentSecretKeyPattern.MatchString(key) && !launchBackupIncidentSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchMalwareScannerSecretKeyPattern.MatchString(key) && !launchMalwareScannerSecretKeyPattern.MatchString(normalized) &&\n\t\t\t!launchSignedDeliverySecretKeyPattern.MatchString(key) && !launchSignedDeliverySecretKeyPattern.MatchString(normalized)) {\n\t\treturn nil\n\t}\n\tlower := strings.ToLower(key) + \"_\" + normalized\n\tkind := SecretKindSensitiveKey\n\tswitch {\n\tcase launchDeployPlatformSecretKeyPattern.MatchString(key) || launchDeployPlatformSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"api_key\") || strings.Contains(lower, \"global_api_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tcase strings.Contains(lower, \"deploy_hook\") || strings.Contains(lower, \"build_hook\") || strings.Contains(lower, \"hook_url\") || strings.Contains(lower, \"pages_deploy_hook\"):\n\t\t\tkind = SecretKindWebhookSecret\n\t\tcase strings.Contains(lower, \"bypass\") || strings.Contains(lower, \"secret\") || strings.Contains(lower, \"approle_secret_id\") || strings.Contains(lower, \"client_secret\"):\n\t\t\tkind = SecretKindCredential\n\t\tcase strings.Contains(lower, \"age_key\") || strings.Contains(lower, \"pgp_key\") || strings.Contains(lower, \"kms_key\") || strings.Contains(lower, \"transit_key\") || strings.Contains(lower, \"key_file\"):\n\t\t\tkind = SecretKindEncryptionKey\n\t\tcase strings.Contains(lower, \"deploy_key\"):\n\t\t\tkind = SecretKindPrivateKey\n\t\tdefault:\n\t\t\tkind = SecretKindToken\n\t\t}\n\tcase launchSignedDeliverySecretKeyPattern.MatchString(key) || launchSignedDeliverySecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"password\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"api_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tcase strings.Contains(lower, \"signing_key\"):\n\t\t\tkind = SecretKindPrivateKey\n\t\tdefault:\n\t\t\tkind = SecretKindSignedURL\n\t\t}\n\tcase strings.Contains(lower, \"docker\") || strings.Contains(lower, \"registry\"):\n\t\tkind = SecretKindRegistryAuth\n\tcase strings.Contains(lower, \"dockercfg\") || strings.Contains(lower, \"pull_secret\"):\n\t\tkind = SecretKindRegistryAuth\n\tcase strings.Contains(lower, \"password\") || strings.Contains(lower, \"passwd\") || strings.Contains(lower, \"pwd\"):\n\t\tkind = SecretKindPassword\n\tcase strings.Contains(lower, \"encryption_customer_key\") || strings.Contains(lower, \"customer_encryption_key\") || strings.Contains(lower, \"sse_customer_key\"):\n\t\tkind = SecretKindEncryptionKey\n\tcase strings.Contains(lower, \"private\") && (strings.Contains(lower, \"key\") || strings.Contains(lower, \"token\")):\n\t\tkind = SecretKindPrivateKey\n\tcase strings.Contains(lower, \"deploy\") && strings.Contains(lower, \"key\"):\n\t\tkind = SecretKindPrivateKey\n\tcase strings.Contains(lower, \"api\") && strings.Contains(lower, \"key\"):\n\t\tkind = SecretKindAPIKey\n\tcase (strings.Contains(lower, \"r2\") || strings.Contains(lower, \"wasabi\") || strings.Contains(lower, \"scw\") ||\n\t\tstrings.Contains(lower, \"scaleway\") || strings.Contains(lower, \"vultr\") || strings.Contains(lower, \"linode\") ||\n\t\tstrings.Contains(lower, \"oci\") || strings.Contains(lower, \"oracle\")) &&\n\t\t(strings.Contains(lower, \"secret\") || strings.Contains(lower, \"private\")):\n\t\tkind = SecretKindCloudKey\n\tcase strings.Contains(lower, \"r2\") && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"wasabi\") && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"scw\") && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"scaleway\") && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"vultr\") && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"linode\") && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase (strings.Contains(lower, \"oci\") || strings.Contains(lower, \"oracle\")) && strings.Contains(lower, \"access\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"access\") && strings.Contains(lower, \"key\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"account\") && strings.Contains(lower, \"key\"):\n\t\tkind = SecretKindAccessKey\n\tcase strings.Contains(lower, \"subscription\") && strings.Contains(lower, \"key\"):\n\t\tkind = SecretKindAccessKey\n\tcase launchMalwareScannerSecretKeyPattern.MatchString(key) || launchMalwareScannerSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"password\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"webhook\") || strings.Contains(lower, \"hmac\"):\n\t\t\tkind = SecretKindWebhookSecret\n\t\tcase strings.Contains(lower, \"authorization\") || strings.Contains(lower, \"auth\"):\n\t\t\tkind = SecretKindAuthorization\n\t\tcase strings.Contains(lower, \"client_secret\"):\n\t\t\tkind = SecretKindCredential\n\t\tcase strings.Contains(lower, \"signing_key\") || strings.Contains(lower, \"private_key\"):\n\t\t\tkind = SecretKindPrivateKey\n\t\tcase strings.Contains(lower, \"api_key\") || strings.Contains(lower, \"apikey\") || strings.HasSuffix(lower, \"_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tcase strings.Contains(lower, \"token\"):\n\t\t\tkind = SecretKindToken\n\t\tdefault:\n\t\t\tkind = SecretKindCredential\n\t\t}\n\tcase strings.Contains(lower, \"webhook\") || strings.Contains(lower, \"signing\"):\n\t\tkind = SecretKindWebhookSecret\n\tcase strings.Contains(lower, \"authorization\"):\n\t\tkind = SecretKindAuthorization\n\tcase strings.Contains(lower, \"cookie\"):\n\t\tkind = SecretKindCookie\n\tcase strings.Contains(lower, \"grafana\") && strings.Contains(lower, \"token\"):\n\t\tkind = SecretKindToken\n\tcase strings.Contains(lower, \"service\") && strings.Contains(lower, \"account\"):\n\t\tkind = SecretKindServiceAcct\n\tcase strings.Contains(lower, \"google_application_credentials\") ||\n\t\tstrings.Contains(lower, \"gcp_service_account\") ||\n\t\tstrings.Contains(lower, \"bigquery_service_account\"):\n\t\tkind = SecretKindServiceAcct\n\tcase strings.Contains(lower, \"snowflake\") || strings.Contains(lower, \"databricks\") ||\n\t\tstrings.Contains(lower, \"dbt_cloud\") || strings.Contains(lower, \"airbyte\") ||\n\t\tstrings.Contains(lower, \"fivetran\") || strings.Contains(lower, \"motherduck\") ||\n\t\tstrings.Contains(lower, \"duckdb\") || strings.Contains(lower, \"neon\") ||\n\t\tstrings.Contains(lower, \"planetscale\") || strings.Contains(lower, \"pscale\") ||\n\t\tstrings.Contains(lower, \"turso\") || strings.Contains(lower, \"libsql\") ||\n\t\tstrings.Contains(lower, \"aiven\") || strings.Contains(lower, \"cockroach\") ||\n\t\tstrings.Contains(lower, \"mongodb\") || strings.Contains(lower, \"mongo_uri\") ||\n\t\tstrings.Contains(lower, \"postgres\") || strings.Contains(lower, \"mysql\"):\n\t\tkind = SecretKindCredential\n\tcase launchPackageRegistrySecretKeyPattern.MatchString(key) || launchPackageRegistrySecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"password\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"api_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tcase strings.Contains(lower, \"deploy_key\"):\n\t\t\tkind = SecretKindPrivateKey\n\t\tcase strings.Contains(lower, \"auth\") || strings.Contains(lower, \"oauth\"):\n\t\t\tkind = SecretKindCredential\n\t\tdefault:\n\t\t\tkind = SecretKindToken\n\t\t}\n\tcase launchObservabilityWebhookSecretKeyPattern.MatchString(key) || launchObservabilityWebhookSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"webhook\") || strings.Contains(lower, \"heartbeat_url\") || strings.Contains(lower, \"ping_url\"):\n\t\t\tkind = SecretKindWebhookSecret\n\t\tcase strings.Contains(lower, \"api_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tdefault:\n\t\t\tkind = SecretKindToken\n\t\t}\n\tcase launchBillingSecretKeyPattern.MatchString(key) || launchBillingSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"password\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"webhook\") || strings.Contains(lower, \"signing\") || strings.Contains(lower, \"hmac\"):\n\t\t\tkind = SecretKindWebhookSecret\n\t\tcase strings.Contains(lower, \"private_key\"):\n\t\t\tkind = SecretKindPrivateKey\n\t\tcase strings.Contains(lower, \"api_key\") || strings.Contains(lower, \"license_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tcase strings.Contains(lower, \"client_secret\"):\n\t\t\tkind = SecretKindCredential\n\t\tcase strings.Contains(lower, \"merchant_account\") || strings.Contains(lower, \"account_id\"):\n\t\t\tkind = SecretKindCredential\n\t\tdefault:\n\t\t\tkind = SecretKindToken\n\t\t}\n\tcase launchExportRenderSecretKeyPattern.MatchString(key) || launchExportRenderSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"password\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"private\") || strings.Contains(lower, \"secret\") || strings.Contains(lower, \"signature\"):\n\t\t\tkind = SecretKindCredential\n\t\tcase strings.Contains(lower, \"webhook\"):\n\t\t\tkind = SecretKindWebhookSecret\n\t\tcase strings.Contains(lower, \"api_key\") || strings.Contains(lower, \"access_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tcase strings.Contains(lower, \"figma\"):\n\t\t\tkind = SecretKindProviderKey\n\t\tdefault:\n\t\t\tkind = SecretKindToken\n\t\t}\n\tcase launchCrawlerResearchSecretKeyPattern.MatchString(key) || launchCrawlerResearchSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"webhook\"):\n\t\t\tkind = SecretKindWebhookSecret\n\t\tcase strings.Contains(lower, \"password\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"proxy_authorization\"):\n\t\t\tkind = SecretKindAuthorization\n\t\tcase strings.Contains(lower, \"api_key\"):\n\t\t\tkind = SecretKindAPIKey\n\t\tdefault:\n\t\t\tkind = SecretKindToken\n\t\t}\n\tcase launchBackupIncidentSecretKeyPattern.MatchString(key) || launchBackupIncidentSecretKeyPattern.MatchString(normalized):\n\t\tswitch {\n\t\tcase strings.Contains(lower, \"password\") || strings.Contains(lower, \"passphrase\") || strings.Contains(lower, \"cipher_pass\"):\n\t\t\tkind = SecretKindPassword\n\t\tcase strings.Contains(lower, \"private\") || strings.Contains(lower, \"identity\") || strings.Contains(lower, \"encryption_key\") || strings.Contains(lower, \"signing_key\"):\n\t\t\tkind = SecretKindPrivateKey\n\t\tcase strings.Contains(lower, \"repository\") || strings.Contains(lower, \"repo\") || strings.Contains(lower, \"replica_url\") || strings.Contains(lower, \"prefix\"):\n\t\t\tkind = SecretKindCredential\n\t\tcase strings.Contains(lower, \"rootly\") || strings.Contains(lower, \"firehydrant\") || strings.Contains(lower, \"statuspage\") ||\n\t\t\tstrings.Contains(lower, \"victorops\") || strings.Contains(lower, \"splunk_on_call\") || strings.Contains(lower, \"squadcast\"):\n\t\t\tkind = SecretKindToken\n\t\tcase strings.Contains(lower, \"s3\") || strings.Contains(lower, \"gcs\") || strings.Contains(lower, \"azure\"):\n\t\t\tkind = SecretKindCloudKey\n\t\tdefault:\n\t\t\tkind = SecretKindCredential\n\t\t}\n\tcase strings.Contains(lower, \"sentry\") || strings.Contains(lower, \"datadog\") || strings.Contains(lower, \"honeycomb\") ||\n\t\tstrings.Contains(lower, \"new_relic\") || strings.Contains(lower, \"splunk\") || strings.Contains(lower, \"grafana\") ||\n\t\tstrings.Contains(lower, \"otel\") || strings.Contains(lower, \"otlp\") ||\n\t\tstrings.Contains(lower, \"posthog\") || strings.Contains(lower, \"segment\") || strings.Contains(lower, \"amplitude\") ||\n\t\tstrings.Contains(lower, \"mixpanel\") || strings.Contains(lower, \"launchdarkly\") ||\n\t\tstrings.Contains(lower, \"langfuse\") || strings.Contains(lower, \"braintrust\") ||\n\t\tstrings.Contains(lower, \"helicone\") || strings.Contains(lower, \"openpipe\") ||\n\t\tstrings.Contains(lower, \"promptlayer\") || strings.Contains(lower, \"portkey\") ||\n\t\tstrings.Contains(lower, \"wandb\") || strings.Contains(lower, \"weights_biases\") ||\n\t\tstrings.Contains(lower, \"weave\") || strings.Contains(lower, \"arize_phoenix\") ||\n\t\tstrings.Contains(lower, \"better_stack\") || strings.Contains(lower, \"better_uptime\") ||\n\t\tstrings.Contains(lower, \"logtail\") || strings.Contains(lower, \"cronitor\") ||\n\t\tstrings.Contains(lower, \"healthchecks\") || strings.Contains(lower, \"uptime_robot\") ||\n\t\tstrings.Contains(lower, \"uptimerobot\") || strings.Contains(lower, \"honeybadger\") ||\n\t\tstrings.Contains(lower, \"rollbar\") || strings.Contains(lower, \"bugsnag\") ||\n\t\tstrings.Contains(lower, \"airbrake\") || strings.Contains(lower, \"scout_apm\") ||\n\t\tstrings.Contains(lower, \"lightstep\") || strings.Contains(lower, \"chronosphere\") ||\n\t\tstrings.Contains(lower, \"signoz\") || strings.Contains(lower, \"axiom\") ||\n\t\tstrings.Contains(lower, \"logflare\") || strings.Contains(lower, \"sematext\") ||\n\t\tstrings.Contains(lower, \"logz_io\") || strings.Contains(lower, \"papertrail\"):\n\t\tkind = SecretKindToken\n\tcase strings.Contains(lower, \"redis_url\") || strings.Contains(lower, \"smtp_url\") ||\n\t\tstrings.Contains(lower, \"smtp_dsn\") || strings.Contains(lower, \"smtp_connection\") ||\n\t\tstrings.Contains(lower, \"elasticsearch_url\") || strings.Contains(lower, \"opensearch_url\") ||\n\t\tstrings.Contains(lower, \"clickhouse_url\") || strings.Contains(lower, \"elastic_cloud_auth\"):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"metabase\") || strings.Contains(lower, \"elastic\") || strings.Contains(lower, \"elasticsearch\") ||\n\t\tstrings.Contains(lower, \"opensearch\") || strings.Contains(lower, \"clickhouse\"):\n\t\tkind = SecretKindToken\n\tcase strings.Contains(lower, \"pagerduty\") || strings.Contains(lower, \"opsgenie\") || strings.Contains(lower, \"zendesk\") ||\n\t\tstrings.Contains(lower, \"intercom\"):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"resend\") || strings.Contains(lower, \"postmark\") || strings.Contains(lower, \"mailchimp\"):\n\t\tkind = SecretKindProviderKey\n\tcase strings.Contains(lower, \"clerk\") || strings.Contains(lower, \"auth0\") || strings.Contains(lower, \"supabase\") ||\n\t\tstrings.Contains(lower, \"firebase\") || strings.Contains(lower, \"okta\"):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"terraform\") || strings.Contains(lower, \"snyk\") ||\n\t\tstrings.Contains(lower, \"circleci\") || strings.Contains(lower, \"buildkite\"):\n\t\tkind = SecretKindToken\n\tcase strings.Contains(lower, \"vercel\") || strings.Contains(lower, \"netlify\") || strings.Contains(lower, \"render\") ||\n\t\tstrings.Contains(lower, \"railway\") || strings.Contains(lower, \"flyio\") || strings.Contains(lower, \"cloudflare\") ||\n\t\tstrings.Contains(lower, \"turnstile\") || strings.Contains(lower, \"recaptcha\") || strings.Contains(lower, \"hcaptcha\") ||\n\t\tstrings.Contains(lower, \"doppler\") || strings.Contains(lower, \"infisical\") || strings.Contains(lower, \"onepassword\") ||\n\t\tstrings.Contains(lower, \"vault\") || strings.Contains(lower, \"sops\"):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"client\") && (strings.Contains(lower, \"secret\") || strings.Contains(lower, \"token\")):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"client\") && strings.Contains(lower, \"assertion\"):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"credential\") || strings.Contains(lower, \"database\") || strings.Contains(lower, \"dsn\") || strings.Contains(lower, \"connection\"):\n\t\tkind = SecretKindCredential\n\tcase strings.Contains(lower, \"token\") || strings.Contains(lower, \"jwt\") || strings.Contains(lower, \"oauth\") || strings.Contains(lower, \"session\"):\n\t\tkind = SecretKindToken\n\tcase strings.Contains(lower, \"openai\") || strings.Contains(lower, \"anthropic\") || strings.Contains(lower, \"openrouter\") ||\n\t\tstrings.Contains(lower, \"deepseek\") || strings.Contains(lower, \"mistral\") || strings.Contains(lower, \"cohere\") ||\n\t\tstrings.Contains(lower, \"gemini\") || strings.Contains(lower, \"figma\") || strings.Contains(lower, \"notion\") ||\n\t\tstrings.Contains(lower, \"langsmith\") || strings.Contains(lower, \"stripe\") || strings.Contains(lower, \"provider\"):\n\t\tkind = SecretKindProviderKey\n\t}\n\treturn []SecretFinding{{Kind: kind, Signal: \"key_name\"}}\n}\n\nfunc isPublicIncidentMetadataKey(normalized string) bool {\n\tswitch normalized {\n\tcase \"public_status_page_component\", \"public_statuspage_component\", \"status_page_component\", \"statuspage_component\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc normalizeSecretKey(key string) string {\n\tvar builder strings.Builder\n\tvar previous rune\n\tfor _, current := range strings.TrimSpace(key) {\n\t\tif current >= 'A' && current <= 'Z' {\n\t\t\tif builder.Len() > 0 && previous != '_' && previous != '-' && previous != '.' && previous != ' ' {\n\t\t\t\tbuilder.WriteByte('_')\n\t\t\t}\n\t\t\tcurrent += 'a' - 'A'\n\t\t}\n\t\tswitch current {\n\t\tcase '-', '.', ' ', '/', ':':\n\t\t\tif builder.Len() > 0 && previous != '_' {\n\t\t\t\tbuilder.WriteByte('_')\n\t\t\t\tprevious = '_'\n\t\t\t}\n\t\t\tcontinue\n\t\tdefault:\n\t\t\tbuilder.WriteRune(current)\n\t\t\tprevious = current\n\t\t}\n\t}\n\treturn strings.Trim(builder.String(), \"_\")\n}\n\nfunc ClassifyString(value string) []SecretFinding {\n\tvar findings []SecretFinding\n\tfindings = append(findings, classifyJSONString(value)...)\n\tif hasURLCredentials(value) {\n\t\tfindings = append(findings, SecretFinding{Kind: SecretKindDSN, Signal: \"url_credentials\"})\n\t}\n\tif hasSensitiveURLQuery(value) {\n\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSignedURL, Signal: \"url_query_secret\"})\n\t}\n\tfor _, detector := range secretValuePatterns {\n\t\tif detector.pattern.MatchString(value) {\n\t\t\tfindings = append(findings, SecretFinding{Kind: detector.kind, Signal: detector.signal})\n\t\t}\n\t}\n\tfor _, match := range assignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchDataSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchPackageRegistrySecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchObservabilityWebhookSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchBillingSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchExportRenderSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchCrawlerResearchSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchDeployPlatformSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchBackupIncidentSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range launchMalwareScannerSecretAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\tfor _, match := range signedDeliveryAssignmentPattern.FindAllStringSubmatch(value, -1) {\n\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSignedURL, Signal: \"signed_delivery_assignment\"})\n\t\tfor _, keyFinding := range ClassifyKey(match[1]) {\n\t\t\tkeyFinding.Signal = \"assignment:\" + keyFinding.Signal\n\t\t\tfindings = append(findings, keyFinding)\n\t\t}\n\t}\n\treturn findings\n}\n\nfunc ClassifyValue(value any) []SecretFinding {\n\treturn classifyValueAt(value, \"\")\n}\n\n// RedactValue removes common secret-bearing fields from values before they are\n// written to logs, errors, audit metadata, support records, or exported traces.\nfunc RedactValue(value any) any {\n\tswitch typed := value.(type) {\n\tcase map[string]any:\n\t\treturn RedactMap(typed)\n\tcase map[string]string:\n\t\treturn RedactStringMap(typed)\n\tcase http.Header:\n\t\treturn RedactStringSliceMap(map[string][]string(typed))\n\tcase url.Values:\n\t\treturn RedactStringSliceMap(map[string][]string(typed))\n\tcase map[string][]string:\n\t\treturn RedactStringSliceMap(typed)\n\tcase map[string][]any:\n\t\tout := make(map[string][]any, len(typed))\n\t\tsignedURLContext := hasSignedURLContextKeys(mapKeys(typed))\n\t\tkubernetesSecretContext := hasKubernetesSecretContext(typed)\n\t\tfor key, values := range typed {\n\t\t\tredactedValues := make([]any, len(values))\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfor i := range values {\n\t\t\t\t\tredactedValues[i] = Redacted\n\t\t\t\t}\n\t\t\t\tout[key] = redactedValues\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif IsSensitiveKey(key) || shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\t\tfor i := range values {\n\t\t\t\t\tredactedValues[i] = Redacted\n\t\t\t\t}\n\t\t\t\tout[key] = redactedValues\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor i, item := range values {\n\t\t\t\tredactedValues[i] = RedactValue(item)\n\t\t\t}\n\t\t\tout[key] = redactedValues\n\t\t}\n\t\treturn out\n\tcase json.RawMessage:\n\t\treturn json.RawMessage(RedactString(string(typed)))\n\tcase []byte:\n\t\treturn []byte(RedactString(string(typed)))\n\tcase []any:\n\t\tout := make([]any, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactValue(item)\n\t\t}\n\t\treturn out\n\tcase []string:\n\t\tout := make([]string, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactString(item)\n\t\t}\n\t\treturn out\n\tcase []map[string]any:\n\t\tout := make([]map[string]any, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactMap(item)\n\t\t}\n\t\treturn out\n\tcase []map[string]string:\n\t\tout := make([]map[string]string, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactStringMap(item)\n\t\t}\n\t\treturn out\n\tcase []map[string][]string:\n\t\tout := make([]map[string][]string, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactStringSliceMap(item)\n\t\t}\n\t\treturn out\n\tcase string:\n\t\treturn RedactString(typed)\n\tcase error:\n\t\treturn RedactString(typed.Error())\n\tcase url.URL:\n\t\treturn RedactString(typed.String())\n\tcase *url.URL:\n\t\tif typed == nil {\n\t\t\treturn typed\n\t\t}\n\t\treturn RedactString(typed.String())\n\tcase slog.Attr:\n\t\treturn redactSlogAttr(typed)\n\tcase slog.Value:\n\t\treturn redactSlogValue(\"\", typed)\n\tcase slog.LogValuer:\n\t\treturn RedactValue(typed.LogValue())\n\tcase []slog.Attr:\n\t\tout := make([]slog.Attr, len(typed))\n\t\tfor i, attr := range typed {\n\t\t\tout[i] = redactSlogAttr(attr)\n\t\t}\n\t\treturn out\n\tcase fmt.Stringer:\n\t\treturn RedactString(typed.String())\n\tdefault:\n\t\tif redacted, ok := redactReflectValue(value); ok {\n\t\t\treturn redacted\n\t\t}\n\t\treturn value\n\t}\n}\n\ntype RedactingSlogHandler struct {\n\tnext slog.Handler\n}\n\nfunc NewRedactingSlogHandler(next slog.Handler) slog.Handler {\n\treturn RedactingSlogHandler{next: next}\n}\n\nfunc (h RedactingSlogHandler) Enabled(ctx context.Context, level slog.Level) bool {\n\treturn h.next.Enabled(ctx, level)\n}\n\nfunc (h RedactingSlogHandler) Handle(ctx context.Context, record slog.Record) error {\n\tredacted := slog.NewRecord(record.Time, record.Level, RedactString(record.Message), record.PC)\n\trecord.Attrs(func(attr slog.Attr) bool {\n\t\tredacted.AddAttrs(redactSlogAttr(attr))\n\t\treturn true\n\t})\n\treturn h.next.Handle(ctx, redacted)\n}\n\nfunc (h RedactingSlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {\n\tredacted := make([]slog.Attr, len(attrs))\n\tfor i, attr := range attrs {\n\t\tredacted[i] = redactSlogAttr(attr)\n\t}\n\treturn RedactingSlogHandler{next: h.next.WithAttrs(redacted)}\n}\n\nfunc (h RedactingSlogHandler) WithGroup(name string) slog.Handler {\n\treturn RedactingSlogHandler{next: h.next.WithGroup(name)}\n}\n\nfunc redactSlogAttr(attr slog.Attr) slog.Attr {\n\tattr.Value = redactSlogValue(attr.Key, attr.Value)\n\treturn attr\n}\n\nfunc redactSlogValue(key string, value slog.Value) slog.Value {\n\tvalue = value.Resolve()\n\tif IsSensitiveKey(key) {\n\t\treturn slog.StringValue(Redacted)\n\t}\n\tswitch value.Kind() {\n\tcase slog.KindString:\n\t\treturn slog.StringValue(RedactString(value.String()))\n\tcase slog.KindAny:\n\t\treturn slog.AnyValue(RedactValue(value.Any()))\n\tcase slog.KindGroup:\n\t\tgroup := value.Group()\n\t\tredacted := make([]slog.Attr, len(group))\n\t\tfor i, attr := range group {\n\t\t\tredacted[i] = redactSlogAttr(attr)\n\t\t}\n\t\treturn slog.GroupValue(redacted...)\n\tdefault:\n\t\treturn value\n\t}\n}\n\nfunc RedactMap(input map[string]any) map[string]any {\n\tout := make(map[string]any, len(input))\n\tsignedURLContext := hasSignedURLContextKeys(mapKeys(input))\n\tkubernetesSecretContext := hasKubernetesSecretContext(input)\n\tfor key, value := range input {\n\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\tout[key] = redactSecretPayload(value)\n\t\t\tcontinue\n\t\t}\n\t\tif IsSensitiveKey(key) || shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\tout[key] = Redacted\n\t\t\tcontinue\n\t\t}\n\t\tout[key] = RedactValue(value)\n\t}\n\treturn out\n}\n\nfunc RedactStringMap(input map[string]string) map[string]string {\n\tif input == nil {\n\t\treturn nil\n\t}\n\tout := make(map[string]string, len(input))\n\tsignedURLContext := hasSignedURLContextKeys(mapKeys(input))\n\tkubernetesSecretContext := hasKubernetesSecretContext(input)\n\tfor key, val := range input {\n\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\tout[key] = Redacted\n\t\t\tcontinue\n\t\t}\n\t\tif IsSensitiveKey(key) || shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\tout[key] = Redacted\n\t\t\tcontinue\n\t\t}\n\t\tout[key] = RedactString(val)\n\t}\n\treturn out\n}\n\nfunc RedactStringSliceMap(input map[string][]string) map[string][]string {\n\tif input == nil {\n\t\treturn nil\n\t}\n\tout := make(map[string][]string, len(input))\n\tfor key, values := range input {\n\t\tredactedValues := make([]string, len(values))\n\t\tif IsSensitiveKey(key) || isSignedURLQueryKey(key) {\n\t\t\tfor i := range values {\n\t\t\t\tredactedValues[i] = Redacted\n\t\t\t}\n\t\t\tout[key] = redactedValues\n\t\t\tcontinue\n\t\t}\n\t\tfor i, value := range values {\n\t\t\tredactedValues[i] = RedactString(value)\n\t\t}\n\t\tout[key] = redactedValues\n\t}\n\treturn out\n}\n\nfunc IsSensitiveKey(key string) bool {\n\treturn len(ClassifyKey(key)) > 0\n}\n\nfunc RedactString(value string) string {\n\tvalue = redactJSONString(value)\n\tvalue = redactURLSecrets(value)\n\tvalue = redactAuthorization(value)\n\tvalue = redactAuthorizationAssignments(value)\n\tvalue = redactKnownSecretValues(value)\n\tvalue = redactAssignments(value)\n\treturn value\n}\n\nfunc redactJSONString(value string) string {\n\ttrimmed := strings.TrimSpace(value)\n\tif trimmed == \"\" || (!strings.HasPrefix(trimmed, \"{\") && !strings.HasPrefix(trimmed, \"[\")) {\n\t\treturn value\n\t}\n\tvar decoded any\n\tdecoder := json.NewDecoder(strings.NewReader(trimmed))\n\tdecoder.UseNumber()\n\tif err := decoder.Decode(&decoded); err != nil {\n\t\treturn value\n\t}\n\tvar trailing any\n\tif err := decoder.Decode(&trailing); err != io.EOF {\n\t\treturn value\n\t}\n\tredacted, err := json.Marshal(RedactValue(decoded))\n\tif err != nil {\n\t\treturn value\n\t}\n\tif len(value) == len(trimmed) {\n\t\treturn string(redacted)\n\t}\n\tprefixLen := strings.Index(value, trimmed)\n\tif prefixLen < 0 {\n\t\treturn string(redacted)\n\t}\n\treturn value[:prefixLen] + string(redacted) + value[prefixLen+len(trimmed):]\n}\n\nfunc classifyJSONString(value string) []SecretFinding {\n\ttrimmed := strings.TrimSpace(value)\n\tif trimmed == \"\" || (!strings.HasPrefix(trimmed, \"{\") && !strings.HasPrefix(trimmed, \"[\")) {\n\t\treturn nil\n\t}\n\tvar decoded any\n\tdecoder := json.NewDecoder(strings.NewReader(trimmed))\n\tdecoder.UseNumber()\n\tif err := decoder.Decode(&decoded); err != nil {\n\t\treturn nil\n\t}\n\tvar trailing any\n\tif err := decoder.Decode(&trailing); err != io.EOF {\n\t\treturn nil\n\t}\n\treturn classifyValueAt(decoded, \"\")\n}\n\nfunc redactURLSecrets(value string) string {\n\tif strings.Contains(value, \"://\") {\n\t\tif isStandaloneURL(value) {\n\t\t\tif redacted, ok := redactSingleURL(value); ok {\n\t\t\t\treturn redacted\n\t\t\t}\n\t\t}\n\t\treturn embeddedURLPattern.ReplaceAllStringFunc(value, func(raw string) string {\n\t\t\tredacted, ok := redactSingleURL(raw)\n\t\t\tif !ok {\n\t\t\t\treturn raw\n\t\t\t}\n\t\t\treturn redacted\n\t\t})\n\t}\n\treturn value\n}\n\nfunc isStandaloneURL(value string) bool {\n\ttrimmed := strings.TrimSpace(value)\n\tif trimmed == \"\" || strings.ContainsAny(trimmed, \" \\t\\r\\n\") {\n\t\treturn false\n\t}\n\tparsed, err := url.Parse(trimmed)\n\treturn err == nil && parsed.Scheme != \"\" && parsed.Host != \"\"\n}\n\nfunc redactSingleURL(value string) (string, bool) {\n\tparsed, err := url.Parse(value)\n\tif err != nil || parsed.User == nil {\n\t\tif err != nil {\n\t\t\treturn value, false\n\t\t}\n\t} else {\n\t\tparsed.User = url.UserPassword(Redacted, Redacted)\n\t}\n\tquery := parsed.Query()\n\tchangedQuery := false\n\tfor key := range query {\n\t\tif IsSensitiveKey(key) || isSignedURLQueryKey(key) {\n\t\t\tquery.Set(key, Redacted)\n\t\t\tchangedQuery = true\n\t\t}\n\t}\n\tif changedQuery {\n\t\tparsed.RawQuery = query.Encode()\n\t}\n\treturn parsed.String(), parsed.User != nil || changedQuery\n}\n\nfunc redactAuthorization(value string) string {\n\treturn regexp.MustCompile(`(?i)\\b(Bearer|Basic)\\s+[A-Za-z0-9._~+/\\-=]{3,}`).ReplaceAllString(value, \"$1 \"+Redacted)\n}\n\nfunc redactAuthorizationAssignments(value string) string {\n\tvalue = regexp.MustCompile(`(?i)\\b(Authorization|Proxy-Authorization)\\s*:\\s*(ApiKey|Token|Digest|Negotiate|AWS4-HMAC-SHA256|SharedKey|SharedKeyLite)\\s+[^\\s,;&]+`).ReplaceAllString(value, \"$1: $2 \"+Redacted)\n\treturn regexp.MustCompile(`(?i)\\b(Authorization|Proxy-Authorization)\\s*=\\s*(ApiKey|Token|Digest|Negotiate|AWS4-HMAC-SHA256|SharedKey|SharedKeyLite)\\s+[^\\s,;&]+`).ReplaceAllString(value, \"$1=$2 \"+Redacted)\n}\n\nfunc redactAssignments(value string) string {\n\tvalue = redactAssignmentMatches(value, assignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchDataSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchPackageRegistrySecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchObservabilityWebhookSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchBillingSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchExportRenderSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchCrawlerResearchSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchDeployPlatformSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchBackupIncidentSecretAssignmentPattern)\n\tvalue = redactAssignmentMatches(value, launchMalwareScannerSecretAssignmentPattern)\n\treturn redactAssignmentMatches(value, signedDeliveryAssignmentPattern)\n}\n\nfunc redactAssignmentMatches(value string, pattern *regexp.Regexp) string {\n\treturn pattern.ReplaceAllStringFunc(value, func(match string) string {\n\t\tparts := pattern.FindStringSubmatch(match)\n\t\tif len(parts) < 4 {\n\t\t\treturn match\n\t\t}\n\t\tif isAuthorizationSchemeAssignment(parts[1], strings.Trim(parts[3], `\"'`)) {\n\t\t\treturn match\n\t\t}\n\t\treturn fmt.Sprintf(\"%s%s%s\", strings.TrimSpace(parts[1]), parts[2], Redacted)\n\t})\n}\n\nfunc isAuthorizationSchemeAssignment(key, value string) bool {\n\tnormalizedKey := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(key), \"_\", \"-\"))\n\tif normalizedKey != \"authorization\" && normalizedKey != \"proxy-authorization\" {\n\t\treturn false\n\t}\n\tswitch strings.ToLower(strings.TrimSpace(value)) {\n\tcase \"apikey\", \"token\", \"digest\", \"negotiate\", \"aws4-hmac-sha256\", \"sharedkey\", \"sharedkeylite\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc redactKnownSecretValues(value string) string {\n\tfor _, detector := range secretValuePatterns {\n\t\tvalue = detector.pattern.ReplaceAllString(value, Redacted)\n\t}\n\treturn value\n}\n\nfunc hasURLCredentials(value string) bool {\n\tparsed, err := url.Parse(value)\n\tif err == nil && parsed.User != nil {\n\t\treturn true\n\t}\n\tfor _, raw := range embeddedURLPattern.FindAllString(value, -1) {\n\t\tparsed, err := url.Parse(raw)\n\t\tif err == nil && parsed.User != nil {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc hasSensitiveURLQuery(value string) bool {\n\tif hasSensitiveQuery(value) {\n\t\treturn true\n\t}\n\tfor _, raw := range embeddedURLPattern.FindAllString(value, -1) {\n\t\tif hasSensitiveQuery(raw) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc hasSensitiveQuery(raw string) bool {\n\tparsed, err := url.Parse(raw)\n\tif err != nil {\n\t\treturn false\n\t}\n\tfor key := range parsed.Query() {\n\t\tif IsSensitiveKey(key) || isSignedURLQueryKey(key) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isSignedURLQueryKey(key string) bool {\n\tnormalized := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(key), \"_\", \"-\"))\n\tswitch normalized {\n\tcase \"x-amz-algorithm\", \"x-amz-credential\", \"x-amz-signature\", \"x-amz-security-token\",\n\t\t\"x-amz-date\", \"x-amz-expires\", \"x-amz-signedheaders\", \"x-amz-policy\",\n\t\t\"x-amz-server-side-encryption-customer-key\", \"x-amz-server-side-encryption-customer-key-md5\",\n\t\t\"x-amz-copy-source-server-side-encryption-customer-key\", \"x-amz-copy-source-server-side-encryption-customer-key-md5\",\n\t\t\"x-goog-credential\", \"x-goog-signature\", \"x-goog-security-token\",\n\t\t\"x-goog-algorithm\", \"x-goog-date\", \"x-goog-expires\", \"x-goog-signedheaders\",\n\t\t\"googleaccessid\", \"x-oss-signature\", \"x-oss-security-token\", \"x-oss-credential\",\n\t\t\"x-oss-date\", \"x-oss-expires\", \"x-oss-signature-version\", \"x-oss-additional-headers\",\n\t\t\"ossaccesskeyid\", \"security-token\",\n\t\t\"x-cos-signature\", \"x-cos-security-token\", \"q-sign-algorithm\", \"q-ak\", \"q-sign-time\",\n\t\t\"q-key-time\", \"q-header-list\", \"q-url-param-list\", \"q-signature\",\n\t\t\"x-bz-info-authorization\", \"x-bz-security-token\", \"authorization\", \"accesskeyid\",\n\t\t\"awsaccesskeyid\", \"signature\", \"sig\", \"token\", \"access-token\", \"download-token\", \"oauth-token\",\n\t\t\"__token__\", \"hdnts\", \"hdntl\", \"edge-auth\", \"akamai-signature\",\n\t\t\"cloud-cdn-signature\", \"cloud-cdn-policy\", \"cloud-cdn-expires\", \"cloud-cdn-key-name\",\n\t\t\"cloud-cdn-url-prefix\", \"url-prefix\", \"urlprefix\", \"key-name\", \"keyname\", \"signed-cookie\", \"signed-policy\",\n\t\t\"signed-signature\", \"cdn-policy\", \"cdn-signature\", \"cdn-token\", \"cf-authorization\",\n\t\t\"cloudflare-access-jwt-assertion\",\n\t\t\"fastly-api-key\", \"fastly-service-token\", \"fastly-edge-auth\", \"fastly-signature\",\n\t\t\"imgix-secure-url-token\", \"imgix-signature\", \"imgix-sign\", \"ix-signature\", \"ix-sign\",\n\t\t\"bunny-api-key\", \"bunny-token\", \"bunny-password\", \"bunny-signature\",\n\t\t\"bunnycdn-api-key\", \"bunnycdn-token\", \"bunnycdn-signature\",\n\t\t\"bunny-cdn-api-key\", \"bunny-cdn-token\", \"bunny-cdn-signature\",\n\t\t\"bunny-storage-password\", \"bunny-storage-token\",\n\t\t\"mux-token-id\", \"mux-token-secret\", \"mux-signing-key\", \"mux-signature\", \"mux-policy\",\n\t\t\"vercel-blob-read-write-token\", \"vercel-token\", \"vercel-signature\", \"x-vercel-signature\", \"x-vercel-token\",\n\t\t\"expires\", \"policy\", \"key-pair-id\", \"cloudfront-signature\", \"cloudfront-policy\", \"cloudfront-key-pair-id\",\n\t\t\"st\", \"se\", \"sp\", \"sip\", \"spr\", \"sr\", \"sv\", \"si\", \"ses\", \"sdd\", \"saoid\", \"suoid\", \"scid\",\n\t\t\"skoid\", \"sktid\", \"skt\", \"ske\", \"sks\", \"skv\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc shouldRedactStructuredSignedURLKey(key string, signedURLContext bool) bool {\n\treturn isStructuredSignedURLSecretKey(key) || (signedURLContext && isSignedURLQueryKey(key))\n}\n\nfunc hasSignedURLContextKeys(keys []string) bool {\n\tfor _, key := range keys {\n\t\tif isSignedURLContextKey(key) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isSignedURLContextKey(key string) bool {\n\tnormalized := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(key), \"_\", \"-\"))\n\tif strings.HasPrefix(normalized, \"x-amz-\") ||\n\t\tstrings.HasPrefix(normalized, \"x-goog-\") ||\n\t\tstrings.HasPrefix(normalized, \"x-oss-\") ||\n\t\tstrings.HasPrefix(normalized, \"x-cos-\") ||\n\t\tstrings.HasPrefix(normalized, \"q-\") ||\n\t\tstrings.HasPrefix(normalized, \"x-bz-\") ||\n\t\tstrings.HasPrefix(normalized, \"x-vercel-\") ||\n\t\tstrings.HasPrefix(normalized, \"cloudfront-\") {\n\t\treturn true\n\t}\n\tif isAzureSASKey(normalized) {\n\t\treturn true\n\t}\n\tswitch normalized {\n\tcase \"awsaccesskeyid\", \"googleaccessid\", \"ossaccesskeyid\", \"signature\", \"sig\", \"security-token\", \"accesskeyid\",\n\t\t\"__token__\", \"hdnts\", \"hdntl\", \"edge-auth\", \"akamai-signature\",\n\t\t\"cloud-cdn-signature\", \"cloud-cdn-policy\", \"cloud-cdn-expires\", \"cloud-cdn-key-name\",\n\t\t\"cloud-cdn-url-prefix\", \"url-prefix\", \"urlprefix\", \"key-name\", \"keyname\", \"signed-cookie\", \"signed-policy\",\n\t\t\"signed-signature\", \"cdn-policy\", \"cdn-signature\", \"cdn-token\", \"cf-authorization\",\n\t\t\"cloudflare-access-jwt-assertion\",\n\t\t\"fastly-api-key\", \"fastly-service-token\", \"fastly-edge-auth\", \"fastly-signature\",\n\t\t\"imgix-secure-url-token\", \"imgix-signature\", \"imgix-sign\", \"ix-signature\", \"ix-sign\",\n\t\t\"bunny-api-key\", \"bunny-token\", \"bunny-password\", \"bunny-signature\",\n\t\t\"bunnycdn-api-key\", \"bunnycdn-token\", \"bunnycdn-signature\",\n\t\t\"bunny-cdn-api-key\", \"bunny-cdn-token\", \"bunny-cdn-signature\",\n\t\t\"bunny-storage-password\", \"bunny-storage-token\",\n\t\t\"mux-token-id\", \"mux-token-secret\", \"mux-signing-key\", \"mux-signature\", \"mux-policy\",\n\t\t\"vercel-blob-read-write-token\", \"vercel-token\", \"vercel-signature\", \"x-vercel-signature\", \"x-vercel-token\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc isStructuredSignedURLSecretKey(key string) bool {\n\tnormalized := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(key), \"_\", \"-\"))\n\tswitch normalized {\n\tcase \"x-amz-algorithm\", \"x-amz-credential\", \"x-amz-signature\", \"x-amz-security-token\",\n\t\t\"x-amz-date\", \"x-amz-expires\", \"x-amz-signedheaders\",\n\t\t\"x-amz-policy\", \"x-amz-server-side-encryption-customer-key\",\n\t\t\"x-amz-server-side-encryption-customer-key-md5\",\n\t\t\"x-amz-copy-source-server-side-encryption-customer-key\",\n\t\t\"x-amz-copy-source-server-side-encryption-customer-key-md5\",\n\t\t\"x-goog-algorithm\", \"x-goog-credential\", \"x-goog-signature\", \"x-goog-security-token\",\n\t\t\"x-goog-date\", \"x-goog-expires\", \"x-goog-signedheaders\",\n\t\t\"googleaccessid\", \"x-oss-signature\", \"x-oss-security-token\", \"x-oss-credential\",\n\t\t\"x-oss-date\", \"x-oss-expires\", \"x-oss-signature-version\", \"x-oss-additional-headers\",\n\t\t\"ossaccesskeyid\", \"security-token\",\n\t\t\"x-cos-signature\", \"x-cos-security-token\", \"q-sign-algorithm\", \"q-ak\", \"q-sign-time\",\n\t\t\"q-key-time\", \"q-header-list\", \"q-url-param-list\", \"q-signature\",\n\t\t\"x-bz-info-authorization\", \"x-bz-security-token\", \"authorization\", \"accesskeyid\",\n\t\t\"awsaccesskeyid\", \"cloudfront-signature\", \"cloudfront-policy\", \"cloudfront-key-pair-id\",\n\t\t\"__token__\", \"hdnts\", \"hdntl\", \"edge-auth\", \"akamai-signature\",\n\t\t\"cloud-cdn-signature\", \"cloud-cdn-policy\", \"cloud-cdn-expires\", \"cloud-cdn-key-name\",\n\t\t\"cloud-cdn-url-prefix\", \"url-prefix\", \"urlprefix\", \"key-name\", \"keyname\", \"signed-cookie\", \"signed-policy\",\n\t\t\"signed-signature\", \"cdn-policy\", \"cdn-signature\", \"cdn-token\", \"cf-authorization\",\n\t\t\"cloudflare-access-jwt-assertion\",\n\t\t\"fastly-api-key\", \"fastly-service-token\", \"fastly-edge-auth\", \"fastly-signature\",\n\t\t\"imgix-secure-url-token\", \"imgix-signature\", \"imgix-sign\", \"ix-signature\", \"ix-sign\",\n\t\t\"bunny-api-key\", \"bunny-token\", \"bunny-password\", \"bunny-signature\",\n\t\t\"bunnycdn-api-key\", \"bunnycdn-token\", \"bunnycdn-signature\",\n\t\t\"bunny-cdn-api-key\", \"bunny-cdn-token\", \"bunny-cdn-signature\",\n\t\t\"bunny-storage-password\", \"bunny-storage-token\",\n\t\t\"mux-token-id\", \"mux-token-secret\", \"mux-signing-key\", \"mux-signature\", \"mux-policy\",\n\t\t\"vercel-blob-read-write-token\", \"vercel-token\", \"vercel-signature\", \"x-vercel-signature\", \"x-vercel-token\":\n\t\treturn true\n\tdefault:\n\t\treturn isAzureSASKey(normalized)\n\t}\n}\n\nfunc isAzureSASKey(normalized string) bool {\n\tswitch normalized {\n\tcase \"st\", \"se\", \"sp\", \"sip\", \"spr\", \"sr\", \"sv\", \"si\", \"ses\", \"sdd\", \"saoid\", \"suoid\", \"scid\",\n\t\t\"skoid\", \"sktid\", \"skt\", \"ske\", \"sks\", \"skv\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc hasKubernetesSecretContext[T any](input map[string]T) bool {\n\tfor key, value := range input {\n\t\tnormalizedKey := normalizeSecretKey(key)\n\t\tif normalizedKey == \"kind\" && strings.EqualFold(strings.TrimSpace(fmt.Sprint(value)), \"Secret\") {\n\t\t\treturn true\n\t\t}\n\t\tif normalizedKey == \"api_version\" && strings.HasPrefix(strings.TrimSpace(fmt.Sprint(value)), \"v1\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc hasReflectKubernetesSecretContext(value reflect.Value) bool {\n\tif value.Kind() != reflect.Map || value.IsNil() {\n\t\treturn false\n\t}\n\titer := value.MapRange()\n\tfor iter.Next() {\n\t\tkey := normalizeSecretKey(stringifyReflectKey(iter.Key()))\n\t\tval := strings.TrimSpace(reflectValueString(iter.Value()))\n\t\tif key == \"kind\" && strings.EqualFold(val, \"Secret\") {\n\t\t\treturn true\n\t\t}\n\t\tif key == \"api_version\" && strings.HasPrefix(val, \"v1\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc hasReflectStructKubernetesSecretContext(value reflect.Value) bool {\n\tif value.Kind() != reflect.Struct {\n\t\treturn false\n\t}\n\tvalueType := value.Type()\n\tfor i := 0; i < value.NumField(); i++ {\n\t\tfieldType := valueType.Field(i)\n\t\tif fieldType.PkgPath != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tkey, include := redactedStructFieldName(fieldType)\n\t\tif !include {\n\t\t\tcontinue\n\t\t}\n\t\tnormalizedKey := normalizeSecretKey(key)\n\t\tval := strings.TrimSpace(reflectValueString(value.Field(i)))\n\t\tif normalizedKey == \"kind\" && strings.EqualFold(val, \"Secret\") {\n\t\t\treturn true\n\t\t}\n\t\tif normalizedKey == \"api_version\" && strings.HasPrefix(val, \"v1\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isKubernetesSecretPayloadKey(key string) bool {\n\tswitch normalizeSecretKey(key) {\n\tcase \"data\", \"string_data\", \"binary_data\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc redactSecretPayload(value any) any {\n\tswitch typed := value.(type) {\n\tcase map[string]any:\n\t\tout := make(map[string]any, len(typed))\n\t\tfor key := range typed {\n\t\t\tout[key] = Redacted\n\t\t}\n\t\treturn out\n\tcase map[string]string:\n\t\tout := make(map[string]string, len(typed))\n\t\tfor key := range typed {\n\t\t\tout[key] = Redacted\n\t\t}\n\t\treturn out\n\tcase map[string][]string:\n\t\tout := make(map[string][]string, len(typed))\n\t\tfor key, values := range typed {\n\t\t\tredactedValues := make([]string, len(values))\n\t\t\tfor i := range redactedValues {\n\t\t\t\tredactedValues[i] = Redacted\n\t\t\t}\n\t\t\tout[key] = redactedValues\n\t\t}\n\t\treturn out\n\tcase map[string][]any:\n\t\tout := make(map[string][]any, len(typed))\n\t\tfor key, values := range typed {\n\t\t\tredactedValues := make([]any, len(values))\n\t\t\tfor i := range redactedValues {\n\t\t\t\tredactedValues[i] = Redacted\n\t\t\t}\n\t\t\tout[key] = redactedValues\n\t\t}\n\t\treturn out\n\tdefault:\n\t\treturn Redacted\n\t}\n}\n\nfunc redactSecretPayloadFromReflect(value reflect.Value) any {\n\tif !value.IsValid() {\n\t\treturn Redacted\n\t}\n\tfor value.Kind() == reflect.Interface || value.Kind() == reflect.Pointer {\n\t\tif value.IsNil() {\n\t\t\treturn Redacted\n\t\t}\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() != reflect.Map {\n\t\treturn Redacted\n\t}\n\tout := make(map[string]any, value.Len())\n\titer := value.MapRange()\n\tfor iter.Next() {\n\t\tout[stringifyReflectKey(iter.Key())] = Redacted\n\t}\n\treturn out\n}\n\nfunc classifySecretPayloadAt(value any, location string) []SecretFinding {\n\tvar findings []SecretFinding\n\tswitch typed := value.(type) {\n\tcase map[string]any:\n\t\tfor key := range typed {\n\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: joinFindingLocation(location, key)})\n\t\t}\n\tcase map[string]string:\n\t\tfor key := range typed {\n\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: joinFindingLocation(location, key)})\n\t\t}\n\tcase map[string][]string:\n\t\tfor key, values := range typed {\n\t\t\tkeyLocation := joinFindingLocation(location, key)\n\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: keyLocation})\n\t\t\tfor i := range values {\n\t\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: fmt.Sprintf(\"%s[%d]\", keyLocation, i)})\n\t\t\t}\n\t\t}\n\tcase map[string][]any:\n\t\tfor key, values := range typed {\n\t\t\tkeyLocation := joinFindingLocation(location, key)\n\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: keyLocation})\n\t\t\tfor i := range values {\n\t\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: fmt.Sprintf(\"%s[%d]\", keyLocation, i)})\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: location})\n\t}\n\treturn findings\n}\n\nfunc classifySecretPayloadReflectAt(value reflect.Value, location string) []SecretFinding {\n\tif !value.IsValid() {\n\t\treturn []SecretFinding{{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: location}}\n\t}\n\tfor value.Kind() == reflect.Interface || value.Kind() == reflect.Pointer {\n\t\tif value.IsNil() {\n\t\t\treturn []SecretFinding{{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: location}}\n\t\t}\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() != reflect.Map {\n\t\treturn []SecretFinding{{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: location}}\n\t}\n\tvar findings []SecretFinding\n\titer := value.MapRange()\n\tfor iter.Next() {\n\t\tfindings = append(findings, SecretFinding{\n\t\t\tKind: SecretKindSecretPayload,\n\t\t\tSignal: \"kubernetes_secret_payload\",\n\t\t\tLocation: joinFindingLocation(location, stringifyReflectKey(iter.Key())),\n\t\t})\n\t}\n\treturn findings\n}\n\nfunc reflectValueString(value reflect.Value) string {\n\tif !value.IsValid() {\n\t\treturn \"\"\n\t}\n\tfor value.Kind() == reflect.Interface || value.Kind() == reflect.Pointer {\n\t\tif value.IsNil() {\n\t\t\treturn \"\"\n\t\t}\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() == reflect.String {\n\t\treturn value.String()\n\t}\n\tif value.CanInterface() {\n\t\treturn fmt.Sprint(value.Interface())\n\t}\n\treturn fmt.Sprint(value)\n}\n\nfunc classifyValueAt(value any, location string) []SecretFinding {\n\tvar findings []SecretFinding\n\tswitch typed := value.(type) {\n\tcase map[string]any:\n\t\tsignedURLContext := hasSignedURLContextKeys(mapKeys(typed))\n\t\tkubernetesSecretContext := hasKubernetesSecretContext(typed)\n\t\tfor key, val := range typed {\n\t\t\tchildLocation := key\n\t\t\tif location != \"\" {\n\t\t\t\tchildLocation = location + \".\" + key\n\t\t\t}\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfindings = append(findings, classifySecretPayloadAt(val, childLocation)...)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, finding := range classifyStructuredKey(key, signedURLContext) {\n\t\t\t\tfinding.Location = childLocation\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t\tfindings = append(findings, classifyValueAt(val, childLocation)...)\n\t\t}\n\tcase map[string]string:\n\t\tsignedURLContext := hasSignedURLContextKeys(mapKeys(typed))\n\t\tkubernetesSecretContext := hasKubernetesSecretContext(typed)\n\t\tfor key, val := range typed {\n\t\t\tchildLocation := key\n\t\t\tif location != \"\" {\n\t\t\t\tchildLocation = location + \".\" + key\n\t\t\t}\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSecretPayload, Signal: \"kubernetes_secret_payload\", Location: childLocation})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, finding := range classifyStructuredKey(key, signedURLContext) {\n\t\t\t\tfinding.Location = childLocation\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t\tfor _, finding := range ClassifyString(val) {\n\t\t\t\tfinding.Location = childLocation\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t}\n\tcase http.Header:\n\t\tfindings = append(findings, classifyStringSliceMapAt(map[string][]string(typed), location)...)\n\tcase url.Values:\n\t\tfindings = append(findings, classifyStringSliceMapAt(map[string][]string(typed), location)...)\n\tcase map[string][]string:\n\t\tfindings = append(findings, classifyStringSliceMapAt(typed, location)...)\n\tcase map[string][]any:\n\t\tsignedURLContext := hasSignedURLContextKeys(mapKeys(typed))\n\t\tkubernetesSecretContext := hasKubernetesSecretContext(typed)\n\t\tfor key, values := range typed {\n\t\t\tchildLocation := key\n\t\t\tif location != \"\" {\n\t\t\t\tchildLocation = location + \".\" + key\n\t\t\t}\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfindings = append(findings, classifySecretPayloadAt(values, childLocation)...)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, finding := range classifyStructuredKey(key, signedURLContext) {\n\t\t\t\tfinding.Location = childLocation\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t\tfor i, item := range values {\n\t\t\t\tvalueLocation := fmt.Sprintf(\"%s[%d]\", childLocation, i)\n\t\t\t\tif shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSignedURL, Signal: \"url_query_secret\", Location: valueLocation})\n\t\t\t\t}\n\t\t\t\tfindings = append(findings, classifyValueAt(item, valueLocation)...)\n\t\t\t}\n\t\t}\n\tcase []any:\n\t\tfor i, item := range typed {\n\t\t\tchildLocation := fmt.Sprintf(\"%s[%d]\", location, i)\n\t\t\tfindings = append(findings, classifyValueAt(item, childLocation)...)\n\t\t}\n\tcase []string:\n\t\tfor i, item := range typed {\n\t\t\tchildLocation := fmt.Sprintf(\"%s[%d]\", location, i)\n\t\t\tfor _, finding := range ClassifyString(item) {\n\t\t\t\tfinding.Location = joinFindingLocation(childLocation, finding.Location)\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t}\n\tcase []map[string]any:\n\t\tfor i, item := range typed {\n\t\t\tchildLocation := fmt.Sprintf(\"%s[%d]\", location, i)\n\t\t\tfindings = append(findings, classifyValueAt(item, childLocation)...)\n\t\t}\n\tcase []map[string]string:\n\t\tfor i, item := range typed {\n\t\t\tchildLocation := fmt.Sprintf(\"%s[%d]\", location, i)\n\t\t\tfindings = append(findings, classifyValueAt(item, childLocation)...)\n\t\t}\n\tcase []map[string][]string:\n\t\tfor i, item := range typed {\n\t\t\tchildLocation := fmt.Sprintf(\"%s[%d]\", location, i)\n\t\t\tfindings = append(findings, classifyValueAt(item, childLocation)...)\n\t\t}\n\tcase json.RawMessage:\n\t\tfor _, finding := range ClassifyString(string(typed)) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\tcase []byte:\n\t\tfor _, finding := range ClassifyString(string(typed)) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\tcase string:\n\t\tfor _, finding := range ClassifyString(typed) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\tcase error:\n\t\tfor _, finding := range ClassifyString(typed.Error()) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\tcase url.URL:\n\t\tfor _, finding := range ClassifyString(typed.String()) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\tcase *url.URL:\n\t\tif typed != nil {\n\t\t\tfor _, finding := range ClassifyString(typed.String()) {\n\t\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t}\n\tcase slog.Attr:\n\t\tfindings = append(findings, classifySlogAttrAt(typed, location)...)\n\tcase slog.Value:\n\t\tfindings = append(findings, classifySlogValueAt(\"\", typed, location)...)\n\tcase slog.LogValuer:\n\t\tfindings = append(findings, classifySlogValueAt(\"\", typed.LogValue(), location)...)\n\tcase []slog.Attr:\n\t\tfor _, attr := range typed {\n\t\t\tfindings = append(findings, classifySlogAttrAt(attr, location)...)\n\t\t}\n\tcase fmt.Stringer:\n\t\tfor _, finding := range ClassifyString(typed.String()) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\tdefault:\n\t\tfindings = append(findings, classifyReflectValueAt(value, location)...)\n\t}\n\treturn findings\n}\n\nfunc redactReflectValue(value any) (any, bool) {\n\tredacted, ok := redactReflectValueAt(reflect.ValueOf(value), map[uintptr]struct{}{}, 0)\n\treturn redacted, ok\n}\n\nfunc redactReflectValueAt(value reflect.Value, visited map[uintptr]struct{}, depth int) (any, bool) {\n\tif depth > 16 || !value.IsValid() {\n\t\treturn nil, false\n\t}\n\tfor value.Kind() == reflect.Interface || value.Kind() == reflect.Pointer {\n\t\tif value.IsNil() {\n\t\t\treturn nil, true\n\t\t}\n\t\tif value.Kind() == reflect.Pointer {\n\t\t\tptr := value.Pointer()\n\t\t\tif _, seen := visited[ptr]; seen {\n\t\t\t\treturn Redacted, true\n\t\t\t}\n\t\t\tvisited[ptr] = struct{}{}\n\t\t}\n\t\tvalue = value.Elem()\n\t}\n\tif redacted, ok := redactKnownInterfaceValue(value); ok {\n\t\treturn redacted, true\n\t}\n\n\tswitch value.Kind() {\n\tcase reflect.Map:\n\t\tif value.IsNil() {\n\t\t\treturn nil, true\n\t\t}\n\t\tout := make(map[string]any, value.Len())\n\t\tsignedURLContext := hasReflectSignedURLContextKeys(value)\n\t\tkubernetesSecretContext := hasReflectKubernetesSecretContext(value)\n\t\titer := value.MapRange()\n\t\tfor iter.Next() {\n\t\t\tkey := stringifyReflectKey(iter.Key())\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tout[key] = redactSecretPayloadFromReflect(iter.Value())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif IsSensitiveKey(key) || shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\t\tout[key] = Redacted\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif redacted, ok := redactReflectValueAt(iter.Value(), visited, depth+1); ok {\n\t\t\t\tout[key] = redacted\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tout[key] = RedactValue(iter.Value().Interface())\n\t\t}\n\t\treturn out, true\n\tcase reflect.Struct:\n\t\tout := make(map[string]any, value.NumField())\n\t\tvalueType := value.Type()\n\t\tsignedURLContext := hasReflectStructSignedURLContextKeys(value)\n\t\tkubernetesSecretContext := hasReflectStructKubernetesSecretContext(value)\n\t\tfor i := 0; i < value.NumField(); i++ {\n\t\t\tfield := value.Field(i)\n\t\t\tfieldType := valueType.Field(i)\n\t\t\tif fieldType.PkgPath != \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkey, include := redactedStructFieldName(fieldType)\n\t\t\tif !include {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tout[key] = redactSecretPayloadFromReflect(field)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif IsSensitiveKey(key) || shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\t\tout[key] = Redacted\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif redacted, ok := redactReflectValueAt(field, visited, depth+1); ok {\n\t\t\t\tout[key] = redacted\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tout[key] = RedactValue(field.Interface())\n\t\t}\n\t\treturn out, true\n\tcase reflect.Slice, reflect.Array:\n\t\tif value.Kind() == reflect.Slice && value.IsNil() {\n\t\t\treturn nil, true\n\t\t}\n\t\tout := make([]any, value.Len())\n\t\tfor i := 0; i < value.Len(); i++ {\n\t\t\tif redacted, ok := redactReflectValueAt(value.Index(i), visited, depth+1); ok {\n\t\t\t\tout[i] = redacted\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tout[i] = RedactValue(value.Index(i).Interface())\n\t\t}\n\t\treturn out, true\n\tcase reflect.String:\n\t\treturn RedactString(value.String()), true\n\tdefault:\n\t\treturn nil, false\n\t}\n}\n\nfunc classifyReflectValueAt(value any, location string) []SecretFinding {\n\treturn classifyReflectAt(reflect.ValueOf(value), location, map[uintptr]struct{}{}, 0)\n}\n\nfunc classifyReflectAt(value reflect.Value, location string, visited map[uintptr]struct{}, depth int) []SecretFinding {\n\tif depth > 16 || !value.IsValid() {\n\t\treturn nil\n\t}\n\tfor value.Kind() == reflect.Interface || value.Kind() == reflect.Pointer {\n\t\tif value.IsNil() {\n\t\t\treturn nil\n\t\t}\n\t\tif value.Kind() == reflect.Pointer {\n\t\t\tptr := value.Pointer()\n\t\t\tif _, seen := visited[ptr]; seen {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvisited[ptr] = struct{}{}\n\t\t}\n\t\tvalue = value.Elem()\n\t}\n\tif findings, ok := classifyKnownInterfaceValueAt(value, location); ok {\n\t\treturn findings\n\t}\n\n\tvar findings []SecretFinding\n\tswitch value.Kind() {\n\tcase reflect.Map:\n\t\tsignedURLContext := hasReflectSignedURLContextKeys(value)\n\t\tkubernetesSecretContext := hasReflectKubernetesSecretContext(value)\n\t\titer := value.MapRange()\n\t\tfor iter.Next() {\n\t\t\tkey := stringifyReflectKey(iter.Key())\n\t\t\tchildLocation := key\n\t\t\tif location != \"\" {\n\t\t\t\tchildLocation = location + \".\" + key\n\t\t\t}\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfindings = append(findings, classifySecretPayloadReflectAt(iter.Value(), childLocation)...)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, finding := range classifyStructuredKey(key, signedURLContext) {\n\t\t\t\tfinding.Location = childLocation\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t\tfindings = append(findings, classifyReflectAt(iter.Value(), childLocation, visited, depth+1)...)\n\t\t}\n\tcase reflect.Struct:\n\t\tvalueType := value.Type()\n\t\tsignedURLContext := hasReflectStructSignedURLContextKeys(value)\n\t\tkubernetesSecretContext := hasReflectStructKubernetesSecretContext(value)\n\t\tfor i := 0; i < value.NumField(); i++ {\n\t\t\tfieldType := valueType.Field(i)\n\t\t\tif fieldType.PkgPath != \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkey, include := redactedStructFieldName(fieldType)\n\t\t\tif !include {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tchildLocation := key\n\t\t\tif location != \"\" {\n\t\t\t\tchildLocation = location + \".\" + key\n\t\t\t}\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfindings = append(findings, classifySecretPayloadReflectAt(value.Field(i), childLocation)...)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, finding := range classifyStructuredKey(key, signedURLContext) {\n\t\t\t\tfinding.Location = childLocation\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t\tfindings = append(findings, classifyReflectAt(value.Field(i), childLocation, visited, depth+1)...)\n\t\t}\n\tcase reflect.Slice, reflect.Array:\n\t\tfor i := 0; i < value.Len(); i++ {\n\t\t\tchildLocation := fmt.Sprintf(\"%s[%d]\", location, i)\n\t\t\tfindings = append(findings, classifyReflectAt(value.Index(i), childLocation, visited, depth+1)...)\n\t\t}\n\tcase reflect.String:\n\t\tfor _, finding := range ClassifyString(value.String()) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\t}\n\treturn findings\n}\n\nfunc redactKnownInterfaceValue(value reflect.Value) (any, bool) {\n\tif !value.CanInterface() {\n\t\treturn nil, false\n\t}\n\tswitch typed := value.Interface().(type) {\n\tcase map[string]any:\n\t\treturn RedactMap(typed), true\n\tcase map[string]string:\n\t\treturn RedactStringMap(typed), true\n\tcase http.Header:\n\t\treturn RedactStringSliceMap(map[string][]string(typed)), true\n\tcase url.Values:\n\t\treturn RedactStringSliceMap(map[string][]string(typed)), true\n\tcase map[string][]string:\n\t\treturn RedactStringSliceMap(typed), true\n\tcase map[string][]any:\n\t\tout := make(map[string][]any, len(typed))\n\t\tsignedURLContext := hasSignedURLContextKeys(mapKeys(typed))\n\t\tkubernetesSecretContext := hasKubernetesSecretContext(typed)\n\t\tfor key, values := range typed {\n\t\t\tredactedValues := make([]any, len(values))\n\t\t\tif kubernetesSecretContext && isKubernetesSecretPayloadKey(key) {\n\t\t\t\tfor i := range values {\n\t\t\t\t\tredactedValues[i] = Redacted\n\t\t\t\t}\n\t\t\t\tout[key] = redactedValues\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif IsSensitiveKey(key) || shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\t\t\tfor i := range values {\n\t\t\t\t\tredactedValues[i] = Redacted\n\t\t\t\t}\n\t\t\t\tout[key] = redactedValues\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor i, item := range values {\n\t\t\t\tredactedValues[i] = RedactValue(item)\n\t\t\t}\n\t\t\tout[key] = redactedValues\n\t\t}\n\t\treturn out, true\n\tcase json.RawMessage:\n\t\treturn json.RawMessage(RedactString(string(typed))), true\n\tcase []byte:\n\t\treturn []byte(RedactString(string(typed))), true\n\tcase []any:\n\t\tout := make([]any, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactValue(item)\n\t\t}\n\t\treturn out, true\n\tcase []string:\n\t\tout := make([]string, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactString(item)\n\t\t}\n\t\treturn out, true\n\tcase []map[string]any:\n\t\tout := make([]map[string]any, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactMap(item)\n\t\t}\n\t\treturn out, true\n\tcase []map[string]string:\n\t\tout := make([]map[string]string, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactStringMap(item)\n\t\t}\n\t\treturn out, true\n\tcase []map[string][]string:\n\t\tout := make([]map[string][]string, len(typed))\n\t\tfor i, item := range typed {\n\t\t\tout[i] = RedactStringSliceMap(item)\n\t\t}\n\t\treturn out, true\n\tcase string:\n\t\treturn RedactString(typed), true\n\tcase error:\n\t\treturn RedactString(typed.Error()), true\n\tcase url.URL:\n\t\treturn RedactString(typed.String()), true\n\tcase slog.Attr:\n\t\treturn redactSlogAttr(typed), true\n\tcase slog.Value:\n\t\treturn redactSlogValue(\"\", typed), true\n\tcase slog.LogValuer:\n\t\treturn RedactValue(typed.LogValue()), true\n\tcase []slog.Attr:\n\t\tout := make([]slog.Attr, len(typed))\n\t\tfor i, attr := range typed {\n\t\t\tout[i] = redactSlogAttr(attr)\n\t\t}\n\t\treturn out, true\n\tcase fmt.Stringer:\n\t\treturn RedactString(typed.String()), true\n\tdefault:\n\t\treturn nil, false\n\t}\n}\n\nfunc classifyKnownInterfaceValueAt(value reflect.Value, location string) ([]SecretFinding, bool) {\n\tif !value.CanInterface() {\n\t\treturn nil, false\n\t}\n\tswitch typed := value.Interface().(type) {\n\tcase map[string]any, map[string]string, http.Header, url.Values, map[string][]string, map[string][]any,\n\t\t[]any, []string, []map[string]any, []map[string]string, []map[string][]string,\n\t\tjson.RawMessage, []byte, string, error, url.URL, slog.Attr, slog.Value, slog.LogValuer, []slog.Attr, fmt.Stringer:\n\t\treturn classifyValueAt(typed, location), true\n\tdefault:\n\t\treturn nil, false\n\t}\n}\n\nfunc stringifyReflectKey(value reflect.Value) string {\n\tif !value.IsValid() {\n\t\treturn \"\"\n\t}\n\tif value.Kind() == reflect.Interface && !value.IsNil() {\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() == reflect.String {\n\t\treturn value.String()\n\t}\n\tif value.CanInterface() {\n\t\treturn fmt.Sprint(value.Interface())\n\t}\n\treturn fmt.Sprint(value)\n}\n\nfunc redactedStructFieldName(field reflect.StructField) (string, bool) {\n\tif tag := field.Tag.Get(\"json\"); tag != \"\" {\n\t\tname := strings.Split(tag, \",\")[0]\n\t\tswitch name {\n\t\tcase \"-\":\n\t\t\treturn \"\", false\n\t\tcase \"\":\n\t\tdefault:\n\t\t\treturn name, true\n\t\t}\n\t}\n\treturn field.Name, true\n}\n\nfunc classifySlogAttrAt(attr slog.Attr, location string) []SecretFinding {\n\tchildLocation := attr.Key\n\tif location != \"\" {\n\t\tchildLocation = location + \".\" + attr.Key\n\t}\n\tvar findings []SecretFinding\n\tfor _, finding := range ClassifyKey(attr.Key) {\n\t\tfinding.Location = childLocation\n\t\tfindings = append(findings, finding)\n\t}\n\tfindings = append(findings, classifySlogValueAt(attr.Key, attr.Value, childLocation)...)\n\treturn findings\n}\n\nfunc classifySlogValueAt(key string, value slog.Value, location string) []SecretFinding {\n\tvalue = value.Resolve()\n\tif IsSensitiveKey(key) {\n\t\treturn nil\n\t}\n\tswitch value.Kind() {\n\tcase slog.KindString:\n\t\tvar findings []SecretFinding\n\t\tfor _, finding := range ClassifyString(value.String()) {\n\t\t\tfinding.Location = joinFindingLocation(location, finding.Location)\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\t\treturn findings\n\tcase slog.KindAny:\n\t\treturn classifyValueAt(value.Any(), location)\n\tcase slog.KindGroup:\n\t\tvar findings []SecretFinding\n\t\tfor _, attr := range value.Group() {\n\t\t\tfindings = append(findings, classifySlogAttrAt(attr, location)...)\n\t\t}\n\t\treturn findings\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc classifyStringSliceMapAt(input map[string][]string, location string) []SecretFinding {\n\tvar findings []SecretFinding\n\tfor key, values := range input {\n\t\tchildLocation := key\n\t\tif location != \"\" {\n\t\t\tchildLocation = location + \".\" + key\n\t\t}\n\t\tfor _, finding := range ClassifyKey(key) {\n\t\t\tfinding.Location = childLocation\n\t\t\tfindings = append(findings, finding)\n\t\t}\n\t\tif isSignedURLQueryKey(key) {\n\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSignedURL, Signal: \"url_query_secret\", Location: childLocation})\n\t\t}\n\t\tfor i, value := range values {\n\t\t\tvalueLocation := fmt.Sprintf(\"%s[%d]\", childLocation, i)\n\t\t\tif isSignedURLQueryKey(key) {\n\t\t\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSignedURL, Signal: \"url_query_secret\", Location: valueLocation})\n\t\t\t}\n\t\t\tfor _, finding := range ClassifyString(value) {\n\t\t\t\tfinding.Location = joinFindingLocation(valueLocation, finding.Location)\n\t\t\t\tfindings = append(findings, finding)\n\t\t\t}\n\t\t}\n\t}\n\treturn findings\n}\n\nfunc classifyStructuredKey(key string, signedURLContext bool) []SecretFinding {\n\tfindings := ClassifyKey(key)\n\tif shouldRedactStructuredSignedURLKey(key, signedURLContext) {\n\t\tfindings = append(findings, SecretFinding{Kind: SecretKindSignedURL, Signal: \"url_query_secret\"})\n\t}\n\treturn findings\n}\n\nfunc mapKeys[T any](input map[string]T) []string {\n\tkeys := make([]string, 0, len(input))\n\tfor key := range input {\n\t\tkeys = append(keys, key)\n\t}\n\treturn keys\n}\n\nfunc hasReflectSignedURLContextKeys(value reflect.Value) bool {\n\titer := value.MapRange()\n\tfor iter.Next() {\n\t\tif isSignedURLContextKey(stringifyReflectKey(iter.Key())) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc hasReflectStructSignedURLContextKeys(value reflect.Value) bool {\n\tif value.Kind() != reflect.Struct {\n\t\treturn false\n\t}\n\tvalueType := value.Type()\n\tfor i := 0; i < value.NumField(); i++ {\n\t\tfieldType := valueType.Field(i)\n\t\tif fieldType.PkgPath != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tkey, include := redactedStructFieldName(fieldType)\n\t\tif !include {\n\t\t\tcontinue\n\t\t}\n\t\tif isSignedURLContextKey(key) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc joinFindingLocation(parent, child string) string {\n\tif parent == \"\" {\n\t\treturn child\n\t}\n\tif child == \"\" {\n\t\treturn parent\n\t}\n\tif strings.HasPrefix(child, \"[\") {\n\t\treturn parent + child\n\t}\n\treturn parent + \".\" + child\n}\n"}}}}