Sessions
A session is a continuous period of AI activity from a single identity — typically one Claude Code or Cursor workspace. Sessions give you a per-task view of cost, tool calls, and governance decisions.
What is a session
Sessions are created automatically when a developer or agent begins sending requests through the proxy. An automatic conversation becomes Inactive after the idle window (session_idle_window_minutes, default 60 minutes; 0 disables this tier). It becomes Expired after session_inactive_expiry_days without activity (default 30 days, configurable from 1 to 3,650 in Settings). The last request determines activity, falling back to creation for a never-used session.
A fresh authenticated request from the same owner reactivates an automatic conversation, including historical expired sessions. Continuation preserves spend, tokens, request counts, limits, and model degradation, and rechecks the concurrent-session limit. Paused, revoked, and pending sessions remain blocked. Explicitly created authorization sessions keep their hard deadline. Known lifecycle or ownership denials reject requests naming that session.
Conversation inactivity is separate from credential and session-scoped exception expiry. Grants end at their original authorization deadline even when the conversation continues. Continuation and the expiry sweep revoke grants transactionally with their configuration audit trail; audit failure rolls back the change for retry. Session deletion retention is a separate setting and begins after the inactivity expiry window for automatic conversations. Final summaries are generated when a conversation expires or is revoked, so the default inactivity window delays finalization until 30 days without activity. Activity-driven and on-demand summaries remain available, including while inactive; entering Inactive does not itself trigger a summary. When an expired conversation resumes, its summary is no longer final: the previous summary stays visible, activity-driven summaries continue, and the next expiry or revocation generates a new final summary that covers the resumed work.
Explicit session creation (including service-account sessions), replacement, and edits to purpose or ticket are also recorded. If audit persistence fails, no new session token is returned, and existing expiry and context values remain unchanged. Replacement commits the new session together with the previous session's 15-minute handoff expiry. The previous session remains usable during that handoff; its grants are cleaned up through the normal expiry lifecycle.
A context edit that conflicts with another edit or session status change fails; reload the session before retrying. Empty purpose or ticket fields retain their existing values. Audit evidence redacts tokens, purposes, tickets, groups, and metadata.
Each session captures:
- The identity (developer email or agent ID) and the tool they were using
- A declared purpose — optionally set by the developer or inferred from the first request
- Total token usage, estimated cost, and model mix for the session
- Every tool call and LLM request made during the session, with governance decisions
How requests are grouped into a session
Some AI tools tell the proxy which conversation a request belongs to; others send nothing at all. AIControls handles both.
- Claude Code, Codex CLI, and the VS Code extension send a session identifier with every request. Their sessions are exact: the boundary is whatever the tool itself considers one conversation.
- Cursor and Gemini CLI send no session identifier. There is nothing in their requests — no header, no conversation ID — that says which conversation a request belongs to. Cursor does include a user ID, but it is the same value for every conversation that person starts.
For tools in the second group, AIControls groups requests itself, using two signals in order:
- Transcript continuity. These APIs are stateless, so every request resends the whole conversation so far. When a request's conversation history matches an open session's history with new messages appended, it is the same conversation. This is the primary signal and it is exact in the common case.
- Activity gap. For requests whose body carries no readable conversation (an embeddings call, an unrecognised request format), consecutive requests from the same identity and tool are grouped while the gap between them stays under the idle window.
A session appears once a second request continues the first. Isolated one-off calls — an inline completion, a code action, a single classification prompt — are not conversations and do not create sessions, so the Sessions page stays a list of actual work rather than a list of requests. Those calls are still fully recorded in the Audit Log with their identity, decision, tokens, and cost.
Sessions grouped this way are marked inferred in the session list, the detail panel, and the full details page. The grouping is accurate enough to make the Context tab, cost attribution, and the governance timeline useful, but it is not something the tool told us, so it is never presented as though it were:
- Two conversations started in quick succession from the same workspace can occasionally be shown as one.
- A conversation whose history the tool rewrites mid-flight (a client-side context compaction) can be split into two sessions.
Inferred sessions are deliberately exempt from the concurrent-session limit and carry no session budget, so a grouping decision can never be the reason a request is blocked or downgraded to a cheaper model.
An agent's sessions, inferred or client-reported, belong to the agent. In Security → Activity, a call the agent makes on its own shows the agent's name and the agent icon, whether or not the call is part of a session, so pinning the agent finds all of those calls. A call that a person delegated to the agent shows that person instead. Agents, Kubernetes or otherwise, are not counted as developers in Adoption, and an agent's own calls are not counted in per-user cost. If an agent's full Kubernetes identity key appears anywhere, it is shortened from the start so the namespace and service account stay visible; hover over it to see the full key.
To switch inference off, set Settings → Data Retention & Session Limits → Session grouping to Client-reported only. Sessions then appear only for tools that send a session identifier. The setting applies to new requests — sessions already recorded keep the boundaries they were recorded with.
Session list
Navigate to Identity → Sessions to see all sessions, filterable by developer, status (active, ended, expired, budget exceeded, paused), and purpose. An admin can pause or resume an active session from the list without affecting the developer's connection. The page subtitle shows how many sessions are active, and the list refreshes every 10 seconds.
The User column shows the developer, with their team and the AI client the session came through beneath the email — Claude Code, OpenAI Codex, or, for a Cross-App Access session, the governed agent's name. The client is derived from the session's own recorded requests, so it also appears on sessions recorded before it was displayed.
Select Has subagents above the list to show only sessions that ran at least one subagent. The Subagents column shows how many subagents the session ran, and is empty for a session with none. Hover over the count to see each subagent's type and description, up to the first ten. It is computed from the subagent registry, not from the session's audit events, so it stays fast on a large list, and it does not affect the list's server-side sorting or paging. You can hide the column from the column picker.
Session detail
Select a session in the list to open its details in a panel that covers half of the window, so the list stays visible beside it. On windows narrower than 900 pixels, the panel fills the window. Select Open full details ↗ in the panel header for the full details page.
The panel header shows the user, the session status, and the session intent, with a close button. A second row has the navigation controls, Open full details ↗, and Audit events →, which lists the audit events recorded for the session, including blocked calls. A call blocked before the session was admitted (for example, by quarantine or an identity check) carries only the client session ID and is still listed; a call already assigned to a different session is not.
The panel has three tabs:
- Overview — the budget bar, the amount spent, the number of requests, Start (when the session was first created), Last turn (the time of its most recent activity), the expiry, the models used, and tags such as the ticket and groups.
- Activity — a chronological list of every tool call and LLM request in the session. Each row shows its risk classification (safe or risky command) and its policy decision. Select a row to open its full audit event detail.
- Security — the security findings for the session.
At the bottom of the panel, admins can extend the session budget, resume a paused session, or revoke the session. The panel and the full details page both show these actions.
Historical and Desktop sessions open in the same half-width panel. They don't have a full details page, because the Historical and Desktop sessions come from a different data source and have their own tabs.
Move between sessions
Use the arrow buttons in the panel header, or the keyboard, to move to the previous or next session without closing the panel. The counter shows your position, for example 3 / 40.
| Key | Action |
|---|---|
| ← | Open the previous session |
| → | Open the next session |
| Shift+← | Open the previous session for the same user |
| Shift+→ | Open the next session for the same user |
The shortcuts don't run while your cursor is in a text field.
By default, the arrow keys follow the order of the Sessions list, including the sort and filters you chose, and move across pages. To review one person's work, select the user name in the All | user toggle in the panel header. The arrow keys and the counter then step through that user's sessions, newest first, and your filters on the Sessions list don't change. Shift+← and Shift+→ always move through the same user's sessions, whichever option you selected. Shift+← moves to a newer session, and Shift+→ moves to an older session, matching the order of the list. The same-user list covers the user's 1,000 most recent sessions. If the open session is older, the user option is unavailable and shows a tooltip.
Share a link to a session
While the panel is open, the page URL contains the session, for example /sessions?session=<id>. Copy the URL to share the session with a teammate, or to bookmark it. The URL also records the selected tab, for example &tab=security.
Opening a session adds an entry to your browser history, so Back closes the panel. Moving to another session with the arrow keys replaces the entry instead, so one Back still returns you to the list. Historical and Desktop sessions use ?historical=<id> and ?desktop=<id> in the same way. If you open the panel from a shared link, Close removes the session from the URL and keeps you on the page. A link with an empty or unknown session ID shows Session not found and opens the list without a panel.
A link to a session on a tab that only the full details page has, such as ?session=<id>&tab=replay, opens the full details page on that tab.
Full details page
Open full details ↗ opens the full details page for the session at /sessions/<id>. It's a normal link, so you can Cmd-click (or Ctrl-click) it to open the page in a new browser tab. In an Audit Log event's detail view, the view → link in the Session row opens this page directly, and replay → opens it on the Replay tab. The page uses the full width of the window and has a Sessions link back to the list. It shows everything in the panel and adds the following:
-
Insights — the Summary, an AI-generated description of what the session accomplished, which tools were used, and key outcomes. When AIControls captured the prompt of a denied LLM request, the summarizer also sees up to its first 300 characters, with personal data such as email addresses redacted and quoted as untrusted data, so it can describe what the developer was trying to do. The redaction applies even when audit-log PII redaction is turned off. The summary prompt quotes the stated purpose, ticket, detected intent, tool names, resource paths, and blocked prompts as untrusted data, and instructs the model to ignore instructions in them and to report blocked calls from the policy decisions
-
Cost breakdown — input tokens, output tokens, cache hits, and estimated cost by model
-
Governance timeline — every allow, deny, warn, and approval decision in chronological order
-
Tool calls — the full list of MCP tool calls with arguments and outcomes
-
Activity details — on the Activity tab, summary cards for websites visited, documents read, data queries run, claude.ai artifacts touched, and skills invoked. Claude Code's known built-in tools (an explicit list that includes, for example,
Artifact,ArtifactData,SendMessage,Agent,Workflow, andStructuredOutput) are tracked like any other tool call and labelled Built-in tool rather than MCP; their details appear on the row: the artifact URL and action, the Agent or Workflow description and subagent type, and theSendMessagerecipient. The Artifacts card lists each distinct claude.ai artifact URL with the number of calls that touched it, and appears only when the session used the artifact tools. Any other name that is neither a known built-in nor an MCP server tool, including an unlisted PascalCase name, is marked Unknown with a review prompt (also listed under Unrecognized Tools in the session's Security tab); this means the name should be checked, not that the session was attacked. The warning links to the cross-session Unrecognized tools view. Theaicontrols_unknown_tool_totalPrometheus counter counts the unknown calls the gateway parses from LLM responses (not unknown calls through the MCP proxy) by client kind (claude_codeorother), with no tool-name label. The Built-in tool label is applied to calls recorded after this recognition shipped, from a Claude Code client (identified by its session header andclaude-cliUser-Agent). Calls recorded earlier cannot be attributed reliably to Claude Code, so they keep their original classification in older sessions. -
Activity graph — on the Activity tab, a Graph toggle switches the list to a visual, single-hop trace: delegator (human, if any) → agent → each tool (or, for MCP calls, each MCP server) the agent called → the resource it reached, colored by decision (allowed, denied, pending). Calls in the graph are grouped by tool or server identity rather than listed one row per call — a group with more than one distinct call shows a count and expands to reveal the individual calls and the resource each one reached; denied calls show as blocked before the resource node, since they never reached it. Both views trace one identity through one agent only — neither shows agent-to-agent delegation chains.
-
Subagent grouping — on the Activity tab, calls a subagent made appear in a collapsible group under the row that launched it (Claude Code's Agent or Workflow, Codex's
spawn_agent), labelled with the subagent's type and description and the number of calls. The group holds the subagent's own LLM requests and tool calls, newest first; nested subagents nest. In the Graph view the subagent is a child row of the Agent row, with its calls totalled, instead of a row of its own. Paging counts top-level rows, so a group is never split across pages. A subagent whose launching call is unknown, and every event recorded before this feature, stays in the flat list, with a Subagent tag when the request is known to come from a subagent. See Subagent attribution. -
Agents — for a session that ran subagents, the Overview tab lists the main agent and each subagent with its calls, duration, cost, and status (Denied or Pending when any of its calls were). Select a row to open Activity for that agent.
-
Agent filter — on the Activity tab of a session with subagents, the Agent list shows all agents, only the main agent, or one subagent together with the subagents it launched. Each subagent's rows are tagged with its type and description.
-
Which agent — in a session with subagents, a Replay step, an attack-pattern evidence step on the Security tab, and an unrecognized tool are tagged with the subagent that made the call. Content Safety findings are not tagged, because they don't record the call they came from.
-
Cost by agent — the Insights tab of a session with subagents has a Cost by agent table: LLM calls, input tokens, cache-read tokens (counted apart from input), output tokens, and cost for the main agent and each subagent, with each one's share of the session's cost.
-
Replay — a forensic-reconstruction timeline of the session, grouped into Steps (one model turn plus the tool calls it triggered) and Phases (windows of related Steps, e.g. "Explore the codebase" or "Run the test suite"). A transport bar steps through the session turn by turn or plays it back at up to 64×, a brushable overview strip shows event density and context-pressure over time, and a detail panel breaks down the arguments, policy trace, and latency for whatever's selected. See Session Replay. Only available once a session has ended — Replay reconstructs Steps and Phases from the session's complete event set, so an in-progress session (whose event set is still growing) doesn't yet have this tab
-
Context — context-window fill, a token breakdown by segment (system prompt, user messages, assistant turns, tool results, tool definitions), and per-turn growth. Available for every provider, including Bedrock, Vertex, and Foundry. A turn appears here once the provider has reported its token usage; Bedrock's streaming response format and Claude-on-Vertex's streaming endpoint do not report usage, so those turns are still audited and still counted toward the session, but they contribute no per-turn context row
-
Optimization — the session cost, token counts, cache savings, and recommendations for lowering cost.
The Overview tab on the full details page shows Start, Last turn, the expiry, and the other session facts as a full list. Until you pick a sort, the Live tab lists sessions by Last turn, most recent activity first, so a session that started days ago but ran a turn a few minutes ago appears near the top.
On Home → Sessions, click the Purpose, Usage / Cost, Status, Start, Last turn or Turns / Requests column header on the Live tab to sort. Sorting applies across all sessions that match your filters, not just the page you are viewing, and the chosen sort is kept in the page URL so it survives a reload or the Back button. Clicking a header cycles through ascending, descending and no sort; clearing the sort returns to Last turn, most recent first. The Last turn header starts on descending, so its first click switches to ascending. In the grouped-by-user view the headers do not sort; switch to the flat list to sort. The Historical tab loads all of its rows and sorts in the browser. The Desktop tab is paginated by the server (20 rows per page by default, up to 200) and always lists the most recently active session first; its column headers do not sort.
For Claude Code observer events, a child's model is attributed independently from its parent and siblings. Model-less child events remain unknown unless the observer has explicit evidence for that child. When content collection is enabled, a child's stop event can report the model from its own transcript. The parent transcript and the observer's default model are never used as child model evidence.
Subagent attribution
When an agent client runs subagents, the gateway attributes each subagent request to its own agent ID and to the call that launched it, so the session shows what the subagents did instead of folding it into the parent's activity.
Attribution works in two steps. First, a subagent's own LLM requests carry its agent ID in request headers; AIControls stores the Agent ID, Parent agent ID (for nested subagents), and Agent type on the LLM request and on every tool call recorded from it. Requests from the main agent carry none of these headers and show no extra fields. Second, the launching call is linked from the parent's next request, which reports the subagent back; AIControls records the link in a small per-client subagent registry, scoped to the client's own session, so an ID never links across sessions. Header values are validated (short, plain characters, nothing shaped like a credential) and anything invalid is dropped. The headers are read for attribution only and are never logged. Attribution is reported by the client and is not independently verified, so treat it as a grouping aid rather than proof of which agent acted. A gateway MCP call made by a subagent is grouped with it when it shares a tool call ID with the subagent's recorded tool use.
The audit event detail for a subagent's LLM request, and for its tool calls, shows Agent ID, Parent agent ID, and Agent type when they are set. For Codex, Agent ID is the sub-agent's task path. Opened from the Activity tab, the detail for a gateway MCP call grouped this way shows the same fields as its row.
Supported clients:
| Client | Subagent attribution |
|---|---|
Claude Code (2.1.x and later, which send the x-claude-code-agent-id headers) | Supported. The launching call is linked from the Agent tool result or, for a background agent, from its completion notification. A subagent of a built-in agent type that returns no agent ID is not linked, and stays in the flat list. Subagents started by the Workflow tool are grouped only when their completion notification names them. |
| OpenAI Codex (with multi-agent on, the default in recent versions) | Supported. A sub-agent is identified by its task path, such as /root/counter; a nested sub-agent's parent is the path above it. The launching call is linked from the spawn_agent result, which names that path. Codex sends the attribution in its x-codex-turn-metadata and x-openai-subagent headers. |
| GitHub Copilot | Tagged, not grouped. Copilot marks a sub-agent's requests (x-interaction-type: conversation-subagent) but sends no agent ID and no link to the call that started it, so all of a session's Copilot sub-agent calls are tagged Copilot subagent and stay in the flat list. Parallel sub-agents can't be told apart. |
Requests that reach the gateway through the Bedrock or Vertex pass-through routes record the agent fields but are not linked to a launching call. Subagent attribution applies to requests recorded after it shipped. Registry rows are removed with the audit retention window.
Concurrent sessions
Settings → General → Data Retention & Session Limits → Max concurrent sessions per user supports whole numbers from 1 to 10,000, inclusive. The default remains 10; existing configured limits stay unchanged when you save other settings. An existing limit above 10,000 remains in effect until you explicitly replace it with a value in the supported range. The settings API also accepts 0 to use the configured fallback limit, or 10 when no fallback is configured, and rejects values above 10,000 before saving any fields in the request. The UI shows the effective limit, including Unlimited for an inherited unlimited limit, without replacing the stored value when you save other settings. Inferred sessions remain exempt from this limit.
Timing of session checks. The limit is enforced when a session is created or resumed, under a per-user lock in the database, so concurrent requests can never open more sessions than the limit. A request that names a session the same user used within the last 30 seconds, that is active and not past its hard deadline, is admitted without taking that lock, because it does not add a session. A pause or revoke committed in the instant between a request reading the session and being admitted takes effect from the next request. The session count that policies see as object.session.activeConcurrentSessions is cached for 3 seconds on each AIControls replica, so it can lag a newly opened session by up to 3 seconds. The aicontrols_session_continuation_skips_total, aicontrols_session_continuation_locks_total, aicontrols_session_active_count_cache_hits_total, and aicontrols_session_active_count_cache_misses_total Prometheus counters show how often each shortcut applied.
A developer can have more than one session running at the same time — one agent per workspace, or an orchestrator driving several sub-agents. Productivity → Usage (/ui/usage) measures that overlap per developer over the window chosen with the time range selector in the page header and reports it in the Concurrent column, both in the Users view and in the per-team drawer that opens when you click a row in the Teams view. Usage opens on the Projects view — switch views with the selector above the table. In the Users view, the Concurrent column is hidden by default along with a few other secondary columns; click the gear icon above the table to show it. The Users view loads one page of users at a time, newest activity first, and the search box filters across all users rather than only the page on screen. Click a column header (User, Sessions, Active days, Cost, Requests, Tokens, or Last Seen) to sort all users, not only the page on screen. Usage columns sort by activity in the selected window, largest first. Requests counts the LLM requests each user sent through the proxy in the window, including requests to models with no price. It leaves out denied requests, requests waiting for approval or confirmation, and cache hits, and it counts a request that fails over between pool upstreams once. Users with no activity in the selected window still appear, with zero metrics and no Last Seen time.
- Peak — the largest number of that developer's sessions running at the same moment. This is the number shown in the column.
- Multi-session share — the percentage of the developer's active time with two or more sessions running at once. Active time is the time at least one session was running, not the whole window, so someone who works in short bursts isn't penalised against someone logged in all day.
- Average — the mean number of simultaneous sessions across that same active time, weighted by how long each level of overlap lasted. It is an average over active time, not over the window.
Hover a value to see the average and multi-session share behind the peak. In the Teams view, rows are ordered by peak, and by multi-session share when peaks tie; the Users view lists users by most recent activity. A developer whose sessions never overlapped shows — rather than 1 — there was no concurrency to report, not missing data.
Three scoping rules shape the numbers:
- Only sessions started inside the selected window are counted. A session that was already running when the window opened is left out entirely, so a short window understates overlap — widen it if a developer's peak looks lower than you expect.
- Overlap runs from a session's start to its Last turn, and never past the end of the window. A session that records no activity at all after it is created counts for a bounded period after its start rather than all the way to its hard expiry, so an abandoned session can't inflate a developer's concurrency for hours.
- A session that was created, recorded no activity, and is already closed contributes nothing. This is why a developer can show a Sessions count with no concurrency at all — the sessions existed, but none of them ran long enough to overlap.
Session budgets
Sessions inherit the default session cap set in Settings → Budgets → Limits. When a session hits its cap, further requests are blocked until the session ends or an admin resets the budget from the session detail panel.
The cap is read from the session a request belongs to, not from the credential, so it applies the same way to every sign-in method: a session token, a portal aic_ personal access token, and a provider credential used in passthrough with the personal access token in X-AIControls-Token. Each client-reported session has its own counters. Two sessions that use the same personal access token are tracked, and capped, independently, and a new session ID starts with no spend. The same applies to a session's token limit and request limit, where one is set on the session.
The default is copied onto a session when the session is created. Changing Default session cap affects sessions created afterwards; sessions that already exist keep the cap they were created with until an admin extends their budget or applies the changed default to existing sessions. A cap of 0 means no limit. The default shown in Limits is the value new sessions receive: the saved setting when it is a number of 0 or more, otherwise the configured developerSessions.defaultSessionBudgetUSD. Inferred sessions carry no cap. Raising a session's budget with Extend Budget lets it continue as soon as the new cap is above its recorded spend, without resetting that spend or changing any other session. This is separate from extending a session's expiry, which does not change its dollar cap.
The check compares a session's recorded spend with its cap before each request is forwarded, so requests already in flight when the cap is reached can still finish and push spend past the cap. Spend and request counts are recorded after each request completes and capacity is not reserved in advance, so parallel requests can overshoot a cap by more than one request.
Admins can raise any session's cap from the detail panel or the full details page.
Apply a changed default to existing sessions
After you save a changed Default session cap, an admin can apply it to sessions that already exist. The same action is available later from Apply to existing sessions… on Cost → Budgets → Limits, where you pick the old cap from the caps existing sessions currently have.
Applying changes only the recorded cap of each matching session. Spend, request counters, extensions, status and expiry are never touched. The change is one update in one transaction, so either every matching session changes or none does, and the audit entry is committed with it.
Which sessions change depends on three choices:
- Active sessions are sessions that can still make requests: every status except expired and revoked (active, degraded, paused, awaiting approval and inactive). The new cap is enforced on them immediately. This is on by default.
- Ended sessions are expired and revoked sessions. They are not the sessions with status Inactive (idle), which count as active here. Only their recorded cap changes, which affects reports and the audit trail; nothing is enforced on them while they stay ended. An expired session that is later continued is checked against its recorded cap from then on. This is off by default.
- Include sessions with a custom or extended cap is off by default. Off, only sessions whose cap is still the old default change, and a session whose cap was changed, for example with Extend Budget, is skipped. A session that only had its expiry extended still has the old default and changes. On, every session in the selected statuses ends up at the new cap.
You can raise or lower the cap, and 0 means unlimited. The dialog previews how many sessions would change and uses the same selection as the update. Raising or removing the cap also shows how many blocked sessions would be unblocked. Lowering, or any apply that would block sessions, shows how many active sessions already have spend at or above the new cap and would be blocked immediately, lists the highest-spending ones, and asks you to type the new value before it can be applied. These counts cover sessions with status active; a degraded session continues on its fallback model and a paused session stays paused whatever its cap.
Sessions whose boundary AIControls inferred carry no cap by design and are never changed.
Applying is safe to repeat: once a session has the new cap it no longer matches, so a second run, or a run from another replica at the same time, changes nothing. A run that changes no session records no audit entry. Otherwise the configuration audit records a sessions.cap_applied entry with the actor, the old and new cap, the selected scope, and how many active and ended sessions changed. Only admins can apply a cap; see the Session cap API.
Session extensions and revocation
An approved session-extension request adds the requested hours to the session's current expiry. Requests must specify a whole number from 1 to 8,784 hours (366 days); an empty value defaults to one hour. Approval rejects malformed or out-of-range values without changing the request or the session. Retrying an approved request does not extend the session again. Only active or degraded sessions can be extended; a session paused before the extension is saved must be resumed first.
When you revoke a session, its audit event records your authenticated identity, authentication method, request ID, user agent, and source IP. Administrator revocations, resumes, and approved extensions retain the administrator's request attribution too. Behind a trusted proxy, the source IP comes from the verified forwarding information; otherwise, it is the connection's peer address. The event does not include your bearer token.
Ending your current session with DELETE /api/v1/sessions/me shortens its expiry to at most 90 seconds from the request, allowing in-flight calls to finish. The expiry change and its attributed audit event are saved together; if the audit write fails, the request fails and the expiry stays unchanged. Repeated end requests do not prolong the grace period.
Adoption dashboard
The Adoption dashboard is built from the same session data described above: it reports how many provisioned developers are actively using AI tooling, with anonymous agents and service accounts counted separately from human developers. See Adoption Analytics for how Active Users, adoption rate, new adopters, and churn are defined (kept here as a single source of truth so the two pages can't drift).
Attack-pattern evidence access
In a session’s Security tab, expand Evidence details to inspect the retained request, response, and classification signals. Builder views show this evidence inline and explain that full audit events require portal access. Admin and viewer portal sessions also provide a View audit event link.
Replay access auditing
Opening Replay is recorded in the administrative audit trail with the viewer and target session. These access records, including historical records, do not count as agent execution, advance session activity, or participate in attack-pattern detection. Replay, Activity, and Security correlate execution through the session owner and supported Claude Code aliases; a request already assigned to a different session is not moved.
Setting the lifecycle idle window to 0 disables the Inactive tier; the inactivity-expiry deadline still applies. Automatic session inference keeps a bounded 60-minute correlation window in this case, so unrelated requests are not grouped forever. Explicit client session IDs continue to identify their conversation independently of that inference window.