Skip to content

Security & Authentication

In Falcone implements defense-in-depth security across all layers: network, identity, authorization, data isolation, and audit.

Authentication

Keycloak Integration

In Falcone uses Keycloak 26.1 as its identity provider with a multi-realm architecture:

Keycloak
├── in-falcone-platform (platform realm)
│   ├── Clients
│   │   ├── in-falcone-gateway (bearer-only, for APISIX)
│   │   └── in-falcone-console (public SPA)
│   ├── Roles
│   │   ├── superadmin
│   │   ├── platform_admin
│   │   ├── platform_operator
│   │   ├── tenant_admin
│   │   ├── tenant_operator
│   │   ├── workspace_admin
│   │   └── workspace_operator
│   └── Client Scopes
│       ├── tenant-context
│       ├── workspace-context
│       ├── plan-context
│       └── workspace-roles

└── tenant-{tenantSlug} (per-tenant realm)
    ├── Workspace clients: {workspaceSlug}-{appSlug}
    └── Service accounts: {workspaceSlug}-svc-{saSlug}

Token Flow

Client → Keycloak → JWT Token → APISIX → Control Plane
           │                       │
           │                       ├── Validate signature (JWKS)
           │                       ├── Check expiration
           │                       └── Project claims to headers:
           │                           X-Auth-Tenant-Id
           │                           X-Auth-Workspace-Id
           │                           X-Auth-Plan-Id
           │                           X-Auth-Roles
           │                           X-Auth-Scopes

           └── Platform realm: password / client_credentials grant
               Tenant realm: password / authorization_code / client_credentials

Supported OAuth 2.0 Flows

FlowUse CaseClient Type
Authorization Code + PKCEWeb console, SPAsPublic
Client CredentialsService accounts, backendsConfidential
PasswordDevelopment / testing onlyPublic

Authorization

Contextual Authorization Model

Authorization is context-aware — permissions depend on the tenant, workspace, and plan of the request:

Request

  ├── Platform Context
  │   └── Role: superadmin, platform_admin, platform_operator

  ├── Tenant Context
  │   └── Role: tenant_admin, tenant_operator
  │   └── Scope: tenant-context (claim: tenant_id)

  └── Workspace Context
      └── Role: workspace_admin, workspace_operator
      └── Scope: workspace-context (claim: workspace_id)
      └── Plan capabilities checked

Scope Enforcement

The APISIX gateway enforces scopes at the routing level:

  1. Claim Projection: JWT claims are projected into HTTP headers
  2. Spoofed Header Protection: Context headers from external sources are stripped
  3. Scope Matching: Route requires matching scope (e.g., /v1/workspaces/{id}/postgres requires workspace-context)
  4. Plan Capability Gating: Routes like /v1/iam/* require specific plan capabilities

Row-Level Security (PostgreSQL)

Every tenant's data is protected by RLS policies:

sql
-- Context functions
CREATE FUNCTION current_tenant_id() RETURNS TEXT AS $$
  SELECT current_setting('app.tenant_id', TRUE)
$$ LANGUAGE sql STABLE;

-- RLS policy on shared tables
CREATE POLICY tenant_isolation ON workspaces
  USING (tenant_id = current_tenant_id());

The runtime connection sets the tenant context before every query:

sql
SET LOCAL app.tenant_id = 'tnt_01HXXX';
SET LOCAL app.workspace_id = 'wks_01HXXX';

Role Separation (PostgreSQL)

RolePermissionsUse Case
platform_runtimeSELECT, INSERT, UPDATE, DELETE (with RLS)Normal API operations
platform_migratorCREATE, ALTER, DROP (DDL)Schema migrations
platform_provisionerCREATE SCHEMA, GRANTTenant provisioning
platform_audit_readonlySELECT on audit tablesAudit queries
platform_break_glassSuperuser (emergency only)Break-glass access

Gateway Security

APISIX Plugins

PluginPurpose
OIDCJWT validation against Keycloak JWKS
Rate LimitingPer-profile request throttling
CORSOrigin, method, header enforcement
Request ValidationRequired headers, body size limits
IdempotencyReplay protection (24h TTL)
CorrelationX-Correlation-Id propagation

Rate Limiting Profiles

ProfileRateBurstApplies To
platform_control240/min60Platform admin APIs
tenant_control240/min60Tenant management
workspace_control240/min60Workspace management
auth_control180/min40Authentication endpoints
provisioning120/min30Provisioning operations
observability300/min80Metrics and health
event_gateway600/min150Event publishing
realtime120/min30WebSocket connections

Request Validation

CheckDefaultNotes
Required HeadersX-API-Version, X-Correlation-IdAll API requests
Max Body Size262 KB1 MB for provisioning, 512 KB for admin
Idempotency-KeyOptionalRequired for mutating operations
Spoofed HeadersStrippedX-Auth-* headers from clients rejected

Secret Management

Architecture

Vault (Source of Truth)

  ├── Platform secrets (Keycloak admin, DB credentials, etc.)
  ├── Tenant secrets (per-tenant credentials)
  └── Workspace secrets (per-workspace API keys)


External Secrets Operator (ESO)

  ├── ClusterSecretStore → Vault connection
  └── ExternalSecret → Kubernetes Secret

      └── Pod (envFrom / volumeMount)

Secret Resolution Strategies

StrategyDescriptionUse Case
kubernetesSecretRendered as secretKeyRefDefault for all components
envPre-injected pod environment variableExternal injection
externalRefExternal secret manager metadataCloud secret managers

Vault Policies

PolicyScopeAccess
platform-policysecret/data/platform/*Read/write platform secrets
tenant-policysecret/data/tenant/*Read/write tenant secrets
gateway-policysecret/data/gateway/*Read gateway credentials
functions-policysecret/data/functions/*Read function secrets
iam-policysecret/data/iam/*Read IAM credentials

Pod Security

All pods run with restricted security contexts:

yaml
podSecurityContext:
  runAsNonRoot: true
  fsGroup: 1001
  seccompProfile:
    type: RuntimeDefault
  fsGroupChangePolicy: OnRootMismatch

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true    # Stateless components
  capabilities:
    drop: [ALL]

Compliance

StandardStatus
Kubernetes Pod Security Standards (Restricted)Compliant
OpenShift restricted-v2 SCCCompliant
Non-root containersAll components
Read-only root filesystemStateless components
No privilege escalationAll containers
Dropped capabilitiesAll containers

Audit Trail

Every operation is audit-logged:

json
{
  "eventId": "evt_01HXXX",
  "correlationId": "corr-abc-123",
  "timestamp": "2024-01-15T10:00:00.000Z",
  "actor": {
    "type": "user",
    "id": "usr_01HXXX",
    "roles": ["platform_admin"]
  },
  "resource": {
    "type": "workspace",
    "id": "wks_01HXXX",
    "tenantId": "tnt_01HXXX"
  },
  "action": "workspace.create",
  "outcome": "success",
  "metadata": { ... }
}

Audit events flow through Kafka topics and are stored in PostgreSQL for querying and compliance export.

Released under the MIT License.