# Security.Run agent API

Status: design contract with a core implementation under validation. The running API/OpenAPI schema defines implemented fields and endpoints; this document also retains planned capabilities. No Windows profile is publicly admitted yet. See [implementation status](implementation-status.md).

## Interaction model

The calling agent owns investigation reasoning and controls the guest through explicit bounded actions. Security.Run supplies execution, evidence and progress. Each run uses one resolved Windows profile, a shared action/evidence history, and one caller control epoch. Internal investigation and model-generated conclusions are deferred.

The interaction is pull-based:

1. Submit a run and receive a durable handle immediately.
2. Check progress when needed, using a cheap state read.
3. Optionally wait within a bounded tool timeout.
4. Explicitly request an interim report or inspect evidence.
5. Retrieve the final report when ready.

No recurring pushed updates are required. A future event subscription may be an optional adapter. A disconnected or timed-out client never implicitly cancels or resubmits the run.

## Authentication and isolation

Tenant-scoped credentials govern run, action, report, and artifact access. Resolve every referenced object against the authenticated tenant. Native host IDs, administrative credentials, and arbitrary hypervisor operations are not agent-facing capabilities.

Artifact uploads are pinned and verified before execution. Use tenant-scoped upload grants and verify size/digest at completion. A URL is not immutable input; any import must create a verified artifact before execution.

Mutating requests carry a tenant/operation-scoped idempotency key. The same key and content returns the original result; different content with the same key conflicts. Direct action requests also carry the current control epoch.

### Agent enrollment and the free tier — product decisions, not implemented

The service will always offer a free tier. During the **initial beta**, it will have **no daily execution-time allowance limit while capacity is available**. Access remains subject to available capacity, queueing and finite per-run timeouts. Each owner receives **one concurrent run shared across all of their agents**.

**Daily execution-time limits will be introduced for the free tier later.** The allowance and introduction date are not yet set. Those limits will apply per owner across all of their agents; the open beta policy is temporary.

Verified owners receive execution access immediately, without manual operator approval. Initial agent access requires its owner's approval; card payments and prepaid usage are deferred until demonstrated traffic.

