MunitasFeature tourAll walkthroughs

Feature walkthrough

Munitas
A governed data platform that can prove what happened to your data.

Munitas is an open-source governed data platform that runs on a single machine. It decides who may read which piece of data, for what purpose and for how long, and keeps a permanent record of every decision, every dataset, every pipeline step that touched it, and every AI agent that read it. Three example organisations run throughout this page and the guided walkthroughs in section 3, for illustration: a health organisation, a finance organisation, and a small clinic used to show closing down an account.

Checked by scripts that run against the live system, not against a mock of it Platform and services under open-source licences that allow commercial use Real sign-in for every person who acts

01 · What it does

It decides who may read which data, and holds AI agents to the same rules

Munitas keeps an organisation's datasets and decides, for every request to read one, whether it is allowed. A dataset is a named collection of records, such as a table of patient admissions. It is kept as numbered versions, and a version that is sealed (finished and closed for good) can never be edited. Each dataset belongs to one department, the team that owns it, and has a sensitivity level that says how restricted it is. A person who needs a restricted dataset asks for it and says what the work is for. An approver of the owning department, called a data custodian, accepts or refuses. An accepted request gives access for that purpose and for a limited time, and every decision is recorded with its reason. The result is the kind of proof a title document gives for a property: what is held, by whom, and on what terms.

The same rules cover AI agents. Most data platforms carefully track datasets and stop there, while the AI agents that read those datasets are treated as ordinary software: deployed, changed and rerun with no permanent record of which version did what. In Munitas an agent is registered and given sealed, numbered versions, exactly like a dataset. When it runs, it gets an identity assigned by the system it runs inside, not by anything the AI model can read or write, so a malicious instruction hidden in a document cannot change what the agent is permitted to do.

Two worked example agents ship with the platform. The triage agent ranks the queue of transcripts waiting for a human to check, so reviewers start with the riskiest rather than the first in the list. The note drafter drafts a visit note from each consultation transcript, for a clinician to read, correct and sign. Section 6 describes the triage job in full, including how it has to ask a custodian for access before it can read that queue at all.

Everything below is built and running today. In detail, the platform can:

Data

  • Seal a dataset version so nobody can alter it afterwards. The database itself blocks the change, so a bug in the application cannot bypass it.
  • Make data available to a wider audience without copying or moving any files. Changing who may read a version only changes which access credential unlocks it.
  • Make a new dataset from a query over an existing one. The new dataset is kept as restricted as its source, and withdrawing access to the source closes it too.
  • Erase a person's records permanently without rewriting any sealed dataset, by destroying the key the records depend on.
  • Lock the columns of a table that identify a person, so the values stay unreadable until an approver of the owning department decides a specific request to read a few rows. A privacy auditor can see how the locked columns were used in a report that contains no names.
  • Lock files as they arrive, each under a key made for one person, so that one person's files can be erased later without touching anyone else's. A mistake in the list of people is caught before anything is sent.

Access

  • Require a real sign-in through Ory Kratos before anyone can act, rather than letting the console take someone's word for who they are.
  • Record every decision to allow or refuse access, along with the reason, so the history can be read back later.
  • Let an organisation set limits on what people may ask for, such as how many rows, for how many days, how many files and hours, and how much may be brought in as tables, each inside a maximum the platform sets.
  • Change who holds which role only through two people: one asks and says why, another decides, and the role lapses rather than lasting because nobody looked. The administrator who runs the platform is not one of the people who may decide.
  • Let a department have several approvers, any one of whom may decide, with every change to the list recorded alongside who made it and why.

De-identification and pipelines

  • Run a six-step pipeline that strips personal information out of audio recordings, then put the result in front of a named reviewer, with every identifier it measured as still left behind, before anything is released more widely.
  • Judge a release by a standard the organisation wrote: a named, versioned set of limits for one audience, chosen by the reviewer, worked out again at the moment of the decision, and kept with the decision together with its version.
  • Keep a pipeline version that is still being built away from real data. It may run only on a development sample that the platform draws, after an approver of the owning department has chosen how much to allow, or on files declared to hold no real person. A sample ends on its own.
  • Let an organisation's own code run as one step of a pipeline, reading files and writing files, but only after an approver of the owning department who did not upload it has approved it. The step runs in a container with no route to the internet, and what it writes is sealed as a new version that waits for a review.

