9. Glossary and Cheatsheet
The 10-second lookup.
Glossary
Alphabetised, one line each.
| Term | Definition |
|---|---|
.appconfig.featureflag/ |
Reserved key prefix marking a key-value as a feature flag. The Feature manager blade is a view over key-values with this prefix |
| Access key | A long-lived HMAC credential (primary/secondary, read-write/read-only) usable as a connection string. Listing it is a control-plane action, which is why it's a data-plane escalation path. Disable with disableLocalAuth |
App Configuration Contributor |
Control-plane role: manage the resource, including ListKeys. Grants no data access once local auth is disabled |
App Configuration Data Owner |
Data-plane role: read and write key-values, flags, snapshots. For the configuration pipeline and platform engineers |
App Configuration Data Reader |
Data-plane role: read key-values, flags, snapshots, revisions. The correct role for every application |
az appconfig kv import/export |
Batch load or dump key-values against a file, another store, or App Service settings. --strict makes import declarative (deletes keys not in the source) |
azconfig.io |
The data-plane DNS suffix. Your endpoint is https://<store-name>.azconfig.io — which is why store names are globally unique |
azapi provider |
Terraform provider that speaks raw ARM, used for features azurerm doesn't cover yet — snapshots and new tier properties, typically |
| Client filter | A condition on a feature flag — percentage, targeting, time window, or custom — evaluated in-process by the feature-management library, never by the store |
| Configuration store | The ARM resource, Microsoft.AppConfiguration/configurationStores. Regional, globally-unique name, owns tier, network, identity, encryption, and replicas |
| Content type | MIME string on a key-value. Advisory except for two magic values: the Key Vault reference type and the feature-flag type |
| Control plane | ARM (management.azure.com) — creates and configures the store. Separate RBAC from the data plane |
| Data plane | https://<store>.azconfig.io — reads and writes the contents. Separate RBAC from the control plane |
disableLocalAuth |
Store property that turns off access keys, making the data plane Entra-only. The single most important security setting on this service. local_auth_enabled = false in Terraform |
| Etag | Concurrency token on a key-value. Enables conditional writes (optimistic concurrency) and cheap 304 Not Modified refresh polling |
| Feature flag | A key-value under the reserved prefix with the flag content type, whose value is JSON describing id, enabled, and client filters |
| Feature management library | Microsoft.FeatureManagement and its siblings — evaluates flags and filters locally, in your process |
| Geo-replication | Adding regional replicas to a store. Each has its own endpoint, replicates asynchronously, and bills as a separate store |
| Key | The setting's name. Case-sensitive; : separators are a .NET binding convention, not real hierarchy |
| Key-value | The atomic item, identified by the pair (key, label) — not by key alone |
| Key Vault reference | A key-value whose value is a JSON pointer (uri) to a Key Vault secret, resolved by the client with the client's own identity. Content type application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8 |
| Label | Optional second half of a key-value's identity — the environment/version dimension, selected by filter at read time. null is a distinct value, not a default |
| Label filter | The read-time selector for labels. Supports exact match, comma-separated lists, and a trailing wildcard; '\0' is how the CLI expresses the null label |
| Point-in-time restore | az appconfig kv restore --datetime — rewinds every key-value under a label to a past moment, within the tier's revision retention window |
| Private endpoint | Private IP for the data plane. Sub-resource configurationStores; private DNS zone privatelink.azconfig.io. There is no service endpoint for this service |
| Provider (configuration provider) | The client library that loads, caches, refreshes, and binds key-values into your app's native configuration system |
| Purge protection | Prevents purging a soft-deleted store before retention expires — so the globally unique name is held for the full window. Generally irreversible once enabled |
| Refresh interval | How often the client re-checks watched items. Formerly SetCacheExpiration, now SetRefreshInterval. Tens of seconds is the sane range |
| Replica | A regional copy of the store with its own endpoint. Asynchronous replication, eventual cross-replica consistency, client-library failover |
| Revision | Immutable historical entry created on every key-value write. The audit trail and the basis of point-in-time restore |
| Sentinel key | One conventional key that clients watch with refreshAll, so a batch of edits is picked up atomically and you pay for one poll instead of twenty. Bump it last |
| Snapshot | Immutable, named composition of key-values built from key/label filters at creation. The versioned configuration artifact; does not refresh, by design |
| Soft delete | Deleting the store makes it recoverable for a retention period — and it still holds its globally unique name, blocking recreation |
| Variant | A multi-valued feature flag with allocation percentages, for A/B assignment and experimentation |
| Workload identity federation (OIDC) | How CI authenticates to Azure without a secret. Federated credential on an Entra app registration, scoped to a repo and environment |
Renamed or retired? Neither — App Configuration has kept its name since GA in 2019. The confusable neighbours are App Service application settings, Azure Automation variables, and Kubernetes ConfigMaps. Note also that Microsoft Entra ID is the current name for what older docs call Azure Active Directory, which is what issues the tokens this service authorises against.
Cheatsheet
# ---- variables ------------------------------------------------------------
RG=rg-example-config-prod
STORE=appcs-example-prod
LABEL=prod
# All kv/feature commands take --auth-mode login to use your Entra identity
# instead of silently fetching an access key. Get in the habit; it's the only
# mode that works once local auth is disabled.
# ---- the store (control plane) --------------------------------------------
az appconfig create -n $STORE -g $RG -l uksouth --sku standard
az appconfig show -n $STORE -g $RG -o jsonc
az appconfig update -n $STORE -g $RG --disable-local-auth true # do this
az appconfig update -n $STORE -g $RG --enable-public-network false
az appconfig list-deleted -o table # soft-deleted stores
az appconfig recover -n $STORE --yes # bring one back
az appconfig purge -n $STORE --yes # free the name
# ---- key-values (data plane) ----------------------------------------------
az appconfig kv set -n $STORE --auth-mode login --yes \
--key "Api:Timeout" --label $LABEL --value "60"
az appconfig kv show -n $STORE --auth-mode login --key "Api:Timeout" --label $LABEL
az appconfig kv list -n $STORE --auth-mode login --label $LABEL --fields key value -o table
az appconfig kv list -n $STORE --auth-mode login --label '\0' -o table # the NULL label
az appconfig kv delete -n $STORE --auth-mode login --key "Api:Timeout" --label $LABEL --yes
# ---- a Key Vault reference (the store never holds the secret) --------------
az appconfig kv set-keyvault -n $STORE --auth-mode login --yes \
--key "Database:Password" --label $LABEL \
--secret-identifier "https://kv-example.vault.azure.net/secrets/db-password"
# omit the version — pinning it means rotation never reaches the app
# ---- bulk: the declarative path -------------------------------------------
az appconfig kv import -n $STORE --auth-mode login --yes \
--source file --format yaml --path config/prod.yaml --label $LABEL --strict
az appconfig kv export -n $STORE --auth-mode login --yes \
--label $LABEL --destination file --format yaml --path backup.yaml
# ---- the sentinel: bump it LAST, or nothing propagates --------------------
az appconfig kv set -n $STORE --auth-mode login --yes \
--key Sentinel --label $LABEL --value "$(date -u +%FT%TZ)"
# ---- feature flags --------------------------------------------------------
az appconfig feature set -n $STORE --auth-mode login --yes --feature Beta --label $LABEL
az appconfig feature enable -n $STORE --auth-mode login --yes --feature Beta --label $LABEL
az appconfig feature disable -n $STORE --auth-mode login --yes --feature Beta --label $LABEL # the kill switch
az appconfig feature list -n $STORE --auth-mode login --label $LABEL -o table
# ---- history and rollback -------------------------------------------------
az appconfig revision list -n $STORE --auth-mode login --key "Api:Timeout" --label $LABEL -o table
az appconfig kv restore -n $STORE --auth-mode login --label $LABEL \
--datetime "2026-07-30T09:00:00Z" --yes
# then bump the sentinel, or clients keep serving the old value
# ---- snapshots: the immutable release artifact -----------------------------
az appconfig snapshot create -n $STORE --snapshot-name "release-$(git rev-parse --short HEAD)" \
--filters "[{\"key\":\"*\",\"label\":\"$LABEL\"}]" --auth-mode login
az appconfig snapshot list -n $STORE --auth-mode login -o table
# ---- data-plane RBAC: the step everyone forgets ---------------------------
az role assignment create \
--assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type ServicePrincipal \
--role "App Configuration Data Reader" \
--scope "$(az appconfig show -n $STORE -g $RG --query id -o tsv)"
# ---- teardown -------------------------------------------------------------
az group delete -n $RG --yes --no-wait
az appconfig list-deleted -o table # confirm you got the name back
⚠️ CLI flags and subcommands change between versions — az appconfig kv import --dry-run in
particular is version-dependent. Verify against az appconfig --help on the version your runner has
pinned.
Client-side knobs worth memorising
options.Connect(new Uri(endpoint), new DefaultAzureCredential())
.Select("*", LabelFilter.Null) // shared defaults first...
.Select("*", environment) // ...environment overrides win
.ConfigureKeyVaultReference(kv => kv.SetCredential(cred)) // omit this and you
// get the raw JSON pointer
.ConfigureRefresh(r => r
.Register("Sentinel", refreshAll: true) // ONE key, not twenty
.SetRefreshInterval(TimeSpan.FromSeconds(30)))
.UseFeatureFlags();
// Web apps: app.UseAzureAppConfiguration() — the middleware triggers refresh.
// Workers: call TryRefreshAsync() yourself on a timer, or you hold startup values forever.
Resource ID shape
Every error message, role-assignment scope, and policy assignment is written against these:
# The store
/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.AppConfiguration/configurationStores/{name}
# A replica
/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.AppConfiguration/configurationStores/{name}/replicas/{replica}
# A key-value as an ARM child resource (the Bicep path); '$' separates key from label
/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.AppConfiguration/configurationStores/{name}/keyValues/{key}${label}
# The data-plane endpoint — NOT an ARM ID, and governed by different RBAC
https://{name}.azconfig.io
Limits worth memorising
Each with the scope it's counted at, because a number without a scope is useless in Azure.
| Limit | Scope | Value |
|---|---|---|
| Total storage | Per store | Tens of MB on lower tiers → ~1 GB at the top ⚠️ verify |
| Single key-value size (key + value + label + metadata) | Per key-value | Single-digit KB — hard limit, no exceptions ⚠️ verify |
| Requests per day (Free) | Per store | A hard cap; throttled for the rest of the UTC day ⚠️ verify |
| Included requests (paid) | Per store, and per replica | Overage charged, not blocked ⚠️ verify |
| Throttling threshold | Per store (and per replica) | Returns 429 with retry-after-ms ⚠️ verify |
| Free-tier stores | Per subscription, per region | A small number — the quota people hit first ⚠️ verify |
| Replicas | Per store | ⚠️ verify |
| Revision retention | Per store, tier-dependent | Bounds how far back restore can reach ⚠️ verify |
| Snapshots and retention | Per store; contents count against storage | ⚠️ verify |
| Key and label length | Per key-value | ⚠️ verify |
Hard vs. soft. The per-key-value size cap and key naming rules are hard — no ticket changes them, and a design needing a 200 KB value needs Blob Storage for the document and App Configuration for the URL. Store counts and some request allowances are soft and raiseable via the portal's quota experience or a support request. Tier limits aren't raiseable at all; the remedy is the next tier up.
The five things to remember if you remember nothing else
disableLocalAuth: true. Until you set it, any resource-group Contributor can list the access keys and is effectively a data owner on every store in the group.- A key-value's identity is
(key, label), and no label is a distinct value, not a default. - One sentinel key with
refreshAll, on a 30-second interval. Fixes torn reads and cuts request volume by orders of magnitude. - Key Vault references are resolved by the client, so the consumer needs
Key Vault Secrets User— and leave the secret URI unversioned or rotation never reaches the app. - A broken store doesn't break running apps — it breaks every process that starts. The pain arrives at your next deployment, not now.
← Back to the Azure App Configuration overview · ← Previous: Interview Questions