Blog · Guides

M2M authentication: how machines prove who they are

Machine-to-machine authentication compared: OAuth 2.0 client credentials, API keys, JWT bearer and mTLS, with the checks that keep service credentials safe.

Casdoor Team · November 2, 2026 · 5 min read

This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 2, 2026. Spotted a mistake? Tell us.

M2M authentication is how one service proves its identity to another when no user is present. A nightly job calls a billing API, a worker reads from a queue, a build pipeline pushes an image: each caller needs a credential, and each callee needs a way to decide whether to trust it.

The options look similar on a whiteboard and behave very differently in production. The main ones are API keys, OAuth 2.0 client credentials, signed JWT assertions and mutual TLS. Most mature systems use more than one.

The four common patterns

Pattern How the client proves itself Best for Main weakness
API key A long-lived secret in a header Simple integrations, low-risk internal calls Hard to scope, rotate and audit; leaks easily
OAuth client credentials Client ID and secret at the token endpoint Service-to-service calls with scopes and short-lived tokens The secret is still a long-lived credential
JWT bearer A signed assertion from a private key Services that should not hold a shared secret Key management and clock synchronization
Mutual TLS A client certificate High-assurance internal and financial workloads Certificate lifecycle is operationally heavy

OAuth 2.0 client credentials

The client credentials grant (RFC 6749, section 4.4) is the default answer for service-to-service authorization. The client sends its ID and secret to the token endpoint, receives an access token, and calls the API with that token.

The advantages over a bare API key:

  • Scopes. The token is limited to what the client was granted, not to everything the API can do.
  • Short lifetime. The token expires, so a leaked token is less useful than a leaked key.
  • Central revocation. Disabling the client or rotating its secret stops new tokens immediately.
  • Audit. The identity provider sees which client requested which scopes and when.

The flow is simple: authenticate the client, check that the client is allowed to use the grant, issue a token with the requested scopes, and let the resource server validate it. The client should cache the token until shortly before expiry rather than requesting a new one for every call.

The weakness is the client secret. It usually sits in an environment variable or a secret manager, and it does not rotate itself. Treat it like a password: one client per service, a secret manager, rotation on a schedule, and no secrets in source control or container images.

API keys

API keys are still reasonable for low-risk integrations and for products that want a dead-simple onboarding path. A key in a header is easy to understand and easy to implement.

They become a problem when they are long-lived, shared across environments, embedded in mobile apps or committed to a repository. A leaked key often has the same permissions as the service that owns it, and revoking it can break several integrations at once.

If you use API keys:

  • Scope each key to the smallest set of operations it needs.
  • Give each consumer its own key, so revocation is isolated.
  • Store a hash, not the key itself, and show the key once.
  • Rotate on a schedule and after any suspected leak.
  • Log key usage and alert on unusual patterns.

Signed JWT assertions

The JWT bearer grant (RFC 7523) lets a client authenticate with a signed JWT instead of a shared secret. The client holds a private key, signs an assertion with a short expiry, and exchanges it for an access token.

This is useful when you do not want to distribute a long-lived secret, or when the client already has a key pair. The cost is key management: public keys have to be published or configured, private keys have to be protected, and both sides need roughly synchronized clocks because the assertion has an expiry.

A related pattern is workload identity. Instead of a secret, the workload presents a token from the platform it runs on: a GitHub Actions OIDC token, a Kubernetes service account token, or a cloud workload identity token. The identity provider trusts that issuer and subject, and issues its own token in return. Nothing long-lived is stored in the workload.

Mutual TLS

In mutual TLS, both sides present certificates. The client certificate is the credential, and the server can bind the resulting token to the certificate (RFC 8705) so a stolen token cannot be replayed without the private key.

mTLS is common in banking, internal service meshes and zero-trust networks. It gives strong cryptographic assurance, but it moves the operational burden to certificate issuance, renewal and revocation. If your certificates are managed manually, mTLS can become the least reliable part of the system.

What good M2M identity looks like

A service identity program usually converges on the same checklist:

  1. One identity per workload. Do not share a client across a cron job, a web service and a developer laptop.
  2. Least privilege scopes. Give the client the operations it needs, not a wildcard.
  3. Short-lived tokens. Minutes to hours, not months. Cache them properly.
  4. No secrets in code or images. Use a secret manager or workload identity.
  5. Rotation. Rotate client secrets and certificates on a schedule, and make rotation a tested procedure.
  6. Audience restriction. A token issued for one API should not work at another; use the resource parameter or separate audiences.
  7. Monitoring. Alert on token requests from new locations, unusual scopes or a sudden spike in failures.
  8. Revocation. Know how to disable a client, revoke its tokens and rotate its secret before you need to.

How Casdoor handles M2M

Casdoor supports the client credentials grant, the JWT bearer grant (RFC 7523), token exchange (RFC 8693) and federated credentials for workload identity. The application's grant types control which flows are allowed, and scopes limit what the issued token can do.

For a service that runs in GitHub Actions, Kubernetes or a cloud workload identity, federated credentials let the workload exchange its platform token for a Casdoor token without storing a client secret. For a service that holds a private key, the JWT bearer grant avoids a shared secret entirely.

See the OAuth documentation for the endpoints and grant settings, and the MCP authorization guide if the service is an AI agent or MCP server. Casdoor Cloud starts at $6.67/month billed yearly for a dedicated instance with no per-user fees.

FAQ

Is client credentials the same as an API key? No. A client credentials token is short-lived and scoped, and the client secret is only used at the token endpoint. An API key is usually a long-lived bearer secret sent on every request.

Should M2M tokens be JWTs? Not necessarily. A JWT lets the resource server validate the token locally, while an opaque token requires introspection. Use JWTs when local validation matters and the token does not need to be revoked instantly.

How long should a service token live? As short as the workload can tolerate, often 5 to 60 minutes. Long-lived tokens are the reason leaked credentials stay useful for months.

Can I avoid secrets entirely? Yes, with workload identity or mTLS. Both replace the shared secret with a key or a platform-issued token, at the cost of more setup and certificate or key management.