#4754: Why Code Authentication Needs So Many Keys

API keys, OAuth tokens, service accounts — why can't one authenticator rule them all? The answer is trust topology.

Featuring
Listen
0:00
0:00
Episode Details
Episode ID
MWP-4933
Published
Duration
34:49
Audio
Direct link
Pipeline
V5
TTS Engine
chatterbox-regular
Script Writing Agent
deepseek-v4-pro

AI-Generated Content: This podcast is created using AI personas. Please verify any important information independently.

The authentication world has two hemispheres: proving a human is a human, and proving a piece of software is allowed to act. These hemispheres can't merge because humans and software have completely different threat profiles. Humans can do multi-factor auth and tap "yes" on a phone; software needs to authenticate while running unattended in a batch job at 3 AM. Humans can quit and walk out the door, requiring credentials revocable per person. Software gets compromised, requiring credentials revocable per workload. Those revocation paths demand different credential types.

Three concrete examples illustrate the non-human side. An S3 script uses an access key — effectively a password with better branding, sent over HTTPS signed with HMAC so the secret never travels the wire. A GitHub app uses a private key to sign a JWT, exchanges it for an installation access token, and uses that token to call the API — binding the credential to a specific installation on a specific repository. A Google Cloud function uses a service account, which in the modern pattern authenticates through workload identity federation where the virtual machine itself vouches for the software, eliminating the long-lived credential entirely.

OAuth sits in the middle, shape-shifting between representing a human, representing software, and representing software acting on behalf of a human — the third case nothing else handles well. The refresh token / access token split exists because access tokens are exposed constantly and should be disposable, while refresh tokens are stored securely and used infrequently. The industry is converging on short-lived tokens and platform-attested identity where possible, but long-lived keys persist because they're embedded in tooling, documentation, and habits — the historical sediment from the pre-OAuth era when giving your Gmail password to a third party was the standard protocol.

Downloads

Episode Audio

Download the full episode as an MP3 file

Download MP3
Transcript (TXT)

Plain text transcript file

Transcript (PDF)

Formatted PDF with styling

#4754: Why Code Authentication Needs So Many Keys

