Your API Keys Outlive Your Employees
I used to be the solutions architect for a product provisioning and fulfillment provider. We sold access to our APIs. Companies paid us so their systems could automatically purchase products, activate services, and manage inventory through our platform.
Every client got a set of credentials: a client ID, a client secret, and a static API key. The client ID and secret got them through the front door, our API gateway. The API key told our system who they were and what account to bill.
It was a standard setup. The kind you’ll find at thousands of companies right now.
In that role, I saw firsthand how credentials accumulated across teams: in onboarding emails, test scripts, shared configuration files, support tickets, internal wikis, Postman collections. I saw how easily they could be copied and forwarded without anyone thinking twice. And I saw how difficult it was to coordinate disruption-free rotations across dozens of active integrations, which meant rotations were something that simply never happened proactively.
When someone left the company, their access to internal systems was revoked. But the client credentials they’d encountered along the way? Those lived on, in chat logs, in local files, in email threads. Nobody tracked who had seen which key. Nobody could.
The Quiet Risk
Here’s what made this unsettling: there was nothing in the architecture that would distinguish a legitimate request from one created by a bad actor. The API gateway would see valid credentials and let the traffic through. The backend would see a valid API key and process the request normally. It would look like routine client activity.
There would be no alert. No anomaly detection to flag it. The requests would be indistinguishable from real ones, because as far as the system is concerned, they are real ones. Valid credentials, properly formatted, hitting the right endpoints.
A client in that situation might eventually notice charges for transactions they didn’t initiate. Or they might not. Routine API activity doesn’t exactly generate a lot of scrutiny.
This Is Every Company
This isn’t a story about one company with unusually bad practices. This is the default state of API security at most organizations.
Think about everyone who touches API credentials in a typical company:
- The developer who set up the integration
- The contractor who helped with the migration
- The QA engineer who tested against production
- The solutions architect who onboarded the client
- The support engineer who debugged a connectivity issue
Every one of those people has likely seen, copied, or stored credentials at some point. When they move on, those credentials don’t follow them out the door in any trackable way. They just continue to exist, scattered across systems, valid indefinitely.
And that’s just one side of the relationship. Every credential exists on both sides, the provider’s team and the client’s team. The client has their own developers, their own contractors, their own QA engineers, their own support staff, all of whom have touched those same credentials during integration, testing, and troubleshooting. A provider with 50 clients doesn’t have 50 sets of credentials to worry about. They have 50 sets of credentials scattered across 50 other organizations, each with their own turnover, their own offboarding gaps, and their own people who have quietly accumulated access.
If each of those 50 client organizations has even 5 people who’ve touched the credentials, that’s 250 people outside your company who can make authenticated requests on behalf of your clients. You don’t know who they are. You don’t know when they leave. You have no way to find out. All any of them need are your public API docs and they have access to the entire platform.
And you have no control over how those organizations handle your credentials. Some will hardcode them in configuration files checked into version control. Some will paste them into shared wikis or Slack channels. Some will commit them to public GitHub repositories, and it happens constantly. Some will store them in plaintext on developer laptops with no disk encryption. Some will embed API keys and even client ID/secret pairs directly in client-side JavaScript, making OAuth token requests straight from the browser, shipping your secrets to every user who opens developer tools. You’re trusting that every developer at every client organization follows security best practices with your credentials, and you have absolutely no way to verify that they do.
The Assumptions That Don’t Hold
The problem isn’t that people are untrustworthy. The problem is that static credentials assume a world where:
- People never leave companies
- Credentials never get copied outside their intended system
- Every key is tracked, inventoried, and rotated on a strict schedule
- Every developer at every partner organization follows security best practices without exception
- Someone notices when a credential is used by the wrong person
None of those things are true. Not at small companies, not at large ones.
Most organizations don’t even know how many active API keys they have, let alone who has access to each one. Rotation policies exist on paper but rarely in practice, because rotating a key means coordinating with every system that uses it, testing that nothing breaks, and doing it all without downtime. That’s a project, not a policy. So the keys sit there, valid forever, waiting.
What Should Be True Instead
In a system designed around this reality, where people leave, credentials scatter, and rotation is hard, the architecture itself should make old credentials worthless.
Keys that expire on their own. Instead of issuing a credential that’s valid until someone remembers to revoke it, every key should have a short lifespan. Seconds, not months. If a key ends up somewhere it shouldn’t be, it’s already expired before anyone could use it.
Credentials that can’t be replayed. Every request should carry a signature that proves it was made right now, by this specific service, for this specific purpose. A credential copied from an old email six months ago shouldn’t be able to produce a valid signature today.
Every request proves when it was made. Credentials aren’t just checked at the door. Every request should carry a cryptographic timestamp that proves it was made right now, not replayed from last week. Stale credentials can’t produce fresh signatures.
No single point of compromise. If one credential leaks, it shouldn’t unlock everything. Every request should prove who is making it and define which specific service it’s targeting. Authorization should be scoped to specific service-to-service relationships, so a compromised key for one integration can’t be used to access another.
Why I Built Harden
That experience, watching credentials accumulate in places they shouldn’t be, knowing that rotation was always deferred because it was too disruptive, and understanding that nothing in the architecture would catch misuse, is why I started Harden.
The existing solutions all had the same fundamental flaw: they still relied on static secrets somewhere in the chain. They just moved the problem around. OAuth tokens expire, but the client secret used to obtain them doesn’t. API gateways can enforce rate limits, but they can’t tell the difference between a legitimate request and one made with credentials that should have been retired long ago.
Harden takes a different approach. Signing seeds rotate automatically, as frequently as every 30 seconds, and the keys they derive from expire within minutes to hours. Each request includes a time-based one-time password that’s valid for just 10 seconds. The SDK handles all of this silently, deriving fresh signing material locally without additional network calls. Every request is cryptographically signed with proof of when it was made and who made it. And the entire system operates out-of-path, meaning it never touches your actual API traffic.
And here’s what doesn’t change: your API documentation. Harden doesn’t require you to redesign your endpoints or rewrite your integration guides. Your docs stay exactly the same. But a third party armed with stolen keys, client secrets, and your full API documentation still can’t get anywhere, because every request without a valid, fresh cryptographic signature is rejected before it ever reaches your application.
If a company is using Harden, it doesn’t matter who saw a credential last quarter, last year, or an hour ago. The signing material from that moment is long dead. There’s nothing to steal, nothing to reuse, and nothing to worry about when someone leaves.
That’s not a feature. That’s how security should have always worked.
Want to see this in action?
Book a demo and we'll walk you through how HardenAPI and HardenMCP work in your environment.
Request a Demo