security: Fail closed.

ConvOps security fails closed. No context, no data. No verified person, no write. No approval, no step. Every layer a request crosses is built to refuse first.

row-level security with force · server-stamped identity · gates that refuse

request pathexample
Claude CodeAdvance step: release notes approved
  1. Verified sign-inwho is calling
  2. Workspace isolationwhich workspace
  3. Role checkallowed for this role
  4. Engine gateis the step ready
  5. Audit recordkept, before and after
travelling
in short

Is ConvOps secure enough for AI agents in production?

It is built to fail closed: no workspace context, no data; no verified person, no write; no approval, no step. Each claim below names its limit.

ConvOps is the operations layer for AI agents: an MCP server that holds your team's process as workflows, with approval gates, a shared memory and an audit trail. It runs no AI models.

key facts · october 2026

  • Tenant isolation uses Postgres row-level security with FORCE, so even the table owner is subject to the policy.
  • The human identity on every write is derived on the server from the verified credential. It is never a request parameter.
  • The MCP surface uses OAuth 2.1 with JWKS verification. API keys are bcrypt-hashed, shown once, and act as their user until revoked.
  • There are three roles (owner, admin, member), enforced with real 403 refusals at the route and service layer.

best for

  • Security reviewers who want specific controls and their limits in writing.

not for

  • Teams that need scoped or expiring API keys today. Keys have no scopes or expiry.
  • Buyers who need a certification report. See what we do not claim below.

updated

the review

The three questions every review asks.

Before a team lets AI touch real work, someone has to answer these. Plainly, and with evidence.

“Can another team see our data?”

One missing filter in one query, and a workspace leaks. Application checks alone are one bug away from it.

“Was that the AI or a person?”

If the log trusts whatever name the caller sends, the log proves nothing.

“What stops an agent going too far?”

A rule written in a prompt is a request. The model can skip it, and nobody sees it happen.

the request path

Five layers. Each one can say no.

Every request from an AI client crosses the same layers, in the same order. Pick one and watch where it stops.

send a request
request pathexample
Claude CodeAdvance step: release notes approved
  1. Verified sign-inwho is calling
  2. Workspace isolationwhich workspace
  3. Role checkallowed for this role
  4. Engine gateis the step ready
  5. Audit recordkept, before and after
travelling
data isolation

Every workspace is sealed.

A query reads only the workspace its context points to. The wall is in the database itself, so an app bug cannot open it.

member of Support · exampleShow the refund tasks
Support
  • Refund over 200
  • Reply to ticket
  • Close duplicate
Finance
Engineering
global catalogthe only shared rows
what holds

Six claims. Each with its limit.

Every claim comes with how far it goes and how it works. Read the middle row first.

Workspace isolation

01
What holds
A query without workspace context returns nothing. Not an error path: the default.
How far it goes
Every workspace-scoped table. Global catalog rows are the only shared surface.
How it works
Postgres row-level security with FORCE, so even the table owner cannot bypass it. App scoping and middleware sit on top.

Who did it

02
What holds
The person on every audit row comes from their verified sign-in.
How far it goes
The agent name beside it is self-declared, and is shown as exactly that.
How it works
Stamped server-side. No field, header or tool parameter exists that could carry it.

Sign-in

03
What holds
People sign in through the browser. No credentials sit in the AI client config.
How far it goes
API keys exist for automation. They have no scopes and no expiry.
How it works
OAuth 2.1 with JWKS verification. Keys are bcrypt-hashed and shown once, at creation.

Roles

04
What holds
Owner, admin, member. A refusal is a real 403, not a hidden button.
How far it goes
Three roles. No custom roles and no per-item permissions.
How it works
Checked at the route and the service layer. Last-owner protection keeps every workspace owned.

Audit

05
What holds
Every change to a task or a workflow run is kept, field by field, before and after.
How far it goes
Tasks and workflow instances. Not every table. Read it in the web app or the API.
How it works
Field-level diffs, plus a per-step history with the decision context.

Gates

06
What holds
A step whose gate is not met does not move. The agent is told what is missing.
How far it goes
Gates are the enforcement. Policies are guidance the agent reads at the step.
How it works
The engine checks the gate against real state on every advance, not the agent.
on the record