Corn
Daniel's question this week is deceptively simple. He wants to know why, when a piece of code needs to prove who it is, we've ended up with a drawer full of different keys. API keys, OAuth tokens, service accounts, refresh tokens, access tokens. Why isn't there just one universal authenticator? He's asking us to build a mental model, not just list definitions. What fundamentally different problems are these things solving? Which ones authenticate a human, which authenticate software, and which can do both? And how much of this complexity is inherent to security, versus just... historical sediment?
Herman
The short answer is yes. To all of it. It's inherent and it's sediment. But the thing that makes the question worth an hour rather than a sentence is that the different mechanisms aren't just solving different technical problems. They're solving different trust problems. And the trust problem a web browser has with Google is not the same trust problem a server in a data center has with AWS at three in the morning.
Corn
That's the frame, then. Trust topology.
Herman
Trust topology. I'm stealing that. So let's start with the cleanest split. The authentication world really has two hemispheres. On one side, you're proving a human is a human. On the other, you're proving a piece of software is allowed to act. And the reason those hemispheres don't merge is that humans and software have completely different threat profiles. A human can do multi-factor auth. A human can look at a phone and tap yes. Software can't do that. Software needs to authenticate while running unattended, in the middle of a batch job, at a time when nobody is awake to approve anything.
Corn
And a human can quit and walk out the door.
Herman
Right. That's the other half. With a human, the credential needs to be revocable per person. With software, the credential needs to be revocable per workload. Those revocation paths are different. If someone leaves the company, you don't want to rotate every API key they ever touched. You want to disable their account and have everything cascade. If a service gets compromised, you don't want to disable a human's account. You want to cut off that specific service's access. So you need different credential types just to make revocation work correctly.
Corn
So the first fork in the road is: is the thing at the keyboard made of meat or not.
Herman
That's... yeah. That's the first fork. And let's walk through the meat side because it's actually the simpler one to explain. When you log into Google Workspace, you're doing what's called interactive authentication. You type a password, you get a push notification, maybe a hardware key. Behind the scenes, you're issued a session token. That token lives in your browser and it's short-lived. When it expires, you re-authenticate. This is the pattern everyone knows. The credential that represents you is ultimately your password plus your second factor. The token is just a temporary stand-in.
Corn
And the non-meat side?
Herman
That's where it gets interesting. Let's take three concrete examples. First, a script that needs to list the contents of an S3 bucket every hour. Second, a GitHub app that needs to read issues from a repository. Third, a Google Cloud function that needs to write to BigQuery. None of these have a human anywhere near them when they run. They all need to authenticate. And they all use different mechanisms. The S3 script uses an access key, which is really a long-term credential — an access key ID and a secret access key — stored as a file or an environment variable.
Corn
Which is just a password with better branding.
Herman
It is exactly a password with better branding. And that's not a criticism. It's a password designed for a very specific context. The access key is meant to be used with the AWS CLI or an SDK. It's sent over HTTPS with every request, signed with HMAC so the secret never actually travels over the wire. But at rest, it's a string in a file. If someone gets that file, they are you, for whatever permissions that key has. That's why AWS tells you never to put access keys in code repositories. And people do it constantly anyway.
Corn
The GitHub secret scanning that catches those must be doing a brisk business.
Herman
Oh, it's a firehose. Thousands of keys a day. But the access key pattern is what you reach for when software is acting on its own behalf. The key represents an IAM user — which can be a human or a machine identity. And here's where the line blurs. An IAM user can have a password for console login and an access key for programmatic use. Same identity, two different authentication mechanisms for two different channels. The console gets interactive auth. The API gets a static credential.
Corn
So the identity is the thing. The credential is just how you prove you hold the identity, and the mechanism varies by entry point.
Herman
And that's a pattern we'll see everywhere. Let's move to the GitHub example. You've got a GitHub app that needs to read issues. It doesn't use an API key. It uses a private key to sign a JWT, exchanges that JWT for an installation access token, and uses the token to call the API. That's three steps. Why? Because GitHub wants to bind the credential to a specific installation of the app on a specific repository. The app's private key proves the app's identity. The installation token proves that the owner of the repository actually installed the app and granted it permission. Those are two different trust assertions, and they're handled by two different artifacts.
Corn
The private key says "I am the app called IssueBot." The installation token says "and the owner of repo X invited me in."
Herman
That's it. And the installation token expires after an hour. So even if it leaks, the blast radius is small. This is fundamentally different from an AWS access key, which lasts until you rotate it, which in practice means until someone notices it's in a public repo. The GitHub model is more complex to set up, but it's designed for a world where the app is distributed to many organizations. Each installation gets its own scoped, short-lived token.
Corn
So that's two patterns. Long-lived static credential for a single account, versus short-lived scoped token derived from a private key and an authorization grant. What's Google Cloud doing?
Herman
Google Cloud has its own taxonomy and it's worth understanding because it maps cleanly to the problems. They have three main categories. API keys, which are for identifying a project — not a user or a service — when calling an API. They're the weakest form. They just say "this request is associated with project X." They don't prove who made the request. They're used for things like accessing public data where you still need a billing identity attached.
Corn
So an API key is basically a name tag, not a guard at the door.
Herman
A name tag that also routes the bill. Then you've got service accounts. A service account is an identity for software. It's an email address that doesn't represent a person. It can be granted roles and permissions just like a human user. And it authenticates using a service account key — a JSON file with a private key — or, in the modern pattern, using workload identity federation, where it doesn't need a key at all because it's running on a Google Cloud service that can prove its own identity.
Corn
That's the part where the virtual machine itself vouches for the software running on it.
Herman
Right. The metadata server on a Compute Engine instance hands out short-lived tokens. The software doesn't hold a key. It asks the platform for a token, and the platform says "I know who you are because I launched you." This is the direction everything is moving. Eliminate the long-lived credential entirely. But it only works when the workload is running on a platform that can provide that attestation. If your script is running on a Raspberry Pi in a closet, you're back to keys.
Corn
And then OAuth sits somewhere in the middle of all this.
Herman
OAuth is the shape-shifter. It can represent a human, it can represent software, and it can represent software acting on behalf of a human. That third case is the one that nothing else handles well. When you install a third-party app that wants access to your Google Drive, you get the OAuth consent screen. You click allow. What happens technically is that the app receives an access token and a refresh token. The access token is short-lived — typically an hour. The refresh token is long-lived and can be used to get new access tokens without bothering you again.
Corn
So the refresh token is the persistent secret, and the access token is the disposable one.
Herman
Yes. And that split exists for a reason. The access token is sent with every API call. It's exposed constantly. If it leaks, it's only valid for an hour. The refresh token is stored securely and used infrequently. It's the crown jewel. If a refresh token leaks, the attacker can keep generating access tokens indefinitely.
Corn
That's a cleaner design than one long-lived token doing both jobs. Which is what the AWS access key effectively does.
Herman
And AWS knows this. They've been pushing IAM roles and temporary credentials through STS for years. The access key pattern is the legacy. The modern AWS pattern is: assume a role, get temporary credentials that expire. Those credentials include an access key ID, a secret access key, and a session token. Three parts instead of two. The session token is the new piece. It's what makes the credential temporary. When you use an EC2 instance profile, the instance is constantly getting these temporary credentials rotated in. The software doesn't even know it's happening.
Corn
So we're converging on a pattern. Short-lived tokens, platform-attested identity where possible, long-lived keys only as a last resort. But the old patterns don't disappear because they're embedded in tooling, documentation, and habits.
Herman
And that's the historical sediment Daniel was asking about. Let me trace the actual history. Before OAuth, if you wanted a third-party service to access your email, you gave them your password. That was the protocol. You typed your Gmail password into some social network's "find your friends" feature. It was catastrophic. OAuth was designed specifically to solve that. The third party never sees your password. You authenticate to Google directly, and Google gives the third party a token scoped to exactly what you approved. The token can be revoked without changing your password.
Corn
So OAuth was born to solve the password-sharing anti-pattern.
Herman
OAuth 1 came out in 2007, OAuth 2 in 2012. And OAuth 2 is not a single protocol. It's a framework with multiple grant types. The authorization code grant is for web apps acting on behalf of users. The client credentials grant is for server-to-server communication with no user involved. The device grant is for TVs and IoT things that don't have a browser. Same framework, completely different trust topologies.
Corn
That's the part that confuses people. They see OAuth and think it's one thing. But the client credentials grant is essentially a service account pattern. Two pieces of software talking to each other, no human in the loop. The authorization code grant is the "sign in with Google" flow. Same name, different problems.
Herman
And Microsoft's ecosystem makes this even more explicit. They have the Microsoft identity platform, which is the unified OAuth 2 and OpenID Connect endpoint behind Azure AD, now Entra ID. When you build an app that talks to Microsoft 365 or Azure, you register it in the portal and you pick which grant type you need. Delegated permissions mean the app acts on behalf of a signed-in user. Application permissions mean the app acts on its own. Same app registration, two completely different authentication flows.
Corn
Delegated versus application. That's the split again. Human in the loop or not.
Herman
And the permissions model changes completely. With delegated permissions, the effective permissions are the intersection of what the app is allowed to do and what the user is allowed to do. The app might request the ability to read all files, but if the user only has access to three files, the app only gets three files. With application permissions, there's no user to constrain it. The app gets exactly what it's granted, which is why application permissions require admin consent. It's a much more dangerous grant.
Corn
So the credential type is downstream of the authorization model, which is downstream of the trust topology. It's not just that we ended up with different keys by accident. The keys encode different answers to the question "who is asking, and who is vouching for them?"
Herman
Let me give you a concrete example that ties all of this together. Imagine a company using Google Workspace and Google Cloud. They've got employees using Gmail and Drive interactively. They've got a Cloud Function that processes uploaded files. They've got a third-party backup service that needs access to Drive. That's three different authentication patterns, all in one organization. The employees authenticate with passwords and MFA, get session tokens. The Cloud Function runs as a service account, and because it's on Google Cloud, it uses the metadata server to get tokens — no keys stored anywhere. The backup service uses OAuth with a refresh token, because it's running outside Google's infrastructure and needs persistent access.
Corn
And if you tried to force all three into one mechanism, what breaks?
Herman
If you use passwords for everything, the Cloud Function has a password stored in an environment variable that never rotates. The backup service has a password that some employee typed in and then that employee left the company, and now nobody knows which password it's using or whether changing it will break the backups. If you use service account keys for everything, your employees are carrying around JSON key files and nobody can do MFA. If you use OAuth for everything, your Cloud Function has to show a consent screen to nobody.
Corn
The consent screen to nobody is a great image.
Herman
It's absurd but it points at something real. Each mechanism assumes a particular interaction model. OAuth's authorization code grant assumes a browser and a human who can click allow. If you try to use it for server-to-server, you're doing the client credentials grant, which is OAuth but it's not the OAuth that most people picture. And at that point it's functionally equivalent to a service account with a key.
Corn
So let's do the taxonomy Daniel asked for. Which mechanisms authenticate a human, which authenticate software, and which can do both?
Herman
Passwords plus MFA: human only. No serious system lets software use a password for programmatic access anymore. API keys: software only, but they identify a project or an application, not a specific workload. They're the least expressive credential. Service account keys: software only, and they identify a specific machine identity with its own permissions. Access tokens: can represent either. An OAuth access token might represent a user, or it might represent an application in the client credentials flow. The token itself doesn't tell you. You have to inspect it. Refresh tokens: in practice, they represent a user's delegated authorization. They're the long-lived secret that says "this user said this app can act on their behalf."
Corn
And the session token from interactive login?
Herman
Human. It's the browser cookie or the mobile app token that says you proved who you are an hour ago and you're still you. It's tied to a specific device and session.
Corn
What about GitHub's personal access tokens? Those feel like they blur the line.
Herman
They absolutely do. A GitHub personal access token is a credential that a human generates and then hands to software. It's a human delegating to a tool. The token authenticates as the human, not as a separate machine identity. If you use a personal access token to push code from your laptop, the commit shows up as you. If you use a GitHub app installation token, the commit shows up as the app. That distinction matters for auditing. Who pushed this? Was it Corn at his desk, or was it the CI pipeline?
Corn
And if Corn leaves the company and his account is disabled, the personal access token stops working. If the CI pipeline used a personal access token, the pipeline breaks. If it used a GitHub app, it keeps working because the app isn't tied to Corn's employment.
Herman
That's the operational reason organizations should enforce app-based authentication for automation. But it's also why personal access tokens are so common. They're easy. You click a button, you get a token, you paste it somewhere. It works. The friction of setting up a GitHub app with private key management and installation tokens is real. And that friction is part of why we have so many patterns. The easy thing and the correct thing are different, and both paths stay open.
Corn
The complexity isn't just technical. It's that the industry keeps the legacy path available because removing it would break everything, and the legacy path is often the path of least resistance for the person writing the script at two in the morning.
Herman
The cloud providers know this. AWS still supports long-lived access keys because there are millions of workloads using them. They've added the ability to enforce policies that block creating new ones, but they can't turn them off. Google Cloud has the same tension. The documentation pushes workload identity federation hard, but the quickstart for every service still shows you how to download a service account key, because that's what works in five minutes on any machine.
Corn
Let's come back to Daniel's question about whether this complexity is inherent or historical. I think the answer is both, but the proportions vary by mechanism. The split between human and machine auth is inherent. The existence of refresh tokens versus access tokens is inherent — it's a direct response to the threat model of tokens that travel over the wire constantly. But the fact that we have API keys, service account keys, and personal access tokens all coexisting? That's history.
Herman
The API key is the oldest pattern. It predates OAuth, predates cloud. It's the "here's a string, include it in your request" model. It's simple to implement and simple to use, and it solves a real problem — identifying and rate-limiting callers. What it doesn't solve is fine-grained authorization. An API key gives you access to whatever the key is allowed to do, with no concept of acting on behalf of a user, no scoping beyond what the service hard-codes. It's a blunt instrument.
Corn
Yet Google Cloud still has API keys as a distinct thing from service accounts. They serve different purposes. The API key identifies a project for billing and quota. The service account identifies a workload for authorization.
Herman
That distinction is genuinely useful. If you're calling the Maps API from a mobile app, you use an API key. It's public — it's going to be embedded in the app binary, anyone can extract it. You restrict it by referrer or IP and move on. You would never embed a service account key in a mobile app. That would be catastrophic. So the API key persists because it's the credential you use when you know the credential will be exposed. It's the "this is not a secret" secret.
Corn
The API key's security model assumes compromise. The mitigation is restrictions and quotas, not secrecy. The service account key's security model assumes the key is protected. If it leaks, you've got a problem.
Herman
Then there's the historical artifact that is the AWS access key. The access key ID and secret access key pattern was designed in 2006 when AWS launched. It predates OAuth 2. It predates the modern understanding of token hygiene. It's a signed request pattern — the secret is used to generate a signature, it's not sent over the wire — which is better than a bearer token. But it's still a long-lived credential that sits in a file. AWS has layered temporary credentials on top of it through STS and IAM roles, but the underlying credential format is the same. The session token just gets added as a third field.
Corn
The format persists even as the security model evolves around it. That's the sediment.
Herman
Here's another layer of sediment. SAML. The Security Assertion Markup Language. It's XML-based, it's from the early 2000s, and it's still how most enterprises federate identity between their on-premises Active Directory and cloud services. When you sign into Salesforce or Workday or AWS with your corporate credentials, there's a good chance SAML is involved behind the scenes. It's not OAuth. It's not OpenID Connect. It's its own thing, with its own token format and its own flow. And it persists because it's embedded in thousands of enterprise identity providers.
Corn
It solves the same problem OAuth solves, more or less.
Herman
It solves a narrower version of the same problem. SAML is for federation. Company A vouches for user B to service C. That's it. OAuth is for delegation. User B authorizes app C to access resource D. Related but different. And OpenID Connect, which sits on top of OAuth 2, handles authentication — proving who you are — which OAuth 2 explicitly does not do by itself. OAuth 2 is about authorization, not authentication. That's the most common misconception in this entire space.
Corn
Wait. Say that again. OAuth 2 doesn't authenticate?
Herman
OAuth 2, by itself, does not tell the client who the user is. It gives the client an access token that says "the bearer of this token can access these resources." The token doesn't contain the user's identity. OpenID Connect adds an ID token — a JWT that contains claims about the user, like their email and name. That's what "sign in with Google" actually uses. It's OAuth 2 plus OpenID Connect. But people say "OAuth" and mean the whole stack.
Corn
The complexity is partly that the protocols have layered on top of each other. OAuth 2 solved delegation. OpenID Connect layered authentication on top. And now the combined thing is what everyone thinks of as OAuth.
Herman
Underneath all of it, the actual cryptographic primitives are often the same. JWTs signed with RSA or ECDSA. HMAC signatures. TLS for transport. The differences are in the flows, the token lifetimes, the revocation semantics, and the trust relationships. That's why understanding the trust topology is more important than memorizing the protocol details. If you know who is vouching for whom, the mechanism usually makes sense.
Corn
Let's test that. Take a GitHub Actions workflow that deploys to AWS. What's the trust topology?
Herman
The workflow runs on GitHub's infrastructure. It needs to prove to AWS that it's authorized to deploy. The modern way to do this is OpenID Connect federation. GitHub Actions gets an OIDC token from GitHub's token service. The token includes claims about the repository and the workflow. AWS trusts GitHub's OIDC provider, validates the token, and maps the claims to an IAM role. The workflow assumes the role and gets temporary credentials. No long-term keys stored anywhere. The trust chain is: AWS trusts GitHub to accurately identify its own workflows, and GitHub vouches for the workflow's identity.
Corn
And the old way?
Herman
Store an AWS access key as a GitHub secret. The workflow uses the key directly. The trust chain is: whoever knows the key is allowed. If the key leaks, the trust chain is broken. The OIDC method is better because it eliminates the long-lived secret and ties the credential to the specific workflow run. The token expires when the job ends.
Corn
The direction of travel is clear. Eliminate static credentials. Bind everything to an attested identity with a short-lived token. But the static credentials hang around because not everything supports OIDC, not everything runs on a platform that can attest, and not everyone has done the work to migrate.
Herman
That's the answer to Daniel's question about whether the complexity is inherent. Some of it is. The difference between authenticating a human with a browser and authenticating a cron job is fundamental. The difference between a token that travels over the wire and a secret that stays on disk is fundamental. But the proliferation of formats — SAML assertions, OAuth tokens, JWTs, AWS access keys, GitHub personal access tokens, Google service account keys — that's history. Each one was designed for its moment, and they all stuck around.
Corn
The credential drawer is full because nobody ever throws out a credential type.
Herman
Because each one encodes assumptions that were true when it was designed. SAML assumes XML and SOAP and browser redirects. OAuth 1 assumed HMAC signing on every request. OAuth 2 dropped the signing requirement and moved to bearer tokens over TLS. Each generation learned from the previous one, but the previous one didn't disappear.
Corn
If you were designing from scratch today, with no legacy, what would you keep?
Herman
Short-lived tokens bound to attested identities. Platform-provided identity where the platform can vouch for the workload. OAuth-style delegated authorization for third-party access, with refresh tokens for persistence. And one thing we haven't mentioned: fine-grained access control that travels with the token. A JWT that embeds the specific permissions, so the resource server can make an authorization decision without calling back to the identity provider. That's the direction. The token is self-contained and verifiable. You validate the signature, check the claims, and you're done.
Corn
You'd throw out long-lived static keys entirely.
Herman
In the greenfield design, yes. But the greenfield design doesn't have to deal with the reality that half the world's automation runs on cron jobs on under-maintained VMs in corners of data centers that nobody has documented. Those workloads need a credential. And if the platform can't provide one, someone's going to put a key in a file. The challenge isn't designing the perfect system. It's migrating the real one.
Corn
Which brings us to the operational question. If you're the person responsible for this at a company, where do you start?
Herman
You start by classifying every workload by its trust topology. Is there a human in the loop? Is the workload running on a platform that can attest to its identity? Is it accessing resources in the same cloud or across trust boundaries? The answers tell you which mechanism fits. Human in the loop and third-party access: OAuth with refresh tokens. Workload on GCP talking to GCP: workload identity federation, no keys. Workload on-premises talking to cloud: you're probably stuck with a key, but you can vault it, rotate it automatically, and alert on anomalous usage. Cross-cloud: OIDC federation where both sides support it, keys where they don't.
Corn
The personal access token pattern, where a human generates a token and hands it to a script, is the one you want to eliminate first.
Herman
Because it binds the automation to a human account. It's the pattern most likely to break when someone leaves, and it's the pattern that makes auditing impossible. Was that production change made by the CI system or by someone using the CI system's token from their laptop? You can't tell.
Corn
Alright. I think we've got the mental model Daniel was asking for.

