I opened the Commercetools admin panel one Friday to add a single integration, and I never got to it. Because thirty-four API clients were staring back at me. Most of them I had never seen. Some were older than the current team. That is the moment I dropped my task and started building a way to find, audit, and kill stale API clients — the old credentials that pile up in every enterprise and quietly wait for someone to exploit them.
The panel nobody scrolls to the bottom of
Here is the honest version of API credential hygiene in most companies: someone creates a client during a sprint, hardcodes the secret into a service, ships it, and moves on. Two years later that person has left, the service may or may not still call the API, and the client is still sitting there with whatever scopes it was born with. Nobody decommissions it, because nobody can prove it is safe to.
The security posture for these credentials? Just vibes and prayers.
When I actually looked, the numbers were worse than messy. They were a liability.
The first real audit
I pulled every client and cross-referenced it against actual API usage logs. Not what the client was named. Not what someone thought it did. What it actually called, and when. The breakdown:
- 34 API clients total
- 12 active with legitimate, documented usage
- 18 zombies with zero activity in the last 90+ days
- 4 with full admin scope to production that had not been touched in six months
Read that last line again. Four credentials with full write access to production data, from a project that ended eighteen months ago, still live. Any one of them compromised, and someone could have modified production data without a trace — no owner to notice, no rotation to expire the secret, no audit trail to catch it.
Four open doors to production that nobody knew existed.
Why the graveyard keeps growing
The interesting part is that none of this is a technical problem. It is an ownership problem wearing a technical costume.
Every sprint creates new API clients. No sprint has a task called "delete the client we stopped using." Credentials accumulate like technical debt, except this debt is invisible — there is no failing test, no red dashboard, no latency spike. A dead client with admin scope looks exactly like a live one until the day it gets used against you.
And the reason nobody cleans them up is embarrassingly simple: nobody can tell which ones are still in use. No mapping. No usage tracking. Just a list of names that meant something to someone who probably doesn't work here anymore.
You cannot clean up what you cannot see.
The tool: make the invisible visible
So I built the thing that should have existed from day one. It is deliberately boring: Python, Dockerized, runs anywhere with no setup. Point it at the Commercetools API and it does four things:
- Discovers every client the account has, ignoring nobody
- Cross-references each one against real usage logs to sort alive from dead
- Validates scope against the API calls the client actually makes, so you can see who is over-permissioned
- Recommends rotation for anything holding more power than its behavior justifies
Running it once is satisfying. Running it once solves nothing long-term, because the graveyard starts refilling the next sprint. So the real fix is that it does not run once.
Keeping it visible, automatically
The tool lives in the CI/CD pipeline now:
- Weekly automated scans — the audit is not a heroic once-a-year event, it is a cron job
- Slack alerts the moment any client sits idle for 30 days, so a zombie gets flagged while people still remember the project
- Scope validation on every run, so over-permissioned clients surface before they age into risk
The credential graveyard stopped growing the moment someone started watching it. That is the whole trick. Not a smarter algorithm — a standing watch.
Go check your own numbers
Every enterprise has this. Most teams pretend they don't, because looking means admitting how many keys to the kingdom are lying in the street. The invisible problem stays invisible until someone makes it visible — and then keeps it that way on a schedule.
So here is the uncomfortable homework: how many API credentials in your infrastructure right now have zero activity in the last 90 days? How many of those can write to production? Go open the panel and scroll to the bottom.
The number will bother you. It should.