> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-change-1791323909-75c753a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Add identity to Managed Deep Agents

> Authenticate callers to a Managed Deep Agents deployment with a LangSmith API key, Supabase, or your own backend.

Identity controls who can invoke your managed deep agent, such as apps and SDK clients that start runs or send messages.

<Note>
  Managed Deep Agents is in **public [beta](/langsmith/release-stages)** and available on [LangSmith Cloud](/langsmith/cloud) in the US region only.
</Note>

Put the identity declaration at the project root:

```text theme={null}
my-agent/
  agent.ts
  identity.ts
```

For the full project layout, see [Project structure](/langsmith/javascript/managed-deep-agents-project-structure).

## Choose the identity provider

By default, `mda init` requires callers to present a LangSmith API key. Anyone who has that key can use the same deployment and may see the same threads. To give each signed-in end user private conversations, use Supabase instead:

| Goal | Use |
| - | - |
| Lock down the deployment for SDK clients, scripts, and services | [LangSmith API key (default)](#configure-identity-with-a-langsmith-api-key) |
| Signed-in end users with private chats, verified by Managed Deep Agents | [Supabase](#configure-identity-with-supabase) |
| Signed-in end users with private chats, already authenticated by your own API | [Your own backend](#configure-identity-with-your-own-backend) |

Supabase and backend identity both give each end user private threads. The difference is who verifies the user. With Supabase, the browser sends its access token and Managed Deep Agents verifies it. With backend identity, your API verifies the user and asserts the resulting user ID.

For more information, see [Project structure](/langsmith/javascript/managed-deep-agents-project-structure).

<Note>
  On hosted deployments, LangSmith Studio reaches the deployment through a separate workspace-authenticated path. A caller with API access to the LangSmith workspace can read and search every thread in the deployment, whichever identity provider you choose. That caller cannot modify threads owned by your end users. Per-user privacy therefore holds against your end users, not against members of your LangSmith workspace.
</Note>

## Configure identity with a LangSmith API key

`mda init` scaffolds this identity provider as a secure default. Callers must present a valid LangSmith workspace API key. Managed Deep Agents verifies the key with LangSmith Cloud.

```ts identity.ts theme={null}
import { auth, defineIdentity } from "managed-deepagents";

export const identity = defineIdentity({
  auth: auth.langsmithApiKey(),
});
```

Clients send the key as `x-api-key`. You do not need to add verification endpoint or tenant settings to your project `.env`. LangSmith Cloud supplies those.

<Warning>
  Anyone with the key can reach the deployment, so treat the key as a secret. This default does not give each end user private threads. If Alice must not see Bob's threads, use [Supabase](#configure-identity-with-supabase) or [your own backend](#configure-identity-with-your-own-backend).
</Warning>

## Configure identity with Supabase

Use Supabase when a browser or another client calls the deployment as a signed-in entity. Each user gets private threads. Managed Deep Agents configures that ownership for you. For more information on the underlying LangSmith Deployment pattern, see [Make conversations private](/langsmith/resource-auth).

<Steps>
  <Step title="Enable auth in Supabase" id="enable-auth-in-supabase">
    In the Supabase dashboard, enable the auth provider you will use (for example email/password).
  </Step>

  <Step title="Copy the project reference" id="copy-the-project-reference">
    Copy the project reference: the subdomain before `.supabase.co` in your project URL.
  </Step>

  <Step title="Declare identity" id="declare-supabase-identity">
    Declare identity with that project reference:

    ```ts identity.ts theme={null}
    import { auth, defineIdentity } from "managed-deepagents";

    export const identity = defineIdentity({
      auth: auth.supabase({ projectRef: "your-project-ref" }),
    });
    ```

    Pass `url` instead of the project reference for a custom auth domain.
  </Step>

  <Step title="Send the access token from the client" id="send-the-access-token">
    In the client app, set the Supabase project URL and publishable key (labeled `anon` in the Supabase dashboard). Sign the user in, then send the access token on every deployment request:

    ```ts theme={null}
    await fetch(`${deploymentUrl}/threads/${threadId}/runs`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${supabaseAccessToken}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(runBody),
    });
    ```

    The publishable key (labeled `anon` in the Supabase dashboard) is only for the client to sign in with Supabase. Do not send a LangSmith API key in this mode. The Bearer token is the caller identity.

    Managed Deep Agents verifies the JWT against the project's JWKS URL derived from your project reference (`https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json`).

    <Note>
      Adding Supabase identity to an existing deployment does not add owner metadata to existing threads. Plan and test a migration before relying on identity-based access for those threads.
    </Note>
  </Step>
</Steps>

## Configure identity with your own backend

Use backend identity when your own API already authenticates users and calls the deployment on their behalf. Your backend proves itself with a shared secret and names the caller. Managed Deep Agents trusts that name only after the secret matches, then gives each named user private threads.

The browser never reaches the deployment in this mode. Requests go from the browser to your API, and from your API to the deployment.

<Steps>
  <Step title="Declare identity" id="declare-backend-identity">
    ```ts identity.ts theme={null}
    import { defineIdentity } from "managed-deepagents";

    export const identity = defineIdentity({
      auth: "backend",
    });
    ```
  </Step>

  <Step title="Generate the ingress secret" id="generate-the-ingress-secret">
    Generate a random value and add it to the project `.env` as `MDA_INGRESS_SECRET`:

    ```bash theme={null}
    openssl rand -hex 32
    ```

    ```text .env theme={null}
    MDA_INGRESS_SECRET=<MDA_INGRESS_SECRET>
    ```

    `mda deploy` forwards the value as a hosted deployment secret. A project that declares backend identity without this value fails deploy preflight before any build work, because the deployment would reject every request with 401. For how `.env` values reach a deployment, see [Deploy](/langsmith/javascript/managed-deep-agents-deploy#secrets-and-environment-files).
  </Step>

  <Step title="Send both headers from your backend" id="send-both-headers">
    Authenticate the user in your own API, then send the secret and the resolved user ID on every deployment request:

    ```ts theme={null}
    await fetch(`${deploymentUrl}/threads/${threadId}/runs`, {
      method: "POST",
      headers: {
        "x-mda-ingress-secret": mdaIngressSecret,
        "x-mda-user-id": userId,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(runBody),
    });
    ```

    Use the same identifier for `x-mda-user-id` that your own system uses for that user, and keep it stable across sessions. Threads and stored credentials are keyed on this value, so a user who arrives under a new identifier reaches a different set of threads.
  </Step>
</Steps>

<Warning>
  `MDA_INGRESS_SECRET` is a server-side secret. Managed Deep Agents accepts whatever `x-mda-user-id` accompanies a valid secret, so any holder of the secret can act as any user. Keep it on your backend, never in browser code, a mobile app, or a client bundle.
</Warning>

## Test and deploy

Test the project locally with [`mda dev`](/langsmith/javascript/managed-deep-agents-cli#develop-locally), then deploy it with [`mda deploy`](/langsmith/javascript/managed-deep-agents-deploy). Open deployment traces in LangSmith to inspect model calls, tool calls, errors, and latency.

Authentication failures return 401. For the LangSmith API-key default, confirm that clients send `x-api-key`. For Supabase, confirm that clients send `Authorization: Bearer <access_token>`, that `project_ref` / `projectRef` matches your Supabase project, and that callers cannot access another user's threads (403). For backend identity, confirm that your API sends both `x-mda-ingress-secret` and `x-mda-user-id`, that the secret matches `MDA_INGRESS_SECRET` on the deployment, and that one user's identifier cannot reach another user's threads (403).

***

<div className="source-links">
  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to your agent of choice via MCP for real-time answers.
  </Callout>

  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/langsmith/managed-deep-agents-identity.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