AI agents

  • Pause an agent partway through a run and hold it there until a person approves it. The pause survives a restart, so approval can come days later.
  • Hold AI agents to written risk levels. An AI risk owner writes the levels, and once an organisation switches this on, an agent needs a level the risk owner has confirmed before it can start a run. A named sponsor confirms each agent again on the schedule its level sets.
  • Hold back a new version of an agent that would let it do more: a new tool, a new outside host, a copy of the data or a different model. A version that adds only tools on an approved list is approved in advance, and a first version is always decided by people.
  • Have what an agent drafts reviewed by someone other than the person who started the run, suspend an agent, and bring what the platform holds about it into an evidence pack for an auditor: identifiers, counts, hashes and times, and no personal data.
  • Let a sandboxed agent read the real dataset it was scoped to, through a copy it fetches itself over an isolated network, capped in size before a single byte moves.

Notebooks, storage and accounts

  • Sign a notebook in without pasting a session: the notebook shows a code, the person approves it in the console, and the notebook receives a short-lived pass that the person can end. The notebook installs its client library from the platform itself with pip.
  • Store each organisation's data in its own isolated bucket, and on Cloudflare R2 its own short-lived credential, so a leaked credential reaches one customer rather than all of them.
  • Close down a customer account in two stages, hold it back while a legal matter is open, and produce its records as an encrypted, signed package that no single administrator can request and approve alone.
  • Show what storage each organisation is using, on which backend, and free what is no longer needed, rehearsing exactly what would be removed before removing it.
  • Write one line of log per event carrying identifiers and never contents, with anything resembling a secret redacted before it is written.

02 · Value to your organisation

The hard part is not storing the data. It is accounting for it afterwards.

An auditor gets an answer, not an assurance

"What did this model read, under whose authority, and who approved it" becomes a database query. Every decision to allow or refuse access was recorded at the time, together with the reason, so nobody has to reconstruct events from memory and old chat threads.

An incident can be traced with one query

Any suspicious output can be traced back in a single query to the exact code, software image and input data that produced it. Each agent run permanently records the version that actually ran, so deploying a newer version afterwards does not obscure what happened.

A prompt-injection attempt ends as a refusal

Because an agent's identity is held outside the model, the most a hidden instruction can achieve is to be refused and logged. There is no higher level of access for it to reach, because the permission check never reads anything the model produced.

Serious agent actions cannot skip human review

The review step is built into how the agent runs, not written down as a rule staff are expected to follow. The run stops before the significant step and can only continue once a second person approves it, and that person must belong to the same customer and must not be whoever started the run.

Publication rules keep working as data changes

Whether a dataset may leave the organisation is worked out from where it came from and what its licence permits, traced through everything that has been done to it. It does not depend on a person remembering to set a field correctly.

A leaked storage credential does not become a breach of every customer

Storage credentials are scoped to one organisation's bucket, rather than being one key shared across every customer. A credential that rests on an approved lease, or that is issued to a single task such as a pipeline step, a derivation run or an agent run, opens only the dataset versions that were allowed and ends with the lease or the task. On Cloudflare R2 every credential is short-lived. Losing one credential exposes only what it was scoped to, not the whole platform.

03 · See it working

Real screens, from real live runs

Each walkthrough follows one story step by step, with real screens captured from a running Munitas.

Open the walkthrough index, which also says where to start →

04 · Core concepts

Seven ideas that the rest of the system is built on

The department that owns the data decides who may read it

Every dataset belongs to one department. Only that department's approvers can accept a request to read it, and any one of them can. Ownership therefore decides who may say yes, rather than seniority or whoever happens to be available, and the person asking can never be the one who accepts.

Access is for a purpose and for a limited time

A request names one dataset version, what the work is for and why it needs that data. An accepted request is a lease: it is tied to that purpose and ends on its own. If a lease is withdrawn, any dataset made from the data under it is closed too.

Widening access never moves the data

Every dataset version sits at one of five sensitivity levels, shown in the console in capitals. RAW is the original data and the most restricted. UNDER_REVIEW, OPEN_FOR_ANNOTATION and OPEN_FOR_TRAINING follow, each less restricted than the one before. PUBLISHED is generally available and the least restricted. Moving a version up to a less restricted level changes only which access credential opens it. The files themselves are never copied or rewritten, which was confirmed by checking that their storage keys and checksums are identical before and after.

Sensitivity and origin are two separate questions

Sensitivity decides who inside the organisation may read a dataset. Its origin decides whether it may leave the organisation at all. A public benchmark and a clinical dataset with names removed can be equally safe to read internally, while only one of them may be published. Treating these as one setting either blocks harmless downloads or releases regulated data as soon as it looks safe enough to read.

An agent's identity is assigned, never self-declared

An agent's identity is held by the program running it and is never part of the data the AI model can see or modify. Every time the agent tries to use a tool, its permissions are rechecked against that assigned identity. This is what protects against prompt injection, where an attacker hides instructions inside a document the agent reads. Such an instruction can change what the model asks for, but it cannot change who the system believes the agent is.

Deleting a person's data without rewriting history

