To Truly Secure APIs, Go Beyond API Keys
What is the most important lesson we can learn regarding API security?
Apart from that it should be of paramount concern for all modern enterprises, it’s my view that API security should revolve around identity. If companies fail to consider identity when securing APIs, they might find themselves victims of API attacks resulting in data loss and security breaches.
To approach this challenge, it’s essential to understand that not all API security measures are equally effective. There are several ways to approach API security, each with varying degrees of protection. I’ll discuss some of them below:
- API keys and basic authentication
- Token-based authentication
- Token-based authorization
- Centralized trust using claims
API Keys and Basic Authentication
Many companies start their API security journey by using API keys. They verify API calls and use basic authentication. In this case, API keys are inserted in the header or body of the URL of the API request.
This method is still quite popular and widely used, but it has major drawbacks. First, API keys are easily compromised. Second, the API key verification doesn’t rely on the user’s identity at all; it just depends on machine-to-machine verification. While there are instances where API keys are sufficient, I’d recommend you consider increasing your security measures if this is how you protect your APIs.
One way to level up your API security is by implementing token-based authentication. This means using access tokens for authentication. In this kind of implementation, access tokens determine the type of user, and privileged access can be established in environments where internal and external user separation is required.
Token-based authentication partially focuses on identity, since it’s part of the request, but this approach still has some vulnerabilities. First, privileged access is not necessarily soundproof — it can still be hacked, as anyone with a token might be able to modify the API since the privilege is not bound to the token. So, while access tokens can delineate the type of user, there is no way to determine permissions without writing custom code.
This approach has obvious advantages in comparison to the previous methods. It involves not only token-based authentication but also OAuth-based authorization. This means that the requesting party is not only authenticated by answering the question “Who are you?” but also authorized and assigned certain privileges on what an entity is allowed to do.
One of the advantages of OAuth is the use of scopes. They can contain more valuable data and can be built more easily into a system than if statements. In addition, scopes can specify privileges, allowing you to create custom scopes tailored to your APIs.
However, token-based authorization is not free from issues even with identity in focus. Since the identity is built directly into the API, the logic errors might become a potential threat. Also, within a complex system, in which some API requests rely on other API responses, it becomes problematic if one API calls another failing API.
The scope is bound to the token but not to the user, so it still does not provide fine-grained authorization on a user level.
Practical tip: If you choose to follow the scope-only approach, spend extra time mapping out how the identity information is used and keep track of ALL the APIs — a big task but worth it.
Centralized Trust Using Claims
The most evolved API security approach is establishing centralized trust with claims and — as an additional option — signed JSON Web Tokens (JWTs). If used correctly, this method safely addresses all the above issues.
JWTs are signed pieces of data used by OAuth flows to carry identity information. In addition, JWTs can be used to share scopes, which provide a logical grouping for claims. Claims are assertions containing a subject (about whom a claim is made), an attribute (a particular property about the subject) and an asserting party making a claim.
A claim can be made in plain text: “Jim is a father,” Alexa says. This claim can be trusted only if we trust Alexa. In the OAuth context, it would look like this: “Identity Provider X states that the User Y has attribute Z.” Your API should only put trust in the asserting party (the identity provider).
Instead of trusting attributes, it is far better to trust claims made by familiar parties. This way, the requesting party would first call the asserting party (or the issuer). The issuer returns data, signed with a private key, which is then sent to the replying party. As a result, the signature is verified with a public key, and the claim’s trust is established.
Practical tip: Follow the best practices of using JWTs and claims.
Why Strong API Security Matters
Placing trust only in the issuer of tokens does not give a 100% guarantee that all APIs are protected. However, validating the identity of the requesting parties and standardizing the process with centralized trust is the best way to ensure that critical information is safe and the whole system is less vulnerable. It also means you can limit the need for custom code and decrease the risk of cascading trust issues due to failing API calls.
Without advanced security, APIs become vulnerable with a rogue key left in a GitHub repository, for example. As a result, API providers must make security decisions that safeguard the integrity of the entire platform.