Bitwarden Designer
Bitwarden Product Analyst
Bitwarden Tech Lead
Bitwarden Testing Tools
Claude Config Validator · Reviewing…
Claude Retrospective
65 skills · 321 min
Bitwarden Security Engineer
Skill 42 of 65
This skill should be used when the user asks to “find hardcoded secrets”, “audit for credential leaks”, “check for API keys in code”, “review secret scanning alerts”, “rotate a…
3 minutes · 621 words · 16 sections
Install
npx skills add bitwarden/ai-plugins --skill detecting-secretsnpx skills add bitwarden/ai-plugins/plugin marketplace add bitwarden/ai-pluginsThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
Look for these categories of hardcoded secrets in code:
| Type | Example Patterns |
|---|---|
| API Keys | AKIA[0-9A-Z]{16} (AWS), AIza[0-9A-Za-z_-]{35} (Google), strings assigned to variables named *apiKey*, *api_key* |
| Connection Strings | Server=...;Password=..., mongodb://user:pass@host, postgres://user:pass@host |
| Private Keys | -----BEGIN RSA PRIVATE KEY-----, -----BEGIN OPENSSH PRIVATE KEY----- |
| Tokens | ghp_[A-Za-z0-9]{36} (GitHub PAT), xoxb- (Slack bot), sk- (OpenAI) |
| Passwords | Values assigned to variables named *password*, *passwd*, *secret*, *credential* |
| Certificates | PFX/P12 files with embedded passwords, PEM files with private keys |
https://user:pass@host)Distinguish real secrets from false positives. Not every pattern match indicates an actual secret — consider context:
// NOT a real secret — test fixture with obvious fake value
var testApiKey = "test-api-key-not-real-12345";
var mockPassword = "P@ssword123"; // Used only in unit tests
// REAL secret — production-looking value in non-test code
var apiKey = "sk-proj-abc123def456ghi789jkl012mno345pqr678stu901vwx";Decision criteria:
**/test/**, **/tests/**, **/*.Test/**)?// NOT a real secret — documented example
{
"apiKey": "YOUR_API_KEY_HERE"
}
// REAL secret — actual value in config
{
"apiKey": "sk-proj-abc123def456ghi789jkl012mno345pqr678stu901vwx"
}$2b$, argon2 $argon2id$) are NOT secrets — they’re properly storedSearch these locations when auditing for secrets:
| Location | What to Look For |
|---|---|
appsettings.json / appsettings.Development.json | Connection strings, API keys, service credentials |
.env / .env.local | Environment variable definitions with real values |
web.config / app.config | Machine keys, connection strings |
docker-compose.yml / Dockerfile | ENV directives with credentials, build args with secrets |
CI/CD files (.github/workflows/*.yml) | Inline secrets instead of ${{ secrets.* }} references |
| Test seed scripts / migration files | Database passwords, service account credentials |
| Comments and TODO notes | “Temporary” credentials left in comments |
| Default parameter values | function connect(password = "admin123") |
| Constants files | Centralized credential definitions |
# List all secret scanning alerts
gh api /repos/{owner}/{repo}/secret-scanning/alerts --jq '.[] | {number, state, secret_type, secret_type_display_name, created_at, push_protection_bypassed}'
# Get details for a specific alert
gh api /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}
# List alerts that bypassed push protection
gh api "/repos/{owner}/{repo}/secret-scanning/alerts?state=open" --jq '.[] | select(.push_protection_bypassed == true)'Push protection prevents commits containing detected secrets from being pushed. When someone bypasses push protection, the alert is flagged — review these with extra scrutiny.
When a secret is found in code, follow this sequence:
Assume any committed secret is compromised. Even if the repo is private, the secret may have been cached, logged, or accessed by CI/CD systems.
Replace the hardcoded secret with a secure reference:
// WRONG — hardcoded secret
var connectionString = "Server=prod.db;Password=s3cr3t!";
// CORRECT — environment variable
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING");
// CORRECT — Azure Key Vault (Bitwarden's approach)
var connectionString = await keyVaultClient.GetSecretAsync("db-connection-string");If the secret was committed to a public repo or a repo that will become public:
# Using git filter-repo (preferred over filter-branch)
git filter-repo --path-glob '*.json' --replace-text expressions.txt
# expressions.txt format:
# literal:the-secret-value==>REDACTEDWarning: Rewriting git history is destructive and affects all collaborators. Only do this when the secret was exposed in a public or soon-to-be-public repository.
.gitignore for files that should never be committed (.env, *.pfx, appsettings.Development.json)Bitwarden uses Azure Key Vault for secrets management, provisioned by the BRE team:
| Instead Of | Use |
|---|---|
| Hardcoded connection strings | Azure Key Vault secrets |
| API keys in config files | Environment variables set at deployment |
| Certificates in source | Azure Key Vault certificates |
| Shared team credentials in code | Managed identities (Azure) |
| Secrets in CI/CD workflow files | GitHub Actions secrets (${{ secrets.NAME }}) |
For local development, use user-secrets or .env files that are .gitignored — never commit them.
git log -p -S "secret-pattern" to search history.This skill should be used when the user asks to "find hardcoded secrets", "audit for credential leaks", "check for API keys in code", "review secret scanning alerts", "rotate a leaked secret", or needs to detect hardcoded credentials, review secret handling patterns, or remediate exposed secrets.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
main, last pushed 23 September 2026.SKILL.md, not by matching a directory convention. 13 distinct layouts observed: plugins/bitwarden-atlassian-tools/skills/*/SKILL.md, plugins/bitwarden-code-review/skills/*/SKILL.md, plugins/bitwarden-delivery-tools/skills/*/SKILL.md, plugins/bitwarden-design-tools/skills/*/SKILL.md, plugins/bitwarden-designer/skills/*/SKILL.md, plugins/bitwarden-devops-engineer/skills/*/SKILL.md, plugins/bitwarden-product-analyst/skills/*/SKILL.md, plugins/bitwarden-security-engineer/skills/*/SKILL.md, plugins/bitwarden-shepherd/skills/*/SKILL.md, plugins/bitwarden-tech-lead/skills/*/SKILL.md, plugins/bitwarden-testing-tools/skills/*/SKILL.md, plugins/claude-config-validator/skills/*/SKILL.md, plugins/claude-retrospective/skills/*/SKILL.md..claude-plugin/marketplace.json by Bitwarden, declaring 16 plugins. It is read for editorial metadata only — never as the skill index, which is always the repository tree./bitwarden/ai-plugins.md, and each skill at its own .md URL.