A person's records can be erased permanently without editing any sealed dataset. The platform destroys the key the record depends on, so the record becomes unreadable everywhere it ever appeared, while the dataset versions and audit trail stay exactly as they were. A short marker is kept to record that the deletion happened, so the fact of the erasure is not itself erased.

Agents and releases are held to rules the organisation writes

An organisation writes its own risk levels for agents, and its own standards for what a de-identified result must meet before it is released. Both are named and versioned, and neither is ever edited: a change adds a version with who made it and why, and a decision keeps the version it was judged by.

05 · Architecture

Four layers, and one record across all of them

Munitas is arranged in layers. People work through the Console or a notebook. Every request passes the governance layer: sign-in establishes who the person is, the API receives the request, and the policy engine decides it. Work that runs code happens in the processing layer, and the three kinds of code that are not the platform's own, an organisation's custom pipeline steps, derivation queries and sandboxed AI agents, run in places with restricted reach. Files and tables live in storage, one bucket per organisation, with a key for each person whose data is locked. A record of every decision runs across all of the layers.

Munitas in layers A layered picture of Munitas. People work through the Console and notebooks. Governance decides every request: sign-in, the policy engine and the API. Processing runs pipelines and jobs, and three kinds of code that are not the platform's own, in places with restricted reach. Storage holds files, tables and the keys for locked data. One record of every decision runs across all the layers. People and tools Governance Processing Storage Across every layer Console where a person works Notebooks Python and client library Sign-in knows who each person is Policy engine decides every request API every request passes here Pipelines and jobs long jobs run here Custom pipeline steps an organisation's own code Derivation queries run with no network Sandboxed AI agents every tool call is checked Object storage one bucket per organisation Tables readable with open tools Person keys one key per person Record of decisions and the reason for each Legend A service the platform runs A place with restricted reach: it has no route to the internet A layer API Application Programming Interface, the one place every request goes through

The picture is simplified. It shows the layers and the places with restricted reach, not every service or every connection.

06 · Who uses it

Eleven roles, and what each one does

Munitas has eleven roles that people hold. Every organisation is staffed from these same roles: someone who brings data in, someone accountable for each department's data, someone who asks to read it, someone who checks the decisions, an administrator who runs the platform itself, and so on. The entries below follow one example organisation, the health organisation used throughout this page. The finance organisation, covered in its own walkthroughs, is staffed by a different cast in the same roles. Each role signs in for real through Ory Kratos, and nothing can be approved, revoked or decided without that signed-in identity behind it. Open a role to read its steps. Each entry ends with the problem the steps solve.

Every person, including the administrator, can read published data by default and nothing more sensitive without a specific request that somebody else approves. Only the de-identification pipeline reads raw data, because removing personal information from raw recordings is the entire job it exists to do.

Ownership decides who may say yes. Hartley is a data custodian for Cardiology and Okonjo for Radiology: Hartley can approve access to Cardiology's data and cannot approve access to Radiology's, and Okonjo the reverse. A request goes to the people accountable for that particular data rather than to whoever happens to be senior or available. Every other role is barred from approving access. The data protection officer is excluded because approving access means deciding how data gets used, and GDPR Article 38(6) requires that an officer's other duties never create a conflict of interest with that oversight. The platform administrator is excluded because the account that operates the system should not also be able to grant itself access to what the system protects.

People who bring data in and use it

DeviData engineer

Brings data in, registers code and runs the jobs. Does not read what the jobs produce.

  1. Registers a new dataset, naming the department that owns it and where the data came from. The registration is refused if the department does not exist or the origin is left unstated.
  2. Loads the data in, either by uploading files or by importing from HuggingFace. The import runs in the background, so the screen responds immediately no matter how large the source is.
  3. Seals the version once loading has finished. The system refuses to seal it while an import is still running, so a version can never be sealed halfway through arriving.
  4. Uploads recordings for de-identification and seals them as recordings rather than as anonymous files. The platform reads each one and tells Devi its length and sample rate, so a truncated file is refused as it is added instead of surfacing later. If the set is incomplete, sealing is refused with every problem listed at once and nothing is sealed.
  5. Starts the de-identification personally, from the screen where the recordings were just sealed, instead of asking whoever has a terminal on the machine that does the work. Devi is refused, in writing and before anything starts, if the version holds ordinary files rather than recordings, if a recording arrived without the answer key the scoring needs, or if nothing is running to do the work. A refused start leaves nothing behind to clean up.
  6. Follows the run on its own page while it happens, step by step, rather than waiting without knowing whether it is working or stuck. At the end Devi is told it is waiting on a reviewer, and that Devi cannot be that reviewer, because Devi is the one who started it.
  7. Does not read the sensitive data the pipeline later produces from it. Running the loading process does not grant access to the results.
  8. Starts the triage agent against the review queue the pipeline left behind. Devi opens the agent, picks that dataset version, and says what the run is for.
  9. Is told before starting that the agent cannot read that data, which custodian would be asked, and that the request will be filed in Devi's name. Nothing is asked of anybody until Devi confirms.
  10. Sees the run listed as waiting for data access rather than as running. It has not begun, the screen does not pretend otherwise, and it moves only when the custodian decides.
  11. Registers an agent for a department and proposes a level for it. A new version that would let the agent do more waits for the approvals its level asks for, and nothing is deployed until they have said yes.