Hilbert: The real reason there are so many credential types is one meeting at Microsoft in 2004.
Corn
Go on.

Hilbert: Identity and access management team. They had Passport, which was supposed to be the universal login for the internet. It was already losing. The team split. Half went off to work on what became Active Directory Federation Services. The other half got absorbed into the Windows CardSpace project. CardSpace was a whole thing about users selecting identity cards in a wallet interface. It shipped in Vista. Nobody used it. But the architectural decisions from that split — SAML tokens for the federation camp, a card-based metaphor for the other camp — shaped everything Microsoft shipped for the next decade. Azure AD, now Entra ID, still carries the SAML claim format internally. That's why a Microsoft token looks the way it looks. Not because anyone sat down and designed the optimal credential format. Because two teams had a fight and both won.
Herman
CardSpace. I haven't thought about CardSpace in... fifteen years.

Hilbert: Nobody has. That's the point. The thing nobody used is still in the plumbing.
Corn
The universal authentication mechanism was the plan. It just didn't survive contact with organizational politics.

Hilbert: The universal mechanism is always the plan. Passport was the plan. OpenID was the plan. OAuth was supposed to simplify things and now there are seven grant types and three token formats. The industry doesn't converge. It layers. Everyone agrees the current thing is too complicated, builds a new thing that simplifies the old thing, and now there are two things.
Herman
That's... I mean, it's reductive, but it's not wrong. The OAuth 2 specification is literally longer than the OAuth 1 specification. And it was supposed to be simpler.

