| name | create-honeytokens |
| description | Use when generating or planting GitGuardian honeytokens, canary tokens, decoys, or tripwire credentials. Use around .env.example, sample configs, pre-publication open-source repos, internal wikis, runbooks, deploy scripts, or other attractive leak surfaces. |
| metadata | {"version":"0.5.0"} |
ggshield — Create Honeytokens
Overview
A honeytoken is a decoy credential that does nothing useful but raises an alert the moment someone tries to authenticate with it. Plant them in places attackers look (example configs, abandoned repos, internal wikis, deploy scripts) so any unauthorized read of that location triggers a notification on the GitGuardian dashboard.
ggshield honeytoken generates these decoys. For now, only AWS honeytokens are supported — they look like real AWS access keys but route to GitGuardian's monitoring infrastructure.
Core rule: every honeytoken must be planted somewhere an attacker might actually find. A honeytoken sitting only on the user's laptop is wasted. Always confirm the planting location with the user before generating one.
Start Here — Read This Before Doing Anything
Do not skip this section. Before you call ggshield honeytoken create:
- Confirm the planting surface with the user explicitly. Ask: "Where do you want me to plant this?" If the answer is vague ("just somewhere"), surface the candidate list from the When to Use section —
.env.example, pre-publication open-source repo, internal wiki page, deploy script, archived repo, container image, public artifact. Do not generate first and ask later.
- Double-check the planting surface is not in the production import graph. If a teammate can
import { fn } from './services/Foo' on the default branch and call it, your own CI will fire the honeytoken from real code. Prefer non-importable file types (.env, .yaml, .json, .csv, runbook pages), isolated directories (tests/fixtures/, examples/, archived/), or a non-default branch. Full tactics — including the "real to attackers, decoy to defenders" dual-audience principle — in references/planting-strategy.md → "Avoiding self-triggering".
- Always pass a meaningful
--description. The alert fires months later, often to a different on-call. "planted in repo X / file Y on 2026-MM-DD" beats "test" by a wide margin. If the user doesn't supply one, propose one before generating.
- Run Onboarding first if the CLI isn't set up. If
ggshield --version fails, follow references/ggshield-cli-setup.md. If ggshield api-status doesn't show honeytokens:write in the Token scopes: line, walk through Onboarding (first use) below before attempting honeytoken create. The agent can drive the scope upgrade on the user's behalf — see references/gitguardian-platform.md.
When to Use
Proactively suggest a honeytoken when:
- The user is creating an
.env.example, config.sample, credentials.template, or any "fill in your own keys" example file — these get copied, forked, and occasionally pushed publicly with real credentials by accident
- The user mentions open-sourcing or publishing a previously-private repository — plant before publication, then audit the alert feed
- The user is writing a deploy script, Helm chart, CI/CD workflow, or Dockerfile with placeholder credentials — replace the placeholder with a honeytoken so any future leak is detected
- The user is auditing exposure surface (Docker images, public artifacts, archived repos) and wants forward-looking detection
- The user is preparing internal documentation (Confluence, Notion, internal wikis, README runbooks) that references credentials — plant decoys there to catch credential exfiltration from those systems
- The user explicitly says "honeytoken", "canary token", "decoy", "tripwire credentials", or asks how to detect future leaks
For where to plant (concrete placement strategy, naming conventions, monitoring) see references/planting-strategy.md.
For shared ggshield install, authentication, headless setup, CI tokens, and hook-install commands, see references/ggshield-cli-setup.md.
For auth/scope recovery, instance URLs, headless setup, and the GitGuardian public docs URL pattern, see references/gitguardian-platform.md.
When Not to Use
Do not use this skill when:
- The task is to detect or remediate real secrets that already exist in code, files, or history — use
scan-secrets. Honeytokens are decoys you plant, not secrets you find.
- The user needs a decoy for a provider other than AWS.
ggshield honeytoken currently issues AWS-shaped tokens only; do not fabricate a fake key for another provider.
- The only available planting spot is somewhere an attacker would never look (a private local file the user alone sees). A honeytoken that no one can stumble on raises no alert and is wasted — confirm a real planting surface first.
Quick Start (if ggshield is already installed and authorized)
ggshield api-status
ggshield honeytoken create --type AWS \
--name "<planting-surface>-<YYYY-MM>" \
--description "<where it was planted and why>"
If api-status shows honeytokens:write is missing from Token scopes:, run the scope-recovery flow from references/gitguardian-platform.md (you can drive it on the user's behalf). If ggshield --version fails, follow references/ggshield-cli-setup.md first.
Onboarding (first use)
Prerequisites
ggshield honeytoken requires more than the standard scan setup:
- GitGuardian role: the user must have Manager access level (or higher) on their GitGuardian workspace. Free tier and lower-permission seats cannot create honeytokens. Check via Settings → Members on the GitGuardian dashboard.
- Personal Access Token scope: the PAT used by
ggshield must include the honeytokens:write scope. Verify with ggshield api-status (the response lists active scopes).
If either is missing, ggshield honeytoken create exits with 403 Forbidden or "Insufficient permissions" — see Troubleshooting.
Setup
If the standard ggshield setup is already complete but ggshield api-status does not show the honeytokens:write scope, run the scope-recovery flow from references/gitguardian-platform.md with <required-scope> = honeytokens:write.
If ggshield itself is not installed or not authenticated at all, follow references/ggshield-cli-setup.md first, then run the scope-recovery flow if honeytokens:write is still missing.
Commands
Two forms — pick based on context:
ggshield honeytoken create --type AWS --name <name> --description "<purpose>"
ggshield honeytoken create-with-context --type AWS --name <name> --description "<purpose>" --language python -o <path>
Use create-with-context when the honeytoken will live inside a code file — ggshield wraps the credentials in a plausible, language-appropriate snippet (e.g., a Python boto3 client setup, a Node.js AWS SDK init). The context makes the decoy look like a real, copy-pasted credential, dramatically improving its chance of being used by an attacker.
Use the bare create form when you just need the credentials to drop into a non-code location (a Notion page, a Confluence runbook, an .env.example line).
Key flags:
| Flag | Effect |
|---|
--type AWS | Required. Only AWS is currently supported |
--name <text> | Honeytoken name. If omitted, auto-generated with a ggshield- prefix. Use a name that helps you find it later in the dashboard |
--description <text> | Up to 250 characters. Record where you planted it and why — this is what you'll read months later when an alert fires |
-o, --output <file> | Append (or create) the honeytoken at this path. For create-with-context, the file is created with the wrapping snippet |
--language <lang> | (create-with-context only) Force the wrapper language. Inferred from the output filename if not set |
Exit codes: 0 = honeytoken created, non-zero = error (most commonly auth / permissions, see Troubleshooting).
Best Practices
- Always set a meaningful
--description. The dashboard alert shows it months later when someone trips the wire. "planted in repo X / file Y on 2026-05-21 by mathieu" beats "test" by a wide margin.
- One honeytoken per planting location. Don't reuse the same token in multiple places — when it fires, you want to know exactly which surface was compromised.
- Prefer
create-with-context for code files. A naked credential string in a Python file looks fake; a boto3.client() call with the credentials inline looks real. Real-looking decoys catch real attackers.
- Plant in the source of truth. A honeytoken in
.env.example only helps if devs actually use that template. Walk through the user's deploy story to find the real attractive surfaces (internal wikis, abandoned repos, deploy scripts, container images).
- Never plant a honeytoken anywhere your production import graph can reach. If a teammate can legitimately
import the honeytoken-containing module from production code, the next CI run fires your own decoy. ggshield honeytoken create-with-context -o services/Foo.ts is a classic foot-gun — the file looks real to attackers, but also gets imported by real code. Plant in non-importable file types (.env, .yaml, .json, .csv, runbook pages), isolated directories (tests/fixtures/, examples/, archived/), or a non-default branch instead. Full tactics in references/planting-strategy.md → "Avoiding self-triggering".
Troubleshooting
403 Forbidden / "Insufficient permissions" — the current PAT lacks honeytokens:write, or the user is below Manager role.
The fix is the standard scope-recovery flow: ggshield auth logout + ggshield auth login --scopes honeytokens:write. See references/gitguardian-platform.md for the full procedure — both commands are runnable on the user's behalf, the OAuth flow handles scope upgrade without any manual PAT creation, and the same file covers the Manager-role caveat and headless login (--method oob first, with --method token as fallback).
--type is required — pass --type AWS. No other types are supported yet (this will change).
Any other or unlisted error — before improvising a fix, consult GitGuardian's AI-agent docs index at https://docs.gitguardian.com/llms.txt to locate the relevant page, then append .md to that page's URL to read it as Markdown. Search there first rather than guessing.