Security
Exposing Crisalid AI on the web without proper security puts you at risk of:
- Data leaks β institutional or personal data from the knowledge graph accessible to unauthorised users
- LLM exhaustion β uncontrolled consumption of tokens, which is critical with pay-per-token or quota-limited providers
Crisalid AIβs four-layer architecture means that security must be configured at each layer independently. The sections below cover each layer from the graph up.
πΈοΈ The graph layer β Neo4j
Neo4j is secured by a username and password, configured in docker/neo4j/.env.
Neo4j Community Edition does not support role-based access control (RBAC). All authenticated users have the same level of access to the graph. For fine-grained access control, the Enterprise Edition is required.
In a Community Edition deployment, the choice of toolset (crisalid-restricted vs crisalid-unrestricted) is the primary access control mechanism β see the tools layer below.
In production, avoid storing the Neo4j password in plain-text .env files. Use a sovereign secret management solution such as HashiCorp Vault.
π οΈ The tools layer β Neo4j MCP
The Neo4j MCP Toolbox does not support passwords or API keys. Authentication relies exclusively on JWT tokens issued by an OIDC provider β in the Crisalid stack, this is Keycloak.
Each client application (such as crisalid-agents-owui or crisalid-agents-chat-api) must be provisioned with a Keycloak service account to obtain tokens. This setup requires the Keycloak component of the Crisalid stack to be deployed and running.
The Keycloak requirement makes MCP toolbox authentication impractical on a local workstation. For local development, leave KEYCLOAK_CLIENT_ID and KEYCLOAK_CLIENT_SECRET empty in docker/crisalid-agents/.env β the toolbox client will then connect without authentication (suitable for a trusted local environment only).
Port 5000 is not exposed on the host β it is only reachable inside the Docker network. See the local workstation page if you need to access it from outside the stack.
For the full Keycloak service account setup procedure, see Using CRISalid AI Skills.
π€ The agent layer β Crisalid Agents (OpenWebUI Pipelines)
OpenWebUI Pipelines exposes a FastAPI server on port 9099. This endpoint is secured by a shared API key (PIPELINES_API_KEY).
The key is set once and must be provided by any client connecting to the pipelines server β in the Crisalid stack, this client is OpenWebUI itself.
In the Docker deployment, the key is configured in the shared docker/.env:
CRISALID_AGENTS_PIPELINES_API_KEY=<your-secret-key>It is injected into crisalid-agents-owui as PIPELINES_API_KEY β the server uses it to authenticate incoming requests.
When adding the pipelines connection in OpenWebUI (Admin panel β Settings β Connections, URL http://crisalid-agents-owui:9099), enter this key by hand in the API key field.
Port 9099 is not exposed on the host β it is only reachable inside the Docker network (agents-network).
The chat API (crisalid-agents-chat-api)
A second agent service exposes the same graph agent as a streaming chat API for SoVisuPlus (port 9100). It is secured by a shared API key, following the same scheme as the Apollo GraphQL endpoint: the key is configured once in the shared docker/.env and injected on both sides β
SOVISUPLUS_CHAT_API_KEY=<your-secret-key>The chat API checks the x-api-key request header against it; SoVisuPlus sends it with every request. The check is always on.
Port 9100 is not exposed on the host β the chat API is only reachable inside the Docker network (crisalid-front), server-to-server.
π₯οΈ The interface layer β OpenWebUI
OpenWebUI is the only layer directly exposed to end users.
- User registration is disabled by default (
ENABLE_SIGNUP=false) β accounts must be created manually by an administrator, or provisioned through Keycloak SSO. - An admin account is seeded on first run via
OPENWEBUI_ADMIN_EMAILandOPENWEBUI_ADMIN_PASSWORDindocker/openwebui/.env. - Keycloak SSO can be enabled via OAuth2/OIDC β see Configuring OpenWebUI.
π Supporting services β CRISalid Taxi
CRISalid Taxi has no authentication of its own. It is designed to be reached only by IKG on the internal Docker network, and its port is not published to the host.
- Do not expose it on the web. Each request triggers embedding calls to the shared endpoint, so an exposed instance is an easy way to exhaust your embedding quota.
- On a multi-server deployment, if you publish its port for IKG, restrict access to the IKG host with a firewall rule (see Multi-Server Deployment).
- The optional OpenSearch Dashboards profile publishes port
5601without authentication: keep it for local inspection only.