Secret scanner
Before skl sync uploads a skill, skl scans every line of every file in the skill directory. Each finding is a block or a warning. A block stops the upload of that skill. A warning stops it unless you pass --allow-warnings. --allow-warnings never overrides a block.
Blocks
| Kind | Matches |
|---|---|
private_key | -----BEGIN PRIVATE KEY-----, with or without a key type such as RSA |
aws_access_key | AKIA followed by 16 uppercase letters or digits |
aws_secret_key | aws_secret_access_key assigned a 40-character value |
github_token | ghp_ followed by 36 characters, or github_pat_ followed by 20 or more |
slack_token | xoxb-, xoxa-, xoxp-, xoxr-, or xoxs- followed by 10 or more characters |
stripe_live_key | sk_live_ followed by 16 or more characters |
anthropic_key | sk-ant- followed by 20 or more characters |
openai_key | sk- or sk-proj- followed by 20 or more characters |
npm_token | npm_ followed by 36 characters |
env_secret in a .env file | An assignment to api_key, secret_key, access_token, auth_token, password, or private_key, with _ or - as the separator, in .env, .env.local, .env.production, or .env.development |
Warnings
| Kind | Matches |
|---|---|
jwt | Three base64url segments where the first two start with eyJ |
google_api_key | AIza followed by 35 characters |
env_secret in any other file | The same assignment pattern as above, outside the .env files |
An env_secret value is ignored when it looks like a placeholder: shorter than 8 characters, all x, todo, or containing example, placeholder, changeme, your-, your_, or starting with xxx, <, or ${.
Output
blocked: writing-tests / SKILL.md:12 (aws_access_key)
warning: writing-tests / notes.md:3 (jwt)
scrub: 1 blocked, 1 warnings
With a block, skl sync exits with upload blocked: .... The scanner reads bytes as UTF-8 and skips files it cannot read.
Limits
The scanner matches these patterns and nothing else. It does not detect a secret in an unknown format, and it does not rewrite files. Keep secrets out of skills.