account-config.mdRaw

Tenant configuration (Dashboard & API)

This document describes tenant-level configuration options that affect the behavior of AISentinel. It focuses on which settings are available in the Dashboard UI, which are only available via the API, the default values used by the system, and the role requirements that control who can change a setting.

High-level summary:

  • There are two places where tenant configuration is stored and edited:
    • Dashboard (Next.js UI): GET /api/config and PATCH /api/config are used to show and update general, non-sensitive tenant settings (for example, rate limits and API timeouts). The UI also proxies calls to backend tenant-config endpoints for a number of per-tenant overrides.
    • Backend Tenant Config (encrypted): GET /api/v1/tenant-config/{key} and PUT /api/v1/tenant-config/{key} handle per-tenant overrides stored in the backend's encrypted tenant config storage (the tenant_configs table). Only the keys listed in the server's _TENANT_CONFIG_DEFAULTS are accepted by these endpoints.

Where to edit (examples):

  • Dashboard UI (no raw API key required):
    • Visit the Dashboard configuration page (Dashboard ➜ Configuration). The UI will call the frontend routes and may proxy to backend APIs to read or write tenant overrides.
  • Backend API (programmatic):
    • Read an override: GET /api/v1/tenant-config/{KEY}
    • Set an override: PUT /api/v1/tenant-config/{KEY} with JSON body { "value": ... } to set or { "value": null } to clear the override and revert to default
    • Provision SSO with secrets: POST /tenants/provision-sso (Admin-only, can persist client secrets in a secret manager)

Authorization & role restrictions:

  • Some configuration keys are user-scoped and may be changed by any authenticated tenant member. These are often preferences (for example, cost estimator overrides).
  • Some configuration keys are sensitive (security and resource limits) and require ADMIN/OWNER to modify. The backend enforces role restrictions. The UI also hides or disables these fields for non-admins.

Common UI vs API keys

The sections below list keys that are either exposed via the Dashboard UI, or only accessible through the API. Each entry indicates whether it is modifiable in the Dashboard and the role required to change it.

Note: The server determines which tenant-config keys are recognized by looking at the _TENANT_CONFIG_DEFAULTS table in the backend implementation (src/AISentinel_auditor/app.py). The Dashboard exposes a subset of these keys via the UI.

Dashboard UI (fields shown on the Configuration page)

  • rateLimit — (dashboard: UI top-level) requests per minute; patchable via PATCH /api/config.
  • apiTimeout — (dashboard: UI top-level) API request timeout in seconds; patchable via PATCH /api/config.
  • estimatorPerTokenUsdESTIMATOR_PER_TOKEN_USD — per-token USD estimator; editable by any tenant member via tenant-config API.
  • estimatorToolBaseCostsESTIMATOR_TOOL_BASE_COSTS — JSON object of base tool costs; editable by any tenant member.
  • safeDocsUrlSAFE_DOCS_URL — Admin-only; trusted doc fallback for the LLM.
  • urlWhitelistURL_WHITELIST — Admin-only; domain patterns allowed by web tools.
  • llmSkipLowRiskToolsLLM_SKIP_LOW_RISK_TOOLS — Comma-separated list of tools to skip LLM checks; user preference.
  • llmFeatureWeightsLLM_FEATURE_WEIGHTS — Admin-only; JSON weights for LLM assessments.
  • llmModelLLM_MODEL — Admin-only; selects the LLM for assessments.
  • enableResearchEndpointENABLE_RESEARCH_ENDPOINT — Admin-only boolean that enables autonomous research features.
  • maxMemoryUsageMbMAX_MEMORY_USAGE_MB — Admin-only; resource limit in MB.
  • maxDiskUsageMbMAX_DISK_USAGE_MB — Admin-only; resource limit in MB.
  • maxToolExecutionTimeMAX_TOOL_EXECUTION_TIME — Admin-only; maximum per-tool execution time in seconds.
  • ssoProvider, ssoOktaClientId, ssoOktaIssuer, ssoAzureAdClientId, ssoAzureAdTenantId, ssoGoogleClientId, ssoAuth0Domain, ssoAuth0ClientId — SSO-related client IDs/metadata; CMS-style UI editing is supported for client IDs and issuer fields; secrets remain server-level protected data and are provisioned via POST /tenants/provision-sso.

