API keys vs tokens – what’s the difference?
Auth is hard enough as it is. Be sure you understand the difference between your two primary modes of authentication: API keys and tokens.
They say the two hardest problems in computer science are cache invalidation and naming things. Honestly, that’s not wrong. Those are super hard.
What makes naming things difficult is being clear yet concise. There should be no doubt about the meaning of a variable, term, function, or class. If you think a term could mean one of two things, it’s not named correctly.
Such is the case with API keys and tokens. I was having a discussion the other day where the two words were being thrown around interchangeably. About two minutes in, I had to stop the conversation and say “you know those are different, right?”
Apparently they did not know. As it turns out, many people can’t tell me the difference between an API key and a token. So let’s set the record straight.
Definition
We can differentiate between an API key and a token with the following definitions:
- API key – A value provided by code when calling an API to identify and authorize the caller. It is intended to be used programmatically and is often a long string of letters and numbers.
- Token – A piece of data that represents a user session or specific privileges. Used by individual users for a limited period of time.
Generation
The method of creation is typically different between the two as well.
- API key – Created one time, often through a user interface, and remains static until rotated. These can optionally be configured to expire after a certain amount of time.
- Token – Generated dynamically on successful authentication or login event. Often has a short expiration time but is able to be refreshed for longer periods.
Scope
It wouldn’t be a discussion about auth without talking about permission scope. By permission scope, I mean the authorization portion or what functionality can be performed when using the provided auth method.
- API key – Fixed, unchanging set of permissions to app capabilities. Whoever has the key can access the allowed resources.
- Token – Limited to specific data or capabilities an individual has access to. This can be affected by roles or other business-level requirements. Tends to be more focused on data restriction.
Security
How secure is each method? If the key or token is compromised or acquired by a malicious user, how bad is the potential damage?
- API key – Since these are generally long-lived and do not limit access to data, these can be devastating if compromised. They require the key to be revoked as the only means of resolution. Applications often need to have good observability to identify compromised keys and finding the malicious user.
- Token – Designed with security in mind. Generally short-lived and easily revoked. A compromised token will only have scope of the data the user has access to and will expire automatically.
Use cases
So, when would you use one over the other? It looks like they have a good balance of pros and cons.
- API key – Use for server-to-server communications, accessing public data like a weather API, integrating with 3rd party systems.
- Token – Use for user authentication, fine-grained access control (FGAC), granting temporary access to resources, browser access, and managing user sessions.
Examples
Now that we understand the difference between the two, let’s look at two practical examples using the Momento JavaScript SDK.
API Keys
I did say that API keys are generally issued via a user interface. With that in mind, I don’t have a code sample to share. However, below is how you’d get an API key via the Momento Console as a user.
You’d select the permissions you want, set the optional expiration date, and generate. You can then immediately use the API key in your workflows.
Tokens
Contrast that with a user-based disposable token that is issued on successful login. We can take a role-based example for a user who gets read-only access to the calendar-events cache, but publish and subscribe access to a topic for collaboration.
// called on successful login
exports.handler = async (event) => {
const user = await loadUserMetadata(event.userId);
let token;
switch(user.role){
case 'data-entry':
token = await getDataEntryToken(user.tenantId);
break;
case 'admin':
token = await getAdminToken(user.tenantId);
break;
default:
throw new Error('Role not supported');
}
return token;
};
const getDataEntryToken = async (tenantId) => {
const scope = {
permissions: [
{
role: 'readonly',
cache: 'calendar-events',
item: {
keyPrefix: tenantId
}
},
{
role: 'publishsubscribe',
cache: 'collaboration',
topic: `${tenantId}-events`
}
]
};
const response = await authClient.generateDisposableToken(scope, ExpiresIn.minutes(15));
return {
token: response.authToken,
expiresAt: response.expiresAt.epoch()
};
};
You can see here, we create a token valid for 15 minutes scoped to readonly permissions for capabilities and allowed to access only cache items that start with the tenantId the user belongs to. So we’ve restricted both the functionality and the data based on attributes of the user.
Key Takeaways
API keys and tokens have their pros and cons. One is not better than the other. As with all things in computer science, it depends on your use case. When deciding which auth mechanism you’re going to implement, consider how your users will be interacting with your application.
Is it user based sessions on the web? Go with tokens. Maybe you’re expecting programmatic access only with no need to scope what data is available. Go with an API key. Feel free to save our reference table up top for quick reference.
Regardless of the path you take, please remember to keep your data secure. Nobody wants a data breach to take them out of business. Be safe.
If you’re interested in how you can get started with Momento and need help determining your level of access control, you’re always welcome to hop onto our Discord and ask the team directly. If you’re more of a reader, the developer docs are available 24/7.
Happy coding!