The proposed flow follows the interaction pattern of the [OAuth device authorization grant](https://www.rfc-editor.org/rfc/rfc8628.html): an agent creates a pending registration, receives an expiring claim URL and a separate polling secret, and waits for owner approval. The owner signs in, reviews the agent, and approves the registration. The agent then redeems its polling credential for its own API credential. Approval links an agent to the owner's account; it does not prove global uniqueness of the software or person.

Keep one stable agent ID and one active credential per agent. Key rotation revokes the previous credential without resetting the agent ID, owner, usage counters, or run history. Owner-scoped enrollment tokens can later support additional agents without repeating interactive approval for every installation. Creating, replacing, deleting, or re-registering an agent must not grant extra concurrency or free allowance.

Enforce concurrency atomically at the owner level across every key and agent, including a leased but idle guest. Retain the reservation until the guest is confirmed stopped or fenced from execution; a timed-out HTTP request must not release it. Bound queued work separately and return a machine-readable limit response with a retry hint. Agent bearer keys can be copied, so one active key is not proof of one running process.

The initial owner-verification method remains to be selected. Keep a unique mapping from each verified external identity to its owner account; repeated sign-in or agent enrollment must resolve to that same owner. Owner approval alone does not stop someone creating multiple verified external accounts. This is an explicit limitation, not a guarantee of one account per person or organization.

Finite run deadlines, request throttling, fair queueing, and the execution pool's global capacity still apply. Future daily allowances must be documented explicitly when introduced. Payment integration and mandatory payment verification are outside the initial scope.

## HTTP surface

- POST /v1/artifacts — create a bounded upload grant.
- POST /v1/artifacts/{id}/complete — verify the uploaded bytes.
- GET /v1/profiles — supported immutable versions, capabilities, coverage, and indicative availability.
- POST /v1/runs — create an isolated Windows run; no question or prompt required.
- GET /v1/runs/{id} — cheap state/progress and latest report references; optional bounded wait.
- POST /v1/runs/{id}/commands — execute an explicit PowerShell command.
- POST /v1/runs/{id}/artifact-deliveries — copy and verify an admitted artifact in Windows; execution is a separate command.
- POST /v1/runs/{id}/captures — capture memory, disk, or both.
- POST /v1/runs/{id}/screenshots — capture the VM display.
- POST /v1/runs/{id}/desktop-input — send explicit keyboard or pointer events.
- GET /v1/runs/{id}/actions — list the shared history of commands, deliveries, and captures.
- GET /v1/runs/{id}/actions/{action_id} — intent, execution state, receipts, output/evidence references.
- GET /v1/runs/{id}/evidence — paginated, filtered evidence with stable cursors.
- POST /v1/runs/{id}/reports — explicitly request a provisional summary of current evidence.
- GET /v1/runs/{id}/reports/{report_id} — immutable interim or final report.
- POST /v1/runs/{id}/control — fence a previous caller epoch at an action boundary; ownership remains `caller`.
- POST /v1/runs/{id}/finish — stop accepting new work and finalize a directly controlled run.
- POST /v1/runs/{id}/cancel — cancel work and seal available evidence.
- POST /v1/runs/{id}/repeat — create a fresh caller-controlled run from retained inputs, profile and the original explicit initial action; subsequent actions are not replayed.

Status reads do not synthesize a fresh report. An interim report request may return a pending report handle if synthesis takes time; it must not delay command/evidence processing. Final reports are immutable.

## Submission

A run request contains:

- Optional description metadata and verified input artifact references. The description never drives execution.
- An optional exact profile identifier.
- An explicit network policy compatible with the tenant's isolated real-internet policy.
- Finite time, action, and observation limits and an optional stop predicate.
- An optional parent run reference.

The normal selection is one appropriate profile. Do not automatically run all five Windows versions. If selection assumptions materially change the answer, request input or report unsupported capabilities. Exact initial profile names and all default limits will be set after qualification.

Create a run, then send an explicit command through `/commands`. Commands can be queued immediately while the run acquires a host. Capture and delivery endpoints use the same durable action history, timeout budget, idempotency protection, and control epoch. Poll `/actions/{action_id}` to obtain the result. An idle deadline prevents an abandoned run from holding capacity indefinitely.

Earlier beta HTTP clients remain accepted through the legacy `question` alias, `mode: direct`, `initial_action`, and generic `POST /actions` route. These are omitted from the published schema and examples. New integrations use optional `description` metadata and the distinct action endpoints. This compatibility does not enable model calls.

Default limits are 900 seconds per run, 300 seconds per action and 300 seconds of caller idle time after the last completed action. The caller explicitly finishes or cancels; abandoned runs stop at their bounds. `investigate` mode and `service` ownership are rejected. Existing model settings do not enable provider calls.

### Accepted response

The immediate response includes:

- Run ID and durable acceptance timestamp.
- Current phase and execution status.
- Accepted input identities and verification status.
- Selected immutable profile when resolved, otherwise explicit selection_pending.
- Control mode/owner and the current control epoch where applicable.
- Admitted limits and network-policy identity.
- Links/references for status, actions, evidence, and reports.
- Queue/capacity reason when applicable.
- First useful action start time only if known; never infer it from dispatch acceptance.

A short optional wait can return an already-started state, but has a fixed response deadline. Acceptance is neither proof of execution nor completion.

Return a durable needs_input or unsupported result before leasing when the missing requirement is identifiable. Runs waiting for a depleted profile have a visible queue deadline. Do not silently broaden the environment or fall back to an unqualified capture mode.

## Progress and bounded waiting

Progress includes phase, elapsed time, resolved profile, last completed action, current action, counts/references to committed evidence, collection health, latest provisional findings, and any blocker.

GET with a bounded wait returns either updated/terminal state or the current state plus wait_expired. Server timeouts must fit the adapter's execution window. Repeated reads preserve the same run ID and never start a second experiment.

Do not invent percent-complete values or completion estimates for open-ended analysis. Progress descriptions reflect actual state, such as executing, observing, waiting_for_caller, collecting_capture, or finalizing.

The server may retain internal lifecycle events for recovery and diagnostics without requiring a streamed client workflow.

## Actions and controller transfer

Each action records its ID, run/slot generation, control epoch, operation, target execution identity and desktop session when relevant, artifact references, bounds, and timestamps.

Possible action outcomes distinguish accepted, dispatched, started, succeeded, failed, timed_out, cancelled, and outcome_unknown. Evidence of action effects is returned separately from the transport receipt or guest exit code.

Duplicate delivery returns the stored result. An unknown non-idempotent action is not automatically replayed.

Desktop screenshots and input use the actual prepared desktop session. Record image references and input actions in the shared history. Guest commands and GUI input never grant host administration or permission to expand network policy.

Control transfer occurs at a recorded boundary. Reject stale epochs, expose in-flight/uncertain actions, and reject actions from older caller epochs. Already-authorized independent evidence collection continues through handoff.

## Reports and evidence

Interim reports are explicitly requested, immutable snapshots with provisional status and source watermarks. The final report is produced against the sealed observation scope.

Every report contains:

- Optional run description, tested inputs/digests, resolved environment, invocation, and relevant policy.
- Deterministic execution/evidence summary and record-level observations; behavioral interpretation belongs to the caller.
- Evidence and action references per finding.
- A recorded behavior timeline and extracted indicators where supported.
- Which facts are directly observed and which are correlations or interpretations.
- Per-source coverage/health, loss/truncation, and analysis limitations.
- Unresolved questions and useful follow-up suggestions.
- Stop reason and whether the run exhausted a budget.
- Input/observation/analysis tool versions and capture references.

Use scoped conclusions such as observed, not_observed_in_scope, inconclusive, or mixed. Do not reduce the result to an unsupported universal safe/malicious verdict.

The implementation collects evidence while an action is in flight, so callers can poll progress before command completion. Reports include bounded network/native indexes with source references and explicit omissions. `observation_facts` contains deterministic facts about retained records, and `evidence_indexes` exposes bounded network/native indexes. Reports identify `analysis_owner: caller`, `answer_kind: execution_evidence_summary`, and a null behavioral verdict/model. They do not assess maliciousness. The report watermark and ledger head bind the full ledger snapshot even when its displayed records are a subset.

Report completeness, execution outcome, and cleanup status remain independent. Evidence transport may be complete while sensor coverage is limited. A failed or cancelled run may return a partial report.

Evidence queries let the agent inspect preserved source records, captures, network observations, file artifacts, screenshots, and command output. Return their provenance and declared trust/interpretation boundary. Do not expose unrelated tenant data or platform secrets.

For network findings, distinguish queries, attempts, blocked traffic, connected endpoints, and observed transfers. Preserve limits on encrypted payload visibility and process attribution.

## Finishing, cancellation, and cleanup

A caller-controlled run may be explicitly finished, become idle, or reach a hard deadline.

Finish/cancel acknowledgements are not proof all guest activity stopped. Finalization records the observation cutoff, quiesces/stops execution as appropriate, drains expected sources, and seals available evidence. Missing final checkpoints produce partial coverage.

If the guest cannot be confirmed stopped, use external stop authority. Uncertain native state is quarantined and retains capacity ownership. Cleanup continues after a report is available, with its state exposed.

## Proposed MCP tools

Thin adapters should cover these capabilities without reimplementing the service:

- security_run_create_run — create a Windows run with optional description metadata.
- security_run_command — execute a PowerShell command.
- security_run_deliver_artifact — copy and verify a run input in Windows.
- security_run_capture — capture memory, disk, or both.
- security_run_screenshot — capture the VM display.
- security_run_desktop_input — send explicit keyboard or pointer events.
- security_run_get_action / security_run_actions — inspect action receipts and history.
- security_run_get — read progress, optionally with bounded waiting.
- security_run_evidence / security_run_blobs / security_run_view_screen — inspect retained evidence.
- security_run_request_report / security_run_report — request and read deterministic evidence summaries.
- security_run_control — fence an earlier caller epoch.
- security_run_stop — finish or cancel a run and preserve evidence.
- security_run_repeat — create a fresh linked run with retained inputs.

Artifact upload may use the HTTP/client helper. Tool timeouts must be resumable. Never resubmit solely because an MCP wait expired.

## Repeat and historical inspection

Recorded review reads the original timeline and captured evidence. It does not restore a guest to an arbitrary past state.

Repeat creates a fresh run with explicit lineage and retained input/profile references. Subsequent actions are supplied explicitly by the caller. For earlier beta runs, an explicitly supplied initial action is retained. No model chooses or replays an investigation plan.

GUI scripts must account for the new screen state. Repeating actions against real internet services is not deterministic replay, and the API must not name it exact replay.