General (UI: Patch /api/config)

  • Rate Limit (rateLimit) — Number (requests per minute)
    • Where: Dashboard UI PATCH /api/config (frontend Prisma TenantConfig.rateLimit)
    • Default: 60 (server-side default when not set)
    • Notes: Per-tenant rate limiting is enforced in RateLimitMiddleware in the backend. This key is a typical UI-controlled setting, and changes take effect immediately for that tenant.
  • API Timeout (apiTimeout) — Number (seconds)
    • Where: Dashboard UI PATCH /api/config (frontend)
    • Default: 30 seconds
    • Range: 1 - 600 (validated by UI)

Estimator & cost settings (UI & API: tenant-config)

  • ESTIMATOR_PER_TOKEN_USD (ESTIMATOR_PER_TOKEN_USD) — Decimal
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/ESTIMATOR_PER_TOKEN_USD for user-level override; can be changed by any tenant member.
    • Default: 0.0001
    • Type: number
  • ESTIMATOR_TOOL_BASE_COSTS (ESTIMATOR_TOOL_BASE_COSTS) — JSON
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/ESTIMATOR_TOOL_BASE_COSTS (UI shows a JSON field; the backend stores it as a string)
    • Example: {"web":0.001, "python_exec":0.01}
    • Default: {"web":0.001,"python_exec":0.01}

Security & LLM settings (Dashboard UI shows these; many require Admin/Owner)

  • Safe Docs URL (SAFE_DOCS_URL) — string (URL)
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/SAFE_DOCS_URL (Admin-only).
    • Default: empty string
    • Notes: Used as a trusted documentation fallback when LLM assessments consult a “safe” documentation source.
  • URL Whitelist (URL_WHITELIST) — string (comma-separated patterns)
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/URL_WHITELIST (Admin-only)
    • Default: empty string
    • Notes: Controls domain patterns allowed by web tools (for example docs.example.com, .gov, .edu)
    • The backend validates the whitelist and the UI performs basic pattern checks before sending.
  • LLM Model (LLM_MODEL) — string
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/LLM_MODEL (Admin-only)
    • Default: empty string (fallback to provider default)
  • LLM Skip Low-Risk Tools (LLM_SKIP_LOW_RISK_TOOLS) — string (comma-separated)
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/LLM_SKIP_LOW_RISK_TOOLS (User preference: any tenant member)
    • Default: empty string
  • LLM Feature Weights (LLM_FEATURE_WEIGHTS) — JSON
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/LLM_FEATURE_WEIGHTS (Admin-only)
    • Example: {"llm_confidence": 1.5, "llm_expected_impact": 1.0, "llm_policy_risk": -2.0}

Resource limits (Admin-only)

  • Max memory (MAX_MEMORY_USAGE_MB) — integer MB
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/MAX_MEMORY_USAGE_MB (Admin-only)
    • Default: 512 MB
    • Minimum: 1 MB
  • Max disk (MAX_DISK_USAGE_MB) — integer MB
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/MAX_DISK_USAGE_MB (Admin-only)
    • Default: 100 MB
    • Minimum: 1 MB
  • Max tool execution time (MAX_TOOL_EXECUTION_TIME) — seconds
    • Where: Dashboard UI proxies to backend PUT /api/v1/tenant-config/MAX_TOOL_EXECUTION_TIME (Admin-only)
    • Default: 300 seconds
    • Minimum: 1 second

SSO & Identity

  • SSO provider and client ID fields are surfaced in the Dashboard and stored as tenant-config overrides. However, secrets (client_secret) are sensitive and handled by the provisioning endpoints and/or external secret managers:
    • To provision SSO and persist client secret safely, use: POST /tenants/provision-sso (Admin-only). The provisioning flow stores secrets in AWS Secrets Manager when AWS_SECRET_NAME is set, or falls back to encrypted tenant config.
    • SSO config keys used by the system (examples): SSO_PROVIDER, SSO_OKTA_CLIENT_ID, SSO_OKTA_ISSUER, SSO_AZURE_AD_CLIENT_ID, SSO_AZURE_AD_TENANT_ID, SSO_GOOGLE_CLIENT_ID, SSO_AUTH0_DOMAIN, SSO_AUTH0_CLIENT_ID, SSO_DOMAIN_ALLOWLIST.
    • Sensitive secrets: SSO_OKTA_CLIENT_SECRET, SSO_AZURE_AD_CLIENT_SECRET, SSO_GOOGLE_CLIENT_SECRET, SSO_AUTH0_CLIENT_SECRET are sensitive and require the Admin/Owner API flow to set.

