Exactly what protects your data, what's shipped, and what isn't yet — no marketing asterisks.
A log is a row in a database — anyone with admin access can change it, and the log cannot prove they didn't.
The verifier itself is MIT-licensed and published as @runback/verify — install it, read the source, run it against your own export with no Runback account or network call involved. Try it now →
Secrets, API keys, JWTs, emails, card numbers (Luhn-checked), and SSNs are scrubbed inside your own application process — before a trace is sent anywhere. Even your backend never sees them. Two tiers (standard/strict), custom patterns, key allow/deny lists.
Deterministic rules run as an in-process pre-hook: a violating action (an unescalated $250 refund, say) is blocked BEFORE it executes, with no network in the critical path. Every block is recorded as a hash-chained, re-runnable event — proof the control fired — and rules can be simulated against history before you turn them on. This is application-layer control: it runs inside your process, so prompt injection that takes the process can bypass it, and infrastructure isolation is a separate defence. An agent not calling through Runback at all is a different concern, covered below under Gateway credential isolation, SDK bypass detection and Governance coverage.
By default the gateway (@runback/gateway — base-URL swap, no SDK) forwards whatever credential the agent sends, so the key that reaches the gateway also reaches the provider directly, with nothing to tell you. RUNBACK_GATEWAY_UPSTREAM_KEY and RUNBACK_GATEWAY_TOKEN close that: the real credential lives only in the gateway process, injected server-side, while agents authenticate with a token worthless against the provider. Pair it with an egress rule allowing provider traffic only from the gateway. Unset by default, so it won't break local dev silently.
The SDK integration (withDebugger) has no separate credential to isolate — it never held one apart from your real provider key — so a call outside the wrapper can't be made to fail. It can be noticed, though: installBypassGuard() (or enforceCapture: true) watches for calls to a known model-provider host made outside an instrumented call and reports them as a governance finding, through the same ServiceNow/Jira/PagerDuty pipeline as a coverage gap. "observe" (default) reports and lets the call through, matching the gate's fail-open default; "block" throws. Opt-in, because it patches globalThis.fetch process-wide.
Every run exports as a SHA-256 hash chain with a final content digest, signed by Ed25519 by default — asymmetric, verifiable offline against our published key, no shared secret or account required. Change one byte and verification fails. The digest covers the run's replay oracle too, so the record is re-executable, not just readable. Without a keypair configured, deployments fall back to HMAC-SHA256: integrity, but not non-repudiation, since the verifier holds the same key.
Org-wide, hash-chained log of every run's digest, with signed checkpoints carrying a Merkle root for inclusion proofs — an auditor can verify any run belongs to the sealed history.
Our signature proves nobody else altered the chain — not that we didn't, since we hold the key. So every checkpoint is also time-stamped by two independent RFC 3161 authorities, on certificates we don't control and can't backdate: rewriting history changes the checkpoint head, and no authority will date a token for the new head earlier. The raw tokens verify with `openssl ts -verify` against the authority's own CA, so checking our tamper-evidence needs no Runback software. Time-stamping alone wouldn't catch us keeping two divergent but honestly-timestamped histories and showing each to a different party — so every checkpoint is also published to a public, unauthenticated, hash-chained feed (`GET /api/transparency`), where two heads for the same (log, seq) would sit side by side for anyone who archived it, and the database rejects the second write. We skipped a blockchain anchor deliberately: anchoring needs a public network that air-gapped installs correctly refuse to depend on.
Runback is a Next.js app and a Postgres database. Run it in your own VPC — traces never touch our servers, and there's no telemetry call-home in the self-hosted core.
Enterprise SSO via OpenID Connect (Authorization Code flow), with issuer, audience and nonce verification against the IdP's JWKS. Works with Okta, Microsoft Entra ID, Google Workspace, Auth0 and Ping. Routed per-org by email domain.
Four roles — owner, admin, member, viewer — enforced on every privileged route. Ownership is protected: only an owner can grant owner, and the last owner can't be removed or demoted.
API keys and session/magic-link tokens are never stored in the clear — only a non-secret prefix plus a SHA-256 hash. Session cookies are httpOnly, Secure and SameSite=lax with a bounded lifetime.
Recorded today: API key issuance/revocation, member invites/removals/role changes, model-provider credential changes, policy changes, prompt version saves and label moves, a human overriding a pairwise verdict or correcting a judge's calibration, legal holds placed/released, ledger checkpoint seals, evidence-package exports, and org settings changes. Each is written to a hash-chained log using the same primitive as the run ledger — deleting an entry breaks the chain, so the log can't be edited by the people it audits. Actor, source IP, and target are recorded; secrets never are. Not yet covered: SSO configuration and retention-window changes.
Okta, Entra ID or any SCIM 2.0 provider provisions and deprovisions members automatically — including the discovery endpoints an IdP probes at setup, PATCH/PUT profile pushes, and userName lookup resolved in the database whatever the directory size. Deprovisioning removes access immediately rather than flagging a row inactive, so there's no offboarding step to forget. The endpoint authenticates with a scoped token that can't ingest runs, read run content or open a session, and refuses to deprovision the last owner. Groups aren't implemented; ResourceTypes says so rather than letting an IdP find out mid-sync.
Retention deletion can be suspended for runs under a preservation obligation — litigation, a regulator request, an investigation — org-wide or per agent. Every deletion path consults holds first, and if the holds table can't be read the sweep is skipped: the failure favours keeping data. Placing and releasing a hold are both logged.
Administrative audit events forward to Splunk, Microsoft Sentinel, or any HTTPS collector hourly, so access evidence lands in your SOC, not just our dashboard. Delivery is at-least-once from a per-sink watermark, and every event carries its chain hashes so you can verify the feed wasn't altered in transit.
Declare the agents you expect to be governed and Runback reconciles that inventory against what actually reports: declared but never instrumented, reporting then gone silent, or observed while absent from your register. Findings open a deduplicated ticket in ServiceNow, Jira, or PagerDuty.
OIDC client secrets, customer model-provider keys, SIEM tokens, and workflow credentials are each AES-256-GCM encrypted under their own key, so rotating one never invalidates the others. Plaintext is never stored or returned by an API — only whether a secret is set, and its last four characters where that helps.
Every workspace is an isolated org. Run data carries a composite (org_id, run_id) identity enforced by the database, so a cross-tenant reference is rejected by Postgres, not a check someone might forget. Queries are org-scoped, and a source-level test fails any that aren't. Self-hosting gives each customer a dedicated database outright.
A root-cause explanation or a control's evidence summary can be AI-generated on demand, then sealed the way a run is: hash-chained to your org's prior narratives and signed, with the source evidence pinned by digest. If that evidence later changes, re-verification catches it. The explanation is disposable; the proof it wasn't rewritten is not.
A write-only, narrowly-scoped key lets a guardrail vendor (Lakera, Cisco AI Defense or similar) post findings into your own sealed record rather than siloing them in their dashboard. Each is hash-chained and signed on arrival, independently of your oracle chain, so a vendor's webhook can never alter a run's replay identity.
Issue a read-only, time-limited key scoped to specific runs — or all of them — from Settings, and hand an auditor that instead of a login. It downloads the same signed record your team sees: byte-identical, not a summary. Revocable any time, and every grant is checked for expiry and revocation on every read.
Known gaps with a plan, not surprises.
Data at rest is protected by Postgres and disk-level encryption in your VPC. Application-level field encryption (column-level or envelope encryption) is on the roadmap, not yet shipped. For regulated environments that require it, self-hosted deployment in your own KMS-backed VPC is the current path.
Tenancy is enforced by schema for run data: a run is (org_id, run_id), not run_id alone, and events reference runs through a composite foreign key — the database rejects a cross-tenant reference. RLS is enabled on every table, anon/authenticated roles are revoked, and default privileges close new tables on creation. A dedicated `tenant` database role exists that cannot bypass RLS, with policies reading the tenant from a short-lived signed token rather than the query — so a read through it returns only one org's rows, and a missing filter returns nothing rather than another customer's data. Run reads are migrated first; ledger and compliance paths follow. To be precise: policies are load-bearing only where the tenant role is configured — remaining paths still run as a role that bypasses RLS, and writes are unchanged. Until every path migrates, isolation there rests on application-layer filtering plus CI guards that fail any query filtering on a run id without an org. Full design and rollout state: docs/RLS-PLAN.md. Active on this deployment: the migrated read paths run as the `tenant` role.
Session cookies are valid 30 days with no sliding expiry, no rotation on privilege changes, and no admin-initiated revocation. A future release adds per-session revocation (sign out everywhere), automatic rotation on privilege changes, and last-seen tracking. If you suspect a session is compromised, hello@runback.dev can manually delete the session record.
Managed cloud currently resides in the US; self-host keeps data in your own region. EU and AU managed regions are on the roadmap with no committed date. Enterprise self-hosted is available now, in any region.
Runback holds no SOC 2 or ISO 42001 report today, and we are not going to imply otherwise. What we can give your reviewer is the mechanism behind each criterion, so the assessment is about evidence rather than a missing logo. Every row below is behaviour that ships in the product now.
| Criterion | Requirement | How Runback meets it |
|---|---|---|
| CC6.1 | Logical access is restricted | OIDC SSO with per-org domain mapping, four roles enforced server-side beneath every route gate, and API keys issued against narrow scopes that cannot be used outside their purpose. |
| CC6.2 | Access is authorised before being granted | Membership is created only by an admin invite or by SCIM from your identity provider; the default role for federated users is set per org. |
| CC6.3 | Access is removed when no longer required | SCIM deprovisioning removes the membership immediately rather than marking it inactive. The last owner of an organisation cannot be removed, so an IdP error cannot strand a workspace. |
| CC6.6 | Data in transit is protected | HSTS with preload, a strict Content-Security-Policy, and HTTPS enforced at configuration time for every outbound integration — a plain-HTTP collector endpoint is rejected rather than accepted and used. |
| CC6.7 | Data at rest is protected | Disk-level encryption, plus AES-256-GCM application-level encryption for every stored credential, each under an independently rotatable key. Field-level encryption of run content is a disclosed gap above. |
| CC7.2 | Anomalies are detected | Server faults are captured, grouped by fingerprint, and pushed as a digest rather than logged unread. Ledger verification re-derives every entry from current data, so alteration is detected, not assumed absent. |
| CC7.3 | Incidents are evaluated and acted on | Governance findings — a ledger that fails verification, a critical agent gone silent — open a deduplicated ticket in ServiceNow, Jira, or PagerDuty, with an owner and an SLA. |
| CC4.1 | Controls are monitored over time | The administrative audit log records in-app operator actions — key changes, membership/role changes, policy changes, legal holds, checkpoint seals, evidence exports — in a hash chain the operators can't rewrite, and exports hourly to your SIEM. See the entry above for coverage detail. |
| C1.1 | Confidential information is identified and protected | On the Vercel AI SDK and Python/LangGraph collectors, redaction runs inside your process before egress, so secrets and PII never reach us. Integrations that ship via OpenTelemetry send raw spans to us first and are redacted server-side before storage or display instead — see the Integrations doc for which paths that applies to. Tenant isolation is enforced by the database through a composite key, not application checks alone. |
| P4.2 | Personal information is retained no longer than needed | Per-plan retention prunes payloads then summaries on a schedule, with deletions recorded so an audit trail can tell policy from tampering. Legal hold suspends deletion where a preservation obligation applies. |
| A1.2 | Availability is monitored | A health endpoint reports readiness against the database and answers 503 when it cannot serve, so an external monitor reacts without parsing a response body. |
A short kit so your assessment doesn't start from a blank page.
A one-page architecture & data-handling summary and a pre-filled questionnaire covering access, encryption, data flow and sub-processors. Open the procurement kit →
A Data Processing Agreement, Terms of Service and Privacy Policy ready for your legal team. DPA available on request for signature.
The fastest security approval is the one where nothing leaves your perimeter. Run Runback in your own VPC and most reviews get short.
On Enterprise, we sit in your security review and answer questions directly. Start one →
Self-host so nothing leaves your perimeter, or start a review with us — we'll bring the documents.
Found a vulnerability? security@runback.dev — acknowledged within two business days.