# Governed Agent Run (`revealuistudio/governed-agent-run`) Actor

Run an AI agent task and get back a cryptographically signed, offline-verifiable receipt of every action it took. If an agent did it, there's a receipt.

- **URL**: https://apify.com/revealuistudio/governed-agent-run.md
- **Developed by:** [Joshua Vaughn](https://apify.com/revealuistudio) (community)
- **Categories:** AI, Agents, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Governed Agent Run

If an agent did it, there's a receipt.

This actor runs an AI agent task for you and hands back both the result and a
cryptographically signed receipt of every action the agent took: every model
call and every tool call, in order, with a signature you can check offline
without ever talking to anyone.

### What you get

- **A completed task.** Give the actor a task and your own LLM API key
  (Anthropic or OpenAI), and it runs an agent loop until the task is done or
  it hits a step limit.
- **A signed, tamper-evident receipt.** Every model call and tool call is
  recorded into an action log, and the whole log, together with the
  identifiers of the Apify run that produced it, is signed with a fresh
  Ed25519 key generated for that run. Anyone can check the signature offline
  with nothing but the receipt itself, and confirm that nothing in it changed
  after signing.
- **A platform-attributable run record.** The actor also publishes the receipt
  to that run's own dataset and key-value store on Apify, the same places the
  rest of the run's output lives. Only the actual running actor process can
  write there for that run, so a verifier who wants proof the run really
  happened, not just that the receipt is internally consistent, can fetch that
  record from the Apify API for the `actorRunId` embedded in the receipt and
  confirm it matches.
- **A free way to check any receipt.** Run this actor again in "verify-receipt"
  mode with a receipt you already have, and it tells you whether the signature
  is valid. This mode is free.

**What a receipt proves, and what it doesn't.** Standalone verification (the
"verify-receipt" mode) proves the action log was not altered after signing. It
does not, by itself, prove the run happened on Apify at all. Anyone can
generate their own Ed25519 keypair and sign a fabricated action log claiming
any `actorRunId` they like, and that receipt will still verify. Proving
provenance, that a specific receipt corresponds to a run this actor actually
executed, needs the extra step above: checking `receipt.actorRunId` against
that run's own dataset or key-value record on Apify. This actor makes no SOC 2,
ISO, or other compliance claim either way.

### Input

| Field | Required | Description |
|---|---|---|
| `mode` | No (default `run-task`) | `run-task` or `verify-receipt` |
| `task` | Yes, for `run-task` | The task prompt for the agent |
| `llmProvider` | Yes, for `run-task` | `anthropic` or `openai` |
| `llmApiKey` | Yes, for `run-task` | Your own API key (bring-your-own-key; never stored or logged) |
| `model` | No | Override the provider's default model |
| `toolAllowlist` | No | Restrict which built-in tools the agent may use; omit for all, `[]` for none |
| `maxSteps` | No (default 10) | Maximum model/tool-call round trips |
| `receipt` | Yes, for `verify-receipt` | A receipt object from a prior `run-task` run |

### Why bring your own API key

This actor charges per governed action and per completed run, not per model
token. Bringing your own LLM key means the price never has to cover model costs
on top of that, and you keep full control of and visibility into your own model
spend.

### Pricing

| Event | Price | Charged when |
|---|---|---|
| Governed action | $0.02 | Once per model call or tool call recorded into the action log |
| Governed run completed | $0.08 | Once when a governed run finishes and a signed receipt is produced |
| Receipt verification | Free | Once per "verify-receipt" run |

### How the receipt works

1. Every model call and tool call the agent makes is appended to an action
   log, in order, along with a final entry recording the run's output.
2. The action log, together with the run's `actorId`, `actorRunId`, and
   `actorBuildId`, is canonicalized with RFC 8785 JSON Canonicalization (so the
   byte representation is deterministic regardless of key order) and signed with
   a fresh Ed25519 keypair generated for that run.
3. The receipt embeds the action log, the run identifiers, the signature, the
   public key, the algorithm, and a timestamp. Because the receipt carries its
   own public key and names its algorithm, you can check the signature with any
   standard Ed25519 library, offline, depending on no external infrastructure
   and on this actor no longer needing to exist. Checking provenance, rather
   than only integrity, does depend on the run's own record still being
   retrievable from Apify.
4. The actor publishes that same receipt to the run's dataset and key-value
   store, both of which only the actual running actor process can write to for
   that run.

### Limitations (v0.1)

- The built-in tool catalog has exactly one tool (`web_fetch`, a bounded
  HTTP(S) fetch). It resolves DNS and blocks the private, loopback, link-local,
  and carrier-grade-NAT ranges across both IPv4 and IPv6 (including IPv4-mapped
  IPv6 addresses), and it does not follow redirects. It does not pin the
  connection to the address it validated, so a true DNS-rebinding attack, where
  the DNS answer changes between that check and the fetch a moment later, is out
  of scope. A public hostname with a static record pointed at a blocked address
  is fully blocked. Expanding the tool catalog is future work.

Built by RevealUI Studio.

# Actor input Schema

## `mode` (type: `string`):

"run-task" executes an agent task and returns a signed receipt. "verify-receipt" checks a receipt you already have (free).

## `task` (type: `string`):

The task prompt for the agent to complete. Required when mode is "run-task".

## `llmProvider` (type: `string`):

Which model provider to call. Required when mode is "run-task".

## `llmApiKey` (type: `string`):

Your own API key for the selected provider (bring-your-own-key). Never stored or logged. Required when mode is "run-task".

## `model` (type: `string`):

Override the default model for the selected provider.

## `toolAllowlist` (type: `array`):

Restrict which built-in tools the agent may use. Omit to allow all built-in tools; pass an empty list to disable tools entirely.

## `maxSteps` (type: `integer`):

Maximum model/tool-call round trips before the run stops itself. Default 10.

## `receipt` (type: `object`):

A receipt object previously returned by a "run-task" run. Required when mode is "verify-receipt".

## Actor input object example

```json
{
  "mode": "run-task"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("revealuistudio/governed-agent-run").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("revealuistudio/governed-agent-run").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call revealuistudio/governed-agent-run --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=revealuistudio/governed-agent-run",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/cbvZcwrohezqw5TDW/builds/T8B6IRTNI8wVaHxft/openapi.json
