Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/admbe/FluxOp/llms.txt

Use this file to discover all available pages before exploring further.

Flux is designed for Azure App Service on Linux, using a system-assigned or user-assigned managed identity for secretless access to Azure Resource Graph, Azure Advisor, and Cost Management, and App Service Authentication (Easy Auth) for user authentication. No client secrets or publish profiles are stored in the repository or the application itself — Entra validates the user token before the request reaches Flux, and the managed identity obtains an Azure management token transparently.

Pre-deployment checklist

1

Create the App Service

Provision a Linux App Service running Python 3.12. The production artifact vendors manylinux_2_28_x86_64 Python wheels, so the OS must be Linux.
az webapp create \
  --resource-group <resource-group> \
  --plan <app-service-plan> \
  --name <web-app-name> \
  --runtime "PYTHON:3.12"
Set HTTPS-only on the resource:
az webapp update \
  --resource-group <resource-group> \
  --name <web-app-name> \
  --https-only true
2

Enable managed identity

Enable a system-assigned managed identity:
$identity = az webapp identity assign `
  --resource-group <resource-group> `
  --name <web-app-name> | ConvertFrom-Json

$principalId = $identity.principalId
Write-Host "Principal ID: $principalId"
Or, if you prefer a user-assigned identity, assign it to the App Service and note its client ID — you will set FLUX_MANAGED_IDENTITY_CLIENT_ID in a later step.
3

Grant RBAC to the managed identity

Flux needs two permission sets on every subscription it will query.Reader — for Azure Resource Graph (inventory, Advisor, Policy):
az role assignment create `
  --assignee-object-id $principalId `
  --assignee-principal-type ServicePrincipal `
  --role Reader `
  --scope /subscriptions/<subscription-guid>
