Secrets, API Keys and Least Privilege

5.Rotate First. Everything Else After.

A

In this chapter

We'll learn what API keys and other secrets are, what to do — in order — when one leaks, how to stop leaks happening, and why least privilege limits the damage, using Thursday's payment key leak and a hotel's keycards.

12–14 min

The Problem in Real Life

Thursday, 8:40 AM. The payment provider's email includes a link. It leads to a public GitHub repository called blueticket-test-scripts, owned by a contractor who helped BlueTicket a year ago. In a file named config.js: PAYMENT_API_KEY = "sk_live_••••••••" — the live key. It's been public for eleven months.

Anna remembers John's warning from Act 16: "One day someone will push a key to GitHub anyway. Rotate the key first, then fix the history." John is already on the phone with the payment provider. "Exactly. Rotate first. Everything else after."

J

A leaked secret is a used secret. Assume someone already has it.

John

One All-Powerful Key That Lives Forever vs. Small Keys That Can Be Replaced

Public means found

Bots scan public code for keys around the clock. A pushed key is usually found within minutes.

Too much power

The leaked key could charge, refund and read every payment — far more than the scripts needed.

Keys that never change

The same key had been in use for three years, copied into who-knows-how-many places.

Secrets, API Keys, Permissions and Least Privilege

The hotel keycard analogy: in a good hotel, a guest's keycard opens their room, for their stay, and nothing else. Cleaners' cards open rooms on their floor during working hours. Only the manager has a master card — and it's kept in a safe. If a card is lost, the hotel cancels it and issues a new one in seconds. Secrets and permissions in software should work the same way.

  • Secrets — anything that grants access: a secret is any value that proves you're allowed in: database passwords, API keys, signing keys for JWTs, encryption keys, tokens for the pipeline (Acts 16, 19, 20). Whoever holds the secret is you, as far as the system knows.
  • API keys — keycards for programs: an API key is a secret a program sends to another company's API (Act 12) to prove who it is: BlueTicket's app sends its payment key with every charge request. Providers usually issue separate test and live keys (Act 16).
  • When a secret leaks — the order matters: 1. Rotate — create a new key, switch production to it, and revoke the old one, so the leaked copy stops working. 2. Investigate — check the provider's logs: was the old key used by anyone but us? 3. Remove — delete it from the code and history (and ask the repository owner to delete the repo). 4. Learn — a blameless review (Act 19): how did it get there, and how do we stop the next one? Removing it from GitHub first is useless — copies may already exist.
  • Stopping leaks — catch them before they leave: secrets live in a secrets manager (Act 16, Act 20), never in code. Secret scanning tools (GitHub has one built in; others run as a pre-commit check) block commits that contain things that look like keys. Contractors and every service get their own keys, so a key can be cancelled without breaking anything else. And keys are rotated regularly, so an old leaked copy expires on its own.
  • Permissions — what each keycard opens: a permission is a specific allowed action: "create charges", "issue refunds", "read payment history". Good systems let you choose exactly which permissions each key, user or service gets.
  • Least privilege — the smallest keycard that does the job: least privilege (Act 20) means giving every person, key and service only the permissions it needs, for only as long as it needs them. A leaked key that can only create charges for BlueTicket's own account is a small problem. A leaked key that can also refund to any card is a disaster.
Table — The leaked key vs. the new keys
KeyUsed byCan doRotated
Old live key (revoked)Everything, for 3 yearsCharge, refund, read allNever
checkout keyCheckout serviceCreate charges onlyEvery 90 days
refunds keyRefunds serviceRefund onlyEvery 90 days
finance keyFinance dashboardRead onlyEvery 90 days
test keyTest scriptsTest mode only — no real moneyEvery 90 days
Table — When a secret leaks
StepWhat to doWhy this order
1. Rotate and revokeNew key in, old key offThe leaked copy stops working right away
2. InvestigateCheck the provider's logs for misuseKnow if damage was done
3. RemoveDelete from code, history, the repoTidy up — but copies may exist already
4. LearnBlameless review, add scanningStop the next one

Thursday, minute by minute: 8:45 — John creates a new restricted key in the payment provider's dashboard and puts it in the secrets manager; 8:52 — the pipeline redeploys with it (Act 19); 8:55 — the old key is revoked; 9:00–11:00 — Anna and John check eleven months of the provider's logs: the old key was only ever used from BlueTicket's own servers. Lucky. 11:30 — the contractor deletes the repo; GitHub secret scanning is turned on for every BlueTicket repository.

Least privilege, applied: the old key could do everything. Now there are four keys: the checkout service can only create charges; the refunds service can only refund; the finance dashboard can only read; the test scripts get a test key. All are rotated every 90 days. Anna writes "Least privilege, always" on the whiteboard, and nobody erases it.

Key Takeaway

A secret is anything that grants access — whoever holds it is you. When one leaks, rotate and revoke first, then investigate its use, then remove it, then learn without blame. Prevent leaks with a secrets manager, secret scanning and separate keys per service, and rotate keys regularly. Least privilege — like hotel keycards — gives every key, person and service only the permissions it needs, so a leak stays small.

Why This Matters

Leaked secrets are among the most common causes of real breaches, and nearly every developer handles keys and passwords. Knowing the right order of response — rotate first — and building with least privilege from the start keeps a small mistake from becoming a disaster.

The key is rotated. Back to Tuesday's mystery: ' OR 1=1 -- in the promo-code box. The attack was blocked — but while checking why, Anna finds one place in the code where it wouldn't have been.

Next