# How vault lock vs screen lock changes an agent test

A locked screen and a locked vault are different controls, and treating them as the same control produces a test that tells you almost nothing. macOS screen lock limits interactive access to a user session. A vault lock must stop protected actions at the point where credentials would be used, including actions requested by a process that was approved before you looked away.

That distinction matters most with autonomous coding agents. An agent can keep a process alive, retain context, schedule work, and retry a failed request. A test that only confirms that a person cannot type at the desktop does not establish whether that process can still call an API or open an SSH connection. Test the two states independently, then test their overlap.

I have seen teams call this a “locked computer” test, take one screenshot of a lock screen, and declare the work finished. That is evidence of a lock screen. It is not evidence of an absolute deny boundary around credentials.

## A locked display does not decide whether a process can act

A macOS screen lock protects the console session from a person who has physical access to the keyboard and display. It does not, by itself, describe every process already running under that session, every network connection it owns, or every credential store an app may use.

Apple's Platform Security documentation separates user authentication and session protection from the protection of secrets such as keychain items. That separation is useful here, even if your exact deployment has fewer moving parts than Apple's documentation covers. Asking “was the screen locked?” and asking “could the agent use a credential?” are different questions with different evidence.

An agent can be harmless while the screen is unlocked and still be dangerous after it has a bearer token in its own environment. Conversely, an agent can run during a locked session and remain unable to make a protected request because the credential never entered its memory and the action gateway refuses it. The screen state cannot tell you which design you have.

Use this practical definition during review:

- A screen lock controls interactive use of the Mac.
- A vault lock controls whether the protected action may execute.
- Session authorization controls whether this particular agent process may ask for protected actions during its lifetime.
- A per-call key controls whether a person must approve this particular credential use.

Those controls can line up in a pleasant demo. They should not depend on lining up in production.

## The vault gate needs an absolute denial test

An absolute vault gate means that a locked vault denies every action that would use a stored credential. The denial must apply before HTTP credential injection and before the SSH helper authenticates. It must apply to a process that previously succeeded, not only to a new process that has never been trusted.

Sallyport makes this boundary explicit: while its vault is locked, every action is denied. On supported macOS hardware, the vault gate is hardware-gated with Secure Enclave and Touch ID. That is stronger and clearer than a convention such as “the agent should not call this tool while I am away.”

The most revealing test starts with success. Configure one low-consequence endpoint you control, such as an HTTP endpoint that records only the request method and an opaque request identifier, or an SSH host with a command that prints a fixed word. Do not start with a production deployment endpoint. You need a target whose logs you can inspect without exposing a live secret or changing anything important.

Then keep the agent process alive, lock the vault through the app, and ask for the same action again. A correct result has three parts:

1. The caller receives a clear denial rather than a timeout or a generic network failure.
2. The Activity journal records the attempt as denied, with enough context to identify the session and credential path without revealing the credential.
3. Your controlled endpoint or SSH host receives no new request and no command.

The third part catches the failure that polished user interfaces conceal. A gateway can display a denial after it has already emitted an authenticated request because it placed the check in the wrong layer. The remote log is the witness that matters.

For SSH, avoid a test such as `ssh host true` if your test host accepts other identities from your normal environment. Use the channel that the agent would use, target an isolated account, and give it a command whose appearance in server logs is unmistakable. If you cannot prove which identity made the connection, you are testing your shell setup, not the vault boundary.

## A prior approval must not outlive the gate

Per-session authorization answers a narrower question than the vault gate: may this agent process use protected actions during this run? It is not a permanent grant, and it cannot override a locked vault.

This is where teams often confuse convenience with authority. They approve an agent, see several calls succeed, lock the vault, and later unlock it. If the process resumes work, they assume the earlier approval either should survive or should disappear based on what feels friendliest. Decide this behavior from the actual control model, then test it. The app's documented decision ladder puts the vault gate first. A closed gate wins.

Run this sequence without restarting the agent:

1. Start a fresh agent process and make one protected call. Approve its session when prompted.
2. Make a second protected call using the same ordinary credential. Confirm that it succeeds without another session card.
3. Lock the vault while that process remains running. Repeat the call and confirm denial before the remote target receives it.
4. Unlock the vault through the required local interaction. Repeat the call and record whether the established session resumes under the documented rules.
5. Exit the agent process, start another fresh process, and make the same call. Confirm that the new run receives its own authorization card.