Microsoft.CostManagement/*/read — for Cost Management queries. The deployed custom FinOps Platform Reader role includes this permission and is the recommended assignment:
az role assignment create `
  --assignee-object-id $principalId `
  --assignee-principal-type ServicePrincipal `
  --role "FinOps Platform Reader" `
  --scope /subscriptions/<subscription-guid>
Repeat both assignments for every subscription Flux will query, or assign at a shared management-group scope. RBAC propagation can take several minutes.
4

Enable App Service Authentication (Easy Auth)

In the Azure portal, open the App Service → AuthenticationAdd identity provider → choose Microsoft.Use the Flux app registration (the same registration used for app roles below). Configure:
  • Require authentication — redirect unauthenticated browser requests to Microsoft.
  • Restrict issuer — set the token issuer URL to https://login.microsoftonline.com/<tenant-id>/v2.0 to reject tokens from other tenants.
  • Ensure no network path bypasses App Service Authentication. The application trusts X-MS-CLIENT-PRINCIPAL only because App Service removes external copies and injects its validated value.
5

Create and assign Flux app roles

On the Entra app registration, define two app roles:
Display nameValueAllowed member types
Flux ReaderFlux.ReaderUsers/Groups
Flux AdministratorFlux.AdminUsers/Groups
Assign users or groups through the Enterprise application blade. Flux maps:
  • Flux.Reader → read-only dashboard, inventory, and opportunities.
  • Flux.Admin → all reader access plus integration configuration and synchronization.
Group object IDs can be used in place of, or in addition to, role values — configure them via FLUX_ENTRA_ADMIN_ASSIGNMENTS and FLUX_ENTRA_READER_ASSIGNMENTS.
6

Set required application settings

In Configuration → Application settings, set these minimum required values:
SettingValue
FLUX_AUTH_MODEentra
FLUX_ENTRA_TENANT_IDYour Entra tenant GUID
FLUX_ENTRA_ADMIN_ASSIGNMENTSFlux.Admin (or comma-separated group object IDs)
FLUX_ENTRA_READER_ASSIGNMENTSFlux.Reader (or comma-separated group object IDs)
For a user-assigned identity, also set:
SettingValue
FLUX_MANAGED_IDENTITY_CLIENT_IDThe client ID of the user-assigned managed identity
A system-assigned identity requires no client ID setting.
7

Select the provider and synchronize

Once the App Service is running:
  1. Open Integrations in the Flux UI.
  2. Add the tenant ID and one or more subscription IDs.
  3. Select App Service managed identity.
  4. Save, then select Synchronize now.
Flux obtains a token for https://management.azure.com/.default and begins paginated inventory, Advisor, and Cost Management collection.

Application settings reference

Set these in App Service → Configuration → Application settings. The pipeline applies non-secret settings additively on every deploy, preserving Key Vault references configured out-of-band.
SettingProduction valuePurpose
FLUX_AUTH_MODEentraEnable Entra Easy Auth principal decoding
FLUX_ENTRA_TENANT_ID<tenant-guid>Required tenant boundary; tokens from other tenants are rejected
FLUX_ENTRA_ADMIN_ASSIGNMENTSFlux.AdminAdmin app-role values or group object IDs (comma-separated)
FLUX_ENTRA_READER_ASSIGNMENTSFlux.ReaderReader app-role values or group object IDs (comma-separated)
FLUX_AUTH_LOGIN_PATH/.auth/login/aadEasy Auth sign-in path used by the frontend
FLUX_AUTH_LOGOUT_PATH/.auth/logoutEasy Auth sign-out path
FLUX_MANAGED_IDENTITY_CLIENT_ID<client-id>User-assigned identity client ID; omit for system-assigned
FLUX_DUCKDB_PATH/home/data/flux.duckdbPersistent storage path (see DuckDB section below)
FLUX_SYNC_WORKER_MODEexternalProduction WebJob mode; web process is a read-only consumer
FLUX_COST_MANAGEMENT_MAX_RETRIES5Retry count for throttled or unavailable cost requests
FLUX_COST_MANAGEMENT_REQUEST_DELAY_SECONDS20Conservative base interval for QPU-weighted cost-job pacing
FLUX_COST_MANAGEMENT_CLIENT_TYPEFluxFinOpsStable client classification sent with every Cost Management query
FLUX_COST_HISTORY_CHUNK_DAYS3Maximum date span committed per daily-history transaction
FLUX_COST_DETAILS_BACKFILL_ENABLEDtrueEnable asynchronous Cost Details fallback for failed Query API scopes
FLUX_COST_DETAILS_MAX_REPORTS_PER_RUN4Maximum monthly fallback reports generated per daily run
FLUX_COST_DETAILS_CURRENT_REFRESH_DAYS7Refresh cadence for current-month Cost Details checkpoints
FLUX_INTELLIGENCE_AI_ENABLEDtrueEnable the Ask Flux assistant API
FLUX_AI_PROVIDERdeepseekProvider adapter (deepseek, openrouter, or foundry)
FLUX_AI_BUDGET_USD50Evaluation budget ceiling
FLUX_AI_STOP_AT_USD50Estimated-cost stop/report threshold
FLUX_AI_MAX_TOOL_CALLS12Maximum bounded governed tool calls per request
FLUX_AI_TOOL_CACHE_SECONDS30In-process TTL for identical bounded read-tool results
FLUX_AI_TRANSCRIPT_RETENTION_DAYS30Prompt/reply review retention; set to 0 to disable
FLUX_DUCKDB_MEMORY_LIMIT1536MBDuckDB analytical memory ceiling
FLUX_DUCKDB_TEMP_DIRECTORY/home/data/.duckdb-tmpDuckDB temporary spill path (persistent storage)
FLUX_DUCKDB_MAX_TEMP_DIRECTORY_SIZE8GBMaximum spill size
FLUX_ANALYTICS_STAGING_DIRECTORY/home/data/stagingStaged analytical payloads awaiting the singleton analytics writer
FLUX_TELEMETRY_BOOTSTRAP_ROOT/home/data/telemetry-bootstrapHistorical telemetry extract root
FLUX_FINOPS_TOOLKIT_CACHE_ROOT/home/data/finops-toolkitFinOps Toolkit open-data download cache
FLUX_BACKUP_STORAGE_ACCOUNT_URLhttps://<account>.blob.core.windows.netBlob service URL for DuckDB backups; empty disables backups
FLUX_BACKUP_CONTAINERflux-backupsPrivate Blob container for database backups
FLUX_BACKUP_RETENTION_DAYS30Age after which Flux-owned backup blobs are pruned
PYTHONPATH/home/site/wwwroot:/home/site/wwwroot/.python_packages/lib/site-packagesPath to vendored production Python wheels
PYTHONUNBUFFERED1Flush Python output immediately to App Service log stream
WEBSITE_RUN_FROM_PACKAGE1Mount the ZIP artifact read-only; required for the vendored wheel layout
Secret settings — FLUX_DEEPSEEK_API_KEY, LM_BEARER_TOKEN, FLUX_OPENROUTER_API_KEY, FLUX_WIKI_API_TOKEN — must be provisioned as Azure Key Vault references out-of-band. The deployment pipeline applies non-secret settings additively with az webapp config appsettings set and will never overwrite Key Vault references.

DuckDB persistence

DuckDB is the Flux analytical database. By default it is stored at data/flux.duckdb relative to the application root, but on App Service this path is inside wwwroot, which is replaced on every ZIP deploy. In production, always set:
FLUX_DUCKDB_PATH=/home/data/flux.duckdb
The /home mount is App Service persistent storage — it survives redeployments and instance restarts. The deployment pipeline migrates any existing database to this path automatically on first deploy and enables WEBSITE_RUN_FROM_PACKAGE=1 so the ZIP is mounted read-only. Configure co-located paths for all other file-backed state:
FLUX_DUCKDB_TEMP_DIRECTORY=/home/data/.duckdb-tmp
FLUX_ANALYTICS_STAGING_DIRECTORY=/home/data/staging
FLUX_TELEMETRY_BOOTSTRAP_ROOT=/home/data/telemetry-bootstrap
FLUX_FINOPS_TOOLKIT_CACHE_ROOT=/home/data/finops-toolkit

WebJob architecture

Production Flux uses external sync worker mode (FLUX_SYNC_WORKER_MODE=external). In this configuration:
  • The web process is a read-only consumer in snapshot mode. It enqueues sync requests and serves the API, but never opens DuckDB as a writer.
  • A singleton continuous WebJob (flux-sync-worker) claims queued sync requests from sync_runs under an execution lease. Only one worker instance runs at a time; if the worker exits, the OS sync lease is released and the replacement worker recovers the unfinished request.
  • Independent scheduled WebJobs enqueue focused requests for inventory, intelligence, cost history, FOCUS ingestion, retail prices, Advisor, LogicMonitor discovery and metrics, FinOps Toolkit data, and right-sizing due-checks. All DuckDB writes are serialized through the one worker.
This prevents concurrent DuckDB writers across multiple App Service instances and ensures restarts can always recover in-progress work from persisted checkpoints.

Production gaps checklist

Before go-live, address each of these items:
Never expose Flux through a route that bypasses App Service Authentication when FLUX_AUTH_MODE=entra. The application trusts the X-MS-CLIENT-PRINCIPAL header only because App Service removes external copies and injects its validated value. A bypassed route allows unauthenticated or spoofed access.
  1. Validate Easy Auth end-to-end. Confirm app-role assignments, managed identity, and subscription RBAC are working in the target App Service before opening access to users.
  2. Eliminate bypass routes. Ensure the application cannot be reached through any network path that bypasses Easy Auth — including internal routes, SCM hostnames, and IP-restricted origins.
  3. Connect health monitoring. Wire the /api/health and /api/operations/health (admin) endpoints to an approved notification destination for operational alerting.
  4. Monitor LogicMonitor warm-up. Track the incremental LogicMonitor collector through its first 14-day rolling-history warm-up and tune FLUX_LOGICMONITOR_METRIC_BATCH_SIZE against observed API rate limits.
  5. Assign a non-human identity for smoke tests. Before enabling the authenticated branch of the production smoke script in CI, assign a dedicated Flux.Reader service principal — do not use a human account.
  6. Complete AI model procurement review. Before wider use of Flux Intelligence, complete model-service procurement and privacy review, adversarial evaluation, stakeholder acceptance criteria, distributed budget enforcement, and service-failover design.

Build docs developers (and LLMs) love