App Configuration
Compatible with azure-appconfiguration SDKs (Java, Python, JavaScript, .NET).
Features
- Key-values — set, get, delete, list with key/label filters
- Labels — independent values per (key, label) pair; list distinct labels
- Feature flags — first-class support via
.appconfig.featureflag/prefix andapplication/vnd.microsoft.appconfig.ff+jsoncontent-type - Revisions — full revision history on every write; queryable via
GET /revisions - Locks — lock/unlock individual key-values to prevent modification
- Snapshots — point-in-time frozen copies of filtered key-value sets; archive/recover lifecycle
- ETags — conditional reads (
If-None-Match) and conditional writes/deletes (If-Match) - Composition types —
key(deduplicate by key) andkey_label(keep all key+label pairs)
Endpoint
Default account: devstoreaccount1
Default endpoint: http://localhost:4577/devstoreaccount1-appconfig
Connection String
The App Configuration SDK expects an HTTPS endpoint. Use the forced-HTTP pattern below for local development:
import com.azure.data.appconfiguration.ConfigurationClientBuilder;
import com.azure.core.http.policy.HttpPipelinePolicy;
import com.azure.core.http.HttpPipelineCallContext;
import com.azure.core.http.HttpPipelineNextPolicy;
import com.azure.core.http.HttpResponse;
import com.azure.core.util.Context;
import reactor.core.publisher.Mono;
import java.net.URL;
// Rewrite https → http for local emulator
static class ForceHttpPolicy implements HttpPipelinePolicy {
@Override
public Mono<HttpResponse> process(HttpPipelineCallContext ctx, HttpPipelineNextPolicy next) {
try {
URL url = new URL(ctx.getHttpRequest().getUrl().toString());
ctx.getHttpRequest().setUrl(new URL("http", url.getHost(), url.getPort(), url.getFile()).toString());
} catch (Exception ignored) {}
return next.process();
}
}
String account = "devstoreaccount1";
String endpoint = "https://localhost:4577/" + account + "-appconfig";
String connStr = "Endpoint=" + endpoint + ";Id=" + account + ";Secret=placeholder";
ConfigurationClient client = new ConfigurationClientBuilder()
.connectionString(connStr)
.addPolicy(new ForceHttpPolicy())
.buildClient();
from azure.appconfiguration import AzureAppConfigurationClient
from azure.core.pipeline.transport import RequestsTransport
class ForceHttpTransport(RequestsTransport):
def send(self, request, **kwargs):
request.url = request.url.replace("https://", "http://", 1)
return super().send(request, **kwargs)
account = "devstoreaccount1"
endpoint = f"https://localhost:4577/{account}-appconfig"
conn_str = f"Endpoint={endpoint};Id={account};Secret=placeholder"
client = AzureAppConfigurationClient.from_connection_string(
conn_str, transport=ForceHttpTransport()
)
Key-Values
Set a key-value
Get a key-value
Delete a key-value
List key-values
Labels
Labels let you maintain environment-specific variants of the same key:
client.setConfigurationSetting(
new ConfigurationSetting().setKey("timeout").setValue("30").setLabel("prod"));
client.setConfigurationSetting(
new ConfigurationSetting().setKey("timeout").setValue("5").setLabel("dev"));
// Fetch by label
String prodVal = client.getConfigurationSetting("timeout", "prod").getValue(); // "30"
String devVal = client.getConfigurationSetting("timeout", "dev").getValue(); // "5"
client.set_configuration_setting(ConfigurationSetting(key="timeout", value="30", label="prod"))
client.set_configuration_setting(ConfigurationSetting(key="timeout", value="5", label="dev"))
prod = client.get_configuration_setting("timeout", label_filter="prod").value # "30"
dev = client.get_configuration_setting("timeout", label_filter="dev").value # "5"
Feature Flags
Snapshots
Snapshots capture a frozen, point-in-time copy of filtered key-values. They are immutable after creation — changes to live key-values do not affect an existing snapshot.
Create a snapshot
Read from a snapshot
Archive and recover
Composition types
| Type | Behaviour |
|---|---|
key (default) |
One entry per key; last matching filter wins when keys overlap |
key_label |
One entry per (key, label) pair; no deduplication |
REST API Reference
All endpoints sit under /{accountName}-appconfig/ with an api-version query parameter (e.g. ?api-version=2023-11-01).
Key-Values
| Method | Path | Description |
|---|---|---|
GET / HEAD |
/kv |
List key-values (supports key, label filters) |
GET / HEAD |
/kv/{key} |
Get a key-value |
PUT |
/kv/{key} |
Set a key-value |
DELETE |
/kv/{key} |
Delete a key-value |
Keys & Labels
| Method | Path | Description |
|---|---|---|
GET / HEAD |
/keys |
List distinct key names |
GET / HEAD |
/labels |
List distinct labels |
Revisions
| Method | Path | Description |
|---|---|---|
GET / HEAD |
/revisions |
List revision history (supports key, label filters) |
Locks
| Method | Path | Description |
|---|---|---|
PUT |
/locks/{key} |
Lock a key-value (prevents modification) |
DELETE |
/locks/{key} |
Unlock a key-value |
Snapshots
| Method | Path | Description |
|---|---|---|
GET / HEAD |
/snapshots |
List snapshots (supports name filter) |
GET / HEAD |
/snapshots/{name} |
Get a snapshot |
PUT |
/snapshots/{name} |
Create a snapshot |
PATCH |
/snapshots/{name} |
Archive or recover a snapshot |
GET |
/kv?snapshot={name} |
List frozen key-values from a snapshot |
Operations (LRO polling)
| Method | Path | Description |
|---|---|---|
GET |
/operations?snapshot={name} |
Poll snapshot creation status (always returns Succeeded) |
Conditional Operations (ETags)
Every key-value response includes an ETag header. Use If-Match for optimistic concurrency:
# Conditional update — only succeeds if ETag matches
curl -X PUT "http://localhost:4577/devstoreaccount1-appconfig/kv/my-key" \
-H "If-Match: \"<etag>\"" \
-H "Content-Type: application/json" \
-d '{"value": "new-value"}'
A mismatch returns 412 Precondition Failed. A locked key returns 423 Locked.
Storage Configuration
floci-az:
storage:
services:
app-config:
# mode: persistent # override global storage mode
flush-interval-ms: 5000
services:
app-config:
enabled: true
| Environment Variable | Default | Description |
|---|---|---|
FLOCI_AZ_SERVICES_APP_CONFIG_ENABLED |
true |
Enable/disable the service |
FLOCI_AZ_STORAGE_SERVICES_APP_CONFIG_MODE |
(global) | Per-service storage mode |