--- title: "Machine to Machine (M2M) Authentication with OAuth 2.0" slug: "machine-to-machine-authentication-with-oauth-20" updated: 2026-07-20T11:10:20Z published: 2026-07-20T11:10:20Z canonical: "help.hyperscience.ai/machine-to-machine-authentication-with-oauth-20" --- > ## Documentation Index > Fetch the complete documentation index at: https://help.hyperscience.ai/llms.txt > Use this file to discover all available pages before exploring further. # Machine to Machine (M2M) Authentication with OAuth 2.0 > [!WARNING] > Machine-to-machine authentication is **required for SaaS deployments** of all versions and **strongly recommended for on-premise deployments** of Hyperscience v40 and later. The Hyperscience application integrates a built-in local identity provider that supports machine-to-machine (M2M) communication via the OAuth 2.0 protocol. It supports the following authorization flows: - Client Credentials Flow - `client_secret_basic` (authentication method) - `client_secret_post` - `client_secret_jwt` - `private_key_jwt` - JWT Bearer Flow ## Setting up the local identity provider (on-premise only) The local identity provided needs to be configured with the environment's public URL. To do so, enter the URL, including its `https://` prefix, as the value for the `HS_PUBLIC_URL` variable in the ".env" file. ### Custom CA certificate bundles In v42.3.6 and later, you can use a custom CA (certificate authority) certificate bundle to acquire tokens for authentication against the URL listed in `HS_PUBLIC_URL`. To use a custom certificate bundle, enter it as the value for the `HS_PUBLIC_URL_CA_BUNDLE` variable in the “.env” file. ## Managing machine credentials Manage machine credentials in the application at `https://{hostname}/users/machine-credentials` (**Users** > **Machine Credentials**). Both client secrets and public keys are maintained in JWKS format. ![M2MAuthentication.png](https://cdn.us.document360.io/87894cef-4958-4f3f-be6f-b75a78c82548/Images/Documentation/29782015990669.png) ## Permissions and access to restricted flows API calls made with M2M access tokens are given the permissions of the **API User** Permission Group. If a flow's access is restricted to specific permission groups, and the API User group is not one of them, M2M requests to that flow's endpoints return a `403 Forbidden` response — even when the credentials and token are valid. To allow M2M access to a restricted flow: 1. In the application, go to **Users** > **Permission Groups**, and find the **API User** permission group. 2. Scroll to the bottom of the group's settings, and grant the **API User** group access to the restricted flow. - Repeat step 2 for each restricted flow that needs to be accessed via the API. ## Making HTTP requests to Hyperscience's API The process involves two steps: 1. Clients use their ID and key to get an access token from `https://{hostname}/api/v5/local_identity_provider/oauth2/token`, which is valid for 10 minutes. 2. Include the access token in the HTTP header for API requests. For more information, see our [API documentation](https://docs.hyperscience.ai/#authentication). > [!NOTE] > **Add API User permission group to a restricted flow** > > If your API calls return `403 Forbidden` for a restricted flow, add the **API User** permission group to that flow's restriction. See [Permissions and access to restricted flows](/deployment/docs/machine-to-machine-authentication-with-oauth-20#permissions-and-access-to-restricted-flows1) above. ### Example code This sample implementation is provided using Python 3.11.7 and Authlib library version 1.7.2. ```python """ Sample code for the OAuth 2.0 Client Credentials flow (client_secret_jwt) """ from authlib.integrations.requests_client import OAuth2Session from authlib.oauth2.rfc7523 import ClientSecretJWT client_id = "b77db512-cda5-4bda-a613-3c358ef144ad" client_secret = {    "kty": "oct",    "k": "ZldVQnRrWEpVNUJ2NTB1RVlVS2FMeUtySWVJdEx6T2o",    "alg": "HS256",    "kid": "d0aa7744-4253-483b-8404-ab2db8b70d6f", } token_endpoint = "http://{hostname}/api/v5/local_identity_provider/oauth2/token" with OAuth2Session(    client_id,    client_secret,    token_endpoint_auth_method=ClientSecretJWT(        token_endpoint,        alg=client_secret["alg"],        headers={"kid": client_secret["kid"]},    ),    token_endpoint=token_endpoint,    grant_type="client_credentials", ) as session:    session.headers.update({"HyperscienceLocalIdentityProvider": "1"})    # Fetch the initial access token. All subsequent access tokens will be    # automatically fetched by the OAuth 2.0 client as they near expiration.    session.fetch_token()    # Make a request to Hyperscience's API    response = session.get("http://{hostname}/api/v5/version")    print(f"{response.status_code=} {response.json()=}") ``` A group of users who share the same set of permissions. Learn more in [User Management](https://help.hyperscience.ai/latest/docs/user-management).