[GH-ISSUE #2420] LangGraph Cloud: @auth.on does not apply metadata.owner on /threads create (history filters fail) #300

Open
opened 2026-02-17 17:19:35 -05:00 by yindo · 0 comments
Owner

Originally created by @farouk09 on GitHub (Jan 31, 2026).
Original GitHub issue: https://github.com/langchain-ai/docs/issues/2420

Summary

When using LangGraph Cloud with custom auth, @auth.authenticate runs but @auth.on is not applied during POST /threads, so metadata.owner is never set. This breaks threads.search filters and conversation history for authenticated users.

Expected

  • Authenticated requests should result in threads with metadata.owner = <user_id>.
  • POST /threads/search with metadata: { owner: <user_id> } should return the user’s threads.

Actual

  • POST /threads succeeds but returns metadata: {}.
  • POST /threads/search with metadata.owner returns 0.
  • Logs show @auth.authenticate receiving the Authorization header; no evidence of metadata injection on thread creation.

Repro (LangGraph Cloud)

  1. Deploy a LangGraph app with custom auth:
from langgraph_sdk import Auth
from langgraph_sdk.auth import is_studio_user

auth = Auth()

@auth.authenticate
async def authenticate(authorization: str | None = None, headers: dict | None = None, body: dict | None = None):
    # validates JWT and returns identity
    return {"identity": "user-id", "is_authenticated": True}

@auth.on
async def enforce_owner_scope(ctx, value: dict):
    if is_studio_user(ctx.user):
        return {}
    metadata = value.setdefault("metadata", {})
    metadata["owner"] = ctx.user.identity
    return {"owner": ctx.user.identity}
  1. Call Cloud API:
curl -X POST https://<deployment>.langgraph.app/threads \
  -H "x-api-key: <LANGSMITH_API_KEY>" \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{}'
  1. Response contains metadata: {}.
  2. Search:
curl -X POST https://<deployment>.langgraph.app/threads/search \
  -H "x-api-key: <LANGSMITH_API_KEY>" \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{"limit":10,"metadata":{"owner":"user-id"}}'

Returns [].

Environment

  • LangGraph Cloud deployment
  • langgraph-api version: 0.7.13
  • langgraph version: 1.0.7

Notes

  • This works in a separate project using Auth0 with the same @auth.on pattern (self-hosted / different setup).
  • In Cloud, @auth.on appears to run for some operations but not for thread creation (no owner metadata).

If @auth.on is not intended to run on thread creation in Cloud, can you clarify the correct way to set thread metadata / owner for per-user history? If it is intended, this looks like a bug.

Originally created by @farouk09 on GitHub (Jan 31, 2026). Original GitHub issue: https://github.com/langchain-ai/docs/issues/2420 ## Summary When using LangGraph Cloud with custom auth, `@auth.authenticate` runs but `@auth.on` is not applied during `POST /threads`, so `metadata.owner` is never set. This breaks `threads.search` filters and conversation history for authenticated users. ## Expected - Authenticated requests should result in threads with `metadata.owner = <user_id>`. - `POST /threads/search` with `metadata: { owner: <user_id> }` should return the user’s threads. ## Actual - `POST /threads` succeeds but returns `metadata: {}`. - `POST /threads/search` with `metadata.owner` returns 0. - Logs show `@auth.authenticate` receiving the Authorization header; no evidence of metadata injection on thread creation. ## Repro (LangGraph Cloud) 1. Deploy a LangGraph app with custom auth: ```python from langgraph_sdk import Auth from langgraph_sdk.auth import is_studio_user auth = Auth() @auth.authenticate async def authenticate(authorization: str | None = None, headers: dict | None = None, body: dict | None = None): # validates JWT and returns identity return {"identity": "user-id", "is_authenticated": True} @auth.on async def enforce_owner_scope(ctx, value: dict): if is_studio_user(ctx.user): return {} metadata = value.setdefault("metadata", {}) metadata["owner"] = ctx.user.identity return {"owner": ctx.user.identity} ``` 2. Call Cloud API: ```bash curl -X POST https://<deployment>.langgraph.app/threads \ -H "x-api-key: <LANGSMITH_API_KEY>" \ -H "Authorization: Bearer <JWT>" \ -H "Content-Type: application/json" \ -d '{}' ``` 3. Response contains `metadata: {}`. 4. Search: ```bash curl -X POST https://<deployment>.langgraph.app/threads/search \ -H "x-api-key: <LANGSMITH_API_KEY>" \ -H "Authorization: Bearer <JWT>" \ -H "Content-Type: application/json" \ -d '{"limit":10,"metadata":{"owner":"user-id"}}' ``` Returns `[]`. ## Environment - LangGraph Cloud deployment - langgraph-api version: 0.7.13 - langgraph version: 1.0.7 ## Notes - This works in a separate project using Auth0 with the same `@auth.on` pattern (self-hosted / different setup). - In Cloud, `@auth.on` appears to run for some operations but not for thread creation (no owner metadata). If `@auth.on` is not intended to run on thread creation in Cloud, can you clarify the correct way to set thread metadata / owner for per-user history? If it *is* intended, this looks like a bug.
yindo added the external label 2026-02-17 17:19:35 -05:00
yindo changed title from LangGraph Cloud: @auth.on does not apply metadata.owner on /threads create (history filters fail) to [GH-ISSUE #2420] LangGraph Cloud: @auth.on does not apply metadata.owner on /threads create (history filters fail) 2026-06-05 17:26:10 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/docs#300