Security
Security
An overview of how Rough is designed to keep your product safe — described from how the system actually behaves, not from marketing language.
Rough sits inside other people's products. That's a serious responsibility. This page describes how the system works in practice. Where we don't yet have a published guarantee, we say so. If you need something specific for a procurement or compliance review, email us at hello@rough.app.
The boundary that matters
The most important security property in Rough is the boundary between the host product and a Rough Feature. Features are run inside an isolated runtime — a sandboxed iframe with a typed postMessage bridge — and they can only interact with the host through that bridge.
That bridge has a fixed shape: a list of named tools, each with its own
input and output schema. Anything that isn't on the list isn't reachable.
There is no eval, no privileged channel, no implicit access to
host cookies, local storage, or DOM. The bridge is the only way in or out.
Practically, this means:
- A Feature cannot read host cookies, headers, or session storage.
- A Feature cannot inspect or modify host DOM outside of its own iframe.
- A Feature cannot call host APIs except through tools the host has registered.
- A Feature cannot escalate to other Surfaces or other Features.
Tools are your access control
Every action a Feature can take on the host has to be registered as a tool. Tools are implemented in your codebase, in your runtime, with your own auth and authorisation logic. Rough's job is to carry the call across the bridge — not to decide whether it's allowed.
The implication is that your usual access checks still apply. If your
createTask mutation already checks that the calling user can
create a task, that check still runs when a Feature triggers it. Don't
skip that work just because the call originated from Rough.
Schema validation on every call
Tool inputs and outputs are described with Zod schemas. Both sides of the bridge validate against those schemas. This means a malformed payload from a Feature is rejected before it reaches your tool implementation, and a misbehaving host can't return shapes the Feature isn't prepared for.
The same schemas drive type generation and mock data, so the contract your engineers reason about is the contract that's enforced at runtime.
Authentication
The Rough SDK is initialised with an API key and a project ID. The API key authenticates your project against Rough's APIs; the project ID scopes everything that follows to a specific Rough project under your workspace.
Authentication of your users is your responsibility. Rough doesn't issue tokens for the people using your product, doesn't sit in your auth flow, and doesn't bypass it. When a Feature calls one of your tools, the call lands in your code with whatever session and identity context your app already had.
Data handling
A Feature only ever sees what the host hands to it through tools and context. If a tool returns a redacted record, the Feature only sees the redacted version. If the host doesn't expose a piece of data, the Feature has no way to obtain it.
For data that does flow through Rough's own systems — Feature definitions, build artifacts, and product management content — see our privacy policy. The privacy policy is the canonical source for how we handle data we receive, including our position on AI provider usage.
The AI provider question
Rough uses third-party AI providers to power the Feature builder. Per our privacy policy, we don't permit those providers to train on customer data, and we don't store AI prompts or outputs beyond what's needed to deliver the Feature you asked for. If your compliance team needs the specific list of providers, contact us.
Workspace isolation
Rough is multi-tenant. Workspaces are the top-level isolation boundary; everything below — projects, surfaces, features, members — is scoped to a single workspace. Cross-workspace access doesn't happen through the product surface.
Things to do on your side
A safe integration is mostly about discipline on the host side. We recommend:
- Treat every tool as a public API. Validate inputs, check authorisation, and rate-limit where it matters.
- Only expose the data and actions the Surface actually needs. Don't pass the whole user record if a Feature only needs a name.
- Be explicit about which Surfaces exist in your product. Embedding
RoughSurfaceis a deliberate choice, not a default. - Watch the management dashboard. It shows what's been built, who built it, and which Features are getting used.
What we'll add to this page
This page is intentionally conservative. We'd rather describe what the system does today than promise things we haven't formalised. As we publish more — independent assessments, standards alignment, regional data residency options — we'll fold the details in here.
If you have a specific security question, write to us at hello@rough.app.