Without this: data arrives via a script somebody ran once, its origin is recorded in a wiki page if at all, and nobody can later establish whether a dataset was finalised before or after the last file landed.
SamResearcher

Works with the published data of an organisation from a notebook.

  1. Requests access to one specific dataset version, stating what the work is for and why it needs that data. Blanket requests for a whole department are not possible.
  2. Waits for an approver of the department that owns the data. Only the approvers of that department can say yes, and any one of them can.
  3. Asks the system for access once approved. It checks whether the role already allows this, and if not, whether an approved and still-valid grant covers it.
  4. Receives a credential for their own organisation's storage only, and only after the decision has been written to the audit record. A credential that rests on an approved lease opens that one dataset version and stops working when the lease ends.
Without this: finding out who can currently read a dataset means asking everyone who might hold a key, and access granted for a short project quietly continues working long after the project ends.
WrenAnalyst

Works with the data an organisation has published.

  1. Opens the datasets an organisation has published and works with them. Published is the least restricted of the five sensitivity levels.
  2. Has no power of its own beyond reading published data. To see anything more sensitive, asks for access to one dataset version and gives the purpose, like anybody else, and an approver of the owning department decides.
  3. Cannot approve a request to read data, register code, or decide whether a de-identified result may be released.
Without this: an account meant for reading published results is widened for convenience until it can read far more than the job needs, and nobody notices.

People who decide who may read

HartleyCardiologyData custodian

Answers for the data a department owns, and decides who may read it.

  1. Checks claims about how sensitive a dataset is. If whoever registered it said the data is less sensitive than the cautious default, an approver of the owning department has to agree before that claim takes effect. A custodian may also bring data in, but never confirms their own claim: another approver of the department does, and a claim made by a department's only approver waits until a second approver has been added.
  2. Reviews access requests for Cardiology's datasets. Each request names a specific dataset version, what it will be used for, and why that use needs this data.
  3. Is refused when trying to approve a request for Radiology's data, because Okonjo is an approver of that department and Hartley is not. Ownership is what grants the authority.
  4. Approves or refuses. Hartley cannot approve a request of their own, or one somebody filed on their behalf. Both the policy engine and the database enforce this independently.
  5. Sees a written reason with every refusal, naming which rule caused it, rather than only an error code.
  6. Sees requests made for an agent in the same queue as requests made for a person, showing which agent will read the data and which engineer asked for it. Approving one starts the waiting run; refusing it closes that run with Hartley's reason attached, so nothing is left waiting on a decision that has already been made.
  7. Manages who the approvers of Cardiology are. Hartley can add a person who already holds the data custodian role, give temporary cover that ends by itself, or remove an approver. Every change needs a written reason and stays in the history, and at least one permanent approver who can act must always remain.
  8. When an organisation is being closed down, its custodian can still cancel during the first 15 days. When records are produced for a legal matter, the custodian named by the legal hold confirms what the package covers.
  9. Agrees to the first version of an agent owned by Cardiology, with the AI risk owner confirming its level. A version that adds only tools on the approved list needs at most the department that owns the agent.
Without this: access is granted in a chat message, with no lasting record of who asked, what for, or what they actually received. Whoever answers first becomes the approver, regardless of whether the data was theirs to give, and the rule against approving your own request exists only on paper.

People who oversee and check

ImaniDe-identification reviewer

Judges whether removing identifying details worked well enough for a result to be released.

  1. Opens a queue of finished pipeline runs waiting on a decision. Each one shows what the run scored, what the check recommends, and why it recommends it.
  2. Reads the identifiers that survived redaction, one row each: which record and which character positions it sat at, what kind of identifier it was, how much of it was removed, and how it failed. This is the material the judgement is made on, so it is shown rather than summarised into a score.
  3. Promotes the result, or holds it back. Either way Imani writes a reason, and neither is possible without one.
  4. Cannot decide a run Imani started. The database refuses it, not only the interface.
  5. Is the only role that may make this call. A custodian owns the data and would be judging their own department's output; an administrator operates the system and holds no standing access to what it protects; and the data protection officer is the one later asked whether the release was sound, which is not a question you can answer about your own signature.
  6. Is under no deadline, and neither is the queue. Nothing expires, escalates or promotes itself while a decision is outstanding.
