Skip to main content

Configuration

info

AquaGen API fetches all secrets from Azure Key Vault at startup. Key Vault credentials are hardcoded in app/enum/env.py — no environment variable setup is required to run the app.

How It Works

FLASK_ENV → selects vault URL → SecretManager authenticates → Config class pulls all secrets
Startup secret loading
  1. FLASK_ENV (dev or prod) selects which Key Vault to connect to
  2. SecretManager in app/services/secret_vault_service.py authenticates using the ClientSecretCredential from app/enum/env.py
  3. Config class in app/config.py calls smi.get(SecretName.XYZ) for each secret at startup

Key Vaults

EnvironmentVault URL
Production (prod)https://aquagen.vault.azure.net/
Development (dev)https://aquagendev.vault.azure.net/

Environment Variables

Only a small number of env vars are read directly from the environment (not Key Vault):

VariableDescriptionDefault
FLASK_ENVSelects dev or prod Key VaultRequired
APPLICATIONINSIGHTS_CONNECTION_STRINGApp Insights connection (fallback if Key Vault secret not set)Optional
TEST_OTP_ENABLEDEnable test OTP bypass (true/false)true in dev
TEST_OTPOTP value used when test mode is on123456
ALLOWED_FRAME_ANCESTORSCSP frame-ancestors header valuePreset list of known frontend origins

To run locally:

export FLASK_ENV=dev
export FLASK_DEBUG=1
flask run --host localhost --port 5001

Azure Key Vault Secrets

All other configuration is pulled from Key Vault. Secret names follow a hyphen-separated convention:

Database

Secret NameDescription
COSMOSDBENDPOINTAzure Cosmos DB endpoint URL
COSMOSDBKEYCosmos DB primary access key

Authentication

Secret NameDescription
SECRET-KEYFlask JWT secret key
AZURE-AD-APP-IDAzure AD application (client) ID
AZURE-AD-ISSUERAzure AD token issuer URL
AZURE-AD-JWKS-URIAzure AD JSON Web Key Set URI
GOOGLE-CLIENT-IDGoogle OAuth client ID
GOOGLE-CLIENT-SECRETGoogle OAuth client secret
ADMIN-ACCOUNT-TIDAdmin Azure AD tenant ID
ADMIN-LOGIN-TYPEAdmin login method
INTERNAL-INDUSTRY-IDInternal/system industry ID

Notifications

Secret NameDescription
FIREBASE-CREDENTIALSFirebase service account JSON
FIREBASE-STORAGE-BUCKETFirebase storage bucket name
SMS-API-ENDPOINTSMS gateway API URL
SMS-USER-IDSMS gateway user ID
SMS-PASSWORDSMS gateway password
MSG-TYPESMS message type
SMS-VERSIONSMS API version
SMS-FORMATSMS response format

Azure Services

Secret NameDescription
APPLICATION-INSIGHTSApp Insights connection string
IOTHUB-CONNECTION-STRINGAzure IoT Hub connection string
WEBPUB-ENDPOINTAzure Web PubSub endpoint
HUB-NAMEWeb PubSub hub name
WEBSOCKET-ENDPOINTWebSocket endpoint URL
WEBSOCKET-HUB-NAMEWebSocket hub name
EVENTHUB-CONNECTION-STRINGAzure Event Hub connection string
EVENTHUB-NAMEEvent Hub name

Analytics & AI

Secret NameDescription
AQUA-GPT-API-KEYAquaGPT API key
AQUA-GPT-ASSISTANT-IDAquaGPT assistant ID
AQUA-GPT-MODELAquaGPT model name
EARTH-ENGINE-SERVICE-ACCOUNTGoogle Earth Engine service account JSON

SecretManager Usage Pattern

from app.services.secret_vault_service import smi
from app.enum.secret_key_type import SecretName
from app.enum.secret_key_format_type import SecretKeyFormatType

# String secret
SECRET_KEY = smi.get(SecretName.SECRET_KEY)

# JSON dict secret
FIREBASE_CREDENTIALS = smi.get(SecretName.FIREBASE_CREDENTIALS, SecretKeyFormatType.dict)

# Integer secret
SOME_INT = smi.get(SecretName.SOME_INT, SecretKeyFormatType.int)

SecretKeyFormatType options: dict (JSON parse), int, float, default is string.

JWT Configuration

Set in app/__init__.py:

app.config["JWT_TOKEN_LOCATION"] = ["headers", "query_string"]
app.config["JWT_SECRET_KEY"] = Config.SECRET_KEY
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=4)
app.config["JWT_REFRESH_TOKEN_EXPIRES"] = timedelta(days=14)
note
  • Access tokens expire after 4 hours
  • Refresh tokens expire after 14 days
  • Token accepted from Authorization header or jwt query string parameter

CORS

CORS is open to all origins:

CORS(app, resources={r'/*': {"origins": '*'}})
tip

The ALLOWED_FRAME_ANCESTORS env var controls the CSP frame-ancestors directive, which restricts which origins can embed the app in an iframe. Defaults to the known set of AquaGen frontend domains.