Authentication

Machine-to-Machine (M2M) Authentication: Methods, Tokens and Best Practices

Machine-to-machine (M2M) authentication is how one piece of software proves its identity to another without a person signing in, such as a backend service calling an API, a nightly job reading a database, or a customer's integration calling your product. Instead of a username and password, the calling service uses a credential issued to it, usually an OAuth 2.0 client ID and secret, a private key or a certificate, and receives a short-lived access token it sends with each request.

The standard way to do this is the OAuth 2.0 client credentials grant. For stronger security, current OAuth guidance recommends authenticating with a private key or certificate instead of a shared secret, and keeping tokens short-lived and narrowly scoped.

How M2M authentication works

Most M2M authentication follows the OAuth 2.0 client credentials grant:

  1. Register the service. An admin creates a client for the service on the authorization server and gives it permissions (scopes or roles). The service gets a client ID and a credential: a secret, a key pair or a certificate.
  2. Request a token. The service sends its credentials to the authorization server's token endpoint and asks for a token.
  3. Receive a short-lived access token. The authorization server checks the credentials and returns an access token, often a signed JWT, that lists what the service may do and when the token expires.
  4. Call the API. The service sends the token in the Authorization header. The API checks the signature, expiry, audience and scopes before responding.
  5. Repeat when it expires. The client credentials grant doesn't use refresh tokens. The service simply requests a new access token.

A token request looks like this:

curl -X POST https://auth.example.com/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d "grant_type=client_credentials" \
  -d "scope=invoices:read"

For a side-by-side of client credentials and the other OAuth flows, see OAuth flows explained.

M2M authentication methods compared

MethodHow the service proves its identityStrengthsWatch out for
API keySends a static key with every requestSimple to build and useLong-lived, carries no permissions or expiry, risky if leaked
Client credentials with a client secretExchanges a client ID and secret for a short-lived access tokenStandard OAuth; tokens expire and carry scopesThe secret is still a shared password that must be stored and rotated
Client credentials with a private key (private_key_jwt)Signs a short JWT with its private key (RFC 7523)No shared secret; the server only stores the public keyKey management and rotation
Mutual TLS (mTLS)Presents a client certificate during the TLS handshake (RFC 8705)Strong identity; tokens can be bound to the certificateCertificate issuance and rotation, harder to set up
Token exchangeSwaps one token for another, for example to act on behalf of a user (RFC 8693)Keeps the user's identity in service-to-service callsNeeds authorization server support

API keys still have a place for simple, low-risk access. For anything sensitive, use OAuth access tokens: they expire, carry permissions and can be checked without a database lookup.

M2M tokens vs user tokens

M2M tokenUser token
Who it representsA service, job or integrationA person who signed in
How it's obtainedClient credentials (or an API key)A sign-in flow such as authorization code with PKCE
Refresh tokensUsually none; request a new tokenCommon, so users stay signed in
PermissionsGranted to the client by an adminThe user's roles, sometimes narrowed by consent
MFANot applicableOften required

M2M authentication in B2B SaaS

In a B2B product, M2M isn't only about your own microservices. Your customers want to connect their systems to your API: syncing data, automating workflows or plugging in their own tools. That raises two questions every B2B API has to answer:

  • Whose token is it? A token can belong to a customer account (tenant), so it keeps working when the employee who created it leaves, or to an individual user, so it carries that user's permissions and is removed with them.
  • Who manages it? Customer admins expect to create, scope and revoke their own API tokens from your product's settings, without filing a support ticket.

Every token must also be tied to one customer account, so a token issued to one customer can never read another customer's data.

Service-to-service authentication best practices

These follow the IETF's OAuth 2.0 Security Best Current Practice (RFC 9700, January 2025) and common OAuth guidance.

  1. Give every service its own credentials. Never share one client or key across services, so a leak affects only one and you can revoke it alone.
  2. Prefer keys or certificates over shared secrets. RFC 9700 recommends asymmetric client authentication, such as private_key_jwt or mTLS, so the authorization server never stores a reusable secret.
  3. Keep access tokens short-lived. Minutes to an hour is typical. Request new tokens instead of storing long-lived ones.
  4. Grant the minimum permissions. RFC 9700 says token privileges should be "restricted to the minimum required" and tied to a specific API (audience).
  5. Bind tokens to the caller where you can. Sender-constrained tokens (mTLS or DPoP) can't be replayed by someone who steals them.
  6. Validate every token at the API. Check the signature, issuer, audience, expiry and scopes on every request, including internal calls.
  7. Store credentials in a secrets manager. Never in source code, container images or logs, and rotate them on a schedule.
  8. Log and monitor M2M access. Record which client called what, and alert on unusual volume, new IP addresses or failed authentications.
  9. Revoke what you no longer need. Remove credentials when a service, integration or customer contract ends.

M2M authentication with Frontegg

Frontegg is customer identity and access management (CIAM) for B2B SaaS, and its M2M authentication is built around the B2B questions above.

  • Two token types. Client credentials tokens give the service a client ID and secret that it exchanges for a short-lived token, sent in the Authorization header. Access tokens are JWTs that work immediately with no exchange step, sent in the X-API-KEY header, with an optional expiration.
  • User or tenant tokens. User tokens carry the user's roles and permissions in the active account and are deleted automatically when the user is removed. Tenant tokens belong to the customer account and get their permissions from the roles assigned when they're created.
  • Customer self-service. Your customers' admins and users can create and manage their own tokens from the Frontegg admin portal inside your product.
  • On behalf of a user. An M2M token can act in a token exchange flow, so the resulting token carries the user's identity plus an act claim naming the service.
  • Limits. Up to 10,000 access tokens per environment and 100 per tenant by default.

Client credentials, access tokens, user- and tenant-level tokens, token restriction policies and the in-app tokens component are all included on the free Pay as you go plan, which covers up to 7,500 monthly active users. See Frontegg pricing.

FAQ

What is M2M authentication?

M2M (machine-to-machine) authentication lets software, such as a backend service, script or integration, prove its identity to an API without a person signing in. It usually uses the OAuth 2.0 client credentials grant to get a short-lived access token.

What is an M2M token?

An M2M token is an access token issued to a service rather than a user. It identifies the calling service, lists what it's allowed to do and expires after a set time.

Is an API key the same as an M2M token?

No. An API key is a static string that usually never expires and carries no permissions. An M2M access token is short-lived, signed and lists the caller's permissions, so it's safer for anything sensitive.

Which OAuth flow is used for machine-to-machine authentication?

The client credentials grant, defined in RFC 6749 section 4.4. The service authenticates with its own credentials and receives an access token. No user or browser is involved.

Do M2M tokens use refresh tokens?

Usually not. RFC 6749 says a refresh token should not be issued with the client credentials grant, so the service requests a new access token when the old one expires.

How do you secure service-to-service authentication?

Give each service its own credentials, prefer private keys or certificates over shared secrets, keep tokens short-lived and narrowly scoped, validate every token at the API, store credentials in a secrets manager and revoke them when they're no longer needed.

Looking to take your User Management to the next level?
Sign up. It's free