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:| Layer | What lives here | Who owns it |
|---|---|---|
| Solutions | Domain apps (Data Insights, Data Governance, your new solution) | Solution teams |
| Platform | Identity (Keycloak), authorization (OpenFGA), Governance/Assets/Utils services, secrets, storage abstraction, LLM gateway, microfrontend shell | Platform team |
| Infrastructure | Cloud provisioning, GitOps, networking, cluster lifecycle | SRE / Infra team |
What the platform provides
| Capability | Where | What you do |
|---|---|---|
| Authentication | Keycloak (multi-realm OIDC/PKCE) | Validate JWTs in your service. See Authenticate Users. |
| Authorization | OpenFGA via Governance SDK | Forward the user JWT + resource ID; receive allow/deny. |
| Multi-tenancy | org_id (from JWT) + X-Project-ID header | Read both from request context; scope all queries by them. See Concepts. |
| Resource registry | Assets API (port 8002) | Register agents, data connections, files, models. See Register a Solution. |
| Secrets | Infisical (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 storage | obstore abstraction over S3, GCS, Azure Blob, MinIO | Initialize a client from a Connection; put/get/list. See Use Shared Storage. |
| LLM access | LiteLLM gateway (provider-agnostic) | Set LLM_GATEWAY_URL; call with the OpenAI SDK. See Access LLMs. |
| Observability | Langfuse for LLM traces; OpenTelemetry for everything else | Set LANGFUSE_HOST; instrument with OTel SDK. See Langfuse Setup. |
| UI shell | em-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 database — no 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 carriesAuthorization: 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’sobstore 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 atLLM_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 Keycloak | Multi-realm setup is platform infrastructure; rolling your own breaks SSO |
| Write your own RBAC | OpenFGA is the platform’s source of truth; permission decisions stay there |
| Bake credentials into images or git | Use the secrets pipeline; rotation depends on it |
| Add a foreign key from your DB to a platform DB | Breaks independent restore/backup; use API contracts instead |
| Call OpenAI/Anthropic from your service code | LiteLLM gateway is the only attribution surface |
| Access another solution’s database directly | Cross-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).