Without this: either a threshold releases data on its own, so a number stands in for a judgement about identifiers nobody looked at, or the release is agreed informally and there is no record of who accepted the risk, on what evidence, or when.
NakamuraData protection officer

Watches how personal data is handled, sets the de-identification standards, and may stop an agent.

  1. Reads every access decision the platform has recorded, both grants and refusals, across every department and customer Nakamura is responsible for overseeing.
  2. Reads no more of the underlying data than any other member of staff. Being able to review decisions is kept separate from being able to see what those decisions were about.
  3. Cannot approve access requests. This keeps the oversight independent of the decisions being reviewed.
  4. Writes the organisation's de-identification standards. Imani chooses one when deciding a release, and a later change to a standard never changes what an earlier decision says.
  5. Can suspend an agent, and makes an evidence pack for an auditor: what the platform holds about one agent over a period, with no personal data in it.
Without this: oversight depends on asking engineers to extract logs whenever a question comes up, and the person reviewing access decisions may well be one of the people making them.
OkaforAI risk owner

Answers for how the organisation holds its AI agents.

  1. Writes the organisation's risk levels, a short list that says how strictly each kind of agent is held: whether a change needs a second approver, how often the agent must be confirmed again, and whether it may be deployed at all. Every change is saved as a new version with who made it and why.
  2. Confirms the level of each agent, together with the first version, after an approver of the owning department has agreed. A first version is always decided by people.
  3. Writes the list of tools the organisation has approved in advance, each with the highest risk level it is approved for, the conditions it is approved under and a date to look at it again. A version that adds only listed tools is approved in advance.
  4. Can suspend an agent.
  5. Reads no more data than anyone else, and cannot approve access requests.
Without this: how carefully an agent is held depends on whoever registered it, and nobody answers for the organisation's rules as a whole.
InesPrivacy auditor

Checks how locked data was used, from evidence that holds no names and no values.

  1. Reads the evidence of how locked data was used: who read it, who was refused, and which keys were opened. The evidence holds no names and no values.
  2. Makes the evidence pack of an agent and checks that its records have not been changed.
  3. Can ask for a short, approved lease to see the real values of locked data, for a stated purpose. Somebody else approves it.
  4. Can report an incident about an agent. Cannot approve a request to read data, so that the checking stays independent, and cannot register code or decide a release.
Without this: checking how personal data was handled means reading the personal data, so the checker needs the same access as the people being checked.
JoaquinNetwork architect

Decides which outside hosts an agent version may call.

  1. Reads the outside hosts that a new agent version declares it needs to call.
  2. Approves or refuses each host and writes the reason. An approved version can then be deployed, and a refused one cannot.
  3. Cannot decide a version that Joaquin uploaded personally, cannot approve a request to read data, and cannot register code.
Without this: an agent's network reach is whatever its author decided, and nobody who answers for the network ever looked at it.

People who run the platform

PriyaPlatform administrator

Runs the platform itself, with no standing access to what is inside an organisation.

  1. Keeps the platform running: starting services, monitoring jobs and traces, and freeing up storage. The last of these is done from a screen rather than from a shell: what each organisation is using, on which storage backend, what can be freed, and a rehearsal of exactly what a clean-up would remove before anything is removed.
  2. Closes a customer account when the relationship ends, in two stages. For the first 15 days the account is read-only, and the organisation's custodian can still cancel. For the next 15 days it is closed. After that everything inside it is deleted, unless a legal hold stands, and only a short record that the deletion happened is kept. A legal hold is recorded by one administrator and approved by a different one. Records for a legal matter are produced the same way: one administrator asks, a different one approves, and the custodian named by the hold confirms the scope. Nobody reads the records themselves, because the result is an encrypted, signed package.
  3. Holds the most powerful account in the system, and deliberately has no standing access to the data it protects and no ability to approve access requests for anyone, Priya's own included.
  4. Cannot change who holds which role, either. Anybody may ask to hold one and somebody else decides it, so the account that runs the system is not also the account that decides who may read what. The role that administers roles cannot be obtained from the running system at all: a second administrator is made the way the first one was, deliberately and from outside.
Without this: whoever can restart the services can usually also read everything those services protect. The account most worth attacking becomes the one with the fewest restrictions on it.
KitSupport and reliability

Keeps the platform running and supported, with telemetry and never records.

  1. Works from telemetry about how the platform is running, never from records.
  2. Sees the storage housekeeping record of every organisation, which names no data.
  3. Cannot approve a request to read data, and cannot reclaim storage or close down an organisation.
Without this: support work needs the administrator's account, and with it the administrator's reach.

Automated roles

De-identification pipelineAutomated

