tmux agent session ownership: approvals and audits
tmux agent session ownership can blur approvals and audit trails. Learn how process identity, detached sessions, screen, and incident evidence fit together.

Terminal multiplexers solve a real operational problem: they keep work alive through dropped SSH connections, laptop sleep, and a terminal window closed by mistake. That same persistence can blur who owns an AI agent, whether its approval still applies, and which process actually sent an authenticated request.
The mistake is treating a tmux window as a security session. It is not. tmux is a process manager for terminal sessions. Its server can outlive the terminal client, and its panes can outlive the person who created them. GNU screen has the same basic property. If your approval model, incident notes, or audit process uses the words "the tmux session" as if they identify a single actor and a single agent run, you have already made an investigation harder than it needs to be.
This matters most when an agent can reach APIs or SSH hosts through a human-controlled gateway. A person may start an agent in a pane, detach, hand a session name to a colleague, reattach from another machine, and later start a second agent in the same pane. Each event feels continuous to the operator. They are separate facts in the process table.
A tmux session is not an agent run
A tmux session is a named collection of windows and panes held by a long-running tmux server. An agent run is one process and the children it creates, bounded by process start and exit. Those are different objects, and collapsing them produces approval scopes that are either too broad or impossible to explain later.
When you run tmux new-session -s build, tmux starts or contacts a server. The server creates a pseudo-terminal for the initial pane and launches a shell. When that shell launches an agent, the agent becomes a descendant of the shell. Detaching removes the client connection to tmux. It does not normally terminate the server, shell, or agent.
A common timeline looks harmless:
- Maya starts
tmux new -s releaseand launches an agent in pane 0. - Maya detaches for a meeting while the agent continues to work.
- Her colleague attaches to
releaselater, reads the pane output, and launches a follow-up command. - That evening, Maya reuses pane 0 for a different agent process.
The session name stayed release. The security-relevant entities did not. There were at least two agent processes, two human interactions, and potentially separate authorization events. The terminal history cannot turn that into one coherent identity.
GNU screen behaves similarly. A detached screen server owns terminal windows and child processes. The exact commands differ, but the security conclusion does not: attachment state describes access to a terminal multiplexer, not ownership of every process inside it.
The tmux manual describes a client-server model and states that the server manages sessions, windows, and panes. That wording is more than implementation trivia. It tells you where continuity lives: in the server, not in the terminal application a person happens to see. Build authorization around the process that requests an action, not around the multiplexer container that happens to hold it.
Process ancestry answers questions pane names cannot
A process tree can show how an agent started and which shell and tmux server parented it. A pane title can only show a label that someone may have changed, copied, or left stale.
On macOS or Linux, start an investigation with a narrow process view while the process is still alive:
ps -axo pid,ppid,lstart,tty,stat,command | grep -E '[t]mux|[s]creen|[a]gent'
The output shape matters more than the exact command names:
8421 1 Tue Mar 12 09:14:03 2025 ?? Ss tmux new-session -s release
8430 8421 Tue Mar 12 09:14:04 2025 ttys002 S -zsh
9917 8430 Tue Mar 12 10:02:51 2025 ttys002 S+ agent-tool run deploy check
PID 9917 is the candidate agent process. PID 8430 is the shell that launched it. PID 8421 is the tmux server. The tty value can help connect a process to a pane while it exists, but do not use it as an enduring identity. Pseudo-terminal assignments can disappear when a process exits and can look different after terminal recreation.
On macOS, pstree is not installed by default. This command gives a usable parent-child view without adding software:
ps -axo pid,ppid,user,lstart,command | sort -n
For a particular PID, inspect its parent repeatedly until you reach the tmux server or a launch service:
ps -p 9917 -o pid=,ppid=,user=,lstart=,tty=,command=
ps -p 8430 -o pid=,ppid=,user=,lstart=,tty=,command=
Record the values before killing anything. An operator who runs tmux kill-session first may erase the most useful live evidence: command lines, parent relationships, and start times. Killing a session may still be the right containment action, but collect a short snapshot first when the situation permits.
Process ancestry has limits. A process can daemonize, fork, or deliberately reparent itself. An agent may also ask an external helper to do work, producing a child tree that stops at the helper. Treat ancestry as evidence of launch context, not proof of a human's intent. You still need action records that identify the requesting process and the authorization that allowed it.
Approval must follow the agent process, not the attached terminal
Per-session authorization should apply to one agent process run and end when that process exits. Attachment, detachment, pane focus, and terminal emulator restarts should not grant, renew, or silently transfer that approval.
Sallyport's per-session authorization follows this principle: the first call from a new agent process asks for approval, identifies the process through its code-signing authority, and keeps that approval only for that process run. The approval does not become a property of a tmux session name or a shell prompt.
That boundary fixes several confusing cases. If a person detaches and later reattaches while the same agent process continues, the process has not changed. Its existing session authorization can remain meaningful, subject to the vault gate and any credential that requires approval for every call. If the agent exits, a shell in the pane launches a new agent, and the pane looks unchanged, the new process must receive a new approval decision.
Do not try to make tmux attachment the approval event. The idea is popular because a human action, tmux attach, feels like a useful signal. It is the wrong signal for credential use. An attachment may happen after the agent began, may come from a different person using the same local account, or may occur only to inspect output. More importantly, a process can keep acting while no tmux client is attached at all.
The opposite error also shows up in teams: treating every command typed into an attached pane as human-supervised. A person can attach, walk away, and leave an agent working. A visible terminal is not a presence check.
For sensitive credentials, approval on every use has a different purpose. It does not establish who owns the process. It requires a human decision at the moment a particular credential action is requested. Keep those ideas separate:
- The vault gate decides whether any action can proceed while secrets remain protected.
- Per-process authorization decides whether this agent run may make calls.
- Per-credential approval decides whether a particular credential use needs a fresh human decision.
These controls answer different questions. A team that uses only one broad approval for a long-lived terminal session has chosen convenience over a defensible boundary.
A reused pane can carry approval confusion across runs
The failure usually begins with a persistent "work" session that has become a shared drawer for unfinished commands. Someone starts an agent, detaches, comes back hours later, stops it, then launches another agent in the same shell. The pane still contains the earlier transcript, environment variables, and prompt. People infer continuity that the operating system does not have.
Consider an incident where an API receives a destructive request at 16:43. The activity record identifies an agent process. The team opens tmux and finds a pane named prod-fix with output beginning at 09:00. They assume the engineer who created prod-fix approved the request. That conclusion may be false in several ways:
- The original agent may have exited at 10:15, and another process may have started at 16:40.
- A second engineer may have attached and issued the new launch command.
- The pane title may have been inherited from an earlier task.
- A shell startup file may have exported credentials or a target environment that no longer matches the current work.
- The process could have started outside tmux and written output into the pane through another mechanism.
The correct question is narrower: which executable process requested the action at 16:43, who approved that process, and what code-signing authority did the approval interface display? Then ask how that process entered the machine's process tree.
Do not overcorrect by banning tmux. A fresh, narrowly named session can improve incident work because it gives operators a visible workspace and keeps a record of output during an unstable connection. The risk comes from reusing a general-purpose session as the container for unrelated agent runs.
Use names that encode a purpose and a short-lived run identifier, such as deploy-4812 rather than work or main. The name is a human aid, not an authorization input. Retire the session when the run ends.
Detached work needs ownership and an expiry decision
A detached tmux or screen session can run safely only when somebody has explicitly accepted that it will continue without a terminal attached. "I thought it stopped" is not an ownership model.
Before detaching an agent that can take authenticated actions, write down four facts in the ticket, incident note, or handoff record: the agent process PID, the tmux session name, the stated task, and the person responsible for stopping it. Add a time at which someone must review whether it should continue. This is mundane work, and it prevents more trouble than elaborate pane naming schemes.
A useful launch pattern creates a new socket namespace for a run instead of adding another window to a durable personal server:
tmux -L agent-4812 new-session -d -s agent-4812 \
'exec agent-tool run "verify deployment 4812"'
tmux -L agent-4812 display-message -p \
'#{session_name} #{session_created} #{pane_pid} #{pane_tty}'
The first command launches a detached session. exec matters because it replaces the shell process with the agent command, making the pane PID a more direct starting point for investigation. Without exec, the pane initially belongs to a shell that later creates the agent as a child. That is still manageable, but it adds one more layer to inspect.
The second command prints metadata with an output shape like this:
agent-4812 1731000000 9917 /dev/ttys002
Save that output where the task is tracked. The process can later fork children or exit, so it is not a complete audit record. It gives responders an early anchor when they need to compare process data with action logs.
When the task ends, terminate the named socket deliberately:
tmux -L agent-4812 kill-session -t agent-4812
Then verify that the expected agent PID has exited. Do not assume kill-session cleaned up every descendant. Programs that create their own sessions or background helpers can survive their original pseudo-terminal. Inspect the process list again, and use the action gateway to revoke the active agent run if its records show it remains authorized.
Screen has the same identity trap with fewer clues
GNU screen creates a detached session that can be resumed later, and its familiar numeric session identifiers can look more precise than they are. They identify a screen server instance, not a specific agent process or a human approval.
The GNU screen manual documents detached sessions and commands such as screen -ls and screen -r. Those commands answer whether a screen server is available for attachment. They do not answer whether the process inside a window is the same one that ran earlier, or whether the current operator is the person who made an earlier authorization decision.
Start with these checks when screen enters an incident:
screen -ls
ps -axo pid,ppid,lstart,tty,stat,command | grep -E '[s]creen|[a]gent'
A result like 12345.build (Detached) identifies a screen session worth examining. Match it with process start times and terminals before you attach. Attaching can alter what a user sees, trigger shell hooks, or prompt an interactive program to continue. In a sensitive incident, preserve evidence first and let the designated responder decide whether interaction is necessary.
screen's multiuser mode deserves extra caution. It can grant other local users access to a shared terminal session. That may be appropriate on a controlled machine, but it weakens any casual claim that "the person who attached" owns the processes. Authorization should still identify the requesting agent process and require a decision from the local human who controls the credential gateway.
Audit records need a join point outside tmux
A defensible investigation joins three records: the operating-system process record, the authorization record, and the individual action record. tmux or screen output can supplement that evidence, but it cannot replace any of it.
For every credential action under review, establish this sequence:
- Identify the action's timestamp, destination, method, and outcome in the activity record.
- Identify the agent run that requested it and the authorization decision associated with that run.
- Compare the run's process details and start time with the live or captured process tree.
- Use tmux or screen session metadata only to reconstruct the operator's workspace and handoffs.
- Verify that the audit record has not changed since capture.
The distinction between an action journal and terminal scrollback is sharp. Scrollback can omit output, rotate away, contain pasted text from another process, or be altered by a user with access to the session. An action journal should state the attempted operation and result. If it is tamper evident, investigators can check whether the record set has remained intact without trusting the terminal that displayed it.
Sallyport records agent runs and individual calls from a hash-chained encrypted audit log, and sp audit verify can verify that chain offline without a vault key. That verification proves integrity of the recorded sequence, not that a tmux title correctly identifies the human who typed a command. Keep those claims separate in incident reports.
A useful incident note avoids prose such as "the release tmux session did it." Write: "At 16:43, agent run [identifier] requested [action]. The request came from process [identifier] started at [time]. The process was a descendant of [shell or service] associated with tmux server [PID] at capture time. [Person] approved the run after the displayed process authority was reviewed." Fill only facts you can support.
That wording also exposes gaps. If nobody captured the parent chain before containment, say so. If the system does not retain the needed process identity, do not fill the gap with a pane name.
Code-signing identity and local-account identity solve different problems
A local macOS account identifies an operating-system user. Code-signing authority identifies who signed an executable. A tmux session identifies a terminal server. None of these identifiers means the same thing, and each catches a different failure.
Local account identity helps answer which account owned the process. It does not tell you whether a binary came from the expected publisher or whether another person used an unlocked account. Code-signing authority helps a person recognize the executable that is requesting access. It does not tell you whether the process was launched in the right tmux pane or whether the task itself was appropriate.
This is why an approval card that leads with code-signing authority is useful when a new agent process asks to act. It gives the approver a stable signal that survives renamed panes, copied tmux configuration, and a terminal emulator restart. It also makes unexpected unsigned or differently signed executables visible at the moment that matters.
Do not reduce this to a blind "same signer equals safe" rule. A trusted signer can ship a bad version, a local wrapper can invoke an approved binary in an unsafe context, and a signed process can receive dangerous instructions. Process identity narrows the approval target. Per-call approval for selected credentials and a complete action trail handle risks that identity alone cannot.
For macOS investigations, you can inspect a binary's signing information with codesign:
codesign -dv --verbose=4 "$(command -v agent-tool)" 2>&1 | \
grep -E 'Identifier=|TeamIdentifier=|Authority='
The output normally includes lines such as Identifier=, TeamIdentifier=, and one or more Authority= entries. Capture it when you need to explain why an approval interface recognized a process. Do not substitute a path like /usr/local/bin/agent-tool for signer evidence. Paths are easy to shadow, replace, and symlink.
Stop using permanent shared sessions for privileged agent work
A permanent tmux server called dev, main, or shared is a bad place to run agents that can reach production credentials. It makes active work easy, but it mixes people, tasks, shell history, environment state, and process lifetimes until nobody can say where one run ended.
Keep personal interactive multiplexing separate from agent execution. Give each agent run its own session or socket. Launch it from a recorded command, capture its PID and start time, and assign an owner before it detaches. If another engineer needs to continue the task, they should start a new agent process and receive a new authorization decision rather than inheriting an old pane by convention.
Teams often resist this because session reuse feels efficient. It is efficient until an agent sends a request after the original task ended and the response team spends an hour reading scrollback. Fresh process boundaries cost seconds. Reconstructing a blurred boundary costs much longer and often ends in an assumption instead of an answer.
The first operational change is simple: forbid unnamed long-lived tmux and screen sessions for agents with authenticated access. Create a short-lived session per run, record the launch identity, and close it when the run ends. That policy gives approval systems and investigators an actual boundary to work with.
FAQ
Does tmux keep an AI agent running after I close my terminal?
A tmux session is a server process that owns pseudo-terminals, windows, and panes. It can keep a shell or agent process alive after the terminal emulator disconnects, so the visible terminal window is not a reliable record of who owns the running work.
Can I identify an agent owner from a tmux pane name?
No. A tmux pane tells you where a process has a terminal, not which human approved its authority. Investigators need the agent PID, its parent process, its start time, the credential action record, and the approval record to make that connection.
Are detached tmux sessions safe for autonomous coding agents?
A detached session is not automatically unsafe, but it needs an explicit owner, a purpose, and an expiry rule. Treat an unnamed session that survives its operator as work that needs review, especially if it can still make authenticated calls.
Should session approval survive tmux detach and reattach?
The practical scope should be one agent process run, ending when that process exits. Tmux attachment and detachment must not renew approval, and a new agent launched in an old pane should require its own authorization.
Why are long-lived screen sessions a security concern?
It can, because the server and its child processes may remain alive while no user has a terminal attached. A stale process is easy to miss when people reuse a session name or assume that closing a laptop ended the run.
How do I investigate an action made from tmux?
Start with ps to record PID, PPID, start time, terminal, and command line. Then capture tmux pane metadata and match it to action logs by time, process identity, and the agent run identifier rather than relying on the pane title.
Is tmux the same as SSH connection multiplexing?
No. SSH multiplexing reuses an SSH connection, while tmux multiplexes terminals and child processes. They create different evidence and failure modes, although both can make a later action look disconnected from the person who started it.
What is the right way to stop a suspicious tmux session?
tmux kill-session -t name asks the server to terminate the session and its panes, but confirm what is running first. A process may have escaped the pane's process group, so inspect the process tree afterward instead of declaring the incident closed too early.
Can I rely on tmux logs as an audit trail?
They are helpful for continuity, logs, and handoff, but they do not prove who launched a process or who approved it. Save them as supporting evidence and corroborate them with operating-system process data and the action gateway's audit records.
How should a team run multiple agents in tmux safely?
Use a fresh socket or session per agent run, give it an incident-friendly name, and record the launch PID immediately. Do not let a general-purpose developer session become a parking lot for agents that carry access to production systems.