Hilbert: Simpler to implement. Not simpler to understand. The complexity moved from the cryptographic signing to the flow logic. And then OpenID Connect added another layer on top. And then everyone added their own extensions. And now you need a diagram to figure out which flow you're supposed to use.
Corn
You're making the case that the complexity is mostly historical, not inherent.

Hilbert: I'm making the case that the complexity is organizational. The technical problems are real. But the reason there are seventeen ways to solve them is that seventeen teams at seven companies built solutions at different times, and none of them were wrong enough to die. They just accumulated.
Herman
The seventeen teams point actually maps to something concrete. AWS IAM, Google Cloud IAM, and Azure IAM all evolved separately. They solve similar problems with similar primitives, but the terminology and the default patterns are different enough that someone who's expert in one is lost in another. That's not inherent. That's three companies building in parallel.

Hilbert: Then the open-source world builds its own thing. And the enterprise middleware vendors build another thing. And then someone writes a library that abstracts over all of them, and the library becomes a de facto standard, and now the library's design decisions are part of the landscape too.
Corn
The mental model Daniel's looking for has to include the fact that the landscape wasn't designed. It grew. The trust topologies are real and the different mechanisms map to them, but the mapping is one-to-many because of parallel evolution.

Hilbert: The other thing nobody talks about is that credentials have different support costs. A long-lived API key costs almost nothing to operate. You hash it in a database, you check it on each request. A short-lived token infrastructure requires a token endpoint, a revocation endpoint, clock synchronization, key rotation for the signing keys. That's operational complexity that someone has to pay for. The reason API keys never die is that they're cheap to run. Not cheap to secure. Cheap to run.
Herman
The total cost of a credential type includes the infrastructure to issue it, validate it, rotate it, and revoke it. And the people who build the infrastructure are not the same people who pay the cost of a breach. So the cheap-to-run credential persists even when it's expensive to secure.

