Skip to main content
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.
Set HTTPS-only on the resource:
2

Enable managed identity

Enable a system-assigned managed identity:
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):
Microsoft.CostManagement/*/read — for Cost Management queries. The deployed custom FinOps Platform Reader role includes this permission and is the recommended assignment:
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: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:For a user-assigned identity, also set: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.
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:
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:

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.