OnDuty

Security and data

What we do with what you connect.

OnDuty reads systems that hold your customers' information. This page is the mechanisms that constrain what it can do with them, and the things we have not done yet.

Two kinds of connector, pointing opposite ways

Almost every question about data handling resolves once this distinction is clear, so it comes first.

Source connectors
Read a system you already use and turn what they find into the Brain's vocabulary. They are read-only. A source connector has no code path that writes to your system, which is a property of what it is rather than a permission it was denied.
Action connectors
Act on the world: send the message, update the record. An action connector is only ever reached by the executor, and the executor is only ever reached by a clean permit from the decision engine.

So anything OnDuty does to a system of yours is an action, and every action goes through the gate. There is no third path where a read turns into a write.

Credentials

A connected source means OnDuty holds a token for one of your systems. How that token is stored is the whole question.

Encrypted at rest
Tokens are encrypted with a key held outside the database, so a copy of the database on its own does not yield a working credential.
No key, no connection
If the encryption key is not configured, connecting a source is refused. It does not fall back to storing the token in plain text, which is the failure mode that turns a missing environment variable into a breach.
Losing the key is unrecoverable
By design. Every source has to be reconnected. A recovery path for the key would be a second way to read the credentials, which is the thing the key exists to prevent.
A refresh token is only replaced by a refresh token
Google returns one on first consent and omits it on later ones. Writing the empty value back would destroy a working connection instead of renewing it, so an absent value leaves the stored one alone.

The controls that matter are the ones a mistake cannot switch off. Read-only is a property of the code, not a checkbox. Fail-closed lives in the executor. An unknown role resolves to the least privilege, not the most.

Who can do what

Two different things get called "role" in most products, and conflating them is how someone ends up with access nobody meant to give them. Here they are separate.

Platform roleWorkspace role
What it saysWhether someone is OnDuty staffWhat someone can do inside one workspace
Where it appliesOur own administrative surfaceYour workspace, and only that one
ValuesStandard, or platform administratorOwner, admin, operator, analyst, viewer
Does one imply the otherNo. A platform administrator gets no workspace permission implicitly.No. A workspace owner has no access to our administrative surface.
Permission, never role
A route asks for a named permission, for example the permission to deploy an agent, not for "admin or owner". Roles map to permissions in one place, so widening a role cannot quietly widen a route nobody reviewed.
Unknown resolves to least
A role string nobody recognises resolves to viewer. A row that got there by a bug or a bad migration is never treated as an owner.
Nobody grants above themselves
An admin cannot make someone an owner. Privilege escalation by invitation is closed at the service, not hidden in the interface.
A workspace keeps an owner
The last owner cannot be removed or demoted, because a workspace with nobody able to administer it is a support ticket that cannot be resolved from inside.
Support access is deliberate
Our reaching into a customer workspace is an explicit act through the administrative surface, and it is recorded. It is not a side effect of being staff.

Agents that run on your machines

On the top plan an agent can run inside your network, so conversation content never leaves it. That means a token of ours lives on a machine we do not control, and the design assumes that machine is hostile.

Two endpoints, and no more
A runner can reach exactly two routes: one to say it is alive, one to ask what it should be running. Every other route in the product is closed to it.
Asserted, not intended
That restriction is a test over the full route inventory rather than a convention. A new route is closed to runners unless someone deliberately opens it, and opening one fails the test until the inventory is updated.
The token is hashed and shown once
We store a hash. If it is lost, it is reissued rather than recovered, because a token we could show you again is a token we could show someone else.
Health is derived from silence
A runner's health is computed from when it last spoke, not from a status it reports. A machine that has died cannot write "unhealthy" anywhere.

Where your data sits

In your workspace, in our Postgres database, scoped by tenant on every query. Documents synced from a connected source are stored so the Brain can cite what a conclusion came from.

Every record the Brain holds carries the source it came from, which is what makes an insight checkable. A conclusion whose source has vanished is one nobody can argue with, so the record of where knowledge came from survives even after a source is disconnected. The live credential does not: disconnecting deletes it.

Deletion of a source removes the connection and its stored credential immediately. The knowledge derived from it remains attributed to it, marked as coming from a source that is no longer connected, rather than silently becoming knowledge from nowhere.

What we have not done

This section exists because you would find these out later anyway, and because a company selling governance should not be vague about its own.

No third-party audit yet
OnDuty has no SOC 2, ISO 27001, or equivalent certification. We are not going to describe our controls as certified when nobody outside has examined them. If a formal review is a requirement for you, tell us and we will talk about the timeline honestly.
Google verification is pending
Reading Gmail and Drive uses scopes Google classes as restricted, which require a verification review before an app can be opened past a limited number of users. That review has a lead time and we are in it, not past it.
No public API, on purpose
There is no self-serve developer API and no public key issuance. Every integration goes through a connector we wrote and can reason about.
Data residency is enterprise-only
Choosing where data lives is an enterprise arrangement rather than a setting on a self-serve plan, because it is a deployment decision and we will not offer it as a toggle that does nothing.

Ask the awkward questions.

We would rather answer them now than have you find the answer yourself in six months.