Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt

Use this file to discover all available pages before exploring further.

Architecture for Solution Developers

This page explains the platform from the solution developer’s perspective: what you can rely on, what you own, and what contracts cross the boundary. It is not a complete platform architecture deep-dive — for that, see Architecture Overview.

Three layers, your job is the top one

CRAFT has three architectural layers. Solutions live at the top:
LayerWhat lives hereWho owns it
SolutionsDomain apps (Data Insights, Data Governance, your new solution)Solution teams
PlatformIdentity (Keycloak), authorization (OpenFGA), Governance/Assets/Utils services, secrets, storage abstraction, LLM gateway, microfrontend shellPlatform team
InfrastructureCloud provisioning, GitOps, networking, cluster lifecycleSRE / Infra team
Your solution inherits platform capabilities — never reimplements them. You do not run your own Keycloak. You do not write your own OpenFGA schema. You delegate via SDK calls and let the platform do the work.

What the platform provides

CapabilityWhereWhat you do
AuthenticationKeycloak (multi-realm OIDC/PKCE)Validate JWTs in your service. See Authenticate Users.
AuthorizationOpenFGA via Governance SDKForward the user JWT + resource ID; receive allow/deny.
Multi-tenancyorg_id (from JWT) + X-Project-ID headerRead both from request context; scope all queries by them. See Concepts.
Resource registryAssets API (port 8002)Register agents, data connections, files, models. See Register a Solution.
SecretsInfisical (self-hosted) or ESO + GCP Secret Manager (cloud)Declare in your chart’s envVars; read from os.environ or /mnt/secrets/. See Manage Secrets.
Shared storageobstore abstraction over S3, GCS, Azure Blob, MinIOInitialize a client from a Connection; put/get/list. See Use Shared Storage.
LLM accessLiteLLM gateway (provider-agnostic)Set LLM_GATEWAY_URL; call with the OpenAI SDK. See Access LLMs.
ObservabilityLangfuse for LLM traces; OpenTelemetry for everything elseSet LANGFUSE_HOST; instrument with OTel SDK. See Langfuse Setup.
UI shellem-runtime-ui (React Module Federation 2.0)Expose your UI as a remote module. (Out of scope for v1 of this guide.)

What your solution owns

You own everything that is specific to your domain:
  • The UI (typically a React microfrontend remote module loaded into em-runtime-ui)
  • The backend services (FastAPI + uvicorn is the platform default; nothing stops you choosing differently)
  • Your own PostgreSQL databaseno cross-service foreign keys with platform DBs. Each service owns its data; consistency across services is by API contract, not joins.
  • Your Helm chart that wraps em-service (one alias per component)
  • Optional Prefect workflows for orchestration-heavy work
  • Optional A2A or Pydantic AI agents for agentic capabilities
  • Your CI/CD pipeline (per-repo, calling shared modules)

Integration contracts

Five contracts cross the platform-solution boundary. Get these right and the rest is implementation detail.

1. JWT (authentication)

Every request to your service carries Authorization: Bearer <jwt>. The token is issued by Keycloak in the user’s organization realm. Validate the signature against Keycloak’s JWKS, extract org_id from the issuer URL, and reject requests with no token. See Authenticate Users for code.

2. X-Project-ID header (project scoping)

JWT alone gives you organization context. The active project is communicated via X-Project-ID. Every database query, storage path, and downstream call must be scoped by both. See Concepts for the full multi-tenancy model.

3. Connections API (data sources)

When your solution needs to talk to a customer database or object store, you do not ask the customer for credentials directly. They register a Data Connection via Assets, and you fetch the configured connection at runtime. Credentials never live in your code or config.

4. obstore (shared storage)

For artifacts, files, and intermediate data, use the platform’s obstore abstraction. Same code works against S3, GCS, Azure Blob, and local MinIO — pick the backend with the configured connection. See Use Shared Storage.

5. LiteLLM gateway (LLM access)

Solutions never call OpenAI or Anthropic directly. Instead, point your OpenAI-compatible SDK at LLM_GATEWAY_URL. The gateway provides central key management, per-project cost attribution, rate-limit enforcement, and observability via Langfuse. See Access LLMs.

What does NOT cross the boundary

You should never…Because…
Run your own KeycloakMulti-realm setup is platform infrastructure; rolling your own breaks SSO
Write your own RBACOpenFGA is the platform’s source of truth; permission decisions stay there
Bake credentials into images or gitUse the secrets pipeline; rotation depends on it
Add a foreign key from your DB to a platform DBBreaks independent restore/backup; use API contracts instead
Call OpenAI/Anthropic from your service codeLiteLLM gateway is the only attribution surface
Access another solution’s database directlyCross-service joins are forbidden; use the other solution’s API

Next steps

Quickstart

Build a working hello-solution in 30 minutes.

Register a solution

Naming, namespaces, image registries, registration steps.

Local development

Iterate quickly with docker-compose, hot reload, and mocked platform services.

Concepts

Read the platform-side concepts (orgs, projects, X-Project-ID).