Skip to content

HARNESS · TRUST · UPDATED

What Harness guarantees, and what it does not yet.

Architecture, isolation layers, declared limits, public receipt keys and how to report a vulnerability. Written for whoever buys and whoever audits.

Early access, by invitation. There is no external security review and no third party certification yet. When there is, the summary goes on this page.

01 / ARCHITECTURE

Five layers between the browser and the server.

Each layer answers for one thing. None needs another to be right in order to deny.

  1. 01

    Edge

    TLS, security headers and a content policy with no inline script on every page. An operational route without credentials answers 401.

  2. 02

    Gateway

    Single use invitation valid for 7 days, password of 12 or more characters stored with scrypt, __Host- cookie with HttpOnly and SameSite=Strict, origin checked on every POST and on the WebSocket, 10 login attempts per IP every 15 minutes and insert only events.

  3. 03

    Policy before the action

    A managed Claude Code hook on every tool, MCP included. The settings live in /etc/claude-code/managed-settings.json, on a read only root.

  4. 04

    One container per person

    Unprivileged user, every capability dropped, no-new-privileges, read only root, /tmp in memory, a ceiling of 1 vCPU, 2 GB and 512 processes. No traffic between workspaces; internal server services are not reachable.

  5. 05

    gVisor

    The shell talks to its own kernel (runsc), not to the server kernel.

Fig. 1 Cloud IDE layers, from the outside in. Each layer denies on its own; none relies on another being right.Source: fixed container definition and gateway configuration of Cloud IDE 0.4.0, on .

02 / GUARANTEES AND LIMITS

What the policy guarantees, and what it does not.

The limits are written next to the guarantees. A hidden limit is a risk without an owner.

Guarantees

  • Every Claude Code tool goes through the policy before it runs. MCP included. A policy deny beats any allow from another hook.ActiveProof: the image managed settings, with matcher: "*" on PreToolUse.
  • Fail closed. No answer from the gateway, a timeout or an error, and the action is denied. It is in the hook code and in the Claude Code settings ("onFailure": "block").ActiveProof: tests for the hook deadline and the managed settings, run on every image deploy.
  • Approval bound to the request. Given only in the browser, with session and origin checked, tied to the input hash and valid once. If the input changes, the approval no longer counts. The workspace token approves nothing.ActiveProof: gateway governance tests, including a request changed after approval.
  • A receipt for every decision. Decision, approval and result go into the same chain, signed with Ed25519. Changing a field breaks the hash, the signature and the next link.ActiveProof: the check in the IDE Receipts panel and the script on this page.
  • A person on outbound actions. The default policy asks for approval on deploy, publishing, remote access, external requests, WebFetch, MCP connectors, personal or confidential data in the input and unknown tools.ActiveProof: the same rule as the runtime, with the gateway copies locked by tests.
  • A protected branch only changes with a person, in git itself too. Commit, merge, rebase, reset or push on main ask for approval in the policy. On top of that, the git of every workspace repository asks Harness before an agent (Claude Code or Codex) changes a protected branch; without a recent human approval, git refuses. The agent cannot turn this guard off.ActiveProof: image self test on every deploy (agent blocked on main, person at the terminal proceeds) and a ref receipt for every decision.
  • In the console, the requester does not approve. The receipt keeps only fingerprints (HMAC) of the request and the answer, never the text.ActiveProof: runtime execution tests, including an approver equal to the requester.

Does not guarantee

  • Codex has no equivalent hook. In the Cloud IDE, Codex actions do not go through the policy and leave no receipt. The git guard on main applies to it: Codex cannot change a protected branch without approval.
  • The workspace owner can bypass the hook inside their own container. For example, by running commands outside the agent. The receipt proves what went through the policy, not the absence of what did not.
  • A shell command classified by its text is a signal, not proof. When in doubt, the policy asks a person. That is why main is also guarded in git, where the branch actually changes. A repository that defines its own hooks (husky, for example) is left with the policy only.
  • Open internet in the workspace. AI APIs, npm, GitHub and the rest. An allowlist of destinations is the next step.
  • No hard disk quota. The screen warns above 8 GB.
  • Same server as the Reveno sites. gVisor reduces the risk; a server dedicated to the IDE separates the blast radius.
  • The gateway talks to Docker, which amounts to root on the server. That is why it only creates containers from a fixed definition, named after the person's internal id, never after typed text.
  • In the runtime, a run can reach any port on 127.0.0.1. An accepted risk because only Reveno code runs and the model output is never executed.
  • A fix only reaches a recreated workspace. A container created before a fix stays on the old image until it is recreated.
  • The public demo executes nothing. Its receipts are rehearsal receipts, chained by SHA-256 and unsigned.

03 / RECEIPTS

Public keys and how to check.

Nobody has to trust the Reveno screen. The check runs with the public key and a receipt.

Ed25519 public keys for Harness receipts
KeySignsSHA-256 of the public key (SPKI DER)
k_2026-10-26_ad98e2c7Runtime console receipts691e69cb475f5cd6fda5ce9d52d174a50ae15019436b691993b2bc272c68505e
ide_4c194d4015439bccAgent action receipts in the Cloud IDEbf60db7332bf13395041b507e8ef5f98088aa44596c3df056ac481ab7bd9dc0c
Fig. 2 The keys that sign receipts. Compare the fingerprint before you trust a signature.Source: keys active on , published at the addresses below.