Strips personal information out of recordings, and releases nothing.

  1. Works through six steps to strip personal information out of audio recordings: transcribe, detect identifiers, hand off for human correction, replace the identifiers, measure what was missed, and write down what it found for a reviewer to decide on. Names in the transcript are replaced with consistent substitute names, and the matching stretch of audio is overwritten with low-level noise of the same length, so the timing of the recording is kept.
  2. Saves its progress after each recording while it transcribes, which is the slowest step, so a transcription that fails partway through resumes rather than starting again.
  3. Is the only account that reads raw, unredacted data, because removing personal information from raw recordings is exactly what it exists to do.
  4. Records whether each run was started by a person or by a schedule, so there is never any doubt about what set it off.
  5. Releases nothing, whatever it scored. Its last step records what it found and the pipeline ends there, waiting on a reviewer, whether the score passed the standard or not.
  6. Gives every step of a run the same identifier, so a run that grows into more than one workflow is still one traceable execution rather than several unrelated ones.
Without this: the job that strips personal data either cannot reach the raw recordings it needs, or is given the same broad access as everything else. There is no way to say that a process is trusted to redact data without also trusting it with everything. And the process that decides whether its own output is safe to release is the same one that produced it.
Background workersAutomated

Run the long jobs away from the process that holds every credential.

  1. The derivation runner executes the query that makes a new dataset, inside an isolated container with no network connection and no passwords. The platform checks the result before the new dataset appears.
  2. The table worker writes large tables in the background as a job, so the screen responds at once however large the table is.
  3. The closing sweep runs on a schedule and moves an account that is being closed down from one stage to the next when its date arrives. An account under a legal hold is not deleted.
Without this: the work would run inside the same process that holds every credential, so one faulty query or one missed date would have the widest possible reach.
Triage agentAutomated: AI agent

Ranks the queue of transcripts so the riskiest are checked first.

The job it does. When the pipeline has finished detecting personal information in a batch of recordings, it leaves a queue of transcripts for a person to check, because a missed identifier is a leak and only a human confirmation closes that risk. The queue is normally far longer than reviewers can work through in a day. This agent reads each waiting transcript and ranks it high, normal or low with a one-line reason, so the riskiest are checked first instead of whatever happens to be at the top of the list.

A transcript in that queue looks like this, with the identifiers still in place because that is exactly what a reviewer is there to confirm. The name and the date of birth are invented:

clinician: Right. Let me pull up the notes. Eoghan Bell, born 12 February 1965, is that correct?

It produces a judgement and nothing else. It cannot release data, change anyone's permissions, or read a dataset on its own authority.

  1. Is deployed as one specific sealed version, identified by the exact code it contains. Deploying a newer version while a run is in progress does not change which version that run is using.
  2. Cannot read the review queue by default. The queue holds unredacted transcripts, so it is held at the most restricted level, and this agent is trusted only with published data.
  3. Gets access the same way a person would. Starting a run against data it cannot read files a request naming the agent as the reader and the person who started the run as the one who asked. The custodian who owns that data approves it, and that approval is what sets the run going.
  4. Runs under an identity held by the surrounding program, not by the AI model. An instruction hidden in a transcript cannot change the identity its permissions are checked against.
  5. Raises any document that appears to address it to high priority, rather than doing what it says. Text aimed at the reader is itself a reason for a person to look at that document.
  6. Stops before its final step and reports that it is waiting for sign-off, rather than reporting success it has not earned. A different person accepts the findings, and the paused state is stored so that can happen days later.
  7. If it runs sandboxed rather than natively, and its version declares it needs a copy of the data, fetches that copy itself over an isolated network only after the same access decision above has been granted, capped at a fixed size before a single byte moves.
Without this: which version of the agent ran, what it read, and who let it continue past the decisive step are all answerable only by trusting whoever built it. An attempt to manipulate the agent through a planted instruction meets no independent check, because every check depends on output the model itself produced.

07 · How it is measured

What is measured, and what each measure decides

Two parts of the platform turn measurements into action. The pipeline that removes personal information is measured on accuracy, because the risk is that it misses something. A person decides what to do with those numbers. An agent run is measured on consumption, because an agent that gets stuck in a loop does not crash: it carries on working, producing reasonable-looking output and occupying the machine. The platform stops that run on its own.

Removing personal information: accuracy

These figures come from comparing the pipeline's output against a known answer key. The recommendation the reviewer is shown when deciding whether a result may be released to a wider audience is made by comparing them with a de-identification standard. A standard is a set of limits the organisation chooses: one for all identifiers together, and one for each kind of identifier (names, dates, phone numbers and the others).

A standard is kept under a name for the audience it is for, such as a closed research team or a public release, and whoever releases a result chooses which standard to judge it by. Every organisation starts with the Platform default standard: at least 98 percent of identifiers removed, and none of the five kinds that name a person directly (a name, a record number, a national identity number, a phone number or an email address) left in the clear.

