Skip to main content
Version: v0.25.0 (Latest)

Cloud Configuration Providers

Cloud configuration providers fetch settings from a remote source, enabling you to manage configuration centrally rather than baking it into each application instance. When a value changes, a feature flag, a rate limit, an API endpoint, you update it in one place and all running instances pick up the change on their next refresh cycle.

The EDK ships two cloud providers: Azure App Configuration for Azure-native deployments, and a REST Config Client for connecting to VDX configuration servers or any compatible REST API.

Both providers share the same behavior: they auto-register when their module is on the classpath, refresh periodically (default 30 seconds), persist to the offline cache for disconnected resilience, and support multi-tenant key scoping.

Azure App Configuration

Azure App Configuration is a managed service for centralizing application settings. It's particularly useful when you have multiple services and environments that need to share configuration without duplicating it in each deployment.

The EDK integration adds features on top of the Azure SDK: automatic label-based environment separation, multi-tenant key conventions, sentinel-based change detection, and fallback to the offline cache when Azure is unreachable.

How It Works

Keys in Azure App Configuration are flat strings with optional labels. The EDK uses labels for environment/profile separation (development, staging, production) and key prefixes for tenant scoping:

Key in AzureLabelResolves to
api.base.urlproductionAPP-scoped api.base.url
tenant.acme.api.rate-limitproductionTENANT-scoped api.rate-limit for tenant acme
myapp/feature.new-ui-feature.new-ui (with prefix trimming)

When the provider refreshes, it fetches all keys matching the configured filter and label, strips the key prefix (if configured), and maps them to configuration properties. Tenant-prefixed keys are automatically scoped to the correct tenant in the resolution pipeline.

Configuration

# Connection — use one of these:
azure.appconfig.connection-string=Endpoint=https://myapp.azconfig.io;Id=...;Secret=...
azure.appconfig.endpoint=https://myapp.azconfig.io # with Azure AD auth

# Key filtering
azure.appconfig.key-filter=myapp/* # Only fetch keys matching this pattern
azure.appconfig.key-prefix=myapp/ # Strip this prefix from fetched keys
azure.appconfig.trim-key-prefix=true

# Environment separation
azure.appconfig.label-filter=production # Only fetch keys with this label

# Change detection
azure.appconfig.sentinel-key=app:version # Key to watch for changes
azure.appconfig.refresh-interval=30s

# Tenant scoping
azure.appconfig.tenant-id=my-tenant

Authentication

The simplest approach, a single string contains the endpoint, ID, and secret. Suitable for development and environments where managed identity isn't available.

export AZURE_APPCONFIG_CONNECTION_STRING="Endpoint=https://myapp.azconfig.io;Id=xxxxx;Secret=xxxxx"

Change Detection

Azure App Configuration supports two change detection strategies:

Polling: the provider periodically re-fetches all keys at the configured refresh-interval. Simple and reliable, but fetches everything every cycle even if nothing changed.

Sentinel key: configure a sentinel key (e.g., app:version) that you update whenever configuration changes. The provider polls only the sentinel key; if its value changed since the last check, it triggers a full refresh. This reduces API calls significantly in large configurations.

In practice, the sentinel approach works well: your CI/CD pipeline updates the sentinel key after pushing new configuration, and all instances refresh within the next poll interval.

Offline Fallback

If Azure App Configuration becomes unreachable, the provider falls back to the offline cache transparently. The last successful fetch is always persisted to disk, so your application can start and serve requests even during an Azure outage, with stale but functional configuration.

REST Config Client

The REST Config Client fetches configuration from any REST API that implements the VDX settings endpoint format. This is the provider to use when you run your own configuration server, use the VDX platform's configuration management, or need a cloud-agnostic alternative to Azure.

How It Works

The client calls GET /api/v1/config/settings?scope=APP&profile=default&limit=1000 and receives a paginated list of settings. Each setting includes the key, value, type, and optional protection metadata:

{
"items": [
{
"key": "api.base.url",
"value": "https://api.example.com",
"valueType": "STRING",
"isFinal": false,
"isInterpolationProtected": false
}
]
}

The isFinal and isInterpolationProtected fields are carried through the resolution pipeline, enforcing property protection rules from the central configuration server.

Configuration

rest.config.base-url=https://config.example.com
rest.config.tenant-id=my-tenant
rest.config.profile=production

# Authentication
rest.config.auth.method=API_KEY # or BEARER_TOKEN, OAUTH2_CLIENT_CREDENTIALS
rest.config.auth.api-key=my-api-key
rest.config.auth.api-key-header=X-API-Key

# Timeouts
rest.config.connect-timeout-ms=5000
rest.config.read-timeout-ms=30000
rest.config.refresh-interval-ms=30000

# Offline fallback
rest.config.offline-cache-enabled=true

Authentication Options

MethodUse case
API_KEYSimple API key in a custom header. Suitable for internal services.
BEARER_TOKENJWT bearer token. Suitable when tokens are available from another auth flow.
OAUTH2_CLIENT_CREDENTIALSClient credentials grant against a token endpoint. Suitable for service-to-service auth.
NONENo authentication. Only for development or when auth is handled by the network layer (mTLS, VPN).

Multi-Platform Support

The REST Config Client is implemented as Kotlin Multiplatform, it runs on JVM, JS (browser and Node.js), and native targets. This means mobile and web applications can fetch centralized configuration from the same server as backend services, using the same provider interface and key conventions.

Health Checks

Both providers expose health check capabilities:

val health = provider.healthCheck().getOrThrow()
// CloudProviderHealth(
// isHealthy = true,
// latencyMs = 45,
// configKeyCount = 127,
// lastSuccessfulRefresh = 2026-03-23T10:30:00Z,
// errorMessage = null
// )

In Spring Boot deployments, health checks can be wired to actuator endpoints to include configuration provider status in readiness probes.

Best Practices

Use labels for environments, not separate App Configuration instances. Azure App Configuration supports label-based filtering. Store all environments in one instance, use labels (development, staging, production) to separate them, and configure azure.appconfig.label-filter per deployment.

Configure a sentinel key for change detection. Polling every 30 seconds with hundreds of keys creates unnecessary load. A sentinel key means the provider only fetches one key per cycle; a full refresh happens only when something actually changed.

Enable offline caching in production. The cost is minimal (a small JSON file on disk) and the benefit is significant, your application survives cloud provider outages gracefully rather than failing to start.

Use property protection for security-critical settings. Mark auth.require-mfa=true as FINAL at APP scope so tenants can't disable it. Mark db.connection-string as INTERPOLATION_PROTECTED so lower scopes can't reference it via ${...} syntax.