Decoy credentials for GitLab and AWS

Give them
something
to find.

Real credentials that grant nothing, placed where intruders and their agents go looking. The first use tells you where and when.

DECOYS / web-01 Armed
.env.production
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
AWS_ACCESS_KEY_ID=AKIAxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxx
# rotated 04-02 — do not commit
AWS key used
sts:GetCallerIdentity · 203.0.113.44
prod .env on web-01 · 02:14:07 UTC

The intruder is increasingly
a program that reads everything

Threat actors now hand the tedious part to agents: sweep a foothold for credentials, try each one, map what it opens. A cloud key or a git token is the prize, because infrastructure and source are where the next moves come from.

Why agents trip decoys
01

They enumerate. Every file, variable and log that might hold a secret gets read, so a decoy in any of them gets read too.

02

They validate. A found credential is tried against its platform to see what it opens. That single call is the alert.

03

They are fast. Minutes from foothold to harvest, which is why the signal has to come from the first touch, not from a pattern learned over weeks.

One decoy in the pipeline

A CI variable nothing legitimate reads. The pipeline runs exactly as before; the first job, script or person that does read it has told you where they are.

A decoy token placed in CI variables raises an alert the moment it is used A pipeline of four stages: source, CI variables, CI runner, deploy. One CI variable is a decoy token. Below, in order: someone reads it by dumping the runner's job environment, the token is used against GitLab, and the alert names the CI variables of that pipeline. 01 · Source push main a3f9c1e 02 · CI variables DATABASE_URL •••••••••••• SENTRY_DSN •••••••••••• GITLAB_TOKEN glpat-xxxxxxxxxxxxxxxxxxxx decoy 03 · CI runner job env loaded 04 · Deploy prod ok reads the job environment 1 · Someone reads it $ env | grep TOKEN 2 · Token used gitlab.com · projects.list · 203.0.113.44 3 · Alert CI variables · pipeline web-api

Three steps, one afternoon

01

Generate

A real GitLab token or AWS key, minted on the platform itself, with access to next to nothing.

02

Place

Put it where someone would go looking, and record the placement in your own words. That is what the alert will name.

03

Hear about it

The first use emails your team the placement, the time and the source address. The decoy's page keeps every use after that.

Where a decoy earns its keep

Where attackers and their agents search first. Your team decides which are in scope.

01Repo config.env files, sample configs, committed fixtures
02CI variablesPipeline variables, Actions secrets, build environments
03Internal docsRunbooks and wiki pages an agent will read first
04Stale branchesAbandoned work nobody audits any more
05Developer laptopsDotfiles, ~/.aws/credentials, local credential stores
06Images and backupsContainer images, VM snapshots, database dumps

One alert, one meaning

A decoy has no legitimate use, so if it fires, someone found it. No tuning, no baseline.

Nothing to deploy

A decoy is a string. No agents on endpoints, no access to your accounts, no change window.

Reads well upstairs

An alert that names a placement and a time reads the same to the engineer triaging it and to the board asking what was touched.

One repo.
Two decoys.
One week.

The free plan needs no card. Put a GitLab token and an AWS key in one repo this week; if nothing fires, you have lost a week and learned where your blind spots are not. Want us on the call when the first alert lands? See the plans that come with our team.

A decoy grants nothing, so nothing in production changes.