A cloud computing platform and infrastructure for building, deploying and managing applications and services through a worldwide network of Microsoft-managed datacenters.
Use managed identity or workload identity wherever the database supports token-based authentication; otherwise, keep each environment’s connection string in a separate Azure Key Vault and let the application retrieve it through managed identity.
Recommended pattern
- Separate Development, Staging, and Production
- Use different database accounts and credentials for every environment.
- Do not reuse production credentials in preproduction.
- For stronger isolation, use separate Key Vaults by application and environment; this limits the impact if one workload is compromised.^1^
- Prefer identity over connection-string credentials
- If the database supports Microsoft Entra authentication, assign the Azure-hosted application a managed identity and grant only the required database permissions.
- This removes the password from the connection string entirely. Microsoft recommends managed identities for Azure workloads wherever supported.^2^
- Use Key Vault when a password or access key is unavoidable
- This commonly applies to databases or client libraries that expect a username and password.
- Store the credential or complete connection string in Key Vault.
- Enable managed identity on the application and grant that identity least-privilege access to the appropriate vault.
- Keep only a nonsecret value—such as the vault URI or secret name—in application settings. Microsoft specifically recommends this pattern for resources that do not support Entra or token-based authentication.^3^
- Use environment variables selectively
- Environment variables are acceptable for local development and runtime secret injection, but they are not equivalent to a managed secret store.
- They are commonly held as plaintext and are visible if the host or process is compromised.^4^
- For development, use environment variables or the framework’s local secret facility, such as ASP.NET Core Secret Manager.
- For production, prefer Key Vault or passwordless identity because these provide centralized access control, auditing, and rotation.
For example, a Python application can use the developer’s Azure CLI identity locally and its managed identity after deployment, without environment-specific authentication code:^5^
import os
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
credential = DefaultAzureCredential()
client = SecretClient(
vault_url=os.environ["KEY_VAULT_URI"],
credential=credential,
)
connection_string = client.get_secret("database-connection").value
Grant this identity access only to the vault and secrets required by that particular environment. Enable audit logging, review access regularly, and automate rotation where possible.^6^
What belongs in configuration files?
Configuration files may safely contain nonsecret settings such as:
- Database hostname or service endpoint, if it does not contain credentials
- Database name
- Key Vault URI
- Secret name
- Feature flags and timeouts
Do not put passwords, access keys, or credential-bearing connection strings in appsettings.json, .env files committed to source control, deployment templates, container images, or pipeline YAML. Microsoft’s EF Core guidance explicitly warns that secrets should never be added to configuration files.^7^
Ensure secret values are also excluded from:
- Application and pipeline logs
- Error messages and telemetry
- Source-control history
- Build artifacts and container layers
- Developer documentation and copied troubleshooting output
If a connection string is exposed
A credential-bearing connection string can allow unauthorized database access with all permissions assigned to that account. Depending on those permissions, the result can include data disclosure, modification or deletion, resource abuse, and movement into connected systems.
Treat any exposed secret as compromised, even if the file was removed quickly or the repository is private:
- Revoke or rotate the credential immediately.
- Update Key Vault with the replacement value and restart or refresh consumers as required.
- Remove the secret from the current file and repository history; deleting only the latest version is insufficient.
- Review database, Key Vault, application, and pipeline logs for suspicious access.
- Reduce the database account’s permissions to the minimum the application needs.
- Run secret scanning across source code, build artifacts, logs, and pipelines. Microsoft recommends treating every secret discovered by scanning as compromised and replacing it.^6^
- Add preventive scanning to pre-commit checks and CI/CD so future commits containing credentials are blocked.
Key Vault is not universally mandatory merely because an application is in production, but a dedicated secret-management service—or eliminating the secret with managed identity—is the recommended production architecture. Plain environment variables are a fallback delivery mechanism, not the preferred system of record for production secrets.
References
- Safe Secrets Standard
- Architecture strategies for protecting application secrets
- Connecting from your application to resources without handling credentials
- Store application secrets safely during development
- Quickstart: Azure Key Vault secret client library for Python
- Best practices for protecting secrets
- Connection Strings