Hilbert: I worked on a billing system at a telecom in the late nineties. Every server had a shared secret in a config file. Rotating it meant touching forty machines. We rotated it once in three years. The secret was the same string for 36 months. That's not a design. That's what happens when the operational cost of the correct thing is higher than anyone's budget for correctness.
Corn
That system is probably still running.

Hilbert: Probably.
Corn
The answer to Daniel's question is: the different credential types exist because they solve different trust topologies, because the industry layers rather than replaces, and because the cheap insecure thing is always cheaper to operate than the secure thing. The mental model is a map of trust relationships overlaid with a history of organizational decisions and a cost curve that favors inertia.
Herman
That's... actually a concise summary.
Corn
I have my moments.
Herman
The one thing I'd add is that the direction of travel is real. OIDC federation for cross-cloud workloads. Workload identity federation for same-cloud. Short-lived tokens everywhere. The patterns are converging even if the formats aren't. If you're building something new today, you can mostly avoid the historical sediment. You just can't avoid it if you're maintaining something old.
Corn
This has been My Weird Prompts. Thanks to our producer, Hilbert Flumingtop.
Herman
Find every episode at my weird prompts dot com, or email the show at show at my weird prompts dot com. We'll be back soon.

This episode was generated with AI assistance. Hosts Herman and Corn are AI personalities.