That is a starting point, not a verdict. Only the organisation's data protection officer sets a standard, and every change is kept as a new version with who made it and why. The remaining figures are recorded and help explain a poor score.

MeasureWhat it tells youUsed for
Recall after transcriptionOf the identifiers that were still readable in the transcript, the share the pipeline removed. This is the fairest measure of the pipeline's own work, because it excludes names the speech recognition had already garbled beyond recognition.Below the standard's overall limit (98 percent in the Platform default standard) so the recommendation is fail
Recall for each kind of identifierThe same share, counted separately for names, dates, phone numbers and every other kind of identifier, so that a good overall figure cannot hide one kind that is being missed.Below the standard's limit for that kind, where it sets one, so the recommendation is fail
Identifiers left in the clearIdentifying text that survived, whole or in part, such as a full name or an email address still in plain sight, or a surname with two letters changed.Above the standard's limit for that kind (none in the Platform default standard) so the recommendation is fail
Recall against everything spokenThe same share, but measured against every identifier actually said aloud, including ones the speech recognition destroyed by accident. Always the lower of the two figures.Recorded only
Identifiers never foundHow many of the leaked identifiers the detectors never marked, even in part.Recorded only
Share destroyed by transcriptionHow many identifiers the speech recognition had already mangled before the pipeline saw them.Explains a score
Transcript accuracyHow closely the transcript matches what was actually said. This separates a pipeline that failed to redact from one that was given a bad transcript to work with.Explains a score

These numbers, with the counts for each kind of identifier, are stored on the decision record itself, not only in the experiment tracker, so the reason a dataset was released stays available even if the older run history is cleared out. The decision also records which standard it was judged by, that standard's version and its limits as they were, so a later change to a standard never changes what an earlier decision says. A run that falls short of its standard is not released automatically: it is shown to a reviewer as a fail recommendation.

The recommendation is advice, and the pipeline acts on none of it. It stops there and a person decides, because a threshold can only measure what the answer key already knows about, and the reviewer is looking at the identifiers that survived rather than at a number standing in for them. A pass is not a release either: an unreviewed result stays where it is until somebody signs for it.

Agent runs: consumption limits

Every run is given two ceilings. The program running the agent enforces them, rather than asking the AI model to respect them. Crossing any one stops the run immediately and records which limit was hit.

LimitDefaultWhy it exists
Tool calls per run25Caps how many times one run can reach for data or take an action
Seconds per run300Caps elapsed time, so a run that is waiting on something rather than looping is also stopped

Alongside these limits, each run keeps a running count of its tool calls and a full record of every access decision those calls produced. The count adds up across a pause and resume rather than restarting, so approving a paused run cannot hide what the first half already spent. An automated test confirms that a task written to loop forever stops at the tool-call limit.

08 · Cost and return

What it costs to run, and which recurring work it removes

Two things drive the return: what the platform costs to run, and which expensive manual work it removes entirely. Both are described below, so each can be set against your own organisation's numbers.

Software licences: nothing

The platform and every service it runs are under open-source licences that allow commercial use, almost all of them MIT, BSD or Apache. Three small libraries are under the Mozilla Public Licence 2.0, which applies file by file and asks for nothing unless you change those files. Speech recognition on a graphics card also uses NVIDIA's CUDA libraries and the FFmpeg audio library, which you install on that machine under their own licences: NVIDIA's are free to use commercially but are not open source. So there are no per-seat charges, no per-machine governance fees and no renewals to negotiate.

Running an agent: hardware, not usage fees

The agent's AI model runs on the machine's own graphics card instead of a paid external service. The cost of a run is therefore the cost of the hardware the platform runs on, rather than a bill that grows with every request. The per-run limits in section 7 cap how much of that hardware any single run can occupy.

Removes: reconstructing an audit trail

Answering "what did this agent read, and who approved it" is a query against records written at the time. The alternative is piecing the answer together from logs, chat history and recollection, which also produces a less reliable answer.

Removes: tracing a bad output by hand

A suspicious result can be traced to the exact code and input data behind it in one query. Doing the same without recorded lineage means manually working out which run, which code revision and which data were involved, under time pressure.

Removes: arguing about whether a release was safe

The figures from section 7 and every identifier that survived are attached to the decision record, along with who accepted them and why. The judgement still belongs to a person, but it is made once, on evidence everyone can see afterwards, rather than re-argued from memory in a meeting.

Caps: a stuck agent has a known worst case

A run that loops instead of finishing is stopped by the two ceilings in section 7, so the worst case is bounded rather than however long it takes someone to notice.

09 · Components, and why

What it is built from, and why each part was chosen

Licences are covered in section 8. Permissive licences for the platform itself were a hard requirement, and they ruled out several otherwise strong options.

