---
title: "Outbound Auth with OAuth2 M2M"
---

OAuth2 M2M (machine-to-machine) is for backend-to-backend authentication—more secure than an API Key and with automatic token refresh. No user is involved: the credential is obtained from the client's own Client ID / Secret. For scenarios that require user consent, see [OAuth2 user federation](/en/docs/framework/oauth2-user-federation). This page covers only what is specific to M2M; the shared `VeIdentityFunctionTool` / `VeIdentityMcpToolset` usage, the `into` default, and the common FAQ live in the [security overview](/en/docs/framework/security#outbound-authentication).

## Create an OAuth2 M2M credential

1. Sign in to the Volcengine console and open the **Agent Identity** service.
2. Go to **Identity Auth > Outbound Credential Hosting > OAuth Client**.
3. Click **New > New OAuth Client**.
4. Under **OAuth2 Flow**, choose **Machine to Machine (M2M)** and click **OK**.

The provider can be configured from three sources:

| Source | What to fill in |
| :--- | :--- |
| Built-in vendor (recommended): Lark / Coze / Google / GitHub | Client ID, Client Secret |
| OIDC config (custom) | Issuer URL (discovery URL, e.g. `https://accounts.google.com/.well-known/openid-configuration`), Client ID, Client Secret, scopes (at least `openid`) |
| Custom OAuth2 config | Client ID, Client Secret, scopes, Issuer, authorization endpoint, token endpoint |

## Use it in code

Create a config with `oauth2_auth(..., auth_flow="M2M")`. OAuth2 credentials inject into the `access_token` parameter by default, so you don't set `into`:

```python
from veadk.integrations.ve_identity import VeIdentityFunctionTool, oauth2_auth
import aiohttp

async def call_service(access_token: str, endpoint: str):
    headers = {"Authorization": f"Bearer {access_token}"}
    async with aiohttp.ClientSession() as session:
        async with session.get(endpoint, headers=headers) as resp:
            return await resp.json()

auth_config = oauth2_auth(
    provider_name="my-oauth2-m2m-provider",
    scopes=["api://your-service/.default"],
    auth_flow="M2M",
)
tool = VeIdentityFunctionTool(func=call_service, auth_config=auth_config)
```

The same config works with `VeIdentityMcpToolset` (same usage as on the [API Key page](/en/docs/framework/api-key#use-it-in-code); only the `auth_config` differs).

`scopes` accepts multiple scopes; omit it to use the default scopes configured for the provider in the console:

```python
auth_config = oauth2_auth(
    provider_name="my-provider",
    scopes=["api://service1/.default", "api://service2/.default"],
    auth_flow="M2M",
)
```

## How it differs from API Key

An API Key is a fixed credential; M2M exchanges a Client ID / Secret for a short-lived token that Agent Identity refreshes automatically—better suited to production. M2M is the service's own identity and involves no user login; to act on behalf of a specific user, use [OAuth2 user federation](/en/docs/framework/oauth2-user-federation).