Other keys (API-only / Not shown in Dashboard)

  • CONTRACT_SEARCH_API_KEY and CONTRACT_SEARCH_API_URL — these are API-backed configuration values for contract-search / research integrations. They are sensitive and require Admin/Owner permissions.
  • Circuit breaker tuning keys: CIRCUIT_BREAKER_FAILURE_THRESHOLD, CIRCUIT_BREAKER_RECOVERY_TIMEOUT, CIRCUIT_BREAKER_SUCCESS_THRESHOLD — API-only in most setups; they can be adjusted via PUT /api/v1/tenant-config/....
  • OFFLINE_MODE_ENABLED, DEFAULT_REPORT_EMAILS, EMBEDDED_TOOLS_DEFAULT, and other advanced keys are available in _TENANT_CONFIG_DEFAULTS but aren't necessarily surfaced in the Dashboard UI — you can still set them via the backend API if needed.

Changing configuration via API — Examples

  • Read a key (returns effective value and the source—either tenant or default):

    GET /api/v1/tenant-config/URL_WHITELIST Response: { "key": "URL_WHITELIST", "value": "docs.example.com,.gov,.edu", "source": "tenant" }

  • Set a key via API (clear override by sending value: null). This requires a valid tenant API token and may require Admin/Owner role based on key sensitivity.

    PUT /api/v1/tenant-config/URL_WHITELIST Body: { "value": "docs.example.com,.gov,.edu" }

    or

    PUT /api/v1/tenant-config/SAFE_DOCS_URL Body: { "value": "https://internal.example/safe" }

    To clear an override and fall back to default: PUT /api/v1/tenant-config/SAFE_DOCS_URL Body: { "value": null }

SSO Provisioning (Admin-only)

  • Provision SSO for a tenant and persist secrets (preferred) with AWS Secret Manager or an encrypted override in tenant config:

    POST /tenants/provision-sso Body: { "name": "My Tenant", "provider": "okta", "client_id": "", "client_secret": "", "issuer": "https://dev-xxxx.okta.com", "domain_allowlist": ["example.com", "*.myorg.com"], "confirm_test": true }

    This will create a tenant (or prepare one if it already exists), store the SSO client ID and client secret in a secret store (when available), and optionally run an OIDC discovery and test.

Permissions & enforcement (important)

  • UI: The Dashboard UI shows and allows editing of many tenant-level settings. However, the UI enforces role-based visibility and edit privileges for sensitive keys (owner/admin only). The front end and back end both enforce these restrictions.
  • Backend: The server enforces the final policy, e.g. calling PUT /api/v1/tenant-config/SAFE_DOCS_URL requires an API key created by an ADMIN or OWNER user (or a system token). All tenant-config changes are audited by the backend.

Validation & safe defaults

  • The PUT /api/v1/tenant-config/{key} endpoint validates values for some keys (for example numeric thresholds, booleans, or JSON weights) and returns 400 on invalid data.
  • If a tenant override is cleared (value: null), the system uses the default value from _TENANT_CONFIG_DEFAULTS or environment variables.

Testing & propagation

  • Most changes are effective immediately. Some enforcement layers cache configuration (for example rate limiters) for a short time; if you change a configuration that affects cached state, the backend clears caches where needed, but allow a short window for propagation.

Debugging note for operators

  • To discover the complete list of server-recognized tenant-config keys and which values are considered sensitive, search for _TENANT_CONFIG_DEFAULTS, _SENSITIVE_CONFIG_KEYS, and _USER_CONFIG_KEYS in src/AISentinel_auditor/app.py in the backend codebase. The Dashboard inspects a subset of these keys.

Per-key reference (table)

Below is a concise table summarizing the tenant-config keys, followed by code examples for each key.

