Executive summary
Sigmaera holds confidential content under a layered, mechanically-enforced security model. No single control carries the isolation guarantee on its own — each layer is designed to hold if the one above it is bypassed, and each is verified by an automated test or a build gate rather than by procedure. The controls an enterprise reviewer cares about most:
Row-level security, forced
Every domain table carries tenant_id NOT NULL with PostgreSQL row-level security and FORCE ROW LEVEL SECURITY. A privilege split between the migration role and the runtime role means the application cannot bypass it, and a startup assertion refuses to run in production if it could.
Membership-verified tenancy
A user token's organization is verified against live membership data at every token issuance and renewal, failing closed. There is exactly one organization per token — the platform issues no multi-organization tokens.
Narrowing-only policy layer
Inside an organization, a second database policy enforces personal, team, and department boundaries. It is structurally incapable of widening visibility — it can only narrow it — and returns nothing if its context is unset.
Derived data inherits its source
Insights, signals, and graph entities inherit the workspace boundary of the evidence they were derived from, most-restrictive-wins. Private material does not become organization-visible by being analyzed.
Per-person, never privileged
Parent organizations can hold consented, derived views across the organizations they manage. The parent never holds a credential that reads its children — every cross-organization read resolves through the individual user's own access.
A real policy decision point
Every agent run and model call passes a policy decision point before it executes: budget, quota, approval, and per-organization policy. No budget attribution, no call.
Tag-and-gate, fail-closed
Content is indexed but every read of a tagged row is filtered against the caller's clearance, fails closed, and emits an audit record. Two categories default to withheld-from-index rather than gated.
Your boundary, your keys
S3-compatible storage, OIDC, SMTP, OpenTelemetry, Vault, PostgreSQL. The data plane runs identically in our cloud and inside your perimeter, including air-gapped. On-premises is the same code with a single tenant.
Security design principles
Six principles govern the platform's security architecture. They are the reason the controls in this document look the way they do, and they are applied consistently rather than per-service.
Defense in depth, by construction
Isolation is enforced at four independent layers — the database connection role, the tenant policy, the workspace policy, and the content-sensitivity filter. Each is designed to hold if the layer above it is bypassed. No single control is load-bearing.
Fail closed, everywhere
An unset tenant context returns zero rows, not every row. An unset workspace context returns zero rows. Unestablished clearance excludes the row. An unclassified document is not yet visible. An exhausted budget denies the run. A failed policy read degrades to the most restrictive setting.
Enforce mechanically, not procedurally
Every platform rule has a matching enforcement mechanism — a schema lint, an API compatibility check, an isolation test, a custom code guard, or a build gate. A rule that cannot be enforced automatically is treated as a gap in the rule, not a matter of developer discipline.
Three orthogonal isolation axes
Organization, content sensitivity, and workspace ownership are separate questions with separate mechanisms. Conflating them is a common source of subtle exposure, and the platform deliberately keeps them independent — see §03.
Least privilege includes machines
Service-to-service calls use asymmetric client authentication with no shared secrets, and each declares the minimum scope it needs. Machine credentials never hold blanket cross-organization access; where cross-organization work is legitimate, the credential is bound to a specific consented relationship.
Portability is a security property
Refusing cloud-vendor-locked primitives in the data plane is not an engineering preference. It is what makes it possible for your content and every derived insight to stay inside your perimeter, with your key management and your storage.
Where we have invested
Security work in the current cycle concentrated on five areas. Each is described in full later in this document.
| Area of focus | What we built | Why it matters to you |
|---|---|---|
| Identity & tenancy | Organization selection at the identity provider, verified against live membership at every token issuance and renewal | A user's organization context is now proven at each token rather than inferred from a stored record. One person, one credential, many organizations — with no weakening of the boundary between them |
| Workspace ownership | A narrowing-only database policy layer, plus inheritance of that boundary through every derived artifact | Personal and team material stays private to its owner even after the platform analyzes it and produces insights from it |
| Multi-organization access | Consent-gated relationships between a parent organization and the organizations it manages, resolved per person | Managed-service providers, holding companies, and investors get portfolio visibility without any standing privileged read path into your data |
| AI governance | A policy decision point in front of every agent run and model call — budgets, quotas, approvals, per-organization policy | AI workloads are bounded and attributable. Cost ceilings are a containment control, not just a billing feature |
| Operational assurance | Fleet-wide metrics and alerting, authentication-failure instrumentation, backup and disaster-recovery procedures, signed container images | Faster detection, verifiable recovery, and a defensible software supply chain |
Data classification
The platform handles these categories of content, each with a defined home and handling shape.
| Category | Description | Where it lives |
|---|---|---|
| Raw transcript text | Pre-transcribed vendor exports (Zoom, Teams, Otter, Fireflies, Granola, Read.ai, WebVTT) or text/markdown | Transcript service database; original file in object storage |
| Uploaded document text | text/plain, text/markdown, PDF text layers, .docx, .eml | Document service database; original file in object storage |
| Connected-source content | Email, Jira, Slack, Asana, SharePoint / OneDrive | Normalized into the existing ingestion paths — connectors introduce no new data store |
| Canonical structure | Speaker turns, sentences, participant labels, document chunks | Transcript and document services |
| Personal-data findings | Type and position of detected personal data — the only place this is persisted | Classification service, in a dedicated table |
| Sensitivity tags | 18-category labels, per segment and rolled up | Classification service; the rollup is written back to the source record |
| Derived intelligence | Entities, signals, findings, work items, reports — inherit sensitivity tags and workspace ownership from their evidence | Knowledge, signal, insights and report services |
| Cross-organization artifacts | Link edges, rollups and portfolio views referencing consented organizations by opaque identifier plus a bounded display snapshot | The parent organization's own records (§09) |
Sensitivity taxonomy & handling shapes
An 18-category canonical taxonomy is declared once in a shared package and distributed to every consuming service as TypeScript and Python siblings with parity tests — so the same tag means the same thing everywhere, and a category cannot drift between services. Representative categories: HR_Compensation, MA_Confidential, MA_HighlySecret, Board_Material, Customer_PII, Customer_PHI, Security_Incident, Security_Vuln.
The default — index everything, gate at read — preserves analytical value while making authorization correctness load-bearing. The platform compensates for that with a single shared filter implementation, fail-closed semantics, two-user isolation tests on every read endpoint, and mandatory per-read auditing.
Three orthogonal axes
The platform separates three questions that are often conflated. Keeping them independent is deliberate: a control that answers one does not answer the others, and treating classification as though it answered ownership is a well-known source of subtle exposure in content platforms.
| Axis | Question it answers | Mechanism |
|---|---|---|
| Organization | Which customer owns this? | Tenant column + forced row-level security + token binding + graph query wrapper |
| Sensitivity | Is this content categorically restricted? | Tag-and-gate taxonomy + shared fail-closed filter + per-read audit |
| Workspace ownership | Whose is this, inside the organization? | Workspace label + narrowing-only policy + server-resolved scope set |
Architecture & trust boundaries
The platform is organized into planes that form the primary trust-boundary structure. The data plane runs identically in our cloud and inside your perimeter — the code does not branch on deployment mode. Two edge-plane services exist only in our cloud and are never shipped on-premises.
| Boundary | What crosses it | Control |
|---|---|---|
| Internet → edge | End-user and application traffic | TLS termination; WAF / ingress rate limits. Application-level rate limiting is additionally applied to the authentication surface |
| Edge → service | Token, trace context, organization header | The edge validates once; every service re-validates independently |
| Service → service | Internal API calls | OAuth 2.1 client credentials with asymmetric client authentication — no shared secrets; least-privilege scopes; cross-organization capability checks; mutual TLS via service mesh in production By deployment |
| Service → datastore | Database, graph, object and event traffic | Isolation-respecting database role with a startup assertion; a single repository chokepoint; the graph query wrapper; signed-URL-only object access |
| Customer A ↔ Customer B | (never, except via §09) | Tenant column + forced row-level security + token binding + graph wrapper; verified by two-organization test suites in every service |
| Parent ↔ managed organization | Consented derived artifacts only | Consent state machine + relationship-bound credentials + per-person read resolution |
| Workspace ↔ workspace | Scoped records inside one organization | Narrowing-only policy on the server-resolved scope set, fail-closed |
| Reader ↔ over-clearance content | Sensitivity-tagged records | Shared filter, fail-closed, mandatory per-read audit |
End-to-end data flow
The lifecycle of a piece of content, hop by hop. Click a stage to see the security control at that hop.
Identity & tenancy
A single identity service is the only token issuer, implementing OpenID Connect and OAuth 2.1. It supports authorization code with PKCE for user login, client credentials for service-to-service calls, refresh tokens with rotation on every use, and RFC 8693 token exchange for delegation. The implicit and resource-owner-password grants are not supported. No other service may issue or sign anything resembling a platform token.
The full authentication surface is implemented: multi-factor authentication with recovery codes, password reset and email verification using single-use hashed tokens, session termination and revocation, personal access tokens, and key publication with rotation.
Membership-verified organization selection
One person frequently belongs to several organizations — a consultant across clients, an executive across portfolio companies, a contractor across engagements. The platform supports this with one credential and one multi-factor enrollment, without weakening the boundary between those organizations.
At authorization time the identity service computes the caller's eligible set from live membership data and issues a token for one organization chosen from it.
-- a token may only ever be issued for an organization in this set eligible(user) = ( { home_organization(user) } ∪ { org | membership(org, user) = 'active' } ) ∩ { org | org.status = 'active' } -- membership is re-verified at EVERY issuance and EVERY renewal, -- and fails closed: never to a different organization.
| Mechanism | Security property |
|---|---|
| A requested organization is honored only if it is in the eligible set; a single eligible organization is selected automatically; otherwise the identity service presents its own selection screen | An ineligible request never silently falls back to a different organization. Tampering with the request cannot widen access |
| Authorization codes and refresh tokens record the granted organization | Renewal does not re-derive the organization from a stored user record; the granted organization survives rotation deterministically |
| Membership is re-verified at every issuance, briefly cached, and fails closed | A revoked membership stops producing tokens. Failure is always to an error, never to a different organization |
| Silent renewal is never interrupted by a selection screen — it returns a standard interaction-required response | Background renewal cannot be redirected into an organization the user did not choose |
| Membership data is read over a dedicated internal endpoint holding a capability no human role can be granted | The lookup is machine-only and every use is attributable in the audit log |
| Issuing a token for an organization other than the user's home organization emits an audit event with the membership evidence | Cross-organization token issuance is always attributable |
Service-to-service & delegated access
Every service is a registered client obtaining tokens with asymmetric client authentication — never a shared secret. Service tokens carry a service subject and the least-privilege scopes that service needs.
For features that must act with an end user's permissions — an analyst agent answering a question on your behalf — the platform uses standards-based token exchange. The delegated token's scope is the intersection of what was requested with what the user actually holds, so delegation can never broaden privilege, and a dedicated claim records the delegation chain for audit. Delegated tokens inherit the same 15-minute lifetime.
Tenant isolation
The most consequential control in a multi-customer intelligence platform. The defense is layered and mechanical, and identical whether the platform runs in our cloud or inside your perimeter.
Repository chokepoint
All data access flows through an organization-scoped repository that refuses to operate without an organization in context. Direct database access outside that module is blocked by an automated code guard in every service, so the chokepoint cannot be quietly bypassed.
Explicit predicate
Every query carries an explicit organization predicate — both for index performance and as defense in depth, so correctness does not depend on the database layer alone.
Row-level security
The database drops other organizations' rows even if a query omits the predicate entirely. This is the backstop, deliberately never the primary defense.
The policy stack
ALTER TABLE <table> ENABLE ROW LEVEL SECURITY; ALTER TABLE <table> FORCE ROW LEVEL SECURITY; -- required: without FORCE the owner is exempt -- The organization boundary. CREATE POLICY <table>_tenant_isolation ON <table> USING (tenant_id = current_setting('app.tenant_id', true)::uuid) WITH CHECK (tenant_id = current_setting('app.tenant_id', true)::uuid); -- The workspace boundary — RESTRICTIVE, so it is AND-ed beneath the policy -- above and is structurally incapable of widening visibility. CREATE POLICY <table>_scope ON <table> AS RESTRICTIVE USING (scope_id = ANY(string_to_array(current_setting('app.scope_ids', true), ','))) WITH CHECK (scope_id = ANY(string_to_array(current_setting('app.scope_ids', true), ',')));
Both policies read their context from a transaction-local setting established at the start of every transaction, so context cannot leak between concurrent requests sharing a connection pool. If that context is unset, the predicate evaluates false and the query returns zero rows — not an error, and emphatically not everything. Both fail closed by construction.
Privilege separation at the database
Schema migrations and grants run under an administrative role. The application runtime connects under a separate role that has no policy-bypass privilege at all. Every service asserts its own runtime role at startup and refuses to start in production if it is connected with a role that could bypass policy.
A separate reserved administrative role exists for explicitly-audited operations that must legitimately span organizations — retention cleanup, re-classification, index maintenance, and the event outbox drain. Each re-establishes per-organization context before touching customer data, so even these paths operate one organization at a time.
Graph isolation
The knowledge graph is the highest-consequence surface in the platform: an unconstrained traversal could otherwise disclose an entire organization's decision, project and personnel structure. It is protected by a single enforced path:
- The graph driver may be imported in exactly one bootstrap module; all access goes through an organization-scoped session wrapper.
- The wrapper parses every query at runtime and rejects any that does not bind the organization on every node and relationship — including variable-length paths, which must carry an explicit predicate across the whole path.
- An automated code guard fails the build on any attempt to open a raw graph session outside the wrapper.
- Callers cannot submit graph queries. The query endpoint accepts only a closed set of named, parameterized patterns — no client-supplied query fragments, and no runtime string construction.
- Graph read endpoints apply the same workspace and sensitivity filtering as every other read path in the platform.
Machine-identity organization selection
Service credentials are organization-agnostic by design, so a background job selects the organization it is operating on per request. Selecting an organization requires a dedicated capability that is deliberately separate from any data-access permission — holding broad read permission does not confer the ability to choose which organization to read from. The two are independent, and both are required.
Workspace isolation
Beyond the organization boundary, the platform provides a finer in-organization boundary so personal, team, and department material can live inside a single organization yet remain invisible to other members. The organization invariant is unchanged: workspaces exist strictly inside one organization and can only narrow, never widen, what that organization's members can see.
| Workspace | Visible to | Notes |
|---|---|---|
| Organization | All members | The default for material that is genuinely shared |
| Department | Department members | Resolved from the membership registry |
| Team | Team members | Existence can be hidden, not merely contents |
| Personal | Owner only | Hidden from everyone else, including organization administrators |
Workspace membership is data, not a token claim. A caller's authorized workspace set is resolved server-side on every request from the membership registry — it is never asserted by the client, never carried in a token, and never resolvable by a service credential. Reading personal or team material requires a delegated user token.
Ownership travels with derived intelligence
A platform that analyzes content produces new records from it — signals, findings, graph entities, rollups. If those inherit only the classification of their source and not its ownership, private material can become organization-visible in derived form even while the original stays private. The platform treats this as a first-class design requirement rather than a downstream concern.
| Control | How it works |
|---|---|
| Boundary travels on the wire | Workspace ownership is a first-class field on classification results, the extraction pipeline context, and the signal and finding schemas — so every downstream writer has it without an additional lookup |
| Current ownership, not stale | Consumers re-resolve the source's current ownership at processing time rather than trusting a value carried on an older message, so re-filing a document is never overtaken by an in-flight event |
| Shared graph holds shared evidence only | Personal and team evidence is excluded from the shared knowledge graph entirely. The graph is a shared-context structure, so the conservative choice is exclusion rather than in-graph filtering |
| Aggregates follow the narrowest input | A finding blending personal and organization evidence is scoped to the most restrictive input and rendered to its owner only, rather than surfacing organization-wide in summarized form |
| Ownership is a stored property | Derived records carry an owner attribute so they can be bound to an individual, and the derivation path runs under a delegated user token so the workspace policy accepts the write |
| Connected email is private by default | Email drawn from a connected mailbox is assigned to its owner as personal at ingestion, enforced server-side regardless of what the caller requests, and an unattributable message is rejected outright |
| A file you upload is your filing decision | Manually uploaded message files are the deliberate exception: a person uploading a file is making a filing decision, so the uploader chooses. Bulk drive synchronization is off by default |
| Nothing is shared without approval | The platform may recommend sharing and may file material into the owner's own private collections, but private-to-shared is always an explicit decision by the owner. The recommendation and its audit trail must not reveal the private item's content or its existence to anyone else |
| Deletion retracts derivations | Derived records carry provenance back to their source, so deleting a private item retracts the signals, findings and graph edges produced from it |
Activation
Multi-organization access
Managed-service providers, parent companies, investors and shared-services teams need visibility across the organizations they are responsible for. The platform supports this without weakening single-organization isolation, and the design deserves close review because it is the one place the platform deliberately spans an organization boundary.
Consent is the precondition
A relationship between a parent and a managed organization is a first-class, consented, auditable grant. It becomes active only after an owner or administrator of the managed organization consents, and only if that organization has enabled linking at all. Every state change — request, consent, decline, revoke — is audited and emits an event. Consent is granted by the organization whose data is at stake, never by the parent, and never by us.
What the parent actually holds
Cross-organization derived artifacts are records in the parent's own organization, protected by the parent's own policy like any other record, holding references as opaque identifiers plus minimal display metadata — a name, a type, a last-seen timestamp — whose refresh honors current access. Source content is never copied.
The consequence for isolation is the important part: a parent record is an ordinary single-organization record that references an identifier. Every read of the referenced content resolves through per-organization access at the time of reading. There is no server-side blending, and the graph remains strictly single-organization — a parent's graph holds link nodes referencing identifiers, never a copy of a managed organization's structure.
Credentials are bound to the relationship
Where a background process computes portfolio rollups, it uses a credential bound to one specific consented relationship, verified against that relationship being currently active — not a general cross-organization capability. The check is deny-by-default: no active relationship, no access. The process writes only into the parent; it never writes into a managed organization.
Revocation
Immediate, then purged
Either side can revoke. Parent-held artifacts referencing that organization are hidden immediately by a query-time check on relationship status, and removed by a cleanup process within the retention window — including cached display metadata.
Fails closed
Institutional artifacts remain in the parent, but that individual's ability to resolve any reference into the managed organization fails closed at their next token.
Cascade extends
Deletion propagates into parent-held references under the same purge commitments that govern the rest of the platform.
Every capability class — linked graph, rollups, portfolio views, live spanning reads — is consented separately by the managed organization and enabled separately by the parent. All default to off. Consent to one class is never consent to another.
Authorization & RBAC
A dedicated authorization service owns the permission catalog, roles, and role assignments, and exposes an evaluation endpoint that every service consults. The permission catalog is append-only — permissions are never silently redefined — and built-in roles are protected at the database layer so they cannot be edited into something more permissive.
| Capability | Purpose | Grant posture |
|---|---|---|
| Membership lookup | Organization selection at the identity service | Machine-only. No human role can hold it |
| Relationship management | Request, consent, decline, revoke a parent relationship | Built-in owner and administrator roles only |
| Organization selection (machine) | Choosing which organization a background job operates on | Deliberately separate from any data-access permission |
| Sharing decisions | Approving a private-to-shared promotion | Bound to the owner of the material |
Sensitivity clearance is expressed as authorization scope: a caller's granted scopes determine which sensitivity categories they may read, and the shared filter takes that scope set as its input. This is why authorization correctness is load-bearing for content confidentiality, and why the filter is centralized rather than reimplemented per service.
Governance & AI policy
Authorization answers may this identity touch this resource? Governance answers a different question that conventional access control does not address: may this AI workload run at all — at this cost, on this data, right now? A dedicated governance service is the platform's policy decision point; the model gateway is the policy enforcement point. Neither is optional, and both fail closed.
What governance decides
Cost as a containment control
Per-organization budgets are consumed through the gateway's usage ledger. A run whose budget is exhausted is denied, not degraded. This bounds the blast radius of a runaway or manipulated workflow — extraction through compute is a cost attack as much as a data attack, and a hard ceiling is the control that bounds both.
Human in the loop
Policy can require explicit approval before a run proceeds. The lifecycle is token-based with an atomic claim and grant verification, so an approval cannot be replayed, raced, or reused. A paused run resumes only against a verified grant.
Policy is configuration
Sensitivity handling shapes, re-classification behavior, workspace enablement and cross-organization capability classes are all per-organization configuration — changeable without a deployment, versioned with optimistic concurrency, and audited when changed.
Validated before the decision
Agent tool arguments are validated against each tool's declared schema at dispatch, before policy and authorization evaluate. A malformed or injected argument is rejected before it can reach a decision point at all, so the decision point only ever sees well-formed input.
Policy surfaces & their defaults
| Policy surface | Scope | Default |
|---|---|---|
| Sensitivity handling shape, per category | Per organization | Tag-and-gate; withheld from index for the two most sensitive categories |
| Workspace boundary enablement | Per organization | Off — enabled with you; fails closed on a read error |
| Cross-organization linking and spanning reads | Per organization, per capability class | Off, and separately consented |
| Re-classification on model upgrade | Per organization | Critical categories only |
| AI budgets & quotas | Per organization | Fail-closed when exhausted |
| Member self-connection of their own accounts | Per organization | Configurable; organization-wide connectors remain privileged |
Roadmap A declarative policy-language runtime, for organizations that want to author complex custom policy themselves, is the next iteration and is not available today. The configuration-driven policy path, budgets and approvals are what enforce in its place.
Sensitivity gating
The sensitivity filter is a single shared implementation used by every service. Reimplementing it locally is blocked by an automated guard that flags any code touching sensitivity data without using the shared filter — so the filter cannot drift or be quietly weakened in one service.
| # | Invariant |
|---|---|
| 1 | Organization context is established before any query runs |
| 2 | The filter is applied on every endpoint that returns tagged content |
| 3 | A broad-read clearance bypasses the filter only with the bypass recorded in the audit event alongside the requester's identity; cross-organization broad read is administrative and separately controlled |
| 4 | Counts of withheld results are rounded — an exact count is itself an inference channel about what you cannot see |
| 5 | Every filtered read emits exactly one audit record, in the same transaction as the response, so a read cannot succeed without being recorded |
If clearance cannot be positively established, the record is excluded. The filter fails closed.
Content classification
The classification service determines what is sensitive, and its result closes the gate that every downstream read depends on. Three independent stages run over each segment, behind a language gate.
Detection & redaction
Findings are stored in redacted form with their position — enough to support downstream redaction and investigation, without copying the underlying personal data into structures intended for indexing.
Named-entity recognition
Produces the entity mentions that feed knowledge resolution. Models are pinned as explicit dependencies so builds are deterministic and no model is fetched from the network at runtime.
Context-aware classification
Runs through the model gateway, inheriting governance, budget attribution, routing, failover and provider-key isolation rather than calling any provider directly.
A strict one-model-library-per-module rule isolates each model, keeping boundaries explicit and making a model replaceable without touching pipeline logic.
Reliability & deletion behavior
- Exactly-once semantics — work is reserved before processing, so a redelivered message is skipped rather than duplicated, and work held by another worker is returned to the queue rather than discarded.
- Durable publication — every event is written in the same transaction as the state change it describes and drained separately, so a state change and its notification cannot diverge.
- Deletion is ordering-independent — a deletion records a marker that suppresses any later-arriving work for that item, so a delayed in-flight message cannot re-materialize content you deleted.
- Replay-safe — reprocessing the full event history produces the same result as processing it live.
Encryption & key management
TLS, and mutual TLS internally
External traffic terminates TLS at the edge. Internal service-to-service traffic is mutually authenticated and encrypted via a service mesh in production. By deployment Where a mesh is not available, the documented fallback is TLS with service tokens still required plus a signed deployment manifest pinning expected service identities.
Your storage, your keys
Database storage is encrypted by the deployment substrate — your managed volumes or your storage class. Uploaded files are encrypted at rest by the object store. The storage service holds metadata and signing keys only, never file contents. Notification recipients are encrypted with AES-256-GCM before persistence.
| Key material | Handling |
|---|---|
| Token signing keys | EdDSA (Ed25519), with RSA available for clients with limited library support. Symmetric signing is prohibited and blocked by an automated check in every service |
| Private signing keys | Held in HashiCorp Vault and injected at runtime. On-premises deployments use your own Vault — we never hold your signing keys |
| Rotation | A new signing key every 90 days; the previous key remains published for verification only for 30 days — covering the longest refresh lifetime — before removal |
| Public keys | Published at a standard discovery endpoint and validated by every consumer with a bounded cache. No key material is embedded in any service |
| Object-store credentials | Vault-issued in production and mounted as secrets. No credentials are baked into container images |
| Model provider keys | Read from Vault with a startup verification probe, so a key store that has lost its contents is detected at startup rather than failing silently under load |
| Connected-source tokens | Vault only. The database row holds a non-secret reference path, never the token itself — verified by automated tests asserting no credential ever reaches the database, logs, traces or events |
Audit & observability
The audit service consumes durably from the platform event bus into an append-only store. Updates are prohibited outright, and deletion exists only within the retention process. Corrections are made by appending a new event, never by altering history — so the audit trail is evidentially sound rather than merely informative. Cross-organization audit access requires an administrative clearance and is itself audited.
What is audited
- Every authentication event and every authorization denial.
- Every administrative or cross-organization action, with a mandatory reason.
- Token issuance for an organization other than the user's home organization, with membership evidence.
- Every change to a cross-organization relationship.
- Every sensitivity-filtered read, retained for a 730-day minimum. The audit record is written in the same transaction as the response, so a read cannot succeed without being recorded.
Observability & operational resilience
Every service emits distributed traces carrying the organization identifier, structured logs carrying it on every request-scoped line, and health and readiness endpoints. Traces and logs never carry content or personal data — attributes are restricted to identifiers and counts, because the audience for telemetry is broader than the audience cleared for the content.
Metrics & alerting
Fleet-wide metrics with a monitoring and alerting stack covering both infrastructure and business-level indicators, so anomalous processing volumes are visible and not only outright failures.
Authentication visibility
The identity service records the code and detail of every client error it returns and every token rejection, so credential-stuffing patterns are distinguishable from ordinary misconfiguration.
Backup & disaster recovery
Documented backup procedures and a tested restore runbook. Restore procedures explicitly account for credential state and for re-running any outstanding deletion obligations, so recovery cannot silently reinstate data you asked us to remove.
Software supply chain
Container images are built and signed in the pipeline, with a vulnerability scanning gate. Dependency updates are automated and grouped, with major-version changes held for explicit review. Build tooling is version-pinned rather than resolved at build time, so a build cannot silently take an unverified upstream change.
Data lifecycle & your rights
| Stage | Commitment |
|---|---|
| Immutability | Finalized content is immutable; a correction supersedes via a new record, preserving the original for audit rather than overwriting it |
| Retention | Soft deletion with asynchronous cleanup of the underlying objects; retention processes mirror the audit retention model. Every service declares a purge commitment of 1–30 days, defaulting to 7 |
| Organization deletion | Every service holding your data must purge within its declared commitment and confirm completion. A reconciliation process verifies every expected confirmation arrived and flags any that did not — deletion is checked, not assumed |
| Cascade | Deleting a source removes its classifications, retracts derived signals and findings, cascades graph evidence, and version-bumps affected reports. Verified end-to-end by an automated test |
| Ordering independence | Deletion records a marker that suppresses later-arriving processing for that item, so an in-flight message cannot re-materialize deleted content |
| Subject access & erasure | Data-subject requests cascade by participant, covering an individual's appearances across content and the intelligence derived from it |
Threat model
The platform maintains a formal threat model; every service inherits its mitigations and adds tests proving they hold. The classes most relevant to a security review:
| Threat | Mitigation | How it is proven |
|---|---|---|
| Cross-organization data exposure | Graph query wrapper; forced row-level security; privilege-separated runtime role with a startup assertion | Suites seed two parallel organizations and assert every endpoint and every graph query returns only the requesting organization's data |
| Exposure through a parent-organization surface | Consent-gated relationships; relationship-bound credentials verified against active status, deny-by-default; no privileged cross-organization read path exists | A parent / managed / unrelated-third-organization triad proves the third organization is never reachable through any parent surface |
| In-organization exposure of private material | Ownership inheritance, most-restrictive-wins; shared graph holds shared evidence only; server-side ownership assignment for connected email; not-visible-until-classified | Tests fail if any persistence path drops an ownership label; cross-user-within-organization suites |
| Clearance bypass | Single shared filter, fail-closed, with a guard against local reimplementation; per-read audit; rounded withheld counts | Two-user tests on each endpoint; a report composed from mixed-clearance inputs contains nothing the reader is not cleared for |
| Organization confusion at the identity layer | Requested organization honored only if eligible; membership re-verified at every issuance, failing closed; silent renewal cannot be redirected | Issuance for a non-member fails at every path — authorization, exchange, renewal, and under request tampering |
| Prompt injection from untrusted content | Per-organization scoped runs; output-schema validation as the load-bearing control; tool arguments validated before policy evaluation; budget ceilings bound the blast radius | Adversarial fixtures assert the validator rejects manipulated output and records the rejection |
| Privilege escalation via workflow registration | A registered workflow's permitted scopes must be a subset of the registrant's own grants | Registration requesting excess scope is asserted to fail |
| Runaway or manipulated AI workload | Governance evaluated before any run; the gateway rejects calls without budget attribution. Fail-closed | With budget exhausted, the next run is asserted denied and audited |
| Personal data leaking into telemetry | Redaction in every service; traces exclude payload bodies; only the classification service persists findings | An adversarial personal-data string is asserted absent from all process output |
| Stale-read exploitation | Consistency is selectable per read; write-then-read paths default to the authoritative store | Simulated projection lag asserts strong reads route to the authoritative store |
| Extraction via signed URLs or events | Signed URLs capped at one hour, with any extension requiring a recorded architectural decision; event payloads carry identifiers only; file contents never pass through the application | Reviewed at design time; payload discipline is test-enforced |
| Credential abuse at the authentication surface | Rate limiting on login and token endpoints; uniform security headers; multi-factor authentication; single-use hashed reset tokens; refresh rotation; short token lifetimes; revocation list | Rate-limit behavior is unit-tested; authentication failures are instrumented for detection |
Deployment, residency & sub-processors
The data plane is identical in both models. In our cloud, customers are isolated by the mechanisms in this document. On-premises, you run the same code for a single organization. The reference target is Kubernetes via a Helm chart with your own or bundled PostgreSQL, event bus, object storage, Vault and telemetry collector. Air-gapped deployment is supported: offline installation bundles, no outbound calls at startup, offline license validation, and telemetry that can be disabled with no loss of function.
Connected sources — a contained, opt-in exception
Connectors are the one place the platform deliberately speaks a third-party API. The exception is contained, not granted:
- Optional and off by default — the platform is fully functional with no connector configured, and air-gapped deployments cannot run external connectors at all.
- Confined to the edge — no core or data-plane service imports a provider SDK; the coupling cannot spread inward.
- Per-connection and consented — a provider you connect is a sub-processor of your own choosing, adding no default third-party dependency for anyone else.
- Credentials in Vault only, never in the database, logs, traces or events — verified by automated tests.
- Content re-enters through existing paths, inheriting classification, the sensitivity gate, isolation policy, per-read audit, and private-by-default ownership for email.
- Individual self-connection is configurable per organization; organization-wide connectors remain a privileged operation.
Data residency
Data services are configurable per region and per organization; data does not cross regions without explicit configuration; audit events record their region of origin; and for sovereign or air-gapped deployments telemetry can be configured never to leave your boundary.
Model processing & training
Standards alignment
| Control area | How it is enforced |
|---|---|
| Multi-tenancy | Isolation tests run as the restricted runtime role; two-organization suites; parent/managed/third triad; database-grant regression guards; a migration check requiring isolation on every new table; ownership-inheritance tests |
| Authentication & authorization | Key-set validation; per-endpoint scope enforcement; asymmetric client authentication; automated checks prohibiting symmetric signing and hand-rolled validation; issuance-path tests |
| Event integrity | Transactional publication; standard envelope; registered subjects; organization-less events prohibited; payloads carry identifiers only |
| On-premises packaging | Chart validation; air-gapped startup test; automated rejection of cloud-vendor SDK imports |
| API compatibility | Schema linting; automated breaking-change detection on every change; prohibition on open-ended response schemas |
Control status & enablement
A consolidated view, on two independent dimensions. Status answers whether the control is built and enforcing — nearly everything here is. Where it is enabled answers the separate question of scope: whether it applies everywhere by construction, or is activated for your organization, per capability, or by how the platform is deployed. We publish both because a security document that collapses them is less useful — and less credible — than one that is precise about each.
| Control | Status | Where it is enabled | Notes |
|---|---|---|---|
| Organization isolation — forced row-level security, privilege-separated runtime role, startup assertion, token binding, graph wrapper | Implemented | Platform-wide | Two-organization suites in every content service; grant regression guards in the build |
| Membership-verified organization selection at the identity provider | Implemented | Platform-wide | Eligible set, provider-hosted selection, granted-organization persistence, re-verified at every issuance and renewal, failing closed |
| One organization per token; no multi-organization tokens | Implemented | Platform-wide | A platform invariant, not a configuration |
| Short-lived tokens, rotation, revocation list, multi-factor authentication | Implemented | Platform-wide | 15-minute access tokens; 90-day signing-key rotation with a 30-day verification overlap |
| Delegated access with intersected scope | Implemented | Platform-wide | Standards-based token exchange; delegation can never broaden privilege; chain recorded for audit |
| Workspace boundary — narrowing-only policy layer | Implemented | Per organization | Live across every content and intelligence service, with the policies in the database and the inheritance rule enforced platform-wide. Activated with you, because a new visibility boundary changes what people can see; fails closed on a configuration read error |
| Ownership inheritance through derived intelligence | Implemented | Platform-wide | Boundary propagation, persistence-time inheritance, shared-graph exclusion, graph-read filtering, delegated derivation, provenance for retraction |
| Connected email private-by-default; not-visible-until-classified | Implemented | Platform-wide | Enforced server-side irrespective of the caller's request |
| Machine organization-selection capability, separate from data access | Implemented | By deployment | Strict enforcement is implemented and tested, and runs in observation mode by default while capability grants are confirmed across background workers. Database policy carries the isolation guarantee throughout, and the user-facing path always rejects a mismatch outright |
| Multi-organization relationships — consent, relationship-bound credentials, per-person resolution | Implemented | Per capability | Consent by the managed organization; capability classes consented and enabled separately; all default off |
| Portfolio rollups and composed views | Implemented | Per capability | Enabled by capability class; each is separately consented |
| Sensitivity tag-and-gate, fail-closed, shared filter, per-read audit | Implemented | Platform-wide | Single implementation with a guard against local reimplementation |
| Classification pipeline — personal data, entities, sensitivity | Implemented | Platform-wide | Output-schema validation as the injection defense; findings stored redacted |
| AI governance — policy decision point, budgets, quotas, approvals | Implemented | Platform-wide | Fail-closed; approvals are token-based with an atomic claim |
| Agent tool-argument validation ahead of policy evaluation | Implemented | Platform-wide | Enforcing by default |
| Append-only audit; 730-day minimum on content-read events | Implemented | Platform-wide | Write in the same transaction as the response; export and webhook delivery available |
| Authentication-surface rate limiting and uniform security headers | Implemented | Platform-wide | Application-level rate limiting on the authentication surface; edge rate limiting is a deployment control for the rest |
| Metrics, alerting, authentication-failure instrumentation | Implemented | Platform-wide | Infrastructure and business-level indicators |
| Signed container images; vulnerability scanning; pinned build tooling | Implemented | Platform-wide | Supply-chain gates in the build pipeline |
| Signed-URL storage gateway; file contents never pass through the application | Implemented | Platform-wide | One-hour cap; organization-prefixed keys |
| Deletion cascade and purge reconciliation | Implemented | Platform-wide | Confirmations verified rather than assumed; extends to derived intelligence and parent-held references |
| Typed-signal extraction over documents and email | Implemented | Per organization | Enabled once the ownership boundary is active for your organization — sequencing that keeps derived intelligence inside the boundary it inherited |
| Backup and disaster-recovery procedures | Implemented | By deployment | Documented and tested restore, accounting for outstanding deletion obligations; operated by us in our cloud and by your team on-premises |
| Connected sources (Jira, Slack, Microsoft, Asana, mail) | Implemented | By deployment | Vault-only credentials, test-verified; coupling confined to the edge; available in our cloud, not in on-premises deployments |
| Mutual TLS service mesh | Implemented | By deployment | Required in the production topology; documented fallback is TLS plus service tokens plus a signed manifest |
| Model processing boundary | Implemented | By deployment | Hosted model by default in our cloud; locally-hosted model keeps content in-boundary and is the on-premises default |
| Declarative policy-language runtime for custom policy | Roadmap | — | The configuration-driven policy path, budgets and approvals are what enforce today, with every decision audited |
| Per-service policy engines with relationship-graph authorization | Roadmap | — | The current evaluator enforces today |
| Physical isolation for search and graph engines | Roadmap | — | The relational store enforces the workspace boundary today; search and graph apply it at the application layer, with the conservative choice of excluding private evidence from shared structures |
| Third-party certification (SOC 2 / ISO 27001 / HIPAA) | Roadmap | — | Not claimed today; this document provides control-coverage evidence instead |
Assurance & verification
A control that is not verified automatically is a control that erodes. The platform's governing discipline is that every security rule has a matching enforcement mechanism that runs on every change — so a regression fails a build rather than waiting to be discovered.
Tested as the restricted role
Isolation tests connect using the same restricted database role the application uses in production — so they prove the policy actually applies, rather than proving it exists. Tests seed two organizations and assert every endpoint returns only the requesting organization's data.
Guards against silent inertness
Database grant configuration is checked on every change, because a permission drift could make a policy inert without any visible failure. Ownership tests are written to fail if a label is dropped, so an inheritance regression cannot pass silently.
The third-organization triad
Cross-organization suites include an unrelated third organization and assert it is never reachable through any parent surface — testing not just that permitted access works, but that unpermitted access is impossible.
Adversarial fixtures
Personal-data strings are fed through request paths and asserted absent from all process output. Prompt-injection payloads are asserted to be rejected by schema validation and recorded.
Structural code guards
Automated checks block direct database access outside the repository chokepoint, raw graph sessions outside the wrapper, local reimplementation of the sensitivity filter, symmetric token signing, hand-rolled token validation, and cloud-vendor SDK imports in the data plane.
Compatibility & supply chain
API schemas are linted and checked for breaking changes on every change. Container images are signed and scanned, and build tooling is version-pinned so a build cannot silently take an unverified upstream change.