Quick start
Two ways to try TAP:
- Local, in 5 minutes — no accounts. The real TAP and console, with a simulated sandbox platform.
- The full stack — TAP on a GCP confidential VM (AMD SEV-SNP), an agent in a Cloudflare Sandbox, a model on Workers AI, a GitHub repository. About an hour the first time.
You need Node.js 22.18 or later.
git clone https://github.com/zkwasm/tap && cd tap
npm install
1. Local, in 5 minutes
node sdk/cli.ts keygen /tmp/demo-owner.pem # your owner key (P-256), stays on your machine
node demo/simulate.ts & # TAP + a simulated Cloudflare side; writes demo/local.json
node console/server.ts --config demo/local.json --owner-key /tmp/demo-owner.pem
Open http://127.0.0.1:5280 and go through the console:
- Attest — TAP's statement. Locally there is no hardware, so it says software · development only.
- Sign & install — your key signs the demo policy; TAP takes it.
- Credentials — type anything for
githubandworkers-ai, then Seal: they are encrypted here to TAP's key. - Run task — a scripted agent triages issues. Watch TAP's decisions on the right: the model and GitHub calls go out with credentials TAP added; the request to an outside log host is refused.
- When it ends, the signed session record is checked by the console against TAP's key.
In the simulation, TAP's decisions, credentials and audit are real; the agent and the upstream APIs are scripted.
2. The full stack
What you will run:
| Piece | Where | Who operates it |
|---|---|---|
| TAP | GCP confidential VM (n2d, AMD SEV-SNP) | in this guide: you (in production: the sandbox platform) |
| Adapter + agent | Cloudflare Workers + Sandboxes | you, in your Cloudflare account |
| Model | Workers AI (@cf/openai/gpt-oss-120b) |
Cloudflare |
| Owner key, console | your machine | you |
Prerequisites: a GCP project with billing and gcloud logged in; a Cloudflare account on the Workers paid plan (Sandboxes); a GitHub account.
A. TAP on a confidential VM
PROJECT=<gcp-project> deploy/gcp/create-vm.sh # n2d-standard-2, SEV-SNP, Ubuntu 24.04, firewall 80/443
PROJECT=<gcp-project> deploy/gcp/install.sh # Node.js, a Let's Encrypt certificate, tap.service on 443
create-vm.sh prints TAP's address, https://<ip-with-dashes>.sslip.io (a public DNS name for the VM's IP, so no domain is needed). install.sh ends by printing TAP's health: "platform":"amd-sev-snp".
Cost: about USD 0.09 an hour on demand. Stop the VM when you are done (see Clean up).
B. Your owner key and the platform token
mkdir -p ~/.tap && chmod 700 ~/.tap
node sdk/cli.ts keygen ~/.tap/owner.pem # keep it; back it up
node sdk/cli.ts token # prints the platform token and its SHA-256
node sdk/cli.ts provision --url https://<tap-host> --owner-key ~/.tap/owner.pem
Save the platform token to ~/.tap/platform-token (only the adapter and you need it).
provision attests TAP — the SEV-SNP report checked up to AMD's root, bound to TAP's keys — registers your key as the owner, and prints TAP's launch measurement. Note it: the console will insist on it from now on.
C. The Cloudflare adapter
cd cloudflare
npm install
npx wrangler login
npx wrangler whoami # your account id
Edit wrangler.jsonc: account_id, TAP_URL (step A), and the account id in MODEL_URL. Then deploy with the two secrets:
printf 'TAP_TOKEN=%s\nDEMO_API_TOKEN=%s\n' "$(cat ~/.tap/platform-token)" "$(openssl rand -hex 24)" > /tmp/secrets
npx wrangler deploy --secrets-file /tmp/secrets && rm /tmp/secrets
Note the workers.dev address and the DEMO_API_TOKEN you generated (the console uses it).
In the Cloudflare dashboard, create an API token with Workers AI permission only. It does not go into the Worker: you will seal it to TAP.
D. The demo repository
- Create an empty GitHub repository, for example
tap-demo-issues. It must be new: the scenario expects the tracking issue to be #1. - Create a fine-grained token: Only select repositories → that repository; Repository permissions → Issues: Read and write (Metadata read-only comes with it). Nothing else.
E. The console
cd ..
cp demo/cloud.example.json demo/cloud.json # fill it in (it is git-ignored)
node console/server.ts --config demo/cloud.json --owner-key ~/.tap/owner.pem
At http://127.0.0.1:5280: Attest (expect amd-sev-snp verified), Sign & install, then seal both tokens under Credentials. Then fill the repository through TAP, so the GitHub token stays in TAP:
node demo/seed-via-tap.ts --config demo/cloud.json --platform-token-file ~/.tap/platform-token
Now Run task. The agent, in a fresh Cloudflare Sandbox, triages the issues with plain HTTP calls; TAP adds the GitHub and Workers AI tokens, refuses the outside log host, and signs the session. The console checks the claim when the task ends. The summary comment appears on issue #1.
Clean up
gcloud compute instances stop tap-demo --zone us-central1-a # or delete it
TAP keeps its state in memory: after the VM restarts, redo Attest → Sign & install → Credentials in the console.
To skip retyping the tokens, keep them in .env at the repository root (it is git-ignored; chmod 600 .env):
TAP_CREDENTIAL_GITHUB=<GitHub token>
TAP_CREDENTIAL_WORKERS_AI=<Workers AI token>
and add "credentials": "../.env" to demo/cloud.json. Every Sign & install then seals them to TAP again (node sdk/cli.ts provision --credentials .env does the same). They are still sealed on your machine to the attested TAP key; the file is only as safe as your machine.
Next
- User guide: the trust model, policy reference, CLI and API.
- Questions and issues: https://github.com/zkwasm/tap/issues