Skip to main content

Security

Metatate Cloud's security model is a set of enforced boundaries, each backed by tests that must stay green for a change to ship. This page walks through them one at a time. Metatate never claims a boundary it cannot demonstrate, and it does not describe internal mechanisms here — only the guarantees they produce.

Workspace isolationDirect link to Workspace isolation

Every workspace-owned table carries its workspace's ID, and row-level security at the database layer is the isolation boundary. Members can read only the workspaces they belong to; a query from one workspace against another workspace's rows comes back empty. Isolation is exercised by dedicated negative tests — cross-workspace reads and writes are required to fail — and every write goes through a server-side operation that re-verifies your role before touching data.

The MCP server adds its own layer. Each tool call resolves the workspace entirely from the bearer token and pins every read to that workspace; auth fails closed. A reference to another workspace's asset is indistinguishable from an asset that does not exist, so the API cannot be used to probe what other workspaces contain.

MCP access tokensDirect link to MCP access tokens

Workspace access tokens for the MCP server are designed to be safe to operate:

  • Hashed at rest. Only a cryptographic hash is stored. The platform cannot re-display a token, and nothing member-readable exposes the hash.
  • Shown once. The plaintext is returned exactly once at issuance and never persisted.
  • Revocable, with optional expiry. Admins and owners issue and revoke tokens; issuance and revocation are recorded in the workspace Activity log.
  • Uniform unauthorized. A missing, malformed, expired, revoked, or unknown token produces the same unauthorized response — the API does not reveal which check failed.
  • Scoped, with the write lane off by default. Every token carries read; the additional request scope exists only if an admin deliberately granted it at issue or by rotating the token. Scopes come only from the verified token row — never from a header or from tool input — are immutable for the life of a token, and a tool whose scope the token lacks is refused before its input is parsed, with one byte-identical message for every tool and token.
  • Optionally identity-bearing. A token may declare an agent kind, an agent name, and a bound role. The bound role is the only actor identity decisions are evaluated against; no tool accepts a role as input. A token with no bound role fails closed on role-gated rules.

Rate limits and quotas are enforced before any tool work runs, and errors use a closed, redacted set of codes that never include raw SQL, token material, credentials, or connector details. See Connect an agent for token setup and scopes.

What an agent can and cannot writeDirect link to What an agent can and cannot write

Metatate's MCP surface is nine tools. None of them can modify governance state — not policies, not deployment plans, not publications, not served decision rows — and none of them reaches your data platforms.

Two nuances are worth stating precisely rather than rounding off to "read-only":

  • authorize_use and validate_query_context write durable decision evidence before returning an answer. That record is what makes the answer citable later. It is not your governance, and it cannot change a decision — but it is a write, and if it fails the tool call fails rather than returning an uncited answer.
  • request_access is the one workflow write: a review request in an admin/owner inbox. It requires the separate request scope, advertises itself honestly as a non-read-only tool, derives its scope and purpose server-side from the record it cites, re-evaluates that record against current published state before accepting, and is capped at 100 open requests per token.

Granted exceptions are the only thing that can relax an answer, and they are tightly bounded: subject-scoped to the single token that asked, scoped to one asset, scenario, and purpose category, expiring in at most 90 days, revocable immediately, and verified twice in the database — subject, liveness, and scope — on every use. A failed verification is one uniform result, so a caller cannot probe whether some other exception exists. Caller-asserted approvals and caller-supplied roles do not exist as inputs anywhere.

The set of denies an exception may waive is empty. Conflicted and insufficient published state can never be exception-overridden; their remedy is authoring and republishing.

Connector credentialsDirect link to Connector credentials

Credentials for your data platforms are stored by reference in a managed secrets vault — application tables hold a reference, never the secret. Decryption happens only inside isolated sync workers; credentials are never returned to the browser and never re-shown after entry. Connector configuration visible in the app excludes secret material entirely. You can rotate a credential at any time — rotation replaces the stored secret in place and is recorded in the activity log — but no flow displays or exports one.

Network egressDirect link to Network egress

Outbound connector traffic is guarded before any connection is made:

  • Private-address refusal. Connections to private, loopback, link-local, multicast, and unspecified addresses are refused. For connectors where you supply a hostname, the name is resolved and checked before dialing, and this refusal is never relaxed in production.
  • Closed allowlists for cloud APIs. Connectors for cloud-vendor APIs talk only to a closed allowlist of the vendor's own endpoints, over verified TLS. Endpoint overrides embedded in an uploaded credential file are ignored in favor of the fixed vendor endpoints.

The AI boundaryDirect link to The AI boundary

AI assistance runs server-side, in an isolated internal service. Model-provider keys live only there — never in the web app and never in the browser — and customer data passes a redaction step before any call to a model provider. Prompts never carry secrets, credential material, or connector details. AI output is a suggestion, not an authority: AI-assisted classifications are written through the same guarded server-side path as deterministic ones, and manual decisions always take precedence over them.

PaymentsDirect link to Payments

Payment processing is delegated to Stripe. Checkout and subscription management happen on Stripe-hosted pages, so card data never touches Metatate. Payment-provider secrets are confined to an isolated billing service that the browser cannot reach; incoming billing events are signature-verified and processed idempotently, and billing logs and audit events never contain card data or raw payment payloads. What your plan entitles you to is decided by Metatate's own records, not inferred from the payment provider.

Roles and least privilegeDirect link to Roles and least privilege

Every membership has one of four roles — viewer, editor, admin, owner — and they are enforced capability tiers, re-checked server-side on every write, not UI labels:

Capabilityviewereditoradminowner
Read the workspace
Author policies, curate the catalog, publish deployments
Manage connectors, MCP tokens, members, billing
Grant owner/admin, change roles, edit workspace settings

A reserved service-account role exists for future machine identities; it is non-grantable — no invitation flow can issue it. Roles are assigned when you create a workspace and invite your team.