KeyTypeDefaultValidation/NotesUI EndpointAdmin required
rateLimitinteger60UI: integer >= 10 (requests per minute)PATCH /api/configNo
apiTimeoutinteger (s)30UI-enforced: 1-600sPATCH /api/configNo
ESTIMATOR_PER_TOKEN_USDdecimal0.0001Numeric, >= 0PUT /api/v1/tenant-config/ESTIMATOR_PER_TOKEN_USDNo
ESTIMATOR_TOOL_BASE_COSTSJSON{"web":0.001,"python_exec":0.01}JSON object with numeric valuesPUT /api/v1/tenant-config/ESTIMATOR_TOOL_BASE_COSTSNo
SAFE_DOCS_URLURL""If non-empty must be http(s) URLPUT /api/v1/tenant-config/SAFE_DOCS_URLYes
URL_WHITELISTCSV string""Comma-separated patterns; UI validates pattern rulesPUT /api/v1/tenant-config/URL_WHITELISTYes
LLM_SKIP_LOW_RISK_TOOLSCSV string""Allowed tools: calc, web, search, python_exec, browserPUT /api/v1/tenant-config/LLM_SKIP_LOW_RISK_TOOLSNo
LLM_FEATURE_WEIGHTSJSON""JSON mapping to numeric weights (keys: llm_confidence, llm_expected_impact, llm_policy_risk)PUT /api/v1/tenant-config/LLM_FEATURE_WEIGHTSYes
LLM_MODELstring""Model id stringPUT /api/v1/tenant-config/LLM_MODELYes
ENABLE_RESEARCH_ENDPOINTbooleanfalseBool-like (true/false etc)PUT /api/v1/tenant-config/ENABLE_RESEARCH_ENDPOINTYes
MAX_MEMORY_USAGE_MBinteger512> 0PUT /api/v1/tenant-config/MAX_MEMORY_USAGE_MBYes
MAX_DISK_USAGE_MBinteger100> 0PUT /api/v1/tenant-config/MAX_DISK_USAGE_MBYes
MAX_TOOL_EXECUTION_TIMEinteger (s)300> 0PUT /api/v1/tenant-config/MAX_TOOL_EXECUTION_TIMEYes
MASK_PII_AUTOMATICALLYbooleantrueBool-likePUT /api/v1/tenant-config/MASK_PII_AUTOMATICALLYNo
OFFLINE_MODE_ENABLEDbooleanfalseBool-likePUT /api/v1/tenant-config/OFFLINE_MODE_ENABLEDNo
DEFAULT_REPORT_EMAILSCSV string""Each entry must be a valid emailPUT /api/v1/tenant-config/DEFAULT_REPORT_EMAILSNo
EMBEDDED_TOOLS_DEFAULTCSV stringcalc,webAllowed tool set: calc, web, search, python_exec, browserPUT /api/v1/tenant-config/EMBEDDED_TOOLS_DEFAULTNo
CONTRACT_SEARCH_API_KEYstring""Sensitive; treat as secretPUT /api/v1/tenant-config/CONTRACT_SEARCH_API_KEYYes
CONTRACT_SEARCH_API_URLURLhttps://search.contract/v1/queryIdeally a valid URLPUT /api/v1/tenant-config/CONTRACT_SEARCH_API_URLYes
CIRCUIT_BREAKER_*integer3/60/2Positive integersPUT /api/v1/tenant-config/CIRCUIT_BREAKER_*No
SSO_DOMAIN_ALLOWLISTCSV string""Comma-separated domain patterns; UI & backend validate patternsPUT /api/v1/tenant-config/SSO_DOMAIN_ALLOWLISTYes
SSO_*_CLIENT_SECRETstring (secret)""Sensitive secret - provision via POST /tenants/provision-sso (preferred)POST /tenants/provision-ssoYes

Examples — code samples

Below are per-key code examples; replace placeholders with your tenant host and authorization credentials.

rateLimit (PATCH /api/config)

curl -X PATCH "https://<HOST>/api/config" \
  -H "Authorization: Bearer <FRONTEND_TOKEN_OR_COOKIE>" \
  -H "Content-Type: application/json" \
  -d '{"rateLimit": 1000}'

apiTimeout (PATCH /api/config)

