Implement machine-to-machine authentication with WorkOS Connect.
Machine-to-machine (M2M) applications are designed for use cases where clients are other services, such as a customer’s application. M2M applications use the underlying client_credentials flow for authentication.
M2M access tokens contain an org_id claim representing the third party being granted access via the M2M application.
M2M applications can only be configured as third-party.
M2M applications are one of two ways WorkOS enables credential issuance to customers for programmatic access to an application. The other is API keys. The API Keys vs M2M Applications guide can help determine which approach is best for a given use case.
M2M applications are commonly used to provide API access credentials to customers or partners, allowing them to programmatically access APIs and integrate services into their applications. They are also ideal for partner integrations that run server-to-server without user interaction, where access needs to be tracked and controlled on a per-organization basis.
Machine-to-machine applications can use the client_credentials grant type with the Token Endpoint to obtain an access_token to authenticate calls to the API.
const params = new URLSearchParams({ grant_type: 'client_credentials', client_id: process.env.M2M_APP_CLIENT_ID, client_secret: process.env.M2M_APP_CLIENT_SECRET, scope: 'openid profile email', }); const response = fetch('https://<subdomain>.authkit.app/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params, }).then((response) => response.json()); const accessToken = response.access_token;
M2M applications are always associated with a specific Organization, which represents the customer or partner. Since machine-to-machine applications are associated with a particular organization, issued access tokens contain an org_id claim that the application’s API can use to control access.
This association provides several benefits:
org_id claim that identifies which organization the client is acting on behalf oforg_id to ensure clients only access resources they are authorized forThe application can verify the tokens sent by external M2M applications for the purpose of authenticating requests using the JWKS for the environment. The process is similar to validating the access token JWT provided by an AuthKit login.
import { jwtVerify, createRemoteJWKSet } from 'jose'; const JWKS = createRemoteJWKSet(new URL('https://<subdomain>.authkit.app/oauth2/jwks')); const bearerTokenMiddleware = async (req, res, next) => { const authHeader = req.headers.authorization; const token = authHeader?.match(/^Bearer (.+)$/)?.[1]; if (!token) { return res.status(401).json({ error: 'No token provided' }); } try { const { payload } = await jwtVerify(token, JWKS, { issuer: 'https://<subdomain>.authkit.app', audience: 'client_123456789', }); req.organization = await findOrganizationById(payload.org_id); next(); } catch (err) { return res.status(401).json({ error: 'Invalid token' }); } }; // Example protected route app.get('/api/protected', bearerTokenMiddleware, (req, res) => { res.json({ data: 'Protected resource', organization: req.organization }); });
In addition to fast stateless verification, the Token Introspection API can be used to synchronously check whether a token is still valid.
M2M applications use the client_id and client_secret from a credential to authenticate to the Connect APIs using the client credentials flow.
While not displayed to users (since M2M apps do not have user interaction), the name and description help manage and identify different M2M applications in the dashboard.