How to configure an organization (tenant)¶
RA serves multiple organizations from one deployment. Each org has its own configuration blob and
prompt overrides in the organization_config database table, resolved at request time by
ConfigService: an org's override wins; otherwise the deploy-level Config.<KEY> default applies
(config_service.py). This guide covers reading and writing that per-org configuration.
Prerequisites¶
- The
App.Platform.Operatorrole. The/platform/*endpoints are gated to this role byAuthMiddleware. It is independent ofApp.Admin.FullAccess— an admin user does not automatically have it. Locally, run the backend withFAKE_AUTH_USER_TYPE=PlatformOperator(see the caveat in the repositoryREADME.md— the frontend and load-testing fake-auth adapters do not recognise this value, so set it on the backend service only). - The org's UUID. Org IDs are deterministic UUIDv5 values derived from a slug
(
organizations.py). Worked example: slugaara→36b2b7ae-cd2f-51ab-b9a5-369ca259991d.
Two ways to call the platform API: the altaforge-ra-cli tool (recommended) or raw HTTP. Set up
the CLI first via the CLI setup runbook.
Read an organization's config¶
=== "CLI"
```bash
# Full config blob
altaforge-ra-cli --profile prod api platform config get <org-uuid>
# A single key
altaforge-ra-cli --profile prod api platform config get <org-uuid> --key ENABLE_ESCALATION_WORKFLOW
```
=== "HTTP"
```bash
# Full config blob
curl "$BASE/platform/organizations/<org-uuid>/config" \
-H "Authorization: Bearer $TOKEN"
# A single key
curl "$BASE/platform/organizations/<org-uuid>/config/ENABLE_ESCALATION_WORKFLOW" \
-H "Authorization: Bearer $TOKEN"
```
GET /platform/organizations/{organization_id}/config returns the full JSON blob (404 if the
org has no config row). GET …/config/{key} returns a single top-level value (404 if the key is
absent).
Set a single config key¶
Setting one key leaves the rest of the blob untouched. Values are parsed as JSON with a
raw-string fallback, so 4096 stores an integer and SME Team stores a string.
=== "CLI"
```bash
altaforge-ra-cli --profile prod api platform config set <org-uuid> ENABLE_ESCALATION_WORKFLOW true
altaforge-ra-cli --profile prod api platform config set <org-uuid> ESCALATION_MAX_TOKENS 4096
```
=== "HTTP"
```bash
curl -X PUT "$BASE/platform/organizations/<org-uuid>/config/ENABLE_ESCALATION_WORKFLOW" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d 'true'
```
PUT …/config/{key} returns 204 No Content and invalidates the org's cached config so all
workers pick up the change within the cache TTL window.
Replace the whole config blob¶
PUT …/config overwrites the entire blob — any key not in the body is removed. Use this only
when you intend to set the complete config.
=== "CLI"
```bash
altaforge-ra-cli --profile prod api platform config replace <org-uuid> \
-d '{"ENABLE_ESCALATION_WORKFLOW": true, "ENABLE_QUICK_LINKS": true}'
```
=== "HTTP"
```bash
curl -X PUT "$BASE/platform/organizations/<org-uuid>/config" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ENABLE_ESCALATION_WORKFLOW": true, "ENABLE_QUICK_LINKS": true}'
```
The CLI also offers config apply --body-file <file> to set many keys from a committed JSON file
without wiping the rest of the blob, and config seed to write only missing keys — see the
CLI README for the difference between set, apply, replace, and
seed.
Set a prompt override¶
Prompt overrides are stored under a nested prompts sub-key of the org's config, not as flat
top-level keys, and are resolved by ConfigService.get_prompt. The body is raw UTF-8 text, not
JSON.
=== "CLI"
```bash
altaforge-ra-cli --profile prod api platform prompt set <org-uuid> ESCALATION_EMAIL_FOOTER \
-d "Regards, the Support Team"
```
=== "HTTP"
```bash
curl -X PUT "$BASE/platform/organizations/<org-uuid>/prompts/ESCALATION_EMAIL_FOOTER" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: text/plain" \
--data-binary "Regards, the Support Team"
```
PUT …/prompts/{prompt_key} returns 204 and invalidates the org's cache. Client-customisable
prompt keys that the workflow reads include QUERY_REWRITE_PROMPT, MULTI_QUERY_PROMPT, and
ESCALATION_EMAIL_FOOTER — see the Environment Configuration section of backend/README.md
for each feature's prompt key and behaviour.
What you can configure per org¶
Any key that ConfigService resolves can be set per org; when unset, the org inherits the
deploy-level Config.<KEY> default. Commonly tuned per-tenant settings (full descriptions in
backend/README.md):
| Key | Effect |
|---|---|
ENABLE_ESCALATION_WORKFLOW |
Adds escalation intent classification to the RAG workflow. |
ENABLE_QUERY_REWRITING |
Rewrites the query before retrieval. |
ENABLE_MULTI_QUERY_RETRIEVAL |
Fans out parallel query reformulations. |
ENABLE_QUICK_LINKS |
Exposes the sidebar Quick Links list. |
MANUAL_ESCALATION_EMAIL / MANUAL_ESCALATION_BUSINESS_AREA |
Enable the manual SME contact panel (both required). |
DEFAULT_SEARCH_MODE |
azure_ai_search or agentic — the retrieval mode used when a request omits search_mode. |
ACS_EMAIL_FROM_ADDRESS |
Per-org sender address for escalation emails (overrides the deploy default). |
The Azure AD auth config (special case)¶
The five keys RA needs to validate a tenant's Azure AD tokens — the app client id, tenant id,
issuer URL, JWKS URL, and which JWT claim carries the user id — are per-org config with no code
or env fallback. An org missing any of them cannot authenticate real users, and a request
against it returns 401 (not 500), since a token that cannot be validated is indistinguishable
from an invalid one (middleware.py::JwtAuthBackend, config_service.py::resolve_azure_jwt_config).
Set them the same way as any other key. Locally, make run-dev / make run-prod seed these for
the dev org automatically via the one-shot seed-org-auth-config Compose service, so you do not
need to set them by hand for local development.
TODO(SME): confirm the canonical key names for the five Azure AD config values as stored in the
organization_configblob (the README documents them by role —AZURE_APP_CLIENT_ID,AZURE_TENANT_ID,AZURE_ISSUER_URL,AZURE_JWKS_URL,USER_IDENTIFIER_PROPERTY— but verify these are the exact stored keys before publishing a copy-paste example).