Fast User Switching security for local AI agent actions
Fast User Switching security determines who can approve local AI agent actions on a shared Mac. Learn session, vault, audit, and handoff controls.

A shared Mac changes the meaning of "local" authority. Fast User Switching lets several user sessions remain logged in at once, so a person at the keyboard, an agent process, a credential vault, and an approval prompt can belong to different security contexts. Treating those as one identity is how a routine handoff becomes an unreviewed production call.
The practical rule is plain: account ownership, vault access, and approval authority must stay bound to the same macOS user session. A user switch is not permission to continue somebody else's agent run. It is a signal to check which process still exists, whose credentials it can request, and who can see or satisfy the next prompt.
Fast User Switching security is about concurrent sessions
Fast User Switching security matters because macOS can keep the previous account logged in while another person uses the same hardware. Apple describes Fast User Switching in the macOS User Guide as a way to move between accounts without logging the other user out. That convenience is the whole feature. It also means a switch does not prove that earlier work has stopped.
People often picture a laptop as a single chair: one person gets up, another sits down, and control transfers. A shared Mac with switching enabled behaves more like several rooms in one building. The visible desktop tells you who owns the console right now. It does not tell you whether a terminal, editor extension, local service, or agent launcher remains alive in another logged in account.
That distinction becomes serious when an agent can call an API or connect over SSH. The agent might have started under Alex's account before lunch. Sam might switch into their own account afterward and see a clean desktop. Alex's process may still exist, its job queue may still contain work, and an approval state may still be valid for that run. The Mac did not hand that authority to Sam, but careless software can make the difference hard to see.
Do not treat screen lock, user switching, and process termination as synonyms. They solve different problems.
- A screen lock blocks casual use of the current visible desktop.
- A user switch changes the active console account while preserving another login session.
- Logging out asks macOS to end that user's graphical session and its processes.
- Revoking an agent run removes that run's permission to make further external calls.
The last item is the control teams forget. An agent session should have its own lifetime and its own revocation path. If it only borrows the lifetime of a terminal window or a vague idea of "the developer's computer," it will behave badly on a Mac used by multiple people.
Fast User Switching is not automatically unsafe. It is unsafe when a local action system assumes that every live process and every human who might touch the machine belong to one person. That assumption holds only on a personal Mac with a single active account, and even there it fails the moment someone else knows the login password or uses an unlocked desk.
The active console user must not inherit another account's authority
The active console user should control only the credentials and approvals assigned to their own account. A local credential vault belongs to an identity, not to the physical computer. If an app makes the vault machine wide, any user who can reach the app's interface has a path toward another user's authority.
This is where teams blur two different claims. "The secret never enters the agent" is about secret exposure. "Only the right human can authorize the action" is about authority. You need both. A perfect secret boundary does not help if a different logged in user can approve its use, or if an old session remains approved after the owner leaves the desk.
Make the binding explicit in your design and your operating rules:
- Store each person's credentials under their macOS account, with separate vault material and separate local authentication.
- Require the vault to be unlocked by the account that owns the credential before any external action can occur.
- Make an approval apply to one agent process in one account, then expire it when that process exits or an operator revokes it.
- Do not let a switch into another account satisfy a prompt that originated in the first account.
- Record the account context and originating process with each authorization and call.
The awkward edge case is a support worker who has administrator access on the Mac. Administrator access can change many local conditions, but it should not turn into casual use of another person's API credentials. Ask whether the system forces a new authentication event for the credential owner and whether the audit record makes the account change visible. If the answer is unclear, the design is unclear.
Touch ID makes this sharper, not simpler. A fingerprint approval should confirm the person authorized for the active account and the action shown in the prompt. It should not become a generic physical-presence signal that any enrolled person can use to spend another account's authority. Hardware backed local authentication gives you a strong gate only when the app preserves the identity on the other side of that gate.
Do not solve this with an informal rule such as "we only switch users when the other person is away." Shared machines create interruptions, maintenance work, borrowed chargers, and rushed handoffs. Controls must survive normal human behavior, because that is when people stop remembering unwritten rules.
A hidden process can outlive the person at the desk
A user switch can leave a local agent alive, and you must test that fact in the exact way your team launches agents. Some processes stop when their parent terminal closes. Others run through an editor, a task runner, a login item, or a background launch mechanism and continue. macOS account boundaries constrain what they can access, but they do not promise that every process disappears when another user reaches the login window.
Run a small test before you permit autonomous work on shared hardware. Use a harmless agent task that emits a recognizable local record every minute and does not hold any credential. Start it from the same terminal, editor, or launcher that developers use in real work. Switch users without logging out, wait, switch back, then inspect whether the task continued. Repeat after locking the screen and after logging out.
Write the result down in operational terms. "The agent stops" is not enough. Record the launcher, the account, the event that stopped it, and how long it took. A process that continues after a switch may be acceptable for a local lint job. It deserves far more scrutiny if it can send a request that changes a hosted environment.
A common failure looks harmless at first. A developer starts an autonomous coding run that can create issue comments and update a test environment. They approve the process for the afternoon. They then switch accounts so another person can use the Mac. The coding run hits a retry loop after a transient error and resumes later. The second person did not start it and may not even know it exists. Yet the run retains a valid approval because the software tied approval to the calendar, to the device, or to a broad user session rather than to the originating process.
The fix is not a shorter approval timeout by itself. Short timeouts interrupt real work and teach people to click through prompts. Bind approval to a process instance. When that process exits, its grant ends. When a user intentionally hands the work to someone else, revoke the old run and start a new one. The new process creates a new approval event with an accountable owner.
You also need a visible way to answer "what is still running under my account?" The answer cannot rely on memory. Give operators a session journal that shows the run, whether it remains authorized, and a direct revoke action. On a personal machine, that is convenient. On a shared Mac, it is part of the safety boundary.
Approval prompts need process identity, not a friendly label
An approval prompt must show enough information to distinguish the actual caller from an imitation. A label such as "coding assistant" is useless when two extensions, two shells, or a copied script can use that label. The operator needs the originating process and, where macOS provides it, its code signing authority.
Code signing authority answers a narrow but important question: which developer identity signed this process? It does not prove that the process will make good decisions. It does help the operator detect a request from an unsigned tool, a different build, or an unexpected helper. That is much better than approving an anonymous request because it appeared during a busy afternoon.
The prompt should also name the credential or action category in terms a human can judge. "Use credential X" makes people search a mental spreadsheet. "Send an HTTP request to the deployment API using the staging publisher credential" gives them a decision. Avoid dumping a full request body into every prompt. Large prompts create approval fatigue and expose data that does not belong in a desktop notification. Put the action, destination, method, and credential identity where the user can scan them.
Per session approval and per call approval solve different problems. Per session approval says, "I recognize this agent process and permit its bounded run." Per call approval says, "I am checking this specific use of this credential." Do not replace the second with the first just because the first feels less interruptive.
Use per call approval where consequences are hard to reverse: a credential that can alter production data, remove resources, publish externally, or reach a broad administrative interface. One approval per call adds friction. That friction belongs at the point where a human should pause.
Use per session approval for work where the process is identifiable and the permitted credential has constrained impact. The session must end when the process ends. A blanket grant for "agents on this Mac" is a policy loophole wearing a friendly name.
The popular recommendation to turn off approvals for a trusted local development machine is wrong for shared Macs. It is popular because prompts interrupt flow and because developers think of local processes as private. Fast User Switching removes that premise. A local machine can contain several live user contexts, and a familiar process can continue long after its owner leaves the keyboard.
Shared Macs need a handoff procedure that ends authority
A proper handoff ends the old person's authority before it starts the next person's work. Passing along a terminal tab, a task description, or a chat message does not transfer accountability. The incoming person needs a fresh process and their own authorization for any credential use.
Use this procedure when someone else must take over a local agent task:
- Stop the current agent if it is still making decisions. Let it write its ordinary working files, but do not let it keep calling external systems during the handoff.
- Revoke the old agent session from its session record. Confirm that the revoke changes the session state before the original user leaves.
- Lock the original user's vault or log that account out if the machine will stay with the next person for an extended period.
- Have the incoming person switch to their own macOS account and start a new agent process there.
- Require a new authorization that identifies the new process, then review the task state before permitting external actions.
That procedure sounds strict until the first time an ambiguous handoff sends a request. The cost of restarting an agent is small compared with untangling who authorized a change after the fact. If a workflow cannot tolerate a restart, it needs a deliberate multiuser design rather than an accidental handoff through a shared desktop.
Avoid sharing an account to make handoffs faster. A shared login destroys the evidence you need later. You cannot tell which human unlocked the vault, which terminal started the process, or whose judgment approved the call. Separate macOS accounts do not solve every problem, but they preserve a useful boundary and a usable record.
Teams also need a rule for absent owners. If an agent process runs under a person who is unavailable, nobody should keep it alive by clicking around their account. Stop it, revoke it, and restart under a present owner. The work may wait. An unattended permission to modify external systems should not.
Locking the vault should halt actions before prompts appear
A vault gate must deny every action while locked, even if an agent process previously received a session approval. This is the difference between authorization to run and present permission to use a credential. The first establishes which process the human recognizes. The second asks whether the credential store is available right now.
Sallyport uses this ordering deliberately: its vault gate is absolute, and on macOS it uses Secure Enclave plus Touch ID while locked actions are denied. That ordering prevents a stale agent authorization from becoming a substitute for vault access after a user locks their session.
Keep the controls separate in your mental model. The vault gate protects access to the credential material. Session authorization recognizes a particular agent run. Per call approval adds direct review to selected credentials. If one control takes over the job of another, operators lose the ability to reason about a denial.
For example, do not make per call prompts the only protection for a broad credential. A person can accidentally approve the wrong request after switching back to a crowded desktop. The locked vault should already have denied the action until the credential owner authenticated locally. Then the per call prompt can ask the narrower question: does this specific use deserve permission?
Likewise, do not keep the vault permanently unlocked because a long coding task might need it later. That choice turns a short gap in attention into a period where an old process can act. Unlock for supervised work, then lock when the owner steps away or hands the Mac to someone else. If the job truly requires unattended authority, move it to an environment designed for service identities, bounded credentials, and explicit operational ownership. A shared personal session is the wrong place to fake a server.
The term "human in the loop" often hides the identity question. Which human? Under which account? Approving which process? A prompt that cannot answer those questions does not provide meaningful control. It only creates a record of someone clicking a button.
Audit records settle the timeline, not the permission decision
A tamper evident audit trail lets you reconstruct an agent run after a disputed action, but it cannot prevent a bad authorization at the moment it happens. Use the log to settle sequence and ownership, then fix the control that allowed the action. Do not market audit history to yourself as a substitute for a locked vault or a clear approval boundary.
The record needs two views because operators ask two different questions. A session journal answers, "Which agent run was authorized, and can I revoke it?" An activity journal answers, "Which call occurred, against what channel, and when?" Those records should derive from one append only source rather than two unrelated databases that can drift apart.
Sallyport projects both journals from a write blind encrypted, hash chained audit log, so the activity history and the run history share one source of record. Its offline check is available through this command:
sp audit verify
Run that check when you archive a machine, investigate a disputed handoff, or receive an exported audit store. The verifier checks the chain over ciphertext and does not need the decryption credential. That property matters on shared Macs: an investigator can check whether records still form a valid history without receiving the API tokens or SSH material that the history concerns.
Verification tells you whether the chain has remained internally consistent. It does not prove that every event was wise, that a person understood each prompt, or that the device itself had no compromise. Be precise about the claim. A verified chain makes silent editing of past records harder to hide. It does not turn an unsafe shared account into a safe one.
During an investigation, compare the account context, process identity, session authorization time, vault unlock event, and individual call order. A useful question is not merely "did an agent do this?" Ask whether the same account owned the vault, the agent process, and the approval. If those differ, you found a boundary that needs attention.
HTTP and SSH calls carry different shared-session risks
HTTP and SSH actions both spend authority, but they leave different operational footprints and fail in different ways. HTTP credentials often point to a remote service with broad API scope. SSH credentials can provide a shell on a remote host, where one accepted connection can run several commands. Do not assign both the same approval treatment because they happen to originate from one local agent.
For HTTP, inspect the destination, method, and credential scope. A read request to a narrow development API deserves a different rule from a write request to an environment management endpoint. The agent should request the action through a local gateway that injects the credential itself, so the agent receives the result rather than the bearer token. This limits secret exposure, but it does not reduce the impact of an approved destructive request.
For SSH, focus on host identity, account identity, and command intent. A connection to a development host with a restricted account differs sharply from a connection to a shared production account. If the credential grants an interactive shell, treat it as a high impact permission even when the first command looks harmless. The next command may not be.
Fast User Switching adds a local condition to both channels. A live agent process from one account must not continue issuing HTTP requests or opening SSH sessions merely because another user has made the Mac active. The gateway must associate the request with the originating process and require the vault owner to satisfy the gate. The second user's screen should not become an approval surface for the first user's run.
Keep separate credentials for separate people when accountability matters. A shared deployment token makes it difficult to distinguish a process problem from a human handoff problem. Individual credentials and account scoped vault entries make the audit history useful when you need to find the actual owner.
Some workloads do not belong on a shared workstation
A shared Mac is a reasonable place for supervised local development work with narrow credentials and deliberate approvals. It is a poor place for a long running autonomous agent with authority to change production systems, access broad administrative APIs, or maintain remote shells without a person present.
The dividing line is not whether the agent is clever. It is whether the work can keep acting after its accountable owner leaves the console. If it can, use an environment built for that job. Give the workload a dedicated service identity, a defined owner, limited credentials, and records that operations staff can inspect without borrowing someone's desktop session.
Do not confuse a server design with a local app design. A server has a different threat model, different lifecycle controls, and different expectations around unattended execution. A Mac menu bar app can give a developer tight human control over local actions. It should not pretend to be a headless automation system just because someone wants a task to keep running overnight.
For the shared Mac that you already have, make the first policy concrete: no agent keeps external authority across an unowned handoff. Test what survives a user switch, enforce vault locking when the credential owner leaves, and revoke old runs instead of hoping the next person notices them. That is the point where Fast User Switching stops being a desktop convenience and starts receiving the security treatment it requires.
FAQ
Does Fast User Switching log out the previous Mac user?
No. Fast User Switching preserves another user's login session instead of ending it. Treat the Mac as a machine with several live security contexts, not as a device that cleanly changed hands.
Can a different user approve actions from an agent left running by someone else?
They should not. The person who sits down at the Mac is not automatically the person who owns the running agent process, its session approval, or its credentials. Require a fresh authorization when the process starts and keep the vault locked when no approved user is present.
Should a local agent vault be shared across all Mac accounts?
The vault must belong to a specific macOS account and require that account's local authentication. A machine wide vault turns Fast User Switching into an access control mistake because one user's session can inherit another user's authority.
Do local AI agents keep running after I switch users on macOS?
A process can continue after its user leaves the console, depending on how that process was launched and what macOS permits it to do. Test your exact launcher, terminal, editor, and automation path rather than trusting the visible login screen.
What should an approval prompt show for an AI agent action?
The approval needs to identify the process that made the request, including its code signing authority when available. A generic prompt that says only "allow agent" gives the approver too little information to make a safe decision.
When should I require approval for every credential use?
Use per call approval for credentials that can cause irreversible or broad damage, such as production write access, deletion authority, or a long lived administrative credential. Per session approval fits a narrower, supervised development run with a clear end.
Can an audit log prevent an unauthorized agent action?
The audit record can show which process made a call, when it happened, and which credential path it used. It cannot turn an unsafe authorization into a safe one after the action has already succeeded.
How should a team hand off a local agent task on a shared Mac?
Yes, if the work can wait for the original user's approval and you retain the session record. If someone else needs to continue immediately, revoke the old run, start a new process under their account, and make them authorize it themselves.
Is it safe to run autonomous coding agents on a shared Mac?
A shared Mac can support low privilege development work if accounts stay separate, the vault locks when unattended, and high impact credentials require direct approval. It is a poor place for an unattended agent with broad production authority.
What does offline audit verification prove?
It may verify the integrity chain without opening the encrypted records, because verification works over ciphertext. That check tells you whether the stored history still joins into the expected chain; it does not grant permission to inspect someone else's secrets.