# AI agent production access: a preflight review that holds up

Giving an agent production authority is an operational decision, not a convenience setting. The agent may write a migration, call an internal API, open an SSH session, or run a deployment command correctly nine times and still make the tenth call against the wrong target. A useful review assumes that this will eventually happen and limits the result.

AI agent production access should pass the same test as a human emergency credential: can a named person explain exactly what it can do, stop it during a run, repair its worst plausible action, and prove afterward what happened? If any answer is vague, the team has granted access before it built control.

Teams often focus on whether a model might hallucinate a command. That risk exists, but it is not the only one. An agent can follow an ambiguous ticket too literally, inherit a broad credential from a shell, retry a non-idempotent request, or operate under a process that nobody intended to trust. Production failures usually come from that ordinary plumbing.

## Production authority includes every irreversible side effect

Production authority starts wherever an agent can cause, expose, or authorize a meaningful change. Database writes get attention because they feel dangerous. A read endpoint that returns customer records, an endpoint that mints an access token, a DNS change, an email send, and a command that reloads a service can carry equal or greater consequence.

Make the review describe actions, not systems. "The agent may access production" tells a reviewer nothing. "The agent may read the current deployment revision for service A and restart one named worker group" gives the reviewer something to assess.

This distinction matters because access methods hide authority. An SSH account can run a seemingly harmless status command but inherit permission to edit files, restart services, or read environment variables. An API credential titled "monitoring" may also list users or expose support attachments. The team must inspect the server-side permission set, not rely on the label attached to the credential.

Separate four kinds of authority in the change record:

- Read authority: data, logs, configuration, and metadata the agent can retrieve.
- Change authority: resources it can create, update, delete, restart, or publish.
- Delegation authority: identities, permissions, tokens, or credentials it can issue or alter.
- External authority: messages, payments, tickets, DNS records, and vendor-side changes it can trigger.

Delegation deserves its own category. A credential that lets an agent add a user or generate another credential lets it widen its own future reach. Reviewers often miss this because the first request looks administrative rather than destructive. Do not grant delegation in an initial production run unless the task cannot function without it and a human will approve each use.

The OAuth 2.0 authorization framework, RFC 6749, describes scope as the range of access a client requests and a resource owner grants. That wording is useful, but teams misuse scope when they treat it as a friendly label. A scope only limits an agent if the resource server actually enforces it on every endpoint and every method. Confirm the enforcement with a test account. Do not accept a scope string as proof.

## Credential scope must match one job, one target, and one verb

A production credential should support a single stated job against a bounded target. If the job is "verify that the deployment is healthy," it does not need authority to modify infrastructure. If the job is "repair a failed migration," it may need writes, but it should operate on one database or service and one documented migration path.

The most common bad choice is a broad human credential passed through an environment variable because the team already knows it works. That choice is popular because it avoids permission debugging under deadline pressure. It also destroys attribution, gives the agent every privilege the human has, and forces a disruptive rotation if anything goes wrong. A separate machine identity creates a little setup work and removes a great deal of ambiguity.

Write the requested authority in a table before issuing anything.

| Review field | Acceptable answer | Warning sign |
| --- | --- | --- |
| Job | Verify revision and health after a release | "Help with production" |
| Target | One named service and environment | All production projects |
| Allowed verbs | Read status, restart one worker group | Full administrative access |
| Data boundary | Aggregated health data only | Raw customer records |
| Lifetime | Ends with the approved run or an explicit expiry | Permanent by default |
| Owner | One accountable service owner | A chat channel or a team alias |

Insist on verbs. "Access to billing" does not state whether the agent can view invoices, issue refunds, alter plans, or download customer data. API permission models can split those operations. SSH cannot always do so cleanly, which makes a constrained wrapper command or separate account preferable to a general shell.

For APIs, test both a permitted and a forbidden operation before the agent receives the credential. A minimal record might look like this:

```yaml
agent_job: post-release-check
identity: deploy-check-agent
resource: production/service-a
allowed:
  - GET /v1/releases/current
  - GET /v1/health/summary
forbidden_test:
  request: POST /v1/releases/rollback
  expected_status: 403
expiry: "2025-04-18T18:00:00Z"
owner: service-a-oncall
```

The date is an example. Your record needs a real expiry that matches the run. The useful line is `forbidden_test`: it forces the team to prove a boundary rather than merely describe one.

Do not put an agent in a position where it must choose between failure and privilege escalation. If its normal task requires a write that the credential lacks, stop and change the runbook or ask for explicit human authorization. A broad fallback credential turns an ordinary task failure into a security event.

## Approval frequency must follow the consequence of a call

Approval works when it makes a human assess a meaningful decision. It fails when it becomes a repetitive obstacle that people clear without reading. The approval point should therefore match the unit of consequence, not an arbitrary timer.

One approval for a new agent process is often appropriate when a human has reviewed a bounded job and the process will make many predictable, low-consequence reads. It provides a useful identity check at the moment a new process gains authority. It is a poor fit for actions that create an external commitment or remove data.

Require approval for each use when the individual call can cause a separate event that a person would want to inspect: deleting a resource, rotating a credential, applying a migration, changing permissions, sending a customer-facing message, or invoking a remote command with a broad effect. The prompt should show the calling process and the specific action in plain language. "Approve agent request" asks the human to guess.

Do not ask for approval after the action. Logging a completed destructive call is evidence, not control. Similarly, a blanket "approve all future actions" decision only makes sense when the reviewed run has a narrow, known action set. If a task turns into investigation and starts exploring unfamiliar systems, end the session and request authority again.

Approval fatigue is a design problem. If an agent needs a hundred confirmations to collect health information, reduce the credential's scope to those reads and approve the session. If a human sees ten destructive prompts in a row, the work should move into a reviewed batch with explicit limits or return to manual operation. People do not become more attentive because a dialog appears more often.

The reviewer also needs a stop button that works during the run. Killing a terminal is not enough if a remote command already started or the agent can reconnect with the same authority. Define who can revoke the active authorization, how quickly they can do it, and what the agent sees after revocation. Test it before an incident forces someone to learn the procedure.

## A rollback claim needs a tested recovery path

Every production grant should name the worst plausible side effect and the recovery action for it. "We have backups" does not answer how to reverse a permission change, retract an outbound message, restore an overwritten configuration value, or stop a command that has begun on a remote host.

Start with the actual operation. If the agent can apply a schema migration, decide whether the migration is reversible, whether application code tolerates both schema versions, and who owns the restore decision. If the agent can restart workers, decide how you will detect a restart loop and return to the previous revision. If the agent can call a vendor API, find out whether that vendor supports idempotency tokens, cancellation, or compensating actions.

The Google SRE Book warns that automation can amplify both good and bad actions. That is not an argument against automation. It is an argument for making reversal and rate limits part of the automation design instead of an emergency afterthought.

A usable rollback record includes these facts:

1. The trigger that tells the operator to stop the run, such as an error rate threshold, an unexpected target, or an unreviewed action request.
2. The exact recovery command, console action, or owner who must perform it.
3. The expected state after recovery and the query or observation that confirms it.
4. The point where the team stops trying to repair and escalates to the incident owner.
5. The actions that cannot be reversed, with an explicit decision to accept that risk or remove them from the grant.

Run this on a disposable production resource when possible. Create a clearly named test object, let the agent make its allowed change, remove the object's authority during the session, and execute the recovery procedure. This exercise catches the embarrassing failures: an operator lacks console access, the rollback command points to staging, an endpoint accepts a request but completes it asynchronously, or the evidence log omits the request that mattered.

Idempotency also belongs in this review. Agents retry. Networks fail after a service accepts a request but before the caller receives a response. Without an idempotency identifier or an operation status lookup, the agent may create a duplicate record because it cannot tell whether the first attempt succeeded. If the target API cannot make an operation safe to retry, require a human decision after an ambiguous response.