Storage, control and policy

ComponentWhat it does hereWhy this one
SeaweedFSStores the actual data files, the default storage backendIt supports credentials limited to one folder, or to one organisation's own bucket, which is how a sensitivity level becomes a physical restriction rather than a rule the application is trusted to apply. Every organisation's ordinary ingest and agent-upload writes go through that organisation's own standing identity, never a shared admin key. It also speaks the same interface as Amazon S3, which is why the same code runs against Cloudflare R2.
Apache Iceberg and DuckDBLets a person open a table with a standard analysis tool, through the platformIceberg is an open way of storing a table, and DuckDB is a free tool that reads it. The platform lists only the tables the person may read, and hands the tool a short-lived key for the files of the one table opened. The derive walkthroughs show this running with real DuckDB.
Cloudflare R2A second, optional storage backend, chosen per organisationZero egress fees, which matters because a sandboxed agent's own copy of its data is egress-heavy. Each organisation on R2 gets its own bucket and its own short-lived, bucket-scoped credential, the same shape SeaweedFS's own per-organisation identity takes.
PostgreSQLStores all records, history and audit entriesIt can enforce rules the application cannot bypass, which is what makes sealed datasets genuinely immutable.
TemporalRuns long jobs: the pipeline, imports and agent runsIt records the state of a job durably, so retries, timeouts and resuming after a crash are provable behaviour, not a description of intent. This is what lets an agent pause for days awaiting approval.
Open Policy AgentDecides every access, approval and publication questionKeeping the rules in one testable place means access policy can be unit-tested like code. It returns a reason with every decision, which is what makes the audit trail meaningful rather than a list of yes and no.
Ory KratosHandles real sign-in for every human roleChosen over Keycloak for its lower memory ceiling on a single machine. An identity always comes from a session Kratos issued, never from a name the caller supplies.
Ory HydraSigns a notebook in on a person's behalfIt issues, renews and revokes a short-lived pass, and holds nothing about who people are: Kratos still answers that, and the platform's own API decides what a pass may do on every request. A pass is opaque and not signed, so it can be revoked at once.
FastAPIThe single interface everything else goes throughIt validates incoming data against a declared shape automatically, so malformed requests are rejected before reaching any logic. Keeping this layer thin was deliberate: rules belong in the policy engine and the database, not scattered here.
Munitas consoleThe web app people open in a browserIt asks the API for everything it shows, so what a person sees comes from the same decisions as everything else.
Munitas client libraryLets a person work from Python or a notebookIt sends requests to the API, so the same access decisions apply as in the console.
Derivation runnerRuns the query that makes a new datasetIt runs in a container with no network connection and no passwords, so a query cannot send data anywhere or reach anything it was not handed.
Step gatewayThe one way a custom pipeline step reaches the platformA step runs on a network with no route to the internet, and the gateway is the only other thing on it. It forwards only the platform's step routes to the API and answers 404 to everything else.
cryptography (Python)Encrypts records and stored credentialsIt is the standard, well-reviewed Python library for this, and keeping the key for a record apart from the record is what allows permanent deletion without altering any sealed dataset.

Removing personal information from recordings

ComponentWhat it does hereWhy this one
faster-whisperTurns audio into textIt reports the exact timing of every word, which is required to mute the right moment in the audio and not just the text.
Presidio, spaCy and GLiNERThree separate detectors that find personal informationThey fail in different ways. Presidio matches known patterns such as phone numbers, spaCy recognises names it was trained on, and GLiNER catches categories nobody trained it for. Combining all three means a miss by one can be caught by another, which matters because a single miss is a leak.
Label StudioLets a person correct what the detectors foundIt can be pre-filled with the detectors' output, so reviewers correct existing marks rather than starting from an empty transcript, which is far faster and more consistent.

Agents, models and monitoring

ComponentWhat it does hereWhy this one
LangGraphDefines the agent's steps and where it pausesThe agent's possible paths are written out explicitly rather than left to the model to decide, so the approval pause is a property of the structure. The model cannot skip it. It also saves the paused state so a run can be resumed later.
OllamaRuns the AI modelThe model runs on the machine's own graphics card, so no data or prompt is ever sent to an external service. For regulated data this is often the difference between a system being permissible and not.
OpenTelemetry and JaegerRecords and displays what happened during a runOpenTelemetry is a vendor-neutral standard, so the monitoring backend can be swapped without changing the application. Each trace is tagged with the sensitivity of the data involved, making it visible if sensitive data reaches a place it should not.
MLflowStores measurement results from pipeline runsIt is the established open tool for tracking runs and their scores, and it gives the release decision in section 7 a permanent record to point back to. It has no sign-in of its own here, so what it is given is deliberately limited: the position of each identifier that leaked, never the identifier itself.