Step four is not a cosmetic detail. It exposes whether the product has accidentally treated “vault was opened” as “all running code is trusted again.” Step five exposes whether a process identifier, terminal parent, or loose client label has become an unintended long-lived grant.

The approval card should lead with the process's code-signing authority. A process name is easy to copy. A path can be misleading. Code-signing authority gives the operator something more stable to assess when the agent process asks to use a secret. Record what the card showed during your test, including what you would have seen if an untrusted copy of the client made the same request.

## The lock screen test has a separate purpose

Test the macOS screen lock after you establish the vault behavior, because its purpose is to answer a different operational question: what can continue while no one is at the console, and how do you regain control?

First, leave the vault in its intended available state and start a session that has already been authorized. Trigger one harmless protected action, lock the macOS screen, wait long enough for your normal unattended-work concern, then inspect whether the action could continue. Do not assume the answer. Your Mac's power settings, network state, process lifecycle, and the app's own gate all affect it.

Next, perform the same experiment with the vault explicitly locked before you lock the screen. The result should be simpler: attempts at protected actions are denied. If an agent can keep generating text or editing local files, that is outside this narrow assertion. The assertion is that it cannot turn a stored API key or SSH key into an external action.

This pair of tests separates an uncomfortable but legitimate policy choice from a security bug. Some developers intentionally allow an already-approved agent to continue low-risk work while the display is locked. Others require that every absence locks the vault. Those are operating choices. Letting an agent use credentials after the vault has locked is a boundary failure.

Do not test this by watching a lock screen from across the room. Capture timestamps from the agent request, the controlled endpoint, and the Activity journal. A request that began before the screen locked can complete afterward. That does not prove it began after the lock. Sequence matters.

## Per-call approval is for actions you would regret approving in bulk

A per-call key requires a human approval for every use of that credential. It should sit above an approved session, not replace the session check and not weaken the vault gate.

Use one such credential in the test plan, even if most keys use ordinary per-session approval. Pick a target action with a visible, reversible effect, such as a test endpoint that increments a disposable counter or an SSH command that creates a file in a temporary directory. The purpose is to prove that the app asks again for the second use and that rejecting the prompt prevents the outside action.

Run the following test while the screen is unlocked so you can separate prompt behavior from session state:

- Start a new agent process and approve its session.
- Use the per-call credential and approve that call. Verify one remote event.
- Invoke the same credential again and reject the approval. Verify no second remote event.
- Lock the vault and invoke it once more. The vault denial should occur without presenting a meaningful choice to approve an action the gate cannot permit.

The popular recommendation to mark every credential per-call sounds prudent because it turns every action into a visible decision. In practice, it trains people to approve repeated cards without reading them. Reserve it for credentials whose individual use changes money, access, publishing state, or another consequence you need to witness. For routine calls, a meaningful session approval plus a lockable vault gives the operator fewer decisions and clearer ones.

## A remote log catches the denial that a local test misses

A local error message proves only that the caller saw an error. It does not prove that an authenticated request failed to leave the machine, and it says nothing about retries that arrived later.

Build a test target that reports a short request identifier you choose. The agent action can send a harmless header or request body field such as `test_run=screen-vault-01`, provided your gateway's configured credential path permits the request shape. On the receiver, record the arrival time, method, source information you normally have, and that identifier. Keep the target isolated from production data.

Your test record should contain a small table like this:

| Attempt | Vault state | macOS screen | Expected remote event | Observed result |
| --- | --- | --- | --- | --- |
| A | available | unlocked | one event | event recorded |
| B | locked | unlocked | none | no event, local denial |
| C | available | locked | depends on your operating choice | recorded outcome |
| D | locked | locked | none | no event, local denial |

The word “depends” in row C is deliberate. Do not hide a policy decision inside a pass/fail column. State whether an approved process is allowed to keep working while the screen is locked in your environment, and make the expected outcome match that decision.