curl -X PATCH "https://<HOST>/api/config" \
  -H "Authorization: Bearer <FRONTEND_TOKEN_OR_COOKIE>" \
  -H "Content-Type: application/json" \
  -d '{"apiTimeout": 45}'

ESTIMATOR_PER_TOKEN_USD

curl -X PUT "https://<HOST>/api/v1/tenant-config/ESTIMATOR_PER_TOKEN_USD" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": 0.00012}'

ESTIMATOR_TOOL_BASE_COSTS

curl -X PUT "https://<HOST>/api/v1/tenant-config/ESTIMATOR_TOOL_BASE_COSTS" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": {"web": 0.001, "python_exec": 0.01}}'

SAFE_DOCS_URL

curl -X PUT "https://<HOST>/api/v1/tenant-config/SAFE_DOCS_URL" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "https://docs.example.com/safe"}'

URL_WHITELIST

curl -X PUT "https://<HOST>/api/v1/tenant-config/URL_WHITELIST" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "docs.example.com,.gov,.edu"}'

LLM_SKIP_LOW_RISK_TOOLS

curl -X PUT "https://<HOST>/api/v1/tenant-config/LLM_SKIP_LOW_RISK_TOOLS" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "calc,search"}'

LLM_FEATURE_WEIGHTS

curl -X PUT "https://<HOST>/api/v1/tenant-config/LLM_FEATURE_WEIGHTS" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": {"llm_confidence": 1.5, "llm_expected_impact": 1.0, "llm_policy_risk": -2.0}}'

LLM_MODEL

curl -X PUT "https://<HOST>/api/v1/tenant-config/LLM_MODEL" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "gpt-4"}'

ENABLE_RESEARCH_ENDPOINT

curl -X PUT "https://<HOST>/api/v1/tenant-config/ENABLE_RESEARCH_ENDPOINT" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": true}'

MAX_MEMORY_USAGE_MB

curl -X PUT "https://<HOST>/api/v1/tenant-config/MAX_MEMORY_USAGE_MB" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": 1024}'

MAX_DISK_USAGE_MB

curl -X PUT "https://<HOST>/api/v1/tenant-config/MAX_DISK_USAGE_MB" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": 512}'

MAX_TOOL_EXECUTION_TIME

curl -X PUT "https://<HOST>/api/v1/tenant-config/MAX_TOOL_EXECUTION_TIME" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": 300}'

MASK_PII_AUTOMATICALLY

curl -X PUT "https://<HOST>/api/v1/tenant-config/MASK_PII_AUTOMATICALLY" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": false}'

OFFLINE_MODE_ENABLED

curl -X PUT "https://<HOST>/api/v1/tenant-config/OFFLINE_MODE_ENABLED" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": false}'

DEFAULT_REPORT_EMAILS

curl -X PUT "https://<HOST>/api/v1/tenant-config/DEFAULT_REPORT_EMAILS" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "ops@example.com,reports@example.com"}'

EMBEDDED_TOOLS_DEFAULT

curl -X PUT "https://<HOST>/api/v1/tenant-config/EMBEDDED_TOOLS_DEFAULT" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "calc,web"}'

CONTRACT_SEARCH_API_KEY

curl -X PUT "https://<HOST>/api/v1/tenant-config/CONTRACT_SEARCH_API_KEY" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "<api-key>"}'

CONTRACT_SEARCH_API_URL

curl -X PUT "https://<HOST>/api/v1/tenant-config/CONTRACT_SEARCH_API_URL" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "https://search.contract/v1/query"}'

CIRCUIT_BREAKER_FAILURE_THRESHOLD

curl -X PUT "https://<HOST>/api/v1/tenant-config/CIRCUIT_BREAKER_FAILURE_THRESHOLD" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": 5}'

SSO_DOMAIN_ALLOWLIST

curl -X PUT "https://<HOST>/api/v1/tenant-config/SSO_DOMAIN_ALLOWLIST" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"value": "example.com,*.myorg.com"}'

SSO Provisioning (secrets): POST /tenants/provision-sso

curl -X POST "https://<HOST>/api/tenants/provision-sso" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"name":"TenantName","provider":"okta","client_id":"cid123","client_secret":"s3cr3t","issuer":"https://dev-xxxx.okta.com","confirm_test":true}'