Help Instance Help

Delegated End-User Isolation

The problem it solves

A Ragty tenant is normally an organization whose own staff search their shared knowledge. But some tenants need to store and serve documents that belong to their external end users — for example a bank that ingests each customer's statements and contracts, or an insurer that holds each policyholder's files.

Without a dedicated mechanism this is unsafe or impractical:

  • Cross-customer leakage. If customer documents live in ordinary datasets, a retrieval request could surface one customer's documents to another. Ordinary tenant/workspace permissions were designed for staff, not for isolating millions of external end users from each other.

  • No external identity. End users are not Ragty accounts. There is no Ragty login to attach documents to, and the tenant's own customer identifiers must not be scattered across a second system as plaintext.

  • Gateway trust. A customer-facing application (a "gateway") searches on behalf of one signed-in customer. A leaked gateway credential must not be able to read every customer's documents.

Delegated end-user isolation solves this by letting a tenant ingest documents owned by external end users and guaranteeing that, through the customer-facing gateway, each end user retrieves only their own documents — never another end user's. Tenant staff (operators) remain fully trusted and can see and maintain all of their tenant's documents; the isolation boundary is strictly end-user vs. end-user, in addition to the usual tenant-vs-tenant boundary.

Core concepts

Concept

Meaning

Tenant

The organization (e.g. the bank) — the primary storage and authorization boundary

Operator

Tenant staff who upload and maintain documents and handle support — trusted with all tenant documents

Delegated subject

An external end user (e.g. a bank customer) — the retrieval-isolation owner

Trusted issuer

The external identity provider that authenticates end users (not Ragty)

Identity: issuer + derived subject key

An end user's identifier is issued by an external system, so it is only unique within that issuer. Ragty therefore combines two values:

  • issuer_id — a stable, server-owned label for one trusted external issuer (for example bank-customers), defined only in the trusted-issuer registry.

  • external_subject_key — a non-reversible SHA-256 digest derived on the server from the issuer-qualified subject: sha256(issuer_id + separator + subject).

The raw external subject (the customer's issuer-local identifier) is used only to derive the key and is then discarded. It is never persisted, never logged, and never returned to any client. The 64-character key is the only value used as the retrieval isolation predicate.

Optional display label

Because a hash is not human-readable, each subject key can carry an optional operator-facing label (for example the customer's name). The label:

  • is one value per (tenant, external_subject_key) — a rename applies to every document with that key;

  • is shown to operators and is searchable (by name or filename), but is never used as an authorization/retrieval filter;

  • is never shown to end users and never written to the vector store.

How isolation works

Every delegated retrieval on behalf of a verified end user returns only chunks that satisfy:

tenant_id = the gateway's tenant AND available_int = 1 # current, active document generation AND ( external_subject_key = the caller's key # the caller's own documents OR external_subject_key = "" ) # shared/unowned documents AND dataset_id IN the gateway key's assigned datasets

The "" branch lets an end user also see shared documents that have no delegated owner; another end user's key can never match. This predicate is enforced at a single vector-authorization chokepoint, so it cannot be dropped or weakened by a caller, and applies identically across dense, sparse, and hybrid search on both vector backends.

Operators are not subject to this predicate: a staff search returns the tenant's documents (delegated and non-delegated) under the ordinary tenant and workspace rules.

Where end-user identity enters

There are exactly two boundaries where a raw external subject is accepted, and both immediately derive the key and discard the raw value:

  1. Ingestion. A manifest-driven object-storage datasource lists one record per document with its issuer_id and subject. Records with an unknown issuer, a file outside the configured bucket/prefix, or a missing subject are rejected. Operators can also assign an owner (and label) when manually uploading a single document.

  2. Retrieval. The customer-facing gateway calls the MCP server with a gateway credential and a verified end-user assertion (a JWT). Ragty verifies the assertion against the issuer's published keys (fail-closed) and derives the same subject key. The assertion is never accepted from a tool argument or request body.

A gateway request without a valid end-user assertion is rejected; it never falls back to a broad, all-customers scope.

Dataset-level ownership

An operator can make a dataset authoritative for a single delegated owner. When a dataset carries an owner:

  • Every document in the dataset is shown with that owner; it cannot be overridden per document.

  • Uploading a document to the dataset must resolve to the same owner, or be omitted (and inherit it); a mismatched owner is rejected.

  • Changing the dataset owner re-assigns the documents that are currently unowned or already carry the previous owner. If any document has a different owner, the change is rejected and the conflicting documents are listed, so nothing is silently overwritten. A preview shows how many documents would change before the operator confirms.

This is managed from the dataset's Delegation tab in the UI.

Security guarantees

  • One end user can never retrieve another end user's documents through the gateway.

  • Compromise of a gateway credential alone cannot expose customer documents — a valid, verified end-user assertion is always required.

  • The raw external subject is never stored, logged, or returned; only the derived key (internal) and an optional operator label (display) exist.

  • The capability is off by default and enabled by a single configuration gate only after the ownership storage has been prepared and verified; otherwise the server fails closed at startup.

See also

04 September 2026