## Process identity is separate from agent intent

A chat transcript may explain why an agent acted, but it does not prove which program exercised production authority. Production controls must identify the local process that connected, its executable origin, and the session that received approval.

This is where teams blur two different questions. "Did the model receive a sensible instruction?" concerns intent. "Did the approved process make this call?" concerns authority. A clear instruction cannot protect you when a different process can reuse the same credential. A signed process identity cannot tell you whether the task request was sensible. You need both, and they produce different evidence.

Avoid a setup where a credential enters the agent's context window, shell environment, configuration directory, or tool output. Once the agent can read a secret, the team cannot reliably distinguish ordinary tool use from accidental disclosure. Redacting a value in a transcript helps with display, but it does not erase every copy the process may have received.

For SSH, this problem gets worse when operators load their regular personal identity into an agent-managed environment. The account may reach multiple hosts, forward to other hosts, or authorize access through group membership. Create an account with a narrow command surface, restrict the hosts, and test that the account cannot read files or run commands outside the job.

Sallyport takes a different boundary on macOS: the agent asks a local action gateway to perform HTTP or SSH work, while the encrypted vault retains the credential and returns the result instead of the secret. That approach does not make a bad request safe, but it prevents the routine mistake of handing long-lived production credentials directly to an agent.

A process identity check must identify more than a terminal window title. Record the executable or code-signing authority where the operating system supplies it, the launch time, the user account, and the approved session. If the process changes after approval, treat it as a new process. Do not let a generic background worker inherit an approval intended for a one-off repair run.

## Evidence must let another engineer reconstruct the run

Keep evidence that answers five questions: who authorized the run, what process acted, what authority it held, what each call attempted, and what happened after each call. An audit record that only says "agent completed task" cannot settle a disagreement or guide recovery.

Store authorization events separately from action records, even if they originate from one log. Authorization answers why a process gained access and when someone revoked it. Action records answer the method, target, result, timestamp, and correlation identifier for each operation. Tie the records together with a session identifier that survives retries and handoffs.

Do not log secrets just to make an audit trail complete. Log the credential identity or vault reference, never the bearer value, private key material, authorization header, or full request body when it carries sensitive data. Redact deliberately, then verify that errors and debug logs follow the same rule. Many leaks appear in the error path after someone adds verbose logging during an incident.

An append-only log on the same machine is better than nothing, but it does not prove much if a compromised process can rewrite history. A hash-chained log makes removal or alteration detectable when reviewers retain the chain. Offline verification matters because it lets an investigator check the record without unlocking the credential store.

For example, `sp audit verify` checks Sallyport's encrypted, hash-chained audit record without requiring vault access. Run the check as part of post-run evidence collection, retain its result with the change record, and investigate any verification failure before you trust the journal.

Use a compact evidence manifest so that a reviewer does not have to collect facts from five consoles after the fact:

```yaml
run_id: prd-2025-04-18-017
purpose: repair failed migration 042
approver: service-owner
process_identity: signed-executable-identifier
credential_identity: migration-repair-agent
authorization_started: "2025-04-18T17:05:00Z"
authorization_ended: "2025-04-18T17:21:00Z"
change_reference: CHG-1842
action_log_reference: audit-export-prd-2025-04-18-017
rollback_result: test-object-restored
reviewer: oncall-engineer
```

This manifest does not replace the detailed action record. It gives an investigator a map to the records and makes missing proof obvious before the team closes the change. A human should write or confirm the purpose and approval fields. Letting the agent generate its own evidence summary invites it to omit the awkward parts.

## The preflight review should end in a signed decision

A team should conduct the review immediately before granting authority, while the requested task, target, and operator are known. A generic security questionnaire completed months earlier cannot answer whether today's agent process needs to write to today's production service.

