<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Configuration on GENIE.AI</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/</link><description>Recent content in Configuration on GENIE.AI</description><generator>Hugo</generator><language>en</language><atom:link href="https://genie-ai-7e342b.opensource.unicc.org/docs/configure/index.xml" rel="self" type="application/rss+xml"/><item><title>Keycloak Admin Guide</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/keycloak-admin-guide/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/keycloak-admin-guide/</guid><description>&lt;p&gt;This guide explains how to manage users, roles, and groups for GENIE.AI through the Keycloak admin console. Everything identity-related — sign-up, sign-in, password reset, role assignment — happens in Keycloak; no GENIE.AI-specific UI is needed for user administration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Before proceeding:&lt;/strong&gt; confirm &lt;code&gt;KEYCLOAK_URL&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; matches the public URL users reach your Keycloak at (default: &lt;code&gt;https://localhost/auth&lt;/code&gt; for local dev). The BFF validates tokens against &lt;code&gt;&amp;lt;KEYCLOAK_URL&amp;gt;/realms/&amp;lt;KEYCLOAK_REALM&amp;gt;&lt;/code&gt; — if the value does not match what users see in the browser, every login will be rejected with a JWT signature error. For the full Keycloak env-var list (realm, client IDs, secrets), see &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/reference/env-vars/"&gt;Reference → Environment variables&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>External IdP Integration Guide</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/external-idp-integration-guide/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/external-idp-integration-guide/</guid><description>&lt;p&gt;This guide explains how to connect an external identity provider (Google, Microsoft Entra, generic OIDC, SAML) to GENIE.AI through Keycloak. Once configured, users can sign in via the external IdP without any GENIE.AI code or configuration changes — Keycloak brokers the entire flow and issues a standard OIDC token to GENIE.AI.&lt;/p&gt;
&lt;h2 id="before-you-start"&gt;Before you start&lt;/h2&gt;
&lt;p&gt;Before configuring an external IdP, make sure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GENIE.AI is deployed&lt;/strong&gt; with HTTPS reachable at &lt;code&gt;https://&amp;lt;NGINX_PUBLIC_DOMAIN&amp;gt;/&lt;/code&gt;. See &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/deploy/install-guide/"&gt;Installation &amp;amp; Configuration Guide&lt;/a&gt;. The placeholder &lt;code&gt;&amp;lt;your-domain&amp;gt;&lt;/code&gt; used throughout this guide is the value of &lt;code&gt;NGINX_PUBLIC_DOMAIN&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keycloak is reachable&lt;/strong&gt; at &lt;code&gt;https://&amp;lt;your-domain&amp;gt;/auth/admin&lt;/code&gt; (NGINX proxies &lt;code&gt;/auth/*&lt;/code&gt; to Keycloak).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code&gt;genie&lt;/code&gt; realm exists&lt;/strong&gt; (it is created automatically by the &lt;code&gt;keycloak-config&lt;/code&gt; service during the standard install).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You have admin access&lt;/strong&gt; to your Google Workspace / Microsoft Entra / generic OIDC / SAML IdP tenant, and the authority to register a new OAuth client or SAML relying party in it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outbound HTTPS from the Keycloak container to the IdP&lt;/strong&gt; is allowed by your network/firewall. If your network uses an HTTP proxy, see &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/configure/external-idp-integration-guide/#6-network-requirements"&gt;§6 Network requirements&lt;/a&gt; below.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="key-terms"&gt;Key terms&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Term&lt;/th&gt;
 &lt;th&gt;Meaning&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;OIDC (OpenID Connect)&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;The identity layer on top of OAuth 2.0 used by Google, Microsoft Entra, and most modern IdPs. Issues ID tokens (JWTs) that Keycloak can verify.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Broker (Keycloak)&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;The Keycloak feature that mediates between your app and an external IdP. The user signs in at the IdP, Keycloak translates the result, and issues its own token to GENIE.AI.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;JWKS (JSON Web Key Set)&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Public keys the IdP publishes; Keycloak uses them to verify the IdP&amp;rsquo;s ID token.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;&lt;code&gt;{iss}#{sub}&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Composite key for a federated user. &lt;code&gt;iss&lt;/code&gt; is the Keycloak realm&amp;rsquo;s issuer URL; &lt;code&gt;sub&lt;/code&gt; is the user ID Keycloak assigned to the local account (not the IdP&amp;rsquo;s &lt;code&gt;sub&lt;/code&gt;).&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;JIT (Just-In-Time) provisioning&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;The act of creating or updating the user record in ArangoDB on first authenticated request, using JWT claims as source of truth. See &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/configure/keycloak-admin-guide/#5-end-to-end-data-flow"&gt;Keycloak Admin Guide → §5&lt;/a&gt;.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Identity Provider Mapper&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;A Keycloak transformation that runs during the broker flow to map an IdP claim (e.g., &lt;code&gt;groups&lt;/code&gt;) to a Keycloak realm role. See &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/configure/keycloak-admin-guide/#6-external-idp-attribute--role-mapping"&gt;Keycloak Admin Guide → §6&lt;/a&gt;.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Federated user&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;A user authenticated by an external IdP, as opposed to a user authenticated directly against Keycloak&amp;rsquo;s local database.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 Browser[&amp;#34;Browser (GENIE.AI Frontend - Vue)&amp;#34;]
 Login[&amp;#34;Keycloak Login Page&amp;#34;]
 Local[&amp;#34;Local Keycloak account&amp;#34;]
 ExtBtn[&amp;#34;External IdP button (Google, Microsoft, …)&amp;#34;]
 AuthEP[&amp;#34;External IdP authorization endpoint&amp;#34;]
 Auth[&amp;#34;External IdP authentication &amp;#43; consent&amp;#34;]
 Broker[&amp;#34;Keycloak broker endpoint&amp;lt;br/&amp;gt;(/auth/realms/&amp;lt;realm&amp;gt;/broker/&amp;lt;alias&amp;gt;/endpoint)&amp;#34;]
 Exchange[&amp;#34;Keycloak exchanges code with IdP,&amp;lt;br/&amp;gt;validates token, applies Identity Provider Mappers (role assignment)&amp;#34;]
 Issue[&amp;#34;Keycloak issues its own JWT to GENIE.AI&amp;#34;]
 Store[&amp;#34;Frontend stores JWT and sends it on every API request&amp;#34;]

 Browser --&amp;gt; Login
 Login --&amp;gt; Local
 Login --&amp;gt; ExtBtn
 Local -. &amp;#34;Keycloak JWT&amp;#34; .-&amp;gt; Issue
 ExtBtn --&amp;gt; AuthEP --&amp;gt; Auth --&amp;gt; Broker --&amp;gt; Exchange --&amp;gt; Issue
 Issue --&amp;gt; Store&lt;/pre&gt;
&lt;p&gt;GENIE.AI always receives a standard Keycloak-issued OIDC token. The backend&amp;rsquo;s auth middleware (&lt;code&gt;keycloak-auth-middleware.js&lt;/code&gt;) is completely unaware of which external IdP was used — the JWT signature, claims, and roles look identical regardless.&lt;/p&gt;</description></item><item><title>Local development with self-signed certificates</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/local-dev-self-signed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/local-dev-self-signed/</guid><description>&lt;p&gt;When you point a local GENIE.AI stack at a hostname other than &lt;code&gt;localhost&lt;/code&gt;
(El Salvador-style mobile-test topology, a private-IP GPU node, a colleague&amp;rsquo;s
laptop over LAN), nginx serves a &lt;strong&gt;self-signed&lt;/strong&gt; TLS certificate. Browsers,
&lt;code&gt;curl&lt;/code&gt;, Node.js and Python all reject the connection on certificate-validation
grounds. This page lists every variable GENIE.AI exposes to either bypass or
trust that certificate in dev, names the service each variable reaches, and
spells out the security cost of bypassing.&lt;/p&gt;</description></item><item><title>Branding Customization</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/branding-customization/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/branding-customization/</guid><description>&lt;p&gt;This guide explains how to rebrand a GENIE.AI deployment for a partner institution: swap the logo, favicon, application title, and brand color in the web UI; replace the logo on the Keycloak login, account, admin, and email templates; and verify that everything renders correctly after a reload.&lt;/p&gt;
&lt;p&gt;The brand surface is small (one JSON config, four logo files, two CSS files) and every file is committed to the repository, so rebranding can be a normal code change: open one MR, get one review. Because those same files are also seeded onto every deployed node, you can equally rebrand a running deployment by editing them &lt;strong&gt;on the node&lt;/strong&gt; — no image rebuild, no redeploy. Pick whichever fits; &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/configure/branding-customization/#where-the-brand-files-live-at-runtime"&gt;Where the brand files live at runtime&lt;/a&gt; covers the difference, including the one trade-off that surprises people.&lt;/p&gt;</description></item><item><title>CORS, CSP &amp; Public Domain</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/cors-csp/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/cors-csp/</guid><description>&lt;h2 id="goal"&gt;Goal&lt;/h2&gt;
&lt;p&gt;Configure the three variables that govern what the browser is allowed to do
against GENIE.AI, and what GENIE.AI announces as its public origin — the trust
boundary between the SPA and the API gateway.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A deployed GENIE.AI stack (Docker Compose or Swarm) with HTTPS terminated at
nginx.&lt;/li&gt;
&lt;li&gt;A reachable &lt;code&gt;NGINX_PUBLIC_DOMAIN&lt;/code&gt; (the FQDN clients use to reach nginx) and a
valid TLS certificate for it.&lt;/li&gt;
&lt;li&gt;Access to &lt;code&gt;.env&lt;/code&gt; at the deploy root and to the host running the stack.&lt;/li&gt;
&lt;li&gt;For the OIDC verification step: the Keycloak realm name (default &lt;code&gt;genie&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="at-a-glance"&gt;At a glance&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Variable&lt;/th&gt;
 &lt;th&gt;Set in&lt;/th&gt;
 &lt;th&gt;Where it is consumed&lt;/th&gt;
 &lt;th&gt;Purpose&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NGINX_PUBLIC_DOMAIN&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;nginx redirects + frontend &lt;code&gt;Host&lt;/code&gt; header (&lt;code&gt;default.conf.template:278, 301&lt;/code&gt;), Keycloak &lt;code&gt;redirect_uri&lt;/code&gt; / &lt;code&gt;KC_HOSTNAME&lt;/code&gt;, Grafana &lt;code&gt;GF_SERVER_ROOT_URL&lt;/code&gt;, backend &lt;code&gt;KEYCLOAK_URL&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Hostname every redirect + OIDC issuer URL is derived from&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;CORS_ALLOWED_ORIGINS&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Backend &lt;code&gt;cors&lt;/code&gt; middleware (&lt;code&gt;components/gov-chat-backend/index.js:404&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;Comma-separated allow-list enforced by the backend &lt;code&gt;cors&lt;/code&gt; middleware (with &lt;code&gt;/regex/&lt;/code&gt; syntax — see &lt;a href="https://genie-ai-7e342b.opensource.unicc.org/docs/configure/cors-csp/#cors_allowed_origins"&gt;CORS_ALLOWED_ORIGINS&lt;/a&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;CSP_CONNECT_SRC&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;nginx &lt;code&gt;location /&lt;/code&gt; (&lt;code&gt;default.conf.template:268&lt;/code&gt;), nginx named location &lt;code&gt;@frontend_spa&lt;/code&gt; (&lt;code&gt;default.conf.template:292&lt;/code&gt;), backend Helmet &lt;code&gt;contentSecurityPolicy&lt;/code&gt; (&lt;code&gt;components/gov-chat-backend/index.js:382&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;CSP &lt;code&gt;connect-src&lt;/code&gt; directive emitted by nginx for the frontend HTML responses &lt;strong&gt;and&lt;/strong&gt; by the backend Helmet middleware. Must mirror &lt;code&gt;VUE_APP_CSP_CONNECT_SRC&lt;/code&gt; (frontend dev-server CSP — &lt;code&gt;components/gov-chat-frontend/vue.config.js:5&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;VUE_APP_CSP_CONNECT_SRC&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Frontend dev-server CSP (&lt;code&gt;vue.config.js:5&lt;/code&gt;) and &lt;code&gt;DefinePlugin&lt;/code&gt; injection (&lt;code&gt;vue.config.js:63&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;Build-time &lt;code&gt;connect-src&lt;/code&gt; for the local dev server and the runtime Vue bundle. Same value as &lt;code&gt;CSP_CONNECT_SRC&lt;/code&gt; (different stage: build-time vs. runtime).&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The other nginx locations each handle CSP &lt;strong&gt;independently of &lt;code&gt;CSP_CONNECT_SRC&lt;/code&gt;&lt;/strong&gt; —
this is deliberate (the API has no need for cross-origin &lt;code&gt;connect-src&lt;/code&gt;; Grafana
needs its own because it embeds WebSocket traffic):&lt;/p&gt;</description></item><item><title>Admin dashboard customization</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/dashboard-customization/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/dashboard-customization/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;The GENIE.AI admin dashboard is a single-file Vue 3 component,
&lt;a href="https://opensource.unicc.org/un/itu/genie-ai/-/blob/main/components/gov-chat-frontend/src/components/AdminDashboard.vue"&gt;&lt;code&gt;AdminDashboard.vue&lt;/code&gt;&lt;/a&gt;
(4465 lines, Options API) that renders a left sidebar, four stat tiles, and a
tabbed content area. The eight tabs cover everything an operator needs to run
the platform: &lt;strong&gt;System Health&lt;/strong&gt;, &lt;strong&gt;Knowledge Hierarchy&lt;/strong&gt;, &lt;strong&gt;Document
Management&lt;/strong&gt;, &lt;strong&gt;Database&lt;/strong&gt;, &lt;strong&gt;Logs&lt;/strong&gt;, &lt;strong&gt;Query Inspector&lt;/strong&gt;, &lt;strong&gt;User
Management&lt;/strong&gt;, and &lt;strong&gt;Security&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This page is the &lt;strong&gt;how-to&lt;/strong&gt; for customizing the dashboard. It walks through
the wiring model — sidebar nav-links, the &lt;code&gt;adminTabs&lt;/code&gt; computed property, the
&lt;code&gt;DsTabs&lt;/code&gt; component, and the &lt;code&gt;activeTab === '&amp;lt;tab-name&amp;gt;'&lt;/code&gt; content gates — then
gives step-by-step recipes for adding a tab, removing a tab, and adding a
new action card (the Backup / Optimize style). It also covers per-institution
access control (which goes through Keycloak, not the dashboard) and the
local-dev rebuild loop.&lt;/p&gt;</description></item><item><title>Restrict active locales on a deployment</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/locale-whitelist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/locale-whitelist/</guid><description>&lt;p&gt;GENIE.AI ships &lt;strong&gt;locale files for every supported language&lt;/strong&gt; in the source
tree. A deployment chooses which subset to &lt;strong&gt;expose&lt;/strong&gt; at runtime via three
configuration knobs — one per runtime surface:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Surface&lt;/th&gt;
 &lt;th&gt;Knob&lt;/th&gt;
 &lt;th&gt;Where it is read&lt;/th&gt;
 &lt;th&gt;Default (unset)&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Web UI&lt;/strong&gt; (language selector, vue-i18n runtime)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;VUE_APP_AVAILABLE_LOCALES&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Frontend &lt;code&gt;.env&lt;/code&gt; (build-time, then injected into &lt;code&gt;window.APP_CONFIG&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;All 14 locales&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Keycloak login pages&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;KEYCLOAK_SUPPORTED_LOCALES&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Keycloak realm config (JSON array, read at realm import / restart)&lt;/td&gt;
 &lt;td&gt;Curated default set&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Flutter mobile app&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;KeycloakConfig.supportedLocaleCodes&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Per-flavor Dart config (e.g. &lt;code&gt;mobile/genie_ai_mobile/lib/config/flavors/template.dart&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;Curated default set&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These three knobs are &lt;strong&gt;independent&lt;/strong&gt; — a deployment can restrict the web
UI to &lt;code&gt;en,fr&lt;/code&gt; while keeping all login-page languages (e.g. for a
deployment that federates to several identity providers each serving a
different locale audience).&lt;/p&gt;</description></item><item><title>Deployment flavors</title><link>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/deployment-flavors/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://genie-ai-7e342b.opensource.unicc.org/docs/configure/deployment-flavors/</guid><description>&lt;p&gt;A &lt;strong&gt;flavor&lt;/strong&gt; is the GENIE.AI term for everything that makes a deployment look
like a particular institution rather than the upstream &amp;ldquo;GENIE.AI&amp;rdquo; build. On
mobile, one flavor corresponds to one Dart file in
&lt;code&gt;mobile/genie_ai_mobile/lib/config/flavors/&amp;lt;name&amp;gt;.dart&lt;/code&gt;; every artifact that
should differ between institutions — splash image, app title, Keycloak
branding overrides, locale whitelist, mobile OIDC client — is read from
that file (and the shared assets under &lt;code&gt;assets/&lt;/code&gt;) at build time.&lt;/p&gt;
&lt;p&gt;The production reference flavor is
&lt;code&gt;mobile/genie_ai_mobile/lib/config/flavors/itu.dart&lt;/code&gt; (the ITU El Salvador
deployment). Every other flavor follows the same shape: copy &lt;code&gt;template.dart&lt;/code&gt;
to &lt;code&gt;&amp;lt;institution&amp;gt;.dart&lt;/code&gt;, edit the values that should change, and add a case
in &lt;code&gt;getConfig()&lt;/code&gt; in &lt;code&gt;keycloak_config.dart&lt;/code&gt; for the new flavor.&lt;/p&gt;</description></item></channel></rss>