For HTTP, inspect application logs, not only access logs if a reverse proxy can reject or retry requests before the application sees them. For SSH, inspect the server authentication and command records for the isolated account. Give each test attempt a new identifier. Reusing one label creates an argument about delayed delivery when you need a clean result.

## The audit record should explain the state transition

A good audit trail lets a reviewer reconstruct who ran the agent, which actions it attempted, and whether the gateway denied or executed them. It should not require the reviewer to guess whether a missing remote event came from a vault lock, a lost network connection, or an agent that never made the request.

The app maintains a Sessions journal for agent runs and an Activity journal for individual calls. Both come from one write-blind encrypted, hash-chained audit log, so they are two views of the same underlying record rather than competing logs with different stories. When a test exposes a mismatch between the journals, treat that as a test failure until you can explain it.

After each test run, preserve the following observations in your test notes:

- The session identity shown at authorization and the time you approved or rejected it.
- The precise time you changed vault state and screen state.
- The caller's success or denial result for every attempted action.
- The matching Activity and Sessions entries.
- The controlled target's evidence that it did or did not receive the action.

Then verify the chain offline with:

```
sp audit verify
```

A successful run should report that verification passed, though exact wording can vary by release. The useful property is that verification works over ciphertext and does not require opening the vault. That makes it possible to hand a protected audit artifact to a reviewer who needs to check for tampering without giving that reviewer the credentials or the ability to perform actions.

Do not oversell this command. A valid hash chain tells you that the recorded sequence has integrity under the verifier's model. It cannot prove that you chose the right remote log, that your clock is correct, or that a test target had no other route into it. Pair it with the remote evidence.

## Process lifetime is the boundary that people skip

A session authorization should end when the agent process exits. Test this explicitly because “I opened a new terminal” is not the same thing as “the previous process ended,” and a background supervisor can keep a child alive after its user interface disappears.

Start with a clean baseline. Exit the agent process, confirm in your normal process inspection method that it is gone, then start another process through the same client path. Its first protected call should create a new session and request authorization. If it silently inherits approval, find out what identity carried that grant. It may be a deliberate feature, but it is a much broader authority than per-session authorization implies.

Also test a failed launch and a copied client. If a client process starts, asks for approval, exits before it calls an action, and a replacement process can use that approval, you have found a lifetime bug. If a differently signed process presents the same friendly name, the approval UI must give the operator enough authority information to distinguish it.

This is not hypothetical bookkeeping. Agent tooling evolves quickly, and wrappers spawn helpers, reconnect transports, and recover from crashes. The process that makes the protected call is the object you need to authorize. A project name or a chat transcript is not an execution identity.

## Treat sleep, restart, and network loss as separate experiments

Screen lock is often tested on an awake laptop, then people assume the result covers sleep, reboot, and a network drop. It does not. Each event changes different parts of the system.

For sleep, record whether the agent process remains alive, whether the Mac permits the network path you use, and whether the vault state changes. For restart, treat every agent run as new and require a new local unlock before protected use. For network loss, verify that a failed call does not cause an unsafe retry after the vault locks or after the original process exits.

Keep these experiments small. A useful retry test uses one request identifier and a receiver that can tell whether it saw zero, one, or multiple arrivals. Start the request, remove the network path at a controlled moment, lock the vault, restore the network path, and watch for delayed delivery. If the request has side effects, use a disposable receiver. Retrying an ordinary read is different from retrying a state-changing operation.

Do not turn this into a general policy engine in the test document. The question is narrower: does the fixed decision ladder still produce the expected deny state when normal computer events interrupt an agent? Clear evidence beats a huge matrix of imagined rules.

## The finished test plan should leave one unambiguous claim

Your completed plan should let you say, with evidence, that a locked macOS screen and a locked vault were tested independently. It should also show whether an approved process could act while unattended, whether per-call approval blocked a second use, and whether a denied call stayed off the remote system.

Write the final assertion in plain language: “When the vault was locked, the agent could not use the configured HTTP or SSH credential, whether the macOS screen was locked or unlocked.” Attach the remote target record and the audit verification result. Then add your separate operating decision about what an approved agent may do while only the screen is locked.

That last sentence prevents the usual confusion during an incident review. Someone can disagree with your unattended-work policy. They should not be able to mistake it for proof that the vault gate worked.