Use this review record. Every row needs an answer, an owner, and a clear outcome of approve, change, or decline.

| Review question | Evidence the reviewer checks | Approval standard |
| --- | --- | --- |
| What exact task will the agent perform? | Ticket or change description with success condition | The task has a bounded end state. |
| What production target can it reach? | Account, service, host, namespace, or API route list | The target excludes unrelated systems. |
| Which reads expose sensitive data? | Sample response and field review | The task needs those fields, or the team removes them. |
| Which writes or external effects can occur? | Method list, SSH command list, or dry run | Each effect has an owner and recovery path. |
| Can it create identities or alter permissions? | Permission test and server-side role view | Default answer is decline. |
| Does the credential expire and support immediate revocation? | Issuance settings and a revoke test | An operator can cut off the active run. |
| Who approves the process and who handles an escalation? | Named approver and incident contact | They are available for the run. |
| What prompt frequency matches the consequences? | Session and per-call action classification | Destructive calls receive specific review. |
| How will the team roll back? | Tested command or documented console procedure | Recovery has a measurable success state. |
| What evidence will survive the run? | Authorization and action log locations | Another engineer can inspect it later. |

Do not reduce this to a formality. A reviewer should decline access when the request says "all production" without a target, when a task has no end condition, when the rollback plan relies on undocumented tribal knowledge, or when the credential owner cannot explain how to revoke it.

The decision should also name what will cause the team to stop. Examples include the agent requesting an operation outside the approved method list, a target mismatch, an ambiguous write response, an authorization prompt that the operator cannot interpret, or an audit check failure. A stop condition prevents the operator from improvising while under pressure.

There is no need to demand a full change board for a narrow, reversible health check. There is every reason to demand this level of care before granting a general shell, broad database writes, access to customer data, or the ability to alter authorization. Match review effort to blast radius, but do not confuse speed with skipping the facts.

## Test the denial path before you need it

A permission boundary has not passed review until the team sees it deny something. Happy-path tests show that the agent can work. Denial tests show that the boundary exists.

Use an isolated identity and a clearly marked disposable production resource. Confirm that the agent can perform one intended read or change. Then attempt a forbidden method, a forbidden target, and a call after revocation. Record the response code, error message, and audit entry for each attempt. The exact failure message may vary, but the denied request must not produce a side effect.

Do this with the same route the real run will use. A staging test does not prove a production approval mechanism, production identity binding, or production logging. A direct API test does not prove an SSH wrapper. A mock cannot prove that a vendor endpoint honors an idempotency identifier. Test the boundary that will carry the real action.

Also test interruption. Start a benign operation that takes long enough to observe, revoke authorization while it runs, and check what occurs to the current request and the next request. Some systems cannot cancel work already accepted. That fact belongs in the rollback plan, not in fine print.

Capture the expected denial behavior in the runbook. When an operator sees an error during a real run, they need to know whether it indicates a healthy guardrail, a broken credential, a target mismatch, or a remote service failure. Treating every denial as something to bypass is how a narrow grant quietly grows into broad access.

## Temporary access needs an owner after the agent exits

Production authority should end when the approved task ends. A credential that remains active "just in case" will eventually become an undocumented dependency or an overlooked route back into production.

Assign one owner to remove or disable the grant after the run, verify that removal, and attach the evidence to the same record that authorized access. If the task becomes recurring, design a recurring identity with fixed scope, documented approval rules, and regular review. Do not preserve an emergency exception because it happened to be useful once.

Before closing the work, compare the action journal with the approved method list. Investigate extra calls, retries that changed state, denied requests, and any operation that produced an ambiguous response. Then revoke the session or credential even if the agent reports success. The agent's report is input to the review, not the final authority on what production accepted.

The first action to take is simple: choose one existing agent workflow and force it through the review table before its next production run. Broad credentials, vague task descriptions, and untested recovery steps tend to reveal themselves quickly when someone has to write them down.