Published at /.well-known/harness-keys.json (runtime) and at /cloud/api/chaves (runtime and Cloud IDE, with JWK). After a rotation the old key stays published so older receipts remain checkable.

  1. Check the key

    Download the key and compare its fingerprint with the table: openssl pkey -pubin -in chave.pem -outform DER | openssl dgst -sha256.

  2. Recompute the hash

    The SHA-256 of the receipt's canonical body (keys in alphabetical order, no spaces) must equal the hash field.

  3. Check the signature

    Ed25519 over the text of the hash, with the key named in the receipt (chave_id in the runtime, kid in the Cloud IDE). The signature is base64url.

  4. Follow the chain

    Each receipt points to the hash of the previous one (hash_anterior in the runtime, parent_attestation_id in the Cloud IDE). The first link that does not match marks where the change happened.

Outside the browser, with Node 18 or newer and no dependencies:

// verificar.mjs  ·  uso: node verificar.mjs recibo.json chave.pem
import { createHash, createPublicKey, verify } from 'node:crypto';
import { readFileSync } from 'node:fs';

const canon = (v) => v === null || typeof v !== 'object' ? JSON.stringify(v ?? null)
  : Array.isArray(v) ? `[${v.map(canon).join(',')}]`
  : `{${Object.keys(v).filter((k) => v[k] !== undefined).sort().map((k) => `${JSON.stringify(k)}:${canon(v[k])}`).join(',')}}`;

const r = JSON.parse(readFileSync(process.argv[2], 'utf8'));
const corpo = typeof r.corpo === 'string' ? r.corpo : canon(r.corpo);
const hashOk = createHash('sha256').update(corpo).digest('hex') === r.hash;
const chave = createPublicKey(readFileSync(process.argv[3]));
const assinaturaOk = verify(null, Buffer.from(r.hash), chave, Buffer.from(r.assinatura, 'base64url'));
console.log(JSON.stringify({ hashOk, assinaturaOk }));
process.exit(hashOk && assinaturaOk ? 0 : 1);
Fig. 3 Checking outside the browser. Exits 0 when hash and signature match and 1 when they do not.Source: the same text the site test runs against a signed receipt and a tampered one on every build.

In the browser, the console checks hash, chain and signature of real receipts. Demo rehearsal receipts can be checked on How it works.

04 / STATUS

Ecosystem health, in plain view.

All four Reveno products, Harness among them, have their health checked automatically and published on a single page, with the reason for every failure.

See ecosystem status

05 / VULNERABILITY DISCLOSURE

Found a flaw? Talk to us first.

Good faith reports are welcome. They help more than any badge.

CONTACT

contact@thiagoholtz.com

Subject: Security: Harness. The official Reveno contact.

What to send
What you found, steps to reproduce, the impact you see, the URL and version (it is in the footer of every page) and how to reach you. Do not send third party personal data; if the proof depends on it, describe it without copying.
Scope
harness.reveno.com.br, including the Cloud IDE (/cloud/), the runtime (/api/runtime/), the public keys and the workspace image. Third party services, such as model providers and GitHub, are out of scope.
Good faith rules
Test only in your own workspace and with test accounts. Do not access, change or keep anyone else's data. No denial of service, volume testing or social engineering. Give the fix time before publishing, on a date we agree on together.
How we respond
We confirm receipt, tell you what we will do and, once the fix is live, publish the advisory on this page, with credit to you if you want it. There is no cash bounty program today.

06 / RESOLVED ADVISORIES

What we already fixed, told as it was.

A resolved advisory stays published. Hiding fixes teaches buyers to distrust.

HX-2026-01

The policy hook could let an action proceed when it ran out of time

State
Resolved
Identified
Resolved
Affected
Cloud IDE, the reveno-harness Claude Code hook (PreToolUse)
Found by
Reveno internal review, not an external report

What happened

When an action asked for approval and the network was slow, the hook added the approval wait (up to 118 seconds) to the time of its first gateway call (up to 8 seconds) and could pass the 130 second ceiling Claude Code gives it. By default, Claude Code treats a hook ended by timeout as a non blocking failure: the action moved on to Claude Code's own permissions instead of being denied by Harness.

Reach

Only actions that were waiting for approval and whose hook was ended by timeout. Actions allowed or denied directly by the policy did not change. Codex was not covered by the policy before or after, as the limits section says.

The fix

A hard 120 second deadline counted from the hook start, every call capped to the time left, a watchdog that denies before the ceiling and denial on any unexpected error. In the managed settings, "onFailure": "block" makes Claude Code block if the hook fails, and the required minimum version became 2.1.295, the one with that option. The image test checks the lock.

What to do

Nothing on the user side. The fix applies to every workspace created or recreated with the current image.

HOW TO GET IN

By invitation, with no published price.

Early access opens one workspace at a time. Harness pricing is not published yet, and the AI model cost sits on the account of whoever uses it. To bring owner, policy, approval and records to the flows your company already has, Reveno starts with the Diagnostic.

Discover · open and freeAgents & SkillsSkills, agents and MCP servers with origin and triage.Operate · early accessHarnessThe cloud IDE where every agent runs with an owner and a receipt.Decide · early accessEvidenceSynthetic data to test the decision before you invest.