Security model

Written for the person reviewing it.

One organization reading another's numbers is the worst failure this platform could have. Everything below is arranged around preventing that, and the rules are structural, so breaking one should require deleting code rather than forgetting a check.

This page states the model and then states what we have not proven. If you are compiling a vendor assessment, the second part is the one worth reading twice.

The rules

Thirteen non-negotiables.

#RuleHow it is enforced
1Only the guard binds a projectNot a tool argument, not a URL, not a token claim. One middleware resolves it from a live grant and stamps it on the request.
2No scope, no connectionThe component that reads holds no connection string. It asks for one on every open, so a tool with no bound project cannot open anything.
3Anything touching data is request-scopedA long-lived object could outlive one request and be handed to the next. None exists on that path.
4Caches are keyed by project and re-assert on readA cache hit that belongs to another project is discarded rather than returned.
5Deny by defaultEmpty skill list grants nothing. Unknown profile expands to nothing. Unrecognised tool is assumed to need a database.
6Customer organizations cannot cross organizationsEnforced where grants are created and again where they are used.
7Token audiences are bound to the connector hostA token for one client's address cannot be replayed against another's.
8Fail closed on every unknownNo email, no grant, no project, ambiguous project, unreachable control plane: all refuse. Outside development the service refuses to start at all without auth and a control plane.
9Every narrowing is an intersectionFour gates, each a pure function that can only remove. No layer can grant what another refused.
10A client's contributions run only on its own projectTools and everything else a pack contributes, checked at creation and again at dispatch.
11Refuse, never guess, when a target is ambiguousTwo candidates and no default is a refusal with the list.
12Tenant-authored text is data, never instructionArrives after every decision and after the read, capped, labelled untrusted, and unable to reach another project's session.
13A refusal never teaches the caller about another clientNot whether a project exists, not who owns a tool, not another organization's identifiers.

These are covered by a test suite that runs offline with no database and no network, plus a set against a real SQL Server. A change that weakens one is treated as a security change and gets an adversarial review rather than a normal one.

Isolation

Isolation is the grant, not the deployment.

One service serves every client, and a request reaches exactly the one project the caller holds a live grant on. That is a deliberate choice with a real trade-off, so here is the trade-off.

Why not one deployment per client

It was seriously considered and it stays available. It was not chosen because N deployments per engine change is exactly the per-client maintenance cost that makes small clients uneconomic, and unmaintained instances are their own security problem.

If your review requires process isolation

The code supports it unchanged: a second instance of the same service with only your projects reachable. Ask, and it is a deployment decision rather than a redesign. We would rather have that conversation than pretend the shared model suits everybody.

Identity

Who you are, and what may reach what, are answered by different systems.

Your identity provider answers

  • Who is this. Verified through your own Microsoft work account.
  • Are they still here. Joiners and leavers stay your existing process.

We answer

  • What may they reach. From a grant, in our control plane.
  • What happened. The audit trail.

Keeping that split is what makes revocation a database edit that takes effect on the next call, and it means we hold no directory, no passwords and no group memberships. The broker that federates sign-in holds OAuth machinery only: it knows nothing about clients, projects or entitlements.

Not yet proven

What we would tell you in the meeting anyway.

A security page that lists only strengths is a marketing page. These are the open items as they stand today.

Answer quality is not yet measured here

There is a difference between "the tool answered" and "the tool answered correctly", and the harness that measures the second has not been brought across yet. Treat accuracy as something to verify in your own evaluation rather than something we have proven.

Reviews are internal so far

Adversarial isolation reviews have been run repeatedly against the code and their findings recorded and fixed. They were run by us. An external penetration test is not yet done.

Append-only is an application guarantee

No feature can alter an audit row and the console offers no path to it. That is not the same as write-once storage. If your review requires the cryptographic version, say so early.

Certification status, with dates

Published as a status rather than a badge wall. Ask and you get the honest position, including the parts that would not pass an audit today.

Where our own enforcement is the only one standing.

The next page publishes, per connected system, whether your person's own permissions are enforced by that system or only by us. Two of the four rows are us.