Security
How Arcanon Hub isolates tenant data and protects your service graph.
Multi-tenant isolation
Arcanon Hub is a multi-tenant SaaS. Every piece of data — repos, scans, services, products, teams, members — is scoped to an organization. Isolation is enforced at the database level.
Row-Level Security (RLS)
PostgreSQL RLS policies enforce org isolation on every table. Every authenticated request calls:
SET LOCAL app.current_org_id = '<org-uuid>';All SELECT, INSERT, UPDATE, and DELETE operations are filtered by org_id at the database level. Even if application code has a bug, RLS prevents cross-org data access.
Defense in depth
In addition to RLS, every query includes an explicit WHERE org_id = $1 clause. This provides a second layer of isolation independent of the PostgreSQL session variable.
Authentication
JWT (interactive sessions)
The dashboard authenticates via Keycloak using OIDC PKCE flow. JWTs are RS256-signed and validated against Keycloak's JWKS endpoint on every request.
API keys (programmatic access)
Scanner, CLI, and MCP server authenticate via API keys (arc_...). Keys are stored as SHA-256 hashes — the hub never stores plaintext. Each key is org-scoped.
Input sanitization
Scan payloads are sanitized at ingest:
- HTML tags (including
<script>and<style>content) are stripped from service names - Null bytes and control characters are removed
- This prevents XSS in the multi-tenant dashboard where one org's scan data could contain malicious payloads
Rate limiting
| Endpoint category | Limit |
|---|---|
| Read (GET, GraphQL) | 200 requests/min |
| Write (scan upload) | 50 requests/min |
| Invite accept | 100 requests/min |
Rate-limited requests receive a 429 Too Many Requests response with a Retry-After header. The dashboard shows a countdown banner when rate-limited.
Account deletion
- User deletion —
DELETE /api/v1/users/mescrubs PII from the users table and cascades to org memberships - Org deletion —
DELETE /api/v1/orgs/{orgId}requires owner role + slug confirmation. Purges NATS streams, then deletes all org data in a single transaction
Data residency
All data is stored in PostgreSQL managed by the CloudNativePG operator on bare Kubernetes. No cloud-specific services are used (cloud-agnostic constraint). Data residency configuration is planned for a future enterprise release.