Runtime Platform
The Runtime Platform provides the infrastructure and services required to run, secure, and manage ContentGrid applications. It integrates several components to handle authentication, authorization, policy enforcement, routing, and frontend delivery.
Platform Overview
The Runtime Platform is designed as a Kubernetes-native system. Components dynamically discover resources like ConfigMaps, Secrets, and Services to route requests, enforce policies, and configure applications. This dynamic discovery enables zero-configuration deployment of new applications—the platform automatically detects and integrates them.
graph TB
subgraph "Runtime Platform"
Gateway[Gateway<br/>Entry Point & Routing]
Keycloak[Keycloak<br/>Authentication]
OPA[OPA<br/>Policy Evaluation]
Solon[Solon<br/>Policy Collection]
Navigator[Navigator<br/>Shared Frontend]
Liaison[Liaison<br/>Config Service]
Pathfinder[Pathfinder<br/>Ingress Management]
Ingress[Kubernetes Ingress]
subgraph "Application Instance"
AppServer[Application Server]
end
end
Client --> Gateway
Client --> Keycloak
Gateway --> OPA
Gateway --> AppServer
Client --> Navigator
Navigator --> |webbrowser request| Liaison
AppServer --> Solon
Solon --> OPA
Pathfinder -.->|Creates| Ingress
Ingress -.->|Routes to| Gateway
Core Components
Gateway
The Gateway serves as the entry point for all ContentGrid applications. It handles routing and coordinates with authentication and authorization services.
Primary Responsibilities:
- Route requests to the appropriate application based on the request’s domain
- Enforce CORS policies configured per application
- Coordinate user authentication with Keycloak
- Communicate with Open Policy Agent (OPA) for policy evaluation
Dynamic Routing: The Gateway maintains a mapping from domains to application IDs by reading Kubernetes ConfigMaps. When a request arrives for a specific domain name, the Gateway uses this mapping to determine the corresponding application and routes to the appropriate Service for that application.
CORS Configuration: Each application’s CORS origins are configured in a ConfigMap. The Gateway reads these configurations and merges CORS settings for both the API backend and the Navigator frontend, ensuring cross-origin requests are properly handled.
Application Server
The Application Server serves dynamic REST APIs generated from application models. Each ContentGrid application runs as an instance of the same Application Server container, with behavior determined by the application artifact loaded at startup.
The Application Server follows a configuration-driven approach where a single container image serves all applications, enabling consistent operations and rapid iteration without code generation.
For complete details on the Application Server architecture and components, see Application Server.
Keycloak
Keycloak provides authentication and identity management for the platform. Each application has a corresponding realm in Keycloak, though applications can share a realm (typically one realm per organization).
Key Functions:
- Authenticate users via OpenID Connect (OIDC)
- Store user attributes used in authorization policies
- Issue JWT tokens containing user identity and attributes
- Manage OAuth clients for both API access and frontend applications
User attributes stored in Keycloak (such as department, role, or clearance level) are included in JWT tokens and used by applications when evaluating attribute-based access control policies.
Keycloak is an open source project. More information about Keycloak can be found on keycloak.org.
Open Policy Agent
OPA is a centralized policy engine that evaluates attribute-based access control (ABAC) policies for all applications in the platform.
Key Functions:
- Evaluates Rego policies to determine authorization decisions
- Performs partial evaluation to return residual expressions when complete evaluation isn’t possible
- Receives policy bundles from Solon containing all application policies
- Queried by the Gateway before requests reach applications
When the Gateway receives a request, it queries OPA with user attributes and request context. OPA evaluates the relevant policy and returns either a decision (allow/deny) or a residual expression that the Gateway encodes in a JWT for the application to apply at the database level.
Open Policy Agent is an open source project. More information about Open Policy Agent can be found on openpolicyagent.org.
Solon
Solon collects Rego policy files from all applications and makes them available to OPA for policy evaluation.
Policy Collection:
- Discovers applications by querying Kubernetes Services with policy annotations
- Fetches policy files from application management endpoints via HTTP
- Bundles all policies together for OPA consumption
- Keeps OPA’s policy bundle up to date as applications are deployed or updated
Solon acts as the bridge between individual applications (which serve their own policy files) and the centralized OPA instance (which needs all policies to evaluate authorization requests).
Navigator
Navigator is a shared React frontend application used by all ContentGrid applications. Rather than deploying separate frontends per application, a single Navigator instance dynamically adapts to each application’s data model.
Adaptive Behavior:
- Discovers entities and available operations through HAL links
- Renders forms dynamically using HAL-FORMS templates
- Adapts to user permissions automatically (forms only show permitted actions)
- No application-specific code required—purely hypermedia-driven
Deployment Model: Pathfinder creates a separate Ingress resource for Navigator for each application, routing based
on domain. The Navigator instance then loads application-specific configuration from Liaison based on the request’s
Host header.
Liaison
Liaison serves configuration for Navigator on a per-application basis. It acts as a configuration service that provides the necessary settings for Navigator to connect to the correct application and authentication realm.
Configuration Delivery:
- Serves Navigator configuration based on the domainname of the request
- Provides OIDC client ID and issuer URL for authentication
- Enables a single Navigator instance to serve multiple applications
Pathfinder
Pathfinder automatically creates and manages Kubernetes Ingress resources for applications. It watches ConfigMaps and translates them into Ingress configurations, enabling external access to application services.
Two Deployment Variants:
- Pathfinder: Creates Ingress resources for application API backends
- Pathfinder for webapp: Creates Ingress resources for Navigator frontend
Resource Management:
- Reads ConfigMaps with domain routing configuration
- Creates Ingress resources with appropriate routing rules
- Coordinates with cert-manager for TLS certificate provisioning
Certificate Management: When Pathfinder creates an Ingress, cert-manager automatically provisions TLS certificates. Pathfinder adds annotations to ConfigMaps indicating which cluster issuer to use, and cert-manager handles the certificate lifecycle.
Application Deployment
When an application is deployed to the Runtime Platform, several Kubernetes resources are created to integrate it with the platform services.
Application Service
A Kubernetes Service makes the application accessible to the Gateway and other platform components. The Service is labeled with the application ID and service type, enabling dynamic discovery.
Key Labels:
app.contentgrid.com/application-id: Unique identifier for the applicationapp.contentgrid.com/deployment-id: Unique identifier for the deploymentapp.contentgrid.com/service-type: Type of service (e.g.,api,webapp)
Service Discovery: The Gateway uses these labels to discover Services. When routing a request, the Gateway queries for Services matching the application ID determined from the domain mapping.
OPA Integration: The Service also includes an annotation (authz.contentgrid.com/policy-package) indicating the OPA
policy package location. This enables the platform to collect policies from applications.
Request Flow
Understanding how a request flows through the platform illustrates how these components work together.
sequenceDiagram
autonumber
participant Client
participant Keycloak
participant Gateway
participant OPA as Centralized OPA
participant App as Application Server
participant DB as PostgreSQL
Note over Client, Keycloak: Authentication Flow
Client ->> Keycloak: Login (if no valid token)
Keycloak -->> Client: JWT with user attributes
Note over Client, DB: API Request Flow
Client ->> Gateway: HTTPS Request + JWT
Gateway ->> Gateway: Validate JWT signature
Gateway ->> Gateway: Look up application by domain
Gateway ->> OPA: Authorization query (JWT claims)
OPA -->> Gateway: Allow/Deny + Residual expression
Gateway ->> Gateway: Encode residual in new JWT
Gateway ->> App: Forward request + JWT with residual
App ->> App: Decode residual from JWT
App ->> DB: Query with authorization filter
DB -->> App: Filtered results
App -->> Client: HAL JSON response
Step-by-Step:
- Authentication: Client authenticates directly with Keycloak and receives a JWT with user attributes
- Request with Token: Client makes HTTPS request to Ingress with JWT in Authorization header
- JWT Validation: Gateway validates JWT signature using Keycloak’s public keys
- Gateway Routing: Gateway maps domain to application ID
- Policy Evaluation: Gateway queries centralized OPA with user attributes from JWT
- Residual Encoding: OPA returns residual expression that Gateway encodes in a new JWT
- Application Processing: Gateway forwards request with JWT containing residual to Application Server
- Data Access: Application decodes residual, translates to SQL filter, and queries database
- Response: Application formats response as HAL JSON and returns through Gateway
Scaling and High Availability
The Runtime Platform is designed for horizontal scaling and high availability:
Application Servers: Scale horizontally by increasing replica count. Each replica is stateless (except for database connections) and can handle requests independently. Kubernetes Services load balance across replicas.
Gateway: Runs as a highly available Deployment with multiple replicas. All replicas share the same configuration ( from ConfigMaps), and the Ingress load balances across them.
Keycloak: Can be deployed in clustered mode for high availability. Database-backed session storage enables failover between instances.
Navigator and Liaison: Stateless services that scale horizontally. Liaison reads configuration from Kubernetes API on each request (with caching), so all replicas have consistent configuration.
Database and Storage: PostgreSQL and S3 are external to the platform and have their own high-availability mechanisms (e.g., PostgreSQL replication, S3 redundancy).
Operational Characteristics
Zero-Configuration Deployment: Adding a new application requires only creating the standard Kubernetes resources ( Deployment, Service, ConfigMaps, Secrets). The platform automatically discovers and integrates the application.
Independent Scaling: Each application scales independently. Heavy workloads on one application don’t affect others.
Resource Isolation: Each application has its own database, S3 bucket, and Keycloak realm (or shared by organization). Resource limits prevent one application from affecting others.
Observability: Standard Kubernetes observability tools work out of the box. Platform components expose Prometheus metrics, health check endpoints, and structured logs.
Summary
The ContentGrid Runtime Platform provides a Kubernetes-native infrastructure that:
- Automatically discovers and integrates applications through labels and dynamic service discovery
- Scales applications independently with horizontal scaling and load balancing
- Manages authentication and authorization through Keycloak and OPA
- Provides a shared Navigator frontend that adapts to any data model
- Handles TLS, routing, and CORS through Gateway and Ingress management
The platform’s design enables operational simplicity—deploying applications requires no platform configuration changes, and standard Kubernetes operations handle scaling, updates, and failover.