Every integration project eventually arrives at the same question: how does the API on the other side know that the request it just received actually came from you, and not from someone pretending to be you? That question has a spectrum of answers. At one end sits the humble API key, a single secret string that is quick to issue and quick to leak. At the other end sits mutual TLS, where both the client and the server present certificates and each proves its identity to the other during the connection handshake. In between live the methods most modern integrations actually use day to day: Basic authentication, Bearer tokens and JSON Web Tokens, OAuth 2.0, and HMAC request signing. Choosing correctly among them is one of the quiet decisions that separates an integration that ages gracefully from one that becomes a security incident.
The message up front: authentication is about proving identity, and stronger is not automatically better. The right method is the weakest one that still meets the risk of what the API exposes, deployed correctly, over a channel that is always encrypted. A well-managed API key beats a badly configured OAuth flow. The skill is matching method to risk, not chasing the most sophisticated option. For the wider context of how these APIs fit into a real integration, see the pillar on enterprise system integration explained.
1. Why API authentication matters
An API is a door into a system. Behind it sits data, business logic, and often the ability to change records that other people depend on. Authentication is the mechanism that decides whether the caller knocking at that door is who they claim to be. It is worth being precise about the vocabulary here, because it is routinely muddled. Authentication answers the question "who are you?" Authorisation, a separate concern, answers "what are you allowed to do?" You authenticate first to establish identity, then the system authorises specific actions based on that identity. This guide is about the first half, the proving of identity, though several of the methods below carry authorisation information along with the identity claim.
The reason this deserves careful thought is that APIs are, by design, machine-to-machine. There is no human at a login screen typing a password and passing a captcha. A credential is presented programmatically on every request, often thousands of times a minute, frequently by servers running unattended. That changes the threat model. Credentials sit in configuration files, environment variables, secret managers and, when people are careless, in source control and log files. The failure modes are leaked secrets, replayed requests, and tokens that live far longer than they should. Every method that follows is, in one way or another, an answer to those three risks: how the secret is protected, whether a captured request can be reused, and how quickly a compromised credential can be turned off.
One principle runs underneath everything in this article and cannot be repeated too often: none of these methods is safe on an unencrypted connection. Authentication proves identity, but it is transport encryption, TLS, that stops a network eavesdropper from simply reading the credential off the wire and using it themselves. Assume every example here runs over HTTPS. Where a method is especially dangerous without it, I will say so plainly.
2. API keys
An API key is the simplest credential there is: a single opaque string, issued by the API provider, that the client attaches to every request. It usually travels in a request header, commonly something like X-API-Key or an Authorization header, and occasionally, unfortunately, as a query-string parameter. The server keeps a list of valid keys, checks that the presented key is on it, and if so treats the request as coming from whoever that key belongs to.
The appeal is obvious. Keys are trivial to generate, trivial to hand out, and trivial to use. For a public data API, an internal service-to-service call, or any integration where the risk is low and the caller is a trusted system, an API key is often exactly the right amount of security. It identifies the calling application, lets the provider apply rate limits and quotas per key, and can be revoked by deleting it from the valid list.
The weaknesses are equally clear, and they are all consequences of that single string carrying all the trust. A key is a bearer credential, meaning whoever holds it can use it, with no further proof of identity required. If it leaks, into a public code repository, a log file, a browser network tab, a screenshot in a support ticket, the finder can impersonate the legitimate client until someone notices and rotates it. A key in a query string is especially exposed, because URLs are logged by servers, proxies and analytics tools as a matter of routine. Keys also do not usually expire on their own, so a leaked key stays valid indefinitely unless the provider builds rotation and expiry on top. The mitigations are practical rather than exotic: always send keys in headers rather than URLs, scope each key to the minimum it needs, rotate them on a schedule, and monitor for anomalous usage. For a fuller treatment of when a plain key is enough and when it is not, see the comparison in API key vs OAuth.
3. Basic authentication (and its risks)
HTTP Basic authentication, defined in RFC 7617, is one of the oldest mechanisms on the web and still surprisingly common in enterprise integrations. The client takes a username and password, joins them with a colon into a single string, and encodes the result using Base64. That encoded value is placed in the Authorization header prefixed with the word Basic. The server decodes it, splits it back into username and password, and checks the credentials.
The single most important thing to understand about Basic authentication is what Base64 is and is not. Base64 is an encoding, not encryption. It scrambles the bytes into a printable form, but reversing it requires no key and no secret at all. Anyone who captures the header can decode it back to the original username and password in one trivial step. Base64 provides zero confidentiality. This trips up more people than it should, because the encoded string looks opaque and vaguely secure, and it is neither.
The honest warning: Basic authentication over plain HTTP is genuinely unsafe. The username and password are, for all practical purposes, sent in the clear, because Base64 is reversible by anyone. A single intercepted request hands an attacker the actual account credentials, not a token that can be revoked, but the password itself, which may be reused elsewhere. Basic auth is only acceptable over HTTPS, where TLS encrypts the whole exchange. Even then, it puts real credentials on every request rather than a scoped, revocable token, which is why it has largely given way to Bearer tokens for anything beyond simple internal or legacy systems.
Where Basic auth still earns its place is in low-stakes, internal, or legacy contexts where a token infrastructure would be overkill and the connection is reliably encrypted. Many older enterprise systems and appliances expose Basic-protected endpoints, and plenty of integrations quietly depend on them. That is fine, provided the transport is always TLS and the credentials are dedicated service accounts with tightly limited permissions, never a shared human login. The moment you find yourself wanting per-request expiry, granular scopes, or delegated access, Basic auth has run out of road and a token-based method is the answer.
4. Bearer tokens and JWT
A Bearer token is a credential that the client presents in the Authorization header prefixed with the word Bearer. The name captures the security model exactly: whoever bears the token may use it, just like a key. The difference from a raw API key is that a Bearer token is typically short-lived and issued by an authentication step, so it is a temporary proof of identity rather than a permanent one. If it leaks, the damage is bounded by how soon it expires.
The most widespread form of Bearer token is the JSON Web Token, or JWT, defined in RFC 7519. A JWT is a self-contained token made of three Base64url-encoded parts separated by dots: a header describing the signing algorithm, a payload of claims, and a signature. The claims carry information such as who the token was issued to, who issued it, when it expires, and what the holder is allowed to do. The signature is the clever part. It is computed by the issuer over the header and payload using a secret or a private key, so any recipient who has the matching key can verify that the token was genuinely issued by the trusted authority and has not been altered in transit.
That self-contained, verifiable quality is what makes JWTs so useful in distributed systems. A service can validate a JWT and read the identity and permissions straight out of it, without a round trip back to a central session store on every request. This statelessness scales beautifully across microservices and API gateways. It also introduces the trade-off you must respect: because the token is validated by signature rather than by lookup, a JWT is valid until it expires, and it is awkward to revoke early. That is why sensible designs keep JWT lifetimes short, minutes rather than days, and pair them with a longer-lived refresh token used to obtain new ones. It is also why the payload of a JWT must never be treated as secret. It is signed, which guarantees it has not been tampered with, but it is only encoded, so anyone can read the claims inside. Never put a password or other sensitive secret in a JWT payload. For the anatomy of the token in detail, including how signing and verification actually work, see JWT explained.
5. OAuth 2.0
OAuth 2.0, specified in RFC 6749, sits in the middle of the spectrum and is where a lot of the confusion in this space lives, so it is worth being clear about what it is and what it is not. OAuth 2.0 is not, strictly, an authentication method. It is an authorisation framework. Its purpose is to let a resource owner grant a client application limited access to their resources on another service, without the client ever seeing the owner's password. The classic example is letting a third-party app read your calendar: you authorise the app at the calendar provider, and the app receives a token scoped to calendar reading, rather than your actual login.
The mechanics involve a few roles. The resource owner is the user or system that owns the data. The client is the application requesting access. The authorisation server issues tokens after verifying the owner's consent. The resource server holds the protected data and accepts the tokens. The client sends the user to the authorisation server, the user consents, and the client receives an access token, almost always a Bearer token and often a JWT, which it then presents to the resource server on each request. Different grant types cover different situations: the authorisation code grant for apps acting on behalf of a human user, and the client credentials grant for pure machine-to-machine access where there is no user in the loop at all, which is the common case in server-to-server enterprise integration.
The insight worth keeping: OAuth 2.0 solves delegation. Its whole reason for existing is to let one system act on behalf of a user or another system with a scoped, revocable, expiring token, so the underlying password is never shared and access can be narrowed and withdrawn precisely. If your problem is "let this app do these specific things on behalf of that account," OAuth is the right tool. If your problem is simply "prove this one trusted service is who it says it is," OAuth is often more machinery than you need, and a signed token or a key does the job with far less moving parts.
Because OAuth is a framework rather than a single recipe, it has many options, extensions and provider-specific quirks, which is exactly why it is both powerful and easy to get subtly wrong. Most enterprise platforms expose OAuth for their APIs. Microsoft's Dynamics 365 Business Central, for instance, authenticates its APIs through the Microsoft identity platform using OAuth 2.0 tokens, which is a concrete example of the client credentials flow in daily use; see Business Central APIs and integrations for how that plays out in a real ERP integration. For a step-by-step walk through the flows themselves, the dedicated pillar OAuth 2.0 explained is the place to go.
6. Mutual TLS
Ordinary HTTPS uses TLS, defined in its current version by RFC 8446, to do one-way authentication: the server presents a certificate that proves to the client it is really the server it claims to be, and the connection is encrypted. Mutual TLS, often written mTLS, extends this so that both sides present certificates. The client proves its identity to the server with its own certificate at the same time the server proves its identity to the client. Identity is established during the TLS handshake itself, before a single byte of the application request is sent.
This is the strongest of the common methods, and its strength comes from where the proof lives. There is no bearer secret travelling in a header that could be copied and replayed. Instead, the client holds a private key that never leaves it, and the handshake requires cryptographic proof of possession of that key. A captured request is useless to an attacker, because they do not have the private key needed to complete a handshake. That property makes mTLS the method of choice for high-assurance, system-to-system channels: bank and payment integrations, healthcare data exchange, and internal service meshes where every service authenticates every other service with a certificate.
The cost of that strength is operational. Certificates have to be issued, distributed to clients, trusted by servers, monitored, and rotated before they expire. An expired or misconfigured certificate breaks the connection cleanly and completely, which is good for security and painful for uptime if the renewal process is not automated and watched. Managing a certificate authority, or integrating with one, and keeping the whole fleet of certificates current is real ongoing work. That is why mTLS tends to appear where the value or sensitivity of the channel clearly justifies the overhead, and why lighter methods dominate everywhere else. When you genuinely need both parties to prove themselves with something that cannot be replayed, though, nothing simpler will do.
7. HMAC request signing
HMAC request signing takes a different angle from everything above. Instead of sending a secret and trusting the channel to protect it, the client uses a shared secret to compute a signature over the contents of the request, and sends the signature rather than the secret. HMAC stands for hash-based message authentication code. The client combines a shared secret key with elements of the request, typically the method, the path, a timestamp, and often a hash of the body, and runs them through a keyed hash function to produce a signature that it attaches to the request. The server, which also holds the shared secret, independently recomputes the signature over the received request and checks that it matches.
This design gives two guarantees at once. First, integrity: because the signature covers the request contents, any tampering in transit, a changed amount, a swapped account number, causes the recomputed signature to differ and the request to be rejected. Second, authenticity without transmitting the secret: the shared key is never sent on the wire, only proof that the sender possesses it. Adding a timestamp to the signed material, and having the server reject requests whose timestamp is too old, defends against replay, where an attacker captures a valid request and sends it again later. This is why HMAC signing is favoured by payment providers and webhook systems, where a receiver needs to be sure that an incoming call really came from the expected sender and was not altered on the way.
The trade-offs are the mirror image of the benefits. Both sides must hold the same shared secret and keep it safe, and the signing logic must be implemented identically on client and server, which is fiddly. Get the canonicalisation of the request wrong, a different header order, an unexpected trailing slash, an encoding mismatch, and signatures fail to match even though nothing malicious happened. HMAC does not encrypt anything, so it is still used over TLS for confidentiality. But for the specific job of proving that a request is authentic and unaltered, particularly for server-to-server callbacks and webhooks, HMAC signing is a well-proven and elegant fit.
8. The methods compared
It helps to see these methods laid out as a spectrum, because that is genuinely how they relate to one another. At the simple end, an API key is one secret string, easy to use and easy to leak. As you move along, you trade convenience for stronger guarantees: tokens that expire, delegation that can be scoped and revoked, signatures that prove integrity, and finally certificates that both parties must prove they hold. The diagram below places the main methods on that line from simplest to strongest, with OAuth 2.0 sitting in the middle as the delegation framework that most modern user-facing integrations are built on.
The table below is the reference version of the same idea, setting each method against how it works, the security level it realistically provides, and where it typically belongs. Read it as a starting point for a decision, not a substitute for judging your own risk.
| Method | How it works | Security level | Typical use |
|---|---|---|---|
| API key | One secret string sent in a header on every request; server checks it against a valid list. | Low. Bearer secret, no expiry by default, high leak risk. | Public data APIs, simple internal service calls, rate limiting per client. |
| Basic auth | Username and password joined and Base64 encoded in the Authorization header. | Low. Base64 is not encryption; unsafe on plain HTTP, TLS mandatory. | Legacy and internal systems over HTTPS with dedicated service accounts. |
| Bearer / JWT | Signed, self-contained token in the Authorization header; verified by signature. | Medium to high. Short-lived and revocable via expiry; payload is readable. | Modern web and mobile APIs, stateless microservices, gateway auth. |
| OAuth 2.0 | Authorisation server issues scoped, expiring tokens after owner consent. | High when implemented correctly; complexity is the main risk. | Delegated access, third-party apps, enterprise SSO, ERP and SaaS APIs. |
| HMAC signing | Client signs request contents with a shared secret; server recomputes and compares. | High for integrity and authenticity; secret never sent, replay guarded by timestamp. | Payment APIs, webhooks, server-to-server callbacks needing tamper proof. |
| Mutual TLS | Both client and server present certificates and prove key possession in the handshake. | Very high. No bearer secret to replay; strongest common method. | Banking, healthcare, high-assurance system meshes, regulated exchange. |
9. Choosing the right method
The decision is less about ranking the methods and more about matching them to the shape of your problem. A few questions cut through most of it. Is there a human user whose access you are acting on behalf of, or is this pure machine-to-machine? If there is a user granting consent, OAuth 2.0 with the authorisation code grant is the natural fit. If it is one trusted server talking to another with no user in the loop, the client credentials grant, a signed token, or in low-risk cases a well-managed API key will serve.
How sensitive is what sits behind the API, and how bad is a breach? For public or low-value data, an API key keeps friction low and is entirely defensible. For anything carrying personal, financial or operational data, you want expiring tokens at minimum, and for the highest-assurance channels, banking, healthcare, regulated data exchange, mutual TLS repays its operational cost. Do you specifically need to prove that a request was not tampered with in transit, as with a payment instruction or a webhook? That is HMAC signing's home ground. And always weigh the operational reality: mTLS and OAuth both bring real management overhead, certificate rotation for one, flow configuration and token handling for the other, and a method your team cannot operate correctly is less secure in practice than a simpler one they can.
My working rule, after a lot of integrations, is to start from the risk and choose the lightest method that genuinely meets it, then implement that method well rather than reaching for a heavier one implemented carelessly. A rotated, header-only, tightly scoped API key over TLS is a perfectly respectable choice for the right endpoint. A sprawling OAuth setup nobody fully understands is not made safe by its sophistication. Sophistication is not security; correctness is. For the specific and common decision between the two most-debated options, the dedicated comparison in API key vs OAuth goes deeper, and the whole topic sits inside the broader picture drawn in the enterprise system integration pillar.
10. References
The methods in this guide are grounded in published internet standards. If you want the authoritative detail behind any of them, these are the primary specifications to read:
- RFC 6749, The OAuth 2.0 Authorization Framework. The core specification defining OAuth 2.0 roles, grant types and token issuance.
- RFC 7519, JSON Web Token (JWT). Defines the JWT structure, claims and the signing and verification model.
- RFC 7617, The 'Basic' HTTP Authentication Scheme. Specifies how Basic authentication encodes and transmits credentials.
- RFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3. The current TLS specification underlying HTTPS and mutual TLS.
These are freely published by the IETF and are the definitive source for anyone implementing or reviewing an authentication layer. The practitioner's advice in this article is a guide to choosing among them; the RFCs are the ground truth for building them correctly.
Final thoughts
API authentication is a spectrum, not a ladder you are obliged to climb to the top of. At one end, an API key proves an identity with a single string and asks nothing more; at the other, mutual TLS makes both parties prove possession of a private key before a request is even sent. In between sit Basic authentication, which is only ever acceptable over TLS because Base64 hides nothing, Bearer tokens and JWTs that carry signed, expiring proof of identity, OAuth 2.0 that turns identity into delegated and revocable access, and HMAC signing that proves a request arrived unaltered from a known sender. Each exists because it answers a specific version of the same question: how does the receiver know who is calling, and how much can it trust what arrives?
The judgement that matters is matching the method to the risk, deploying it correctly, and never forgetting that all of it rides on an encrypted channel. Choose the lightest method that meets the real risk, implement it with care, rotate secrets, keep tokens short-lived, and let the sensitivity of what sits behind the door decide how strong the lock needs to be. Do that consistently and authentication stops being the weak seam in your integrations and becomes the quiet, dependable layer it is supposed to be.
Securing an integration and unsure which auth method fits?
Independent advice on API authentication, OAuth and token design, mutual TLS, and secure system-to-system integration across ERP, EAM and CAFM platforms. 22+ years connecting enterprise systems safely. No vendor margins, no reseller arrangements.
Book a conversationRelated reading: Enterprise system integration explained, OAuth 2.0 explained, JWT explained, API key vs OAuth, Business Central APIs and integrations.
Muhammad Abbas
CMMS / CAFM Manager & Enterprise Integration Specialist · 22+ years across ERP, EAM, CAFM and enterprise integration.
Work with me