Semaphor
Security

Security Overview

Unified Security for multi-tenant data isolation in Semaphor

Unified Security is Semaphor's model for controlling data access across the platform. It lets you define security policies on a connection, then assign them to specific actors -- tenants, tenant users, or organization users -- so each person sees only the data they should.

Three policy primitives cover the most common multi-tenant isolation patterns:

PolicyFull NameWhat It Controls
CLSConnection Level SecurityParameterize database connection strings or file paths per actor
SLSSchema Level SecurityRoute actors to specific database schemas
RLSRow Level SecurityFilter rows with WHERE clause predicates

You can use these individually or combine them. A tenant might connect to a dedicated database (CLS), operate within a specific schema (SLS), and still have row-level filtering applied (RLS).


How It Works

Unified Security follows a three-step model: define, assign, resolve.

1. Define policies on connections

An admin creates policy definitions on a connection. A policy definition is a reusable template with placeholders for values that vary per actor.

Example RLS policy definition
tenant_id = {{ tenant_id }}
Example CLS policy definition
postgresql://app:{{ password }}@db.company.com:5432/{{ tenant_db }}

A single policy definition can include CLS, SLS, and RLS rules together, or any subset.

2. Assign policies to actors

An admin creates assignments that bind a policy definition to a specific actor scope and fill in the placeholder values.

For example, assigning the RLS policy definition above to tenant "Acme Corp" with tenant_id = "acme" means every Acme user will have WHERE tenant_id = 'acme' applied to their queries.

3. Resolve at runtime

When a user runs a query, Semaphor resolves their effective security context by collecting all applicable assignments, merging them according to each policy type's rules, and applying the result to the query before execution.

Resolution flow
Actor identity + Applicable assignments + securityParams = Effective security context

The resolved CLS configures the connection, SLS pins the schema, and RLS predicates are injected as WHERE clauses -- all before the query reaches the database.


Actor Model

Unified Security supports four assignment scopes that target different levels of your user hierarchy:

ScopeTargetUse Case
ALL_TENANTSEvery tenant in the projectOptional shared policy and values for tenant actors
TENANTA specific tenantTenant-specific connection params or schema
TENANT_USERA specific end user within a tenantUser-specific security policy and values
ORG_USERAn organization userInternal user policies (independent, no inheritance)

Tenant assignment scopes

Persisted RLS does not require an ALL_TENANTS assignment. Each applicable assignment activates its definition for the targeted actor:

  • ALL_TENANTS activates the definition for every tenant actor.
  • TENANT independently activates it for one tenant.
  • TENANT_USER independently activates it for one user in a tenant.

When more than one applicable assignment supplies the same assignment-owned RLS parameter, the most specific supplied value wins:

TENANT_USER → TENANT → ALL_TENANTS

This is value precedence, not SQL narrowing. Semaphor retains every matching rule from every active definition and combines rules for the same secured entity with AND.

Organization users

Org-user assignments are independent -- they do not participate in tenant assignment precedence. If an org user has no applicable assignment, no persisted Unified Security policy definition is applied to that actor. Other connection, token, and authorization controls still apply.


Connection Security Mode

Each connection operates in one of two security modes:

ModeBehavior
legacyUses the existing token-based CLS, RCLS, and SLS model
unifiedUses Unified Security policy definitions and assignments

This is a per-connection setting, not project-wide. You can migrate connections one at a time while the rest continue using legacy security.

Migration path

  1. Start with all connections in legacy mode.
  2. Author Unified Security policy definitions and assignments (this has no runtime effect while in legacy).
  3. Preview the resolved security for different actors to verify correctness.
  4. Switch the connection to unified mode.
  5. If issues arise, switch back to legacy -- policy definitions and assignments are preserved.

Policy definitions are inert until assigned

Creating a policy definition does not enforce anything on its own. Enforcement begins only when an assignment binds a policy definition to an actor and the connection is in unified mode. An actor without an applicable assignment does not receive that policy definition. Other security layers and authorization controls still apply.


When to Use What

Choose your policy type based on how your data is organized:

Data ArchitectureRecommended Policy
Separate databases per tenantCLS -- parameterize the connection string
Separate schemas per tenantSLS -- route to the correct schema
Shared tables with a tenant identifier columnRLS -- filter rows by tenant
Separate databases with shared tables insideCLS + RLS
Separate schemas with user-level filteringSLS + RLS
File-based sources (S3) with tenant foldersCLS -- parameterize file paths

Most multi-tenant applications need at least one of CLS or SLS for tenant isolation, often combined with RLS for finer-grained access control within the tenant boundary.


Key Concepts

Before diving into configuration, here are the terms you will encounter throughout the security documentation:

  • Policy Definition -- A reusable security policy template attached to a connection. Contains CLS, SLS, and/or RLS configuration with placeholder parameters.
  • Assignment -- Binds a policy definition to an actor scope (ALL_TENANTS, TENANT, TENANT_USER, or ORG_USER) with concrete parameter values.
  • Resolution -- The runtime process that collects applicable assignments for the current actor and merges them into an effective security context.
  • Security mode -- The per-connection setting (legacy or unified) that controls which security model is active.

Next Steps

Legacy Security

For the legacy security model using token-based CLS, RCLS, and SLS policies, see Multi-Tenancy (Legacy).

On this page