Architecture Guide

FLXBL provides two distinct authentication systems: one for you and your development team, and another for your application's end-users. Understanding this separation is key to building secure applications.

The Two Planes

FLXBL operates on a two-plane model that cleanly separates concerns:

100% Drag to pan
flowchart TB
    subgraph control [Control Plane - You and Your Team]
        Dev[Developers]
        Dashboard[FLXBL Dashboard]
        APIKeys[API Keys]
        ServiceAccounts[Service Accounts]
    end
    
    subgraph data [Data Plane - Your App's Users]
        EndUsers[Your End Users]
        IdentityEntity[Identity Entity]
        EndUserTokens[End-User JWTs]
    end
    
    subgraph flxbl [FLXBL Backend]
        SchemaAPI[Schema Management]
        DynamicAPI[Dynamic API]
        IdentityAPI[Identity API]
    end
    
    Dev --> Dashboard
    Dashboard --> SchemaAPI
    APIKeys --> DynamicAPI
    ServiceAccounts --> DynamicAPI
    
    EndUsers --> IdentityAPI
    IdentityAPI --> EndUserTokens
    EndUserTokens --> DynamicAPI
Control Plane for developers, Data Plane for your app's users

Control Plane — For You and Your Team

The Control Plane handles everything related to managing your FLXBL tenant:

  • Dashboard access — Log in with your FLXBL account to manage schemas, view analytics, and configure settings
  • API keys — Programmatic access for your backends, CI/CD pipelines, and integrations
  • Service accounts — Machine-to-machine authentication with audit trails
  • MCP tool — AI-assisted schema design and management

Data Plane — For Your Application's Users

The Data Plane handles authentication for the users of applications you build with FLXBL:

  • Identity entities — Any schema entity marked as an identity provider
  • Registration and login — Public endpoints for user self-service
  • End-user JWTs — Tokens for authenticated access to your data
  • Password management — Automatic hashing, email verification, and reset flows

When to Use Each

Choose the right authentication method based on who or what is making the request:

Scenario Authentication Method Plane
Your backend calling FLXBL API Key with scopes Control
CI/CD deploying schemas Service Account Control
Admin dashboard operations Your FLXBL JWT or API Key Control
Your app's users logging in Identity endpoints Data
Your app's users accessing data End-user JWT Data

Key Principle: Auth vs Authz

FLXBL follows a clear separation between authentication and authorization:

Concern Control Plane Data Plane
Authentication
"Who are you?"
FLXBL handles it
(JWT, API keys)
FLXBL handles it
(Identity endpoints)
Authorization
"What can you do?"
FLXBL handles it
(Roles, scopes)
You handle it
(Your app's logic)

This means for your end-users, FLXBL verifies their identity but you implement the authorization logic in your application. Store a role field on your identity entity and enforce permissions in your code.

API Endpoints by Plane

Control Plane Endpoints

Endpoint Purpose Auth Required
/api/v1/schemas Schema management JWT or API Key
/api/v1/api-keys API key management JWT
/api/v1/users Team management JWT
/api/v1/dynamic/:entity Data operations (admin) JWT or API Key

Data Plane Endpoints

Endpoint Purpose Auth Required
/api/v1/identity/:tenantId/register User registration None (public)
/api/v1/identity/:tenantId/login User authentication None (public)
/api/v1/identity/:tenantId/me Get user profile End-user JWT
/api/v1/dynamic/:entity Data operations (user) End-user JWT

Security Best Practices

Never Expose Control Plane Credentials

  • API keys belong on your server, never in client-side code
  • Use environment variables for all credentials
  • Rotate keys periodically and revoke unused ones

Implement Your Own Authorization

  • Add a role field to your identity entity
  • Check roles in your server middleware
  • Don't rely solely on FLXBL for end-user permissions

Use the Right Pattern for Your App

  • Web apps: Use a Backend-for-Frontend (BFF) pattern
  • Mobile apps: Store tokens in secure storage (Keychain)
  • APIs: Use scoped API keys or service accounts

Database Architecture

FLXBL uses a three-database strategy to optimize for different workloads:

100% Drag to pan
flowchart LR
    subgraph client [Your Application]
        REST[REST API]
        GQL[GraphQL]
        WS[WebSocket]
    end

    subgraph flxbl [FLXBL Backend]
        API[API Gateway]
        Services[Application Services]
    end

    subgraph storage [Data Storage]
        PG[(PostgreSQL<br/>Control Plane)]
        Neo[(Neo4j<br/>Data Plane)]
        Redis[(Redis<br/>Cache & Events)]
    end

    REST --> API
    GQL --> API
    WS --> API
    API --> Services
    Services --> PG
    Services --> Neo
    Services --> Redis
Three databases optimized for their specific purposes
Database Purpose Why This Choice
PostgreSQL Control Plane (schemas, users, tenants) ACID transactions, relational integrity for metadata
Neo4j Data Plane (your entities and relationships) Graph queries, relationship traversal, flexible schema
Redis Caching, events, rate limiting Sub-millisecond latency, pub/sub for real-time

Why Neo4j for Your Data?

FLXBL stores your dynamic entities in Neo4j because it excels at what matters most for application data:

  • Schema flexibility — Add fields without migrations or downtime
  • Relationship-first — Traverse relationships in constant time, regardless of data size
  • Multi-hop queries — Find "products purchased by customers who also bought X" in a single query
  • Multi-tenancy — Tenant isolation enforced at the query level with tenantId

Request Flow

Here's how a typical API request flows through FLXBL's backend:

100% Drag to pan
sequenceDiagram
    participant Client
    participant Gateway as API Gateway
    participant Auth as Auth Guard
    participant Service as Application Service
    participant Neo4j as Neo4j (Data)
    participant Redis as Redis (Cache)

    Client->>Gateway: POST /api/v1/dynamic/Product
    Gateway->>Auth: Validate JWT/API Key
    Auth-->>Gateway: ✓ Authenticated
    Gateway->>Service: Create Product
    Service->>Redis: Check schema cache
    Redis-->>Service: Schema definition
    Service->>Neo4j: CREATE (p:Product {...})
    Neo4j-->>Service: Node created
    Service->>Redis: Publish entity.created event
    Service-->>Client: 201 Created + Product data
Request lifecycle from client to database and back

Key points in this flow:

  1. Authentication — JWT or API key validated at the gateway
  2. Schema lookup — Cached in Redis for sub-millisecond validation
  3. Database operation — Cypher query executed against Neo4j
  4. Event publishingentity.created event sent to Redis pub/sub

Real-Time Architecture

FLXBL's real-time subscriptions use Redis Pub/Sub to broadcast events to all connected WebSocket clients:

100% Drag to pan
flowchart LR
    subgraph trigger [Event Trigger]
        CRUD[REST/GraphQL<br/>Create/Update/Delete]
    end

    subgraph backend [FLXBL Backend]
        Service[Application Service]
        Publisher[Event Publisher]
        PubSub[Redis Pub/Sub]
        WSGateway[WebSocket Gateway]
    end

    subgraph clients [Connected Clients]
        Sub1[Subscription 1]
        Sub2[Subscription 2]
        Sub3[Subscription N]
    end

    CRUD --> Service
    Service --> Publisher
    Publisher --> PubSub
    PubSub --> WSGateway
    WSGateway --> Sub1
    WSGateway --> Sub2
    WSGateway --> Sub3
Events flow from CRUD operations to WebSocket subscribers

This architecture provides:

  • Scalability — Multiple API servers share events via Redis
  • Low latency — Events delivered in milliseconds, not seconds
  • Tenant isolation — Events are namespaced by tenant ID
  • Reliability — WebSocket reconnection with automatic resubscription
Protocol: FLXBL uses the graphql-ws protocol, the modern standard supported by Apollo Client, urql, and most GraphQL clients.

Next Steps