The Architecture of AI Integration in openEduSuite
In openEduSuite, AI is not an add-on product but another class of services that follows the same rules as every other member of the suite: the same source of identity, the same deployment mechanics, the same operational discipline. This post shows how the AI integration is actually built β the layered model, SSO for n8n, Dify and Open WebUI, the planned agentic AI spine, data management, and operations β and where the line runs between productive reality and design.
The guiding idea: AI as a layer, not a monolith
The architecture follows a three-tier model that is not broken even for the AI services.
Platform. Keycloak is the single source of identity (id.example.edu, realm opendesk). Every AI service hangs off the same IdP β no second user management, no admin accounts on demand.
AI services as independent, isolated services. Instead of one AI monolith, the suite operates separate systems with clear responsibilities:
- n8n (
k8s/openedusuite/deploy-n8n.yaml) is the automation and orchestration tier: one pod with its own persistent volume (n8n-data, 5 Gi on Ceph-RBD) and a nix-built image from the project registry (openedusuite-nix/n8n, n8n 2.39.6, started via a Supervisord configuration in the Git manifest). - Dify is a separate app builder for AI applications: API, web, worker, and an nginx router in front (
deploy-dify-api.yaml,deploy-dify-web.yaml,deploy-dify-worker.yaml,deploy-dify-nginx.yaml, version 1.17.0). Dify brings its own data layer: its own PostgreSQL (deploy-dify-postgres.yaml), its own vector store Weaviate (deploy-dify-weaviate.yaml), and its own plugin daemon (deploy-dify-plugin-daemon.yaml); a shared cluster Redis serves only as cache and broker. - Open WebUI is the chat frontend (
nix/k8s/open-webui.nix, Helmfile deployment underai.example.edu); the models run locally (Ollama), prompts never leave the data center. For institutions bound to data protection and organizational confidentiality, local inference is not a convenience β it is the precondition for offering AI at all.
Service layer. Between the AI services and the suite's applications sits the intercom-service (k8s/openedusuite/deploy-intercom-service.yaml): an OIDC-based broker for service-to-service communication with silent login between applications and context passing. The manifest shows the connected systems as connectors (OpenCloud, SOGo, Nextcloud, Matrix, ILIAS); the pod is hardened: non-root, seccomp, read-only root filesystem.
SSO as the foundation: one gate, two patterns
The principle: every AI service stands behind the same Keycloak gate; the gate mechanics follow what each service can do natively. The suite knows two patterns.
Gate-only with oauth2-proxy for services that can consume identity from HTTP headers. Dify sits behind its own oauth2-proxy instance (deploy-oauth2-proxy-dify.yaml, client dify, callback dify.example.edu/oauth2/callback, upstream dify-nginx). The proxy redirects unauthenticated requests straight to Keycloak (with --skip-provider-button, no intermediate click page); only health endpoints are exempt (--skip-auth-regex=/health|/v1/.well-known). The same pattern protects the LMS: deploy-oauth2-proxy-lms.yaml (client lms) enables --set-xauthrequest; ILIAS reads the injected identity from the X-Auth-Request-* headers. Uniform across all instances: one realm, one cookie per service, --backend-logout-url pointing at the IdP for clean logout.
An SSO bridge instead of proxy login for n8n β this is where the AI integration departs furthest from the standard pattern. n8n Community (the OSS build under the Sustainable Use License) has no native SSO: OIDC, LDAP, and SAML exist only in the .ee. enterprise code, which the project neither ships nor will compile for you; a fork of n8n is out of the question. So openEduSuite operates its own n8n SSO bridge: an Express service running as a sidecar in the same pod (configmap-n8n-bridge.yaml, bridge.js, port 8080; the n8n container remains untouched on 5678). The parameters β issuer, client ID, client secret, n8n owner credentials, and an HMAC secret β come from the secret n8n-sso (secret-n8n-sso.yaml, provisioned by scripts/setup-n8n-secrets.sh).
The flow is the heart of the design: the user hits the bridge at n8n.example.edu/, is redirected to Keycloak, and returns via /sso/callback. The bridge exchanges the code for tokens, logs into n8n as the owner via the n8n REST API, finds the n8n user matching the OIDC email, and invites them if needed. It then logs in as exactly that user and hands their session cookie to the browser. No passwords are stored: a deterministic password is derived from sub and email via HMAC. Every Keycloak user gets their own n8n account with their own workspace (role global:member) β no shared admin account, and nobody can escalate to the n8n owner through the bridge.
Why isn't the proxy enough? An oauth2-proxy would establish a session in front of n8n, but n8n itself would remain without real user mapping β the bridge translates the Keycloak identity into a genuine "logged in as exactly this user in n8n," with personal workflows and own credentials. That SSO against unchanged third-party components is treacherous is documented in this blog's OpenCloud OIDC war story; the bridge is therefore backed by unit tests (bridge.test.js).
The agentic AI spine: orchestration with verifiable contracts
The next step β autonomous agents working through service APIs on behalf of humans β is fully documented as design and implementation plan, but not yet productive: docs/superpowers/specs/2026-10-13-agentic-ai-spine-design.md (status: draft) and docs/superpowers/plans/2026-10-13-agentic-ai-spine.md describe the reference saga S13 "Agentic AI".
The spine's central thesis: one invariant, two executors. Every agent contract carries two probes: an env probe executed against the infrastructure by a build or verification agent, and β where agentic β an act probe that the in-suite agent proves at runtime under its own service identity. Both check the same assertion; a contract only counts when both worlds attest it. The source of truth is a registry (docs/requirements/contracts/s13.json), executed by a runner (scripts/contract-check.mjs), rendered into the spec pyramid, and enforced by a trace gate in CI.
The orchestration tier is deliberately n8n β it already exists and is SSO-green. For the first useful loop, the flagship form agent (Grist form β validation β RT ticket β Matrix notification β email confirmation), a small dependency-free script can start in dry-run mode. Governance is at the center of the spec: agents run under Keycloak service accounts (agent-*, client_credentials, non-interactive, rotatable secrets), receive per-service API-only access (Grist, RT, mail, Matrix), no admin rights and no impersonation of humans; idempotency is enforced via the form UUID, every action is auditable, with a kill switch and no hard-coded credentials.
Data and memory: RAG, vector store, differentiated ownership
RAG is not a draft but configured reality in Dify: the manifest configmap-dify.yaml sets VECTOR_STORE=weaviate and points WEAVIATE_ENDPOINT at the suite's own Weaviate service (dify-weaviate, semitechnologies/weaviate 1.26.6 with its own PVC). Document-based Q&A thus stays entirely inside the suite: retrieval from the own vector store, generation from local models.
Dify also uses a two-process architecture: separate workers for asynchronous tasks (deploy-dify-worker.yaml), a plugin daemon (deploy-dify-plugin-daemon.yaml, version 0.6.10) with its own plugin database (dify_plugin), its own API key, and its own persistent plugin storage. Plugins therefore run isolated from the core API.
Differentiated data ownership. Each service owns its own database or volume β the Dify PostgreSQL is separate from the core database, n8n and Weaviate have their own volumes, and the shared Redis serves only as cache with separated indexes. That is operational discipline: one service can scale, patch, or fail without taking another down, and backup and deletion cascades remain manageable per service.
Operations: nix, GitOps, secret scripts, and network discipline
Operating the AI services does not differ from operating the rest of the suite.
Nix-built, from the own registry. Images are built in the Nix toolchain (nix/images/, nix/k8s/n8n.nix, nix/k8s/open-webui.nix) and pushed to the project's privately operated container registry; n8n and the intercom-service run as nix-built images. Reproducible builds, SBOMs, and signing are part of the process (see the "Nix shift" post).
GitOps. The manifests are canonical in Git, ArgoCD applies them (app openedusuite, selfHeal). Even the bridge code lives as a ConfigMap in Git (configmap-n8n-bridge.yaml) β not as an ad-hoc script on a node.
Secrets never in Git. Client secrets are provisioned idempotently: scripts/create-keycloak-clients-sso.sh creates the oauth2-proxy clients in Keycloak and reads the secrets back into Kubernetes secrets; scripts/setup-n8n-secrets.sh and scripts/setup-dify-secrets.sh generate the required secrets (passwords created via openssl rand, never hard-coded); scripts/provision-dify.mjs seeds the first Dify admin without ever storing a password in code. Rotation means: re-run the script, restart the pods.
Network and observability. Every AI pod carries liveness and readiness probes (the bridge on /sso/health, Weaviate on /v1/.well-known/live, Dify on /health). NetworkPolicies enforce deny-ingress by default per namespace and allow only same-namespace traffic plus the ingress controller (k8s/network-policies/). Monitoring (k8s/monitoring/) includes Prometheus, alert rules, and Grafana dashboards.
Outlook: production, design, open
What runs in production today: the SSO foundation with Keycloak and a uniform gate pattern, n8n with SSO bridge and multi-user provisioning, Dify as an independent app builder with its own data layer and RAG, Open WebUI with local models, plus the GitOps, secrets, and operations infrastructure.
What is design and planned work: the agentic AI spine is documented and the toolchain (registry, runner, generator) is concretized as a plan, but the design's DoD is open β service accounts, the form agent, and the env/act probes are not yet uniformly green. The form agent is the first useful loop, not yet productive; the forms foundation emerges via the planned Grist sovereign-forms extension.
What remains open: a consistently uniform "agent identity" across all services. Today every service knows its own session and identity mechanics β the same person acts as a Keycloak subject, as an oauth2-proxy session, as an n8n user, and in future as a service account. Uniformity of scopes, audit, and rights across these worlds (SSO coherence) and AI connectivity for further collaboration services such as the file layer are work, not claims.
Conclusion
AI integration in openEduSuite shows that sovereignty is not a question of individual tools but of architecture: one source of identity, isolated services with their own data ownership, a service layer between AI and applications, an SSO bridge only where the service demands one, and an operation that masters secrets, network, and configuration through Git and scripts. The agentic AI spine points to the next step β a contract system that makes every agent action provable before it goes into production.
Further reading: the spine design and implementation plan under docs/superpowers/, the project roadmap, the war story on the OpenCloud OIDC integration, and the Nix shift post.
AI services in openEduSuite follow the same rules as every other component of the suite. Source and manifests are visible in the public repository.