Showcase
Each example is a real nosecrets run: the files on the left, the session on the right. Open one to see how nosecrets behaves in the situation you are in.
Stop a leak
A token and a database password in one commit
site/captures/usecases/leaked-key/Detail: A token and a database password in one commit →# .env
APP_ENV=production
DATABASE_URL=postgres://admin:Tr0ub4dor-and-3@db.internal:5432/app
# deploy.py
import requests
GITHUB_TOKEN = "ghp_R2kT9xLm4Qv7Bn3Zc8Wd5Hf1Jg6Ys0AaPeXq"
def release(version):
return requests.post(
"https://api.github.com/repos/acme/app/releases",
headers={"Authorization": f"token {GITHUB_TOKEN}"},
json={"tag_name": version},
)$ git add deploy.py .env $ nosecrets scan --staged .env:2:31 [HIGH] Postgres Connection URI (postgres-connection-uri) nsi_31013ade6422 preview: Tr0... deploy.py:3:17 [CRITICAL] GitHub Personal Access Token (github-pat) nsi_5e31772c2cb9 preview: ghp_...PeXq $ echo $? 1
Deleting the line afterwards does not help
site/captures/usecases/staged-snapshot/Detail: Deleting the line afterwards does not help →# config.py
API_URL = "https://api.acme.example"
GITHUB_TOKEN = "ghp_R2kT9xLm4Qv7Bn3Zc8Wd5Hf1Jg6Ys0AaPeXq"$ git add config.py $ sed -i.bak '/GITHUB_TOKEN/d' config.py && rm config.py.bak $ cat config.py API_URL = "https://api.acme.example" $ nosecrets scan --staged config.py:2:17 [CRITICAL] GitHub Personal Access Token (github-pat) nsi_5e31772c2cb9 preview: ghp_...PeXq
Adopt it
Adopt it in a repository that already exists
site/captures/usecases/adopt/Detail: Adopt it in a repository that already exists →# legacy/import_users.py
# One-off migration script from 2021.
GITHUB_TOKEN = "ghp_R2kT9xLm4Qv7Bn3Zc8Wd5Hf1Jg6Ys0AaPeXq"
# src/app.py
import os
TOKEN = os.getenv("GITHUB_TOKEN")$ nosecrets scan --tracked legacy/import_users.py:2:17 [CRITICAL] GitHub Personal Access Token (github-pat) nsi_5e31772c2cb9 preview: ghp_...PeXq $ nosecrets ignore nsi_5e31772c2cb9 --path legacy/import_users.py Added ignore entry to .nosecretsignore $ cat .nosecretsignore nsi_5e31772c2cb9:legacy/import_users.py $ nosecrets scan --tracked No secrets found
Exceptions on purpose, visible in review
site/captures/usecases/exceptions/Detail: Exceptions on purpose, visible in review →# .nosecrets.toml
[ignore]
paths = ["tests/fixtures/"]
# app.py
DOC_EXAMPLE = "ghp_R2kT9xLm4Qv7Bn3Zc8Wd5Hf1Jg6Ys0AaPeXq" # @nsi documented example value
STAGING = "ghp_Zp3Lk8Vn2Xc6Qw1Rt5Mb9Hd4Jf7Ys0GaNeUo"
# tests/fixtures/tokens.py
FIXTURE = "ghp_Qw8Er5Ty2Ui7Op1As4Df9Gh3Jk6Lz0XcVbNm"$ git add -A $ nosecrets scan --staged app.py:2:12 [CRITICAL] GitHub Personal Access Token (github-pat) nsi_8c2b7cfaeaba preview: ghp_...NeUo
Beyond the built-in rules
A token no rule knows
site/captures/usecases/entropy/Detail: A token no rule knows →# settings.py
SERVICE_NAME = "billing"
API_KEY = "changeme"
INTERNAL_SERVICE_TOKEN = "q7Zk2vN9xB4mT8wR1cL6hD3fY5jP0sGe"$ git add settings.py $ nosecrets scan --staged settings.py:3:27 [MEDIUM] High Entropy String (high-entropy-string) nsi_294e8f1228c4 preview: q7Zk...0sGe
Your own token format as a rule
site/captures/usecases/team-rule/Detail: Your own token format as a rule →# deploy.sh
#!/bin/sh
curl -H "X-Acme-Token: acme_Vn4Kq8Zx2Lm7Tc1Rw5Bh9Dj3" https://deploy.acme.example/run
# team-rules.toml
[[rule]]
id = "acme-service-token"
name = "Acme service token"
severity = "high"
pattern = '''\b(acme_[A-Za-z0-9]{24})\b'''
keywords = ["acme_"]
capture = 1$ git add deploy.sh $ nosecrets scan --staged --rules team-rules.toml deploy.sh:2:24 [HIGH] Acme service token (acme-service-token) nsi_a7570523585c preview: acme...
In scripts and CI
Machine-readable output
site/captures/usecases/json/Detail: Machine-readable output →# deploy.py
import requests
GITHUB_TOKEN = "ghp_R2kT9xLm4Qv7Bn3Zc8Wd5Hf1Jg6Ys0AaPeXq"
def release(version):
return requests.post(
"https://api.github.com/repos/acme/app/releases",
headers={"Authorization": f"token {GITHUB_TOKEN}"},
json={"tag_name": version},
)$ git add deploy.py $ nosecrets scan --staged --format json [ { "path": "deploy.py", "line": 3, "column": 17, "rule_id": "github-pat", "rule_name": "GitHub Personal Access Token", "severity": "critical", "fingerprint": "nsi_5e31772c2cb9", "preview": "ghp_...PeXq" } ]
A typo in the configuration stops the scan
site/captures/usecases/bad-config/Detail: A typo in the configuration stops the scan →# .nosecrets.toml
[entropy]
treshold = 4.5
# deploy.py
import requests
GITHUB_TOKEN = "ghp_R2kT9xLm4Qv7Bn3Zc8Wd5Hf1Jg6Ys0AaPeXq"
def release(version):
return requests.post(
"https://api.github.com/repos/acme/app/releases",
headers={"Authorization": f"token {GITHUB_TOKEN}"},
json={"tag_name": version},
)$ git add deploy.py $ nosecrets scan --staged Error: failed to parse .nosecrets.toml: TOML parse error at line 2, column 1 | 2 | treshold = 4.5 | ^^^^^^^^ unknown field `treshold`, expected one of `enabled`, `min_length`, `threshold`, `require_context`, `allow` $ echo $? 2