DocsLetting it run, and with a teamSecurity and privacy

Security and privacy

The short version: Memnox is a control that other controls depend on, so it is built to be inspectable rather than to be trusted.

What it never stores

Not stored

Provider OAuth tokens and refresh grants

The integration provider

Raw tool-call arguments

Nothing, matched in-process, then discarded

Card details

The payment provider

Model credentials for extraction

The deployment's own, held once and never per workspace

The argument one deserves expanding. A rule can match on the contents of a call, command = [ "*rm -rf*" ], and the raw payload is the one thing a control plane should not collect. So it is matched in-process, inside the MCP proxy or the PATH wrapper, which already held it because they sit in the path. What is recorded is the tool, the target and the rule ids that matched, and the argument list survives only as a digest.

What it does store

Source events with their permalinks, decisions with their approvers, audit events with their hashes, people with their resolved identities, and the configuration you set. Every table is classified in the data inventory below, including whether it is encrypted at rest.

Authentication

Caller

A person, in a browser

Google or GitHub sign-in → httpOnly session cookie + CSRF cookie

A person, via IdP

OIDC → same session, and the role still comes from the account here

An agent

Its own grant, minted in the console and shown once

The open runtime has none of this. It issues no token and listens on no port, so there is nothing on a laptop to authenticate to. Everything above is the hosted control plane.

An unknown credential is refused and audited as critical. Fail closed.

Inbound verification

Every webhook route verifies over raw bytes, before parsing, and every shared-token comparison is constant-time.

Route

Integration events, from every toolkit

Standard Webhooks HMAC-SHA256 over id, timestamp and raw body, with a replay window

GitHub App deliveries

GitHub's x-hub-signature-256 with the App's webhook secret

Meeting and document relays

An admin bearer token

Payment provider events

The provider's own signature

Rate limiting applies per workspace on every inbound route. See Connected systems.

Where models are, and are not

Path

Policy evaluation

None

Risk classification and scoring

None

Command classification and the verb tables

None, a fixed table checked into the repository

The briefing memnox policy test returns

None, your own rules quoted verbatim

Decision extraction

An LLM, and its output requires human approval

That table is the security argument for the whole product. Everything that decides is deterministic; the one thing that guesses cannot act.

Fail-closed, and the one exception

Unknown identity, unreadable state or ambiguous input denies.

The ledger is the exception in the other direction: a row that cannot be written is a lost row and never a stopped command, because a gate that fails a command over its own bookkeeping is a gate somebody removes. Provenance is the exception to that: an unreadable taint store means the session is treated as tainted.

Break-glass leaves a mark

An admin override requires a reason, is audited as critical, and opens an incident. Irreversible actions (project.delete, database.drop) refuse break-glass with a 403 and audit the attempt.

Tamper evidence and its limit

The audit chain detects edits to a log you control. It does not stop an operator with database access from rewriting the whole chain.

If you need a stronger property, ship every decision to a sink outside the same trust boundary, an S3 bucket with object lock, or a Kafka topic your security team owns.

Privacy, retention and erasure

Memnox keeps its Article 30 record as code, and a test asserts it covers every table that exists, so storing something new without classifying it fails the build. The consequence is the part you can use: the register cannot drift from reality, so handing it to an auditor is not hoping somebody updated a spreadsheet.

Every table is classified four ways: what kind of personal data it holds (none, identity, content, behavioural, commercial), its lawful basis (contract, legitimate_interest, legal_obligation, not_applicable), how it is erased, and whether it is encrypted at rest.

Rows either delete outright, or are crypto-shredded where deleting would break an integrity guarantee. That second case exists because of the audit chain: each event's hash covers its content, so removing a row would break every hash after it. Destroying the key instead makes the content unreadable while the chain still verifies, which is erasure of the content and preservation of the proof that something happened.

Export returns everything held about a subject, table by table. Erasure applies the per-table strategy and returns a receipt: which tables were touched, how many records, and by which strategy. Keep the receipt, it is the evidence the request was honoured.

The model key, and what a model is never used for

There is one model credential and it belongs to the deployment. A workspace cannot bring its own, and nothing in the API accepts one: no route reads or writes a per-workspace key, and no table holds one.

That has a consequence worth stating rather than hiding, because it is the reason usage is metered at all. Every extraction run in a deployment is spent on the same credential, so one busy tenant can spend the allowance the rest of them were relying on. What bounds it is the plan: extractionRunsPerMonth is spread across the month, and the usage log is what says where it went.

A model is used to

Read decisions

Turn what your team already wrote in Slack, GitHub or Notion into candidate decisions, which a person then approves or throws away.

Summarise a period

Write a paragraph over a timeline somebody is about to read, after every count in it has already been computed deterministically.

Search

Embed source events so search finds a decision by meaning rather than by keyword.

Nothing on that list decides anything. Whether an action is allowed, who has to approve it, what the rules are and what happened afterwards are all answered deterministically, with no model in the path. That is why a workspace with no key at all still governs its agents completely.

Choose the model under Settings → Model: three curated presets, or the full list with its own reasoning control. Only models this deployment can actually construct are offered, and a reasoning level a model does not support is refused rather than quietly lowered.

Reporting a vulnerability

The runtime repository carries a SECURITY.md with the disclosure process. Please use it rather than a public issue.