What we do not claim.

A security review should not find surprises. These are the limits, stated before you ask.

not claimed8 limits, on the record
  • 01

    Scoped or expiring API keys

    Keys have neither. A key acts as its user until you revoke it.

  • 02

    Granular permissions

    Three roles: owner, admin, member. Nothing finer.

  • 03

    An audit trail of everything

    Before and after diffs cover tasks and workflow instances only.

  • 04

    A recorded approver on every gate

    A gate records that approval was given. Who approved is not stored separately.

  • 05

    Policies that block

    Policies are guidance delivered to the agent. Gates are what refuse.

  • 06

    A verified agent name

    The agent label is self-declared. Only the person is verified.

  • 07

    Compliance certifications

    This page lists none. Ask us what your review needs.

  • 08

    Self-hosting

    This page describes the hosted service only. Ask us before assuming more.

the principles

Five ideas the model rests on.

Fail closed

Missing context, a missing identity or an unmet gate all end the same way: nothing happens.

the default state

The wall is in the database

Isolation lives in the database itself. A bug in the app still cannot read across.

row-level security

Identity is derived

Who you are comes from your sign-in, never from what a caller says.

server-stamped

Three plain roles

Owner, admin, member. Simple to review, real refusals.

real 403s

Changes are kept

Before and after, field by field, on tasks and workflow runs.

scoped, honestly

the mechanics

The exact policy and payloads.

For the engineer on the review. The real policy, the real audit fields, and the scope of each.

The policy, as applied

Every tenant-scoped table carries this RLS policy, applied with FORCE. Rows with no owner are the shared global catalog.

payload
USING (
  org_id = current_setting(
    'app.current_tenant_id', TRUE)
  OR org_id IS NULL
)
The policy, as applied. Global catalog rows are the only shared surface.

Two identities on one row

The agent label is self-declared. The user fields are stamped server-side from the verified credential.

payload
{
  "actor": "implementer",
  "actor_user_id": "usr_…",
  "actor_user_name": "David Marsa"
}
Server-derived, never accepted as input.

Authentication

The MCP surface uses OAuth 2.1 with JWKS verification. A static key path exists for automation. Keys are bcrypt-hashed, shown once, scoped to the user across their workspaces.

Audit scope

Field-level before and after diffs on tasks and workflow instances. Per-step history with decision context. The audit endpoints are REST and web app only; there is no MCP tool for them.

security review

Reviews happen with a person.

security review

Bring the questionnaire.

Bring your questions. We go through each control on this page with you, including where it stops.

  • Your questionnaire
  • Your data-flow questions
  • The person who signs off
questions

What reviewers ask first.

What happens if a request arrives without tenant context?

It reads nothing. The row-level security policy keys on the request's tenant setting, and with FORCE applied even the table owner cannot step around it. Fail closed is the default state, not an error path.

Can I recover an API key I lost?

No, by design. Keys are bcrypt-hashed at rest and displayed exactly once at creation; if one is lost, you revoke it and mint another.

Where does the human identity on an audit row come from?

From the verified credential, stamped server-side. There is no request field, header, or tool parameter that carries it, so it cannot be spoofed by an agent or a caller.

Do you support SSO?

SSO and SCIM are part of the Enterprise plan. Standard sign-in is OAuth; the MCP surface authenticates with OAuth 2.1 and JWKS verification, with a static key path for automation.

How granular are roles?

There are three: owner, admin and member. They are enforced with real 403s at the route and service layer, with last-owner protection. There are no custom roles or per-item permissions.

Do API keys expire, or carry scopes?

No to both. A key acts as its user, across that user's workspaces, until it is revoked. People sign in with OAuth; keys are for automation, and should be handled like passwords.

What does the audit log cover?

Field-level before and after diffs for tasks and workflow instances, the places where agents act. It does not cover every table. The audit log is read in the web app and the REST API, not from inside the chat client.

Can my search reach another workspace?

Only the workspaces you are a member of. Recall searches across your own memberships in one query; each memory stays owned by its workspace, and every write lands in exactly one.