Parascope Docs

Tenant Isolation Architecture

What is dedicated to your tenant, what is shared with other tenants, and the controls that hold the boundary in place.

Parascope is multi-tenant SaaS. Four things are provisioned for your tenant alone and carry a boundary the platform enforces: a Kubernetes namespace, a PostgreSQL database, a messaging account, and an identity realm. The infrastructure underneath those four is shared with other tenants. This page describes both halves, because the shared half is what a reviewer needs in order to size the risk.

What is dedicated to your tenant

Your tenant identifier, the slug in {slug}.parascope.io, is unique across the platform, fixed at provisioning time, and used to name each of these boundaries.

BoundaryHow it is provisioned
Kubernetes namespaceps-{slug} holds your API service, your processor, your cloud-hosted collectors, your secrets, your resource quota, and your network policies. The namespace name is immutable after creation.
PostgreSQL databaseDatabase ps_{slug}, reachable by a database role ps_{slug}_app whose permissions are limited to that one database. Application traffic runs through a connection pooler with a pool scoped to that user and database pair.
Messaging accountYour tenant has its own messaging account under the broker's own trust hierarchy. The account boundary is cryptographic and the message broker enforces it, not application code. A subscriber to the account-wide wildcard inside one account receives nothing published in another. The account also carries its own ceilings on connections, message size, throughput, and stream-storage disk.
Identity realmRealm ps-{slug} holds your users, sessions, tokens, password and brute-force policies. Realms do not grant access across each other, so an identity in one realm has no standing in another.

Source credentials you enter in Parascope are stored encrypted (AES-256-GCM) in your tenant's dedicated database and delivered only to your collectors over TLS; the platform's collectors read them one source at a time under an audited reveal grant. Encryption states the at-rest scope precisely, including what is not covered.

What is shared

The four boundaries above sit on infrastructure that serves other tenants at the same time:

Shared componentWhat it hosts
One Kubernetes clusterThe tenant namespaces and the shared services below, in a single Hetzner Cloud region in Helsinki, Finland.
One PostgreSQL clusterA cluster under a high-availability manager hosting the per-tenant databases. Your database is a database on that cluster, on the same nodes and the same storage as other tenant databases.
One messaging clusterThe broker servers that hold the tenant accounts and enforce the account boundaries between them.
Shared identity serviceHosts the per-tenant identity realms. A tenant is assigned to a shared instance at provisioning time and separated from other tenants on it by realm.
One frontend deploymentA single web application serves the tenant subdomains. It resolves the subdomain in the request to a tenant before calling that tenant's own API, and stores no infrastructure data at rest.

The isolation is logical. It rests on configuration the platform applies at provisioning time: namespaces and network policies, database roles, signed messaging account credentials, and identity realms, all of it running on hardware and clusters that tenants share. There is no physical separation between tenants, and no dedicated-instance or single-tenant deployment option today.

The honest limit of that model: a defect in one of the shared components is not bounded by the per-tenant boundaries the way a defect in tenant application code is. The controls that address that limit are documented separately, in Software Supply Chain for how code reaches production, Vulnerability Management for how the shared components are patched, and Availability, Backups and Disaster Recovery for what happens when one of them fails.

For private or air-gapped estates, collectors can run on an appliance inside your own network. That moves collection onto your infrastructure. The platform the appliance reports to is the shared one described above, reached by the outbound connection covered later on this page.

Network and resource controls

Each tenant namespace starts from a deny-all NetworkPolicy covering both ingress and egress.

Traffic is then re-enabled by an explicit allowlist, applied per workload: each workload's allowlist admits the services that workload needs and nothing else. Collector egress is the one deliberately open surface, because the endpoints a customer points a collector at are arbitrary addresses on arbitrary ports. Outbound reach from collector pods toward your sources is open by default, narrowed per collector by an address or hostname allowlist where a deployment wants that, and the cloud provider metadata endpoint (169.254.169.254) is excluded in both modes.

There is no allowlist entry pointing at another tenant's namespace, so cross-tenant pod traffic has no path to take.

Tenant workloads run non-root with a read-only root filesystem, privilege escalation disabled, and Linux capabilities dropped. A per-namespace ResourceQuota caps CPU, memory, ephemeral storage, and pod count, which bounds how much of the shared cluster one tenant can consume. Database work is bounded too: your application role runs under database-enforced statement, lock, and idle-in-transaction timeouts, so a runaway query is terminated by the database.

API rate limits

Rate limits apply per API key inside your own tenant's API. Service keys, used by the product's own server-side data fetching, are allowed more than user keys so that background fetching does not consume a person's budget. The figures below are the defaults. An individual API key can carry its own general-API limit, which is applied in place of the default for that key.

Endpoint groupUser keys (req/min)Service keys (req/min)
General API (/api/v1/*)200600
Change history (/api/v1/changes)60180
ParaQL (/api/v1/paraql)30100
Natural language (/api/v1/paraql/nl)20100
Cost export (/api/v1/cost/export)66
Health check (/api/health)Not rate limitedNot rate limited

The general API allows a burst of 40 requests above the sustained rate. When a limit is exceeded the API responds 429 Too Many Requests with X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After headers, so a client can back off on the value the server gives it. ParaQL queries are additionally gated on a complexity score, and queries above the user tier require a service or admin key.

Appliance connectivity

The on-premises appliance reaches the platform over outbound connections and accepts no inbound connection from Parascope. It does serve its own management interface on your local network, which is how you reach the onboarding wizard and its settings; that listener sits on your network, and nothing on the Parascope side connects to it. Outbound, it reaches two destinations on the platform:

DestinationPurpose
ingest.parascope.io:7422Messaging connection over TLS. Carries collected data to the platform and management requests back to the appliance on the same connection.
registry.parascope.io:443HTTPS pull of signed collector container images.

The appliance is a Rocky Linux host, so it also needs the egress any managed Linux host needs: DNS to your resolvers, NTP to a public time pool, and Rocky Linux package mirrors for its security updates while unattended updating is enabled. Correct time matters more here than usual, because the appliance validates TLS and container image signatures. An egress allowlist limited to the two Parascope destinations above leaves an appliance that cannot sync its clock or patch itself.

No inbound firewall rule, port forward, or site-to-site VPN is required, and the platform holds no route into your network. The credential the appliance uses is scoped inside your tenant's messaging account, so a compromised appliance is bounded by what that credential is permitted to publish and subscribe to within your own account.

Verify it yourself

  • The appliance reaches Parascope outbound only. Your own firewall or egress logs will show connections originating from the appliance to ingest.parascope.io:7422 and registry.parascope.io:443, alongside its host-level DNS and NTP traffic (and package-mirror traffic while unattended updating is enabled), and no inbound rule permitting the platform to reach it. The appliance's built-in connectivity check probes the two Parascope destinations, so it confirms the platform-facing half directly.
  • The rate limits are observable. Send an authenticated request to any /api/v1 endpoint with curl -i and read the X-RateLimit-Limit and X-RateLimit-Remaining headers in the response. They report the limit applied to the key you used.
  • Your identity boundary is visible during login. Signing in at your subdomain redirects to your tenant's own identity realm, https://auth.parascope.io/realms/ps-{slug}, which is in the browser address bar while you authenticate. Another tenant's realm path will not accept your credentials.
  • Platform availability and incident history are on the status page at parascope.instatus.com, hosted independently of the platform it reports on.
  • Isolation controls with their own verify pointers are listed in the control matrix.