Dosu LogoDosu Logo
Ask
Join our Discord
Arize PhoenixPublic
Arize
DocumentsArize Phoenix
Agent Session Authorization
Agent Session Authorization
Type
Topic
Status
Published
Created
Jul 31, 2026
Updated
Jul 31, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Agent Session Authorization#

Overview#

Agent (chat) sessions use ownership-based access control — not the general trace/session DSL filter — enforced at both the GraphQL and REST layers. The core rule is: non-admin users see only their own sessions; admins see all by default but can opt into viewer-only scoping when needed.


GraphQL Layer#

Permission Class: CanAccessAgentSession#

Defined in src/phoenix/server/api/agent_helpers.py (introduced in PR #14680):

  • Non-admin: access denied if owner_id != viewer_id
  • Admin: unrestricted access (all sessions visible)

All fields on the AgentSession GraphQL type (title, created_at, updated_at, user, first_input, latest_output, messages) are gated by permission_classes=[CanAccessAgentSession]. See src/phoenix/server/api/types/AgentSession.py.

List Query Scoping: get_agent_session_owner_filter()#

Also in agent_helpers.py, get_agent_session_owner_filter() generates the SQL predicate used in list queries:

  • Non-admin: returns WHERE user_id == viewer_id
  • Admin: returns None (no filter — full visibility)

viewerOnly Argument on agentSessions#

After PR #14898 (resolves bug #14897), the agentSessions GraphQL query gained a viewerOnly: Boolean! = false argument :

viewerOnlyAuth enabledResult
false (default)YesAdmins see all; members see own
trueYesAll roles see only their own sessions
eitherNoAll persisted sessions returned

The chat window session picker passes viewerOnly: true; the settings admin table uses the default (false), preserving admin-wide visibility. This prevents other users' sessions from being downloaded into the Relay store when opening the chat panel.

Schema change in app/schema.graphql .


REST Layer#

Routes added in src/phoenix/server/api/routers/agents.py (PR #14711):

EndpointBehavior
GET /agents/{agent_id}/sessionsList persisted (non-temporary, non-expired) sessions. With auth: scoped to user_id == request_user. Without auth: all persisted sessions.
GET /agents/{agent_id}/sessions/{session_id}Fetch single session. Returns 404 if expired or owned by another user.

The helper _get_request_user_id(request) extracts the authenticated user ID or returns None when auth is disabled.


Role Model#

Roles are SYSTEM | ADMIN | MEMBER . The require_admin dependency enforces admin-only endpoints elsewhere in the API (e.g., users and user_api_keys queries) — but agent session routes use ownership scoping instead of a blanket admin gate, since members need to access their own sessions.


Key Files#

FilePurpose
src/phoenix/server/api/agent_helpers.pyCanAccessAgentSession permission class; get_agent_session_owner_filter()
src/phoenix/server/api/types/AgentSession.pyAgentSession GraphQL type with per-field CanAccessAgentSession enforcement
src/phoenix/server/api/queries.pyRoot Query type; agentSessions field with viewerOnly arg
src/phoenix/server/api/routers/agents.pyREST routes for session listing/retrieval with ownership scoping
tests/integration/auth/test_auth.pyIntegration tests: member API key sees only own sessions; 404 on others' sessions

Related PRs & Issues#

  • PR #14680 — Introduced CanAccessAgentSession, get_agent_session_owner_filter(), and the settings admin table
  • PR #14711 — Added REST session routes with ownership scoping and CLI session picker
  • Issue #14897 — Bug: admin session dropdown shows every user's sessions
  • PR #14898 — Fix: viewerOnly: true for chat picker; scopes admin view to own sessions in picker context
Documents
Agent Session Authorization
Agent Session Management
Agent Session Persistence
Agent Session REST API
Agent Session Title Management
Annotation Config Form
Annotation Sorting and Filtering
Annotation System
AsyncExecutor Concurrency Management
Column Reordering
CSS Design Tokens
Custom Provider Validation
Database Migrations
Database Schema Management
Dataset Evaluator
Docker Image Configuration
DSL Filter Autocompletion
Experiment Tracing
GenAI to OpenInference Attribute Mapping
Generative Model Database Constraints
Google SDK Integration
GraphQL Query Performance
LLM Provider Tool Support
MCP Code Mode Sandbox Isolation
MCP OAuth2 Integration
Model Cost Pricing
OAuth2 Authorization Server
OpenInference Semantic Conventions
OpenTelemetry Exporter Configuration
OTLP Attribute Serialization
Phoenix CLI
Playground Span Replay
Prompt Detail Page
Prompt Version Tagging
PXI Approval Flow
PXI Sidebar Modal Interaction
PXI Terminal UI
Reverse Proxy Sub-Path Deployment
Session Filtering
Span Attributes
Token Component
Tool Call Validation
Trace Filter DSL
Trace Tree UI
User Authentication Model