The model
Graphor’s tenancy model is single-tenant logical isolation on shared infrastructure. Every customer’s data lives in the same cloud project, the same primary database, the same managed graph store, the same object storage — but is partitioned at the application layer by anorganization_id foreign key that propagates through every customer-owned record.
This is the same model that most modern multi-tenant SaaS products use, including the upstream providers that Graphor itself depends on. It is well understood by SI evaluators, and it scales to high tenant counts without the operational complexity of one project / one cluster / one bucket per customer. The model is not suitable for customers that contractually require physically separated infrastructure; for those cases see §7.
The tenancy hierarchy is:
organization_id (nullable for personal-tier projects that have not been promoted to an Organization). Every authenticated database query, every object-storage key, every graph query is scoped by these identifiers — there is no application path that retrieves data without scoping by the calling user’s accessible Project set.
1. Isolation by layer
The same logical partition is enforced at every layer below the application. The table records how the partition shows up at each layer and what the failure mode would be if the partition were violated.| Layer | Isolation mechanism | Failure mode if violated |
|---|---|---|
| API surface | Every authenticated request resolves to a (User, Organization, Project) tuple in middleware before reaching any business handler. Endpoints that operate on per-project resources require a Project context derived from the API token or session. | Cross-tenant data exposure via API. Mitigated by integration tests and code-review gating that flags handlers without explicit Project scoping. |
| Primary database | Every customer-owned table carries the Project identifier as a column. Every ORM query is parameterized by the Project context from the request. There is no service account with read access to multiple customers’ rows that bypasses application-layer scoping. | Cross-tenant data exposure via SQL injection or a missing project-scope predicate. Mitigated by ORM parameterization, ORM-level constraints, and the parameterized-only query rule enforced by code review. |
| Managed graph store | Source-level nodes carry the Project identifier. Per-Project labelling on retrievable units backs the per-Project indexes, so a retrieval query cannot accidentally surface units from another Project. | Cross-tenant retrieval. Mitigated by the per-Project index design — a missing Project filter does not silently fall through to a global index. |
| Object storage | Every object key is prefixed with the Project identifier. Signed URLs issued to the customer carry a short expiration (15 minutes) and are scoped to a single object. The runtime service account has bucket-level access; per-customer scoping is enforced by the application before signing a URL. | Cross-tenant object access via a leaked signed URL. Mitigated by short URL TTLs and the application-side path-construction rule. |
| Encryption | All data at rest is encrypted with cloud-provider-managed keys by default; enterprise customers may request customer-managed encryption keys on a per-Project basis. See Trust Center Overview. | A single bad key would not allow cross-tenant access at the application layer, but customer-managed keys would let an enterprise customer rotate or revoke their key independently. |
| Observability traces | When tracing is enabled for a Project (see §4), each trace carries the Project identifier as a tag. Synapse personnel access traces under the same Project-scoped filtering as the customer’s own debugging UI. | Cross-tenant trace exposure during Synapse personnel debugging. Mitigated by Project-scoped role assignment on the observability store and by audit logging on the observability instance. |
| Billing | Payment-processor customer identifiers are stored on the Organization row, not on user or project rows. Billing data (payment-processor webhooks, invoice metadata) never reaches a per-Project surface. | Cross-tenant billing-data exposure. Mitigated by the deliberate separation of billing from product data — billing pages query Organization-scoped database tables that are distinct from the customer-content tables. |
2. API tokens
The API token model is the primary mechanism through which the customer authenticates programmatic access to Graphor. Tokens are per-project today. Every API token created in the Graphor UI is bound at creation time to exactly one Project. A token created in Project A cannot read, write, or otherwise act on Project B; the verification middleware rejects the request before it reaches any handler. This per-project model is the customer’s first-line isolation control. The customer-side best practice is to provision one token per Project per integration — do not share a single master token across multiple projects or environments, and do not reuse a development token in production. Each token can be revoked independently, has its own audit trail, and limits the blast radius of a leak. Token format. Every token is structured as<prefix>_<identifier:12chars>_<secret:32chars>. The identifier is indexed for O(1) lookup; the secret is stored only as a hash. The full token is shown to the customer exactly once at creation — Graphor cannot recover a lost token, only revoke and re-issue.
Token controls available today.
| Control | Where | Default | Purpose |
|---|---|---|---|
expires_at (TTL) | Project settings → API Tokens | Nullable (non-expiring) for backward compatibility; recommended to set on every new token | A token with an expiration cannot be replayed after the expiry, even if leaked. |
last_used_at + last_used_ip | Token list in Project settings | Auto-populated | The customer can detect tokens that are no longer in use (candidate for revocation) or that have been used from unexpected IP addresses. |
| Revoke | Token list in Project settings | n/a | A revoked token is rejected at verification time and may be hard-deleted asynchronously. |
| Control | Status | Description |
|---|---|---|
Scopes (sources:read, sources:write, chat:execute, extract:execute, dsr:execute) | Roadmap, no committed date | Per-token permission granularity. Today every token has the equivalent of ["*"] (full access to its bound Project). The roadmap path adds a scopes column on the token and route-level enforcement so customers can issue read-only or extract-only tokens. |
| Per-organization tokens | Not planned today — see §3 | A token that grants access to every Project in an Organization with a single credential would simplify integration for customers with many projects, at the cost of a larger blast radius if leaked. Graphor has chosen isolation over convenience for now. |
| IP allowlist per token | Not planned today — see §3 | Restricting a token to a fixed set of source IPs is available on request for enterprise customers via a manual configuration; there is no UI for it today. |
3. Explicit non-decisions
The following controls are sometimes asked about in SI questionnaires. Graphor has deliberately not built them; this section records that decision so SI reviewers know it is a conscious choice rather than an oversight.| Control | Why not built | Available on request? |
|---|---|---|
| Per-organization API tokens | Aggregating access across all Projects in an Organization into a single credential increases the blast radius of a leak. The per-Project model is the safer default and is sufficient for the vast majority of integrations. If a customer needs a single credential to talk to many Projects, the recommended pattern is to orchestrate per-Project tokens server-side under a customer-controlled secret store. | Considered case-by-case for enterprise contracts. |
| IP allowlist per token | Customer integration topology (serverless functions, dynamic CI/CD egress IPs, mobile clients) makes a static IP allowlist operationally fragile for most customers. The per-token TTL + audit-trail model in §2 captures most of the same risk reduction without the operational fragility. | Available on request for enterprise customers via manual configuration. |
| Physically separated infrastructure (one cloud project per customer) | Graphor’s logical-isolation model is the industry default and is auditable. A physical-separation deployment is a significant operational and cost commitment that few customers ultimately need. | Available on request for enterprise customers under a custom deployment SOW. |
| Bring-Your-Own-Cloud / dedicated tenancy | Same reasoning as physical separation. | Available on request for enterprise customers under a custom deployment SOW. |
4. Observability traces
Observability is tier-aware. The full retention rules and DSR endpoints are in Data Retention §4; this section focuses on the isolation dimension.- Enterprise tier — tracing is off by default. No traces are produced for Enterprise-tier projects unless the project owner explicitly enables tracing. The most conservative isolation posture: there is no trace surface to isolate from.
- Free and Pro tiers — tracing is on by default. Each trace is tagged with the Project identifier; Synapse personnel access traces under the same Project-scoped filtering as the customer’s own debugging UI. A Brazilian-PII regex mask is applied to every string field before send.
5. Customer best practices
There are a few things the customer can do to harden their own use of Graphor beyond the platform defaults:- One token per Project per integration. Do not share a single token across multiple Projects or environments. A leaked token then compromises only the Project and integration it was created for.
- Set
expires_aton every new token. A token that will never expire is a token that will eventually be in a stale backup, a forgotten config file, or a departed-employee’s machine. - Review the token list quarterly. Sort by
last_used_atand revoke any token that has not been used in the last quarter unless you know why it must remain. - Promote Projects to an Organization early. Personal-tier Projects (no
organization_id) cannot apply Organization-level access controls. Once a Project moves to an Organization, member management, billing, and (eventually) Organization-level controls become available. - For Enterprise-tier projects, leave observability tracing off unless you have a specific debugging engagement open. Re-enable it temporarily, then turn it off; the tracing toggle is reversible and does not lose product functionality.
- For Enterprise-tier deployments, ask about customer-managed encryption keys and physical separation early. Both are available but require lead time to provision.
6. Things that explicitly do happen at the Synapse-personnel layer
For transparency, the access Synapse personnel have to customer-owned data:- Project-scoped observability access for engineers actively supporting a customer or investigating an incident. Scoped — not blanket — and audited.
- Read access to the production primary database for the on-call engineer during incident response. All such access is logged via database audit logging.
- Read access to the production customer-content storage for the on-call engineer during incident response. All such access is logged via object-storage audit logging.
7. What Graphor explicitly does NOT offer today
- No physically separated infrastructure by default. Per §3, available on request under an enterprise SOW.
- No row-level encryption with customer keys. Customer keys protect a Project’s data at the storage layer via customer-managed encryption keys on enterprise request, but individual rows are not encrypted with a per-record key.
- No customer-owned database. The primary database is shared across customers; logical isolation is enforced at the application layer.
- No fine-grained scoped tokens today. See §2 for the roadmap.
8. Change history
| Version | Date | Change |
|---|---|---|
| 1.0 | 2026-06-21 | Initial publication. Documents per-Project token model, tier-aware observability, the token TTL + audit posture, and the explicit non-decisions on per-org tokens and IP allowlist. |
Contact
- General privacy and isolation inquiries: privacy@graphorlm.com
- Enterprise deployment options (customer-managed encryption keys, physical separation, BYOC): privacy@graphorlm.com
- Customer support: support@graphorlm.com

