ConfigCat Proxy
The ConfigCat Proxy allows you to host a feature flag evaluation service in your own infrastructure. It's a small Go application that communicates with ConfigCat's CDN network and caches/proxies config JSON files for your frontend and backend applications. The config JSON contains all the data that is needed for ConfigCat SDKs to evaluate feature flags.
The Proxy provides the following:
- Performance: The Proxy can be deployed close to your applications and can serve the downloaded config JSON files from memory. ConfigCat SDKs then can operate on the proxied config JSON. This can reduce the duration of feature flag evaluation for stateless or short lived applications.
- Reliability: The Proxy can store the downloaded config JSON files in an external cache. It can fall back to operating on the cached config JSON if the ConfigCat CDN network becomes inaccessible.
- Security: The Proxy can act as a server side flag evaluation component. Using it like that can prevent the exposure of config JSON files to frontend and mobile applications.
- Scalability: Horizontal scaling allows you to align with the load coming from your applications accordingly.
- Streaming: The Proxy provides real-time feature flag change notifications via Server-Sent Events (SSE) and gRPC.
Architecture
The following diagram shows the high level architecture of the Proxy.
How It Works
The Proxy wraps one or more SDK instances for handling feature flag evaluation requests. It also serves the related config JSON files that can be consumed by other ConfigCat SDKs running in your applications.
Within the Proxy, the underlying SDK instances can run in the following modes:
- Online: In this mode, the underlying SDK has an active connection to the ConfigCat CDN network through the internet.
- Offline: In this mode, the underlying SDK doesn't have an active connection to ConfigCat. Instead, it uses the configured cache or a file as a source of its config JSON.
With the combination of the above modes, you can construct a cluster of proxies where only one node is responsible for the communication with ConfigCat, and all the other nodes are working from a central cache.
Communication
There are three ways how the Proxy is informed about the availability of new feature flag evaluation data:
- Polling: The ConfigCat SDKs within the Proxy are regularly polling the ConfigCat CDN for new config JSON versions.
- Webhook: The Proxy has webhook endpoints (for each underlying SDK) which can be set on the ConfigCat Dashboard to be invoked when someone saves & publishes new feature flag changes.
- Cache polling / file watching: In offline mode, the Proxy can regularly poll a cache or watch a file for new config JSON versions.
These are the ports used by the Proxy by default:
- 8050: for standard HTTP communication. (API, CDN proxy, Webhook, SSE)
- 8051: for providing diagnostic data (status, prometheus metrics).
- 50051: for gRPC communication.
Installation
You can install the ConfigCat Proxy from the following sources:
Docker
The docker image is available on DockerHub. You can run the image either as a standalone docker container or via docker-compose
.
- Standalone
- docker-compose
Pull the docker image:
docker pull configcat/proxy
Run the ConfigCat Proxy:
docker run -d --name configcat-proxy \
-p 8050:8050 -p 8051:8051 -p 50051:50051 \
-e CONFIGCAT_SDKS='{"<sdk-identifier>":"<your-sdk-key>"}' \
configcat/proxy
services:
configcat_proxy:
image: configcat/proxy
environment:
- CONFIGCAT_SDKS={"<sdk-identifier>":"<your-sdk-key>"}
ports:
- "8050:8050"
- "8051:8051"
- "50051:50051"
To start docker services, execute the following command:
docker-compose up -f docker-compose.yml -d
Standalone executable
You can download the executables directly from GitHub Releases for your desired platform.
You can then check the status endpoint of the Proxy to ensure it's working correctly: http://localhost:8051/status
Configuration Options
You can specify options for the Proxy either via a YAML file or with environment variables. When an option is defined in both places, the environment variable's value takes precedence.
The Proxy is able to read the options YAML from the following default locations:
- Windows:
%PROGRAMDATA%\configcat\proxy\options.yml
, usuallyC:\ProgramData\configcat\proxy\options.yml
- macOS:
/Library/Application Support/configcat/proxy/options.yml
- Linux:
/etc/configcat/proxy/options.yml
When the default location is not suitable, you can specify a custom location for your options YAML file via the -c
argument.
- YAML
- Environment variables
Docker
When running the Proxy in docker, you can mount the options YAML file as a volume.
docker run -d --name configcat-proxy \
-p 8050:8050 -p 8051:8051 -p 50051:50051 \
-v <path-to-file>/options.yml:/etc/configcat/proxy/options.yml
(Optional) With the -c
argument to specify a custom path for your options YAML file:
docker run -d --name configcat-proxy \
-p 8050:8050 -p 8051:8051 -p 50051:50051 \
-v <path-to-file>/options.yml:/cnf/options.yml \
configcat/proxy -c /cnf/options.yml
Standalone executable
Run the Proxy as a standalone executable with the options YAML file in its default location:
- macOS / Linux
- Windows
./configcat-proxy
.\configcat-proxy.exe
(Optional) With the -c
argument to specify a custom path for your options YAML file:
- macOS / Linux
- Windows
./configcat-proxy -c /path-to-file/options.yml
.\configcat-proxy.exe -c \path-to-file\options.yml
Docker
When running the Proxy in docker, you can pass environment variables for the executing container.
docker run -d --name configcat-proxy \
-p 8050:8050 -p 8051:8051 -p 50051:50051 \
-e CONFIGCAT_SDKS='{"<sdk-identifier>":"<your-sdk-key>"}' \
configcat/proxy
Standalone executable
Make sure the related environment variables are available for the Proxy's hosting process.
- shell
- PowerShell
export CONFIGCAT_SDKS='{"<sdk-identifier>":"<your-sdk-key>"}'
Then start the Proxy:
./configcat-proxy
$Env:CONFIGCAT_SDKS='{"<sdk-identifier>":"<your-sdk-key>"}'
Then start the Proxy:
.\configcat-proxy.exe
The following sections will go through each available option in detail.
Logging
The Proxy supports the following log levels: debug
, info
, warn
, and error
. The default is warn
.
You can specify the log level either globally or for each individual component. If you don't set a component's log level explicitly, it will inherit the global level's value.
- YAML
- Environment variables
log:
level: "<error|warn|info|debug>"
CONFIGCAT_LOG_LEVEL="<error|warn|info|debug>"
When the main HTTP server's or gRPC server's log level is set to debug
, each HTTP request or RPC the Proxy receives is logged with additional details. (duration, response status, etc.)
Default User Attributes
There's an option to predefine User Object attributes with default values. Whenever the Proxy receives an evaluation request it will automatically attach these predefined attributes to the request. If the evaluation request contains a different value for an attribute you previously defined, the request's value will take precedence.
- YAML
- Environment variables
default_user_attributes:
attribute_key1: "<attribute_value1>"
attribute_key2: "<attribute_value2>"
CONFIGCAT_DEFAULT_USER_ATTRIBUTES='{"attribute_key1":"<attribute_value1>","attribute_key2":"<attribute_value2>"}'
It's also possible to set default user attributes at the SDK level. See the SDK options section below for more details.
SDK
In order to make the Proxy work properly, it must be set up with one or more SDK keys. It will instantiate one SDK instance for each SDK key. In case of environment variables, the SDK keys can be specified in a JSON key-value format, where the key is the identifier of a specific SDK and the value is the actual SDK key. The SDK identifier part is later used in endpoint route variables to recognize which SDK must serve the given flag evaluation request.
Furthermore, when configuring the Proxy via environment variables, the identifier becomes a part of the SDK specific environment variable's name using the following format: CONFIGCAT_<SDK_ID>_<OPTION>
.
For example, suppose we have the following SDK key-value option: CONFIGCAT_SDKS={"my-sdk":"<your-sdk-key>"}
.
In this case, the environment variable that sets the SDK's poll interval will be named as follows: CONFIGCAT_MY_SDK_POLL_INTERVAL
.
The SDK identifier part of the environment variables is always transformed to uppercase and each hyphen (-
) character is replaced with underscore (_
).
In case of a YAML file, the SDK identifier is the property name set under the sdks
node.
sdks:
my_sdk:
...
- YAML
- Environment variables
This is the whole YAML section of the SDK specific options.
sdks:
my_sdk:
key: "<your-sdk-key>"
base_url: "<base-url>"
poll_interval: 30
data_governance: <"eu"|"global">
webhook_signing_key: "<key>"
webhook_signature_valid_for: 300
default_user_attributes:
attribute_key: "<attribute_value>"
log:
level: "<error|warn|info|debug>"
offline:
log:
level: "<error|warn|info|debug>"
enabled: <true|false>
use_cache: <true|false>
cache_poll_interval: 5
local:
file_path: "./path/local.json"
polling: <true|false>
poll_interval: 5
another_sdk:
...
These are the SDK specific environment variables.
CONFIGCAT_SDKS='{"my-sdk":"<your-sdk-key>","another-sdk":"<another-sdk-key>"}'
CONFIGCAT_MY_SDK_BASE_URL="<base-url>"
CONFIGCAT_MY_SDK_POLL_INTERVAL=30
CONFIGCAT_MY_SDK_DATA_GOVERNANCE="<eu|global>"
CONFIGCAT_MY_SDK_LOG_LEVEL="<error|warn|info|debug>"
CONFIGCAT_MY_SDK_OFFLINE_ENABLED=<true|false>
CONFIGCAT_MY_SDK_OFFLINE_LOG_LEVEL="<error|warn|info|debug>"
CONFIGCAT_MY_SDK_OFFLINE_LOCAL_FILE_PATH="./path/local.json"
CONFIGCAT_MY_SDK_OFFLINE_LOCAL_POLLING=<true|false>
CONFIGCAT_MY_SDK_OFFLINE_LOCAL_POLL_INTERVAL=5
CONFIGCAT_MY_SDK_OFFLINE_USE_CACHE=<true|false>
CONFIGCAT_MY_SDK_OFFLINE_CACHE_POLL_INTERVAL=5
CONFIGCAT_MY_SDK_WEBHOOK_SIGNING_KEY="<key>"
CONFIGCAT_MY_SDK_WEBHOOK_SIGNATURE_VALID_FOR=300
CONFIGCAT_MY_SDK_DEFAULT_USER_ATTRIBUTES='{"attribute_key":"<attribute_value>"}'
CONFIGCAT_ANOTHER_SDK_POLL_INTERVAL=15
...
Here's the explanation for each option:
SDK Identifier / SDK Key
Option | Description |
---|---|
| The SDK identifier and the SDK key. The SDK identifier is used in endpoint route variables to recognize which SDK must serve the given flag evaluation request. The SDK key is crucial for the underlying SDK to operate. |
Additional SDK Options
Option | Default | Description |
---|---|---|
| ConfigCat's CDN url. | The CDN base url (forward proxy, dedicated subscription) from where the SDK will download the config.json . |
| 30 | The underlying SDK's polling interval in seconds. |
| global | Describes the location of your feature flag and setting data within the ConfigCat CDN. This parameter needs to be in sync with your Data Governance preferences. More about Data Governance. |
| - | The key used to sign the webhook requests sent to the Proxy. More about the webhook endpoint. |
| 300 | The time period within the webhook requests are considered valid. More about the webhook endpoint. |
| - | Additional SDK specific default user attributes. The Proxy will use these attributes when an evaluation request doesn't contain a value for the predefined attribute. When there's a default value defined for the same attribute at both SDK and global level, the one at the SDK level will take precedence. |
| warn | The verbosity of the SDK related logs. Possible values: error , warn , info , or debug . |
Offline Mode
The following options are specific to the SDK's offline mode. In offline mode, there are two ways the Proxy can get the required feature flag evaluation data for the underlying SDKs.
- Polling a cache: The Proxy can poll a cache for feature flag changes. It can use the same cache that an online Proxy instance writes. More about the cache option.
- Watching / polling a file: The Proxy can watch or poll for modifications in a file that contains the evaluation data of feature flags. For watching, the Proxy uses the fsnotify library.
Option | Default | Description |
---|---|---|
| false | Turns the SDK's offline mode on/off. In offline mode the SDK will not communicate with the ConfigCat CDN network. Instead, it uses the configured cache or a file as the source of its config.json . |
| false | Indicates whether the SDK should use the configured cache as the source of its config.json . More about the cache option. |
| 5 | The cache polling interval in seconds. Used only, when the use_cache option is true . More about the cache option. |
| warn | The verbosity of the offline mode related logs. Possible values: error , warn , info or debug . |
| - | Path to the local file that contains the appropriate config.json . |
| false | Indicates whether the Proxy should switch to local file polling instead of file system watching. |
| 5 | The polling interval of the local file in seconds. |
Global Offline Mode
It is possible to turn on offline mode globally for a whole Proxy instance. When it's turned on, each underlying SDK switches to work from the configured cache.
Option | Default | Description |
---|---|---|
| false | Turns the global offline mode on/off. |
| 5 | The cache polling interval in seconds. More about the cache option. |
| warn | The verbosity of the offline mode related logs. Possible values: error , warn , info or debug . |
When an SDK also has its offline option set, that will override what it would inherit from the global offline option.
Cache
The Proxy in its default setup stores all the information it needs for feature flag evaluation in memory. This behavior is extendable with an external cache that you can use for pointing the underlying SDKs to your own data storage.
Currently, Redis, MongoDB, and DynamoDB is supported as external cache. The cache key for the underlying SDKs is based on the SDK Key. This means that multiple Proxy instances using the same SDK key will read/write the same cache entry.
The ConfigCat Proxy supports shared caching, which means it can feed an external cache that is shared by other ConfigCat SDKs. You can read more about this feature and the required minimum SDK versions here.
Redis
- YAML
- Environment variables
This is the whole YAML section of the Redis specific options.
cache:
redis:
enabled: <true|false>
db: 0
user: "<user>"
password: "<pass>"
addresses: ["<addr1>", "<addr2>"]
tls:
enabled: <true|false>
min_version: <1.0|1.1|1.2|1.3>
server_name: "<server-name>"
certificates:
- cert: "<path-to-cert>"
key: "<path-to-key>"
These are the Redis specific environment variables.
CONFIGCAT_CACHE_REDIS_ENABLED=<true|false>
CONFIGCAT_CACHE_REDIS_DB=0
CONFIGCAT_CACHE_REDIS_USER="<user>"
CONFIGCAT_CACHE_REDIS_PASSWORD="<pass>"
CONFIGCAT_CACHE_REDIS_ADDRESSES='["<addr1>", "<addr2>"]'
CONFIGCAT_CACHE_REDIS_TLS_ENABLED=<true|false>
CONFIGCAT_CACHE_REDIS_TLS_MIN_VERSION=<1.0|1.1|1.2|1.3>
CONFIGCAT_CACHE_REDIS_TLS_SERVER_NAME="<server-name>"
CONFIGCAT_CACHE_REDIS_TLS_CERTIFICATES='[{"key":"<path-to-key>","cert":"<path-to-cert>"}]'
Here's the explanation for each option:
Option | Default | Description |
---|---|---|
| false | Turns caching into Redis on/off. |
| ["localhost:6379"] | The addresses of the Redis instances. The Proxy uses Universal Redis clients, so if the array contains multiple addresses, it will use a ClusterClient instance. |
| 0 | The selected Redis database. |
| - | The username for connecting to Redis. |
| - | The password for connecting to Redis. |
The following options are for securing the connection to Redis with TLS.
Option | Default | Description |
---|---|---|
| false | Turns the TLS connection to Redis on/off. |
| 1.2 | The minimum TLS version to use. |
| - | The name of the Redis server. |
| - | A list of TLS certificate/key pairs. |
MongoDB
When the configured MongoDB database and collection doesn't exist, the Proxy automatically creates them. The following document structure is used to store the downloaded config JSON in BSON format:
{
"key": "<The unique cache key determined by the ConfigCat SDK within the Proxy>",
"payload": "<The downloaded config JSON in a standardized format determined by the ConfigCat SDK within the Proxy>"
}
At the collection creation, the Proxy also creates a unique index for the key
field.
- YAML
- Environment variables
This is the whole YAML section of the MongoDB specific options.
cache:
mongodb:
enabled: <true|false>
url: "<connection-url>"
database: "<database-name>"
collection: "<collection-name>"
tls:
enabled: <true|false>
min_version: <1.0|1.1|1.2|1.3>
server_name: "<server-name>"
certificates:
- cert: "<path-to-cert>"
key: "<path-to-key>"
These are the MongoDB specific environment variables.
CONFIGCAT_CACHE_MONGODB_ENABLED=<true|false>
CONFIGCAT_CACHE_MONGODB_URL="<connection-url>"
CONFIGCAT_CACHE_MONGODB_DATABASE="<database-name>"
CONFIGCAT_CACHE_MONGODB_COLLECTION="<collection-name>"
CONFIGCAT_CACHE_MONGODB_TLS_ENABLED=<true|false>
CONFIGCAT_CACHE_MONGODB_TLS_MIN_VERSION=<1.0|1.1|1.2|1.3>
CONFIGCAT_CACHE_MONGODB_TLS_SERVER_NAME="<server-name>"
CONFIGCAT_CACHE_MONGODB_TLS_CERTIFICATES='[{"key":"<path-to-key>","cert":"<path-to-cert>"}]'
Here's the explanation for each option:
Option | Default | Description |
---|---|---|
| false | Turns caching into MongoDB on/off. |
| - | The connection url to MongoDB. |
| configcat_proxy | The name of the MongoDB database that the Proxy will use for storing data. |
| cache | The name of the collection inside the MongoDB database. |
The following options are for securing the connection to MongoDB with TLS.
Option | Default | Description |
---|---|---|
| false | Turns the TLS connection to MongoDB on/off. |
| 1.2 | The minimum TLS version to use. |
| - | The name of the MongoDB server. |
| - | A list of TLS certificate/key pairs. |
DynamoDB
By default, the Proxy uses the standard AWS CLI environment variables (or a local AWS configuration file) to read the AWS credentials and region for connecting to DynamoDB.
The Proxy doesn't create the DynamoDB table automatically, it must already exist with a partition key called key
. The data stored in the table has the following attributes:
key
: The unique cache key determined by the ConfigCat SDK within the Proxy.payload
: The downloaded config JSON in a standardized format determined by the ConfigCat SDK within the Proxy.
The following permissions are needed to read and write the table:
GetItem
PutItem
- YAML
- Environment variables
This is the whole YAML section of the DynamoDB specific options.
cache:
dynamodb:
enabled: <true|false>
url: "<url>"
table: "<table-name>"
These are the DynamoDB specific environment variables.
CONFIGCAT_CACHE_DYNAMODB_ENABLED=<true|false>
CONFIGCAT_CACHE_DYNAMODB_URL="<url>"
CONFIGCAT_CACHE_DYNAMODB_TABLE="<table-name>"
Here's the explanation for each option:
Option | Default | Description |
---|---|---|
| false | Turns caching into DynamoDB on/off. |
| - | The DynamoDB service endpoint. |
| configcat_proxy_cache | The name of the DynamoDB table that the Proxy will use for storing data. |
HTTP
The following HTTP and HTTP Proxy related options are available:
- YAML
- Environment variables
http:
enabled: <true|false>
port: 8050
log:
level: "<error|warn|info|debug>"
status:
enabled: <true|false>
http_proxy:
url: "<proxy-url>"
CONFIGCAT_HTTP_ENABLED=<true|false>
CONFIGCAT_HTTP_PORT=8050
CONFIGCAT_HTTP_LOG_LEVEL="<error|warn|info|debug>"
CONFIGCAT_HTTP_STATUS_ENABLED=<true|false>
CONFIGCAT_HTTP_PROXY_URL="<proxy-url>"
Here's the explanation for each option:
Option | Default | Description |
---|---|---|
| true | Turns the main HTTP server on/off. This server hosts the CDN proxy, API, SSE, and webhook endpoints. |
| 8050 | The main HTTP server's port. |
| warn | The verbosity of the HTTP related logs. Possible values: error , warn , info , or debug .When debug is set, the Proxy will log each HTTP request with additional details. |
| false | Turns the hosting of the status endpoint on the main HTTP port (default: 8050 ) on/off. |
HTTP Proxy
Option | Default | Description |
---|---|---|
| - | The network proxy's URL that the ConfigCat Proxy must use for communication through the internet. |
Endpoints
The options for HTTP endpoints are discussed in the Endpoints section.
TLS
For securing direct communication to the ConfigCat Proxy, you have the option to set up TLS. Another option would be to use a full-featured reverse proxy that secures the communication and forwards each request to the Proxy.
The following options are for the first scenario where you secure the direct HTTP and gRPC communication.
- YAML
- Environment variables
tls:
enabled: <true|false>
min_version: <1.0|1.1|1.2|1.3>
certificates:
- cert: "<path-to-cert>"
key: "<path-to-key>"
CONFIGCAT_TLS_ENABLED=<true|false>
CONFIGCAT_TLS_MIN_VERSION=<1.0|1.1|1.2|1.3>
CONFIGCAT_TLS_CERTIFICATES='[{"key":"<path-to-key>","cert":"<path-to-cert>"}]'
Here's the explanation for each option:
Option | Default | Description |
---|---|---|
| false | Turns the enforcement of TLS connection to the ConfigCat Proxy on/off. |
| 1.2 | The minimum TLS version to accept. |
| - | A list of TLS certificate/key pairs. |