Skip to main content

This topic describes the Harness Relay Proxy V2 and how to use it with Feature Flags (FF).

note

If Relay Proxy Version 1 is what you're looking for, please go to the Relay Proxy V1 page.

Relay Proxy V2 Overview

What is the Relay Proxy?

The Relay Proxy enables your apps to connect directly to Feature Flag services without having to make a significant number of outbound connections to FF services. The Relay Proxy establishes a connection to the Feature Flags configuration data and relays that connection to clients in an organization's network.

Why use Relay Proxy V2?​

In the following cases, you might want to set up Relay Proxy:

  • Air-Gap Deployments: You can deploy the proxy in your network if you don't have or can't allow external access to your apps. Local apps connect directly to the proxy, and the proxy has external access to the remote feature flag service to synchronize configuration.
  • Offline Mode: This is identical to air-gapped, except that the proxy does not have a connection to the internet. In that scenario, the configuration must be loaded from the outside using configuration files. Configuration files are used to link your programmes to the proxy.
  • High Availability / Reliability: The feature flag service is extremely reliable. We will fail over to the failover cluster in the event of a major failure. However, in the event of a full network loss, the Relay Proxy ensures that your apps continue to run even after restarts.

If you decide to use the Relay Proxy, make sure it has a good place in your network design. For your app to run, it needs to be able to contact the Relay Proxy, and the architecture differs depending on the type of app. For example, if you want to link the Relay Proxy to any client-side apps, don't put it inside a firewall.

Relay Proxy V2 Architecture

HA Mode

Feature Flag's Relay Proxy resides between the SDKs and the hosted Harness Feature Flag services. Upon startup, proxy loads the necessary data from the Feature Flag services to ensure that it is completely functional even if the network connection drops temporarily. The diagram below shows the Relay Proxy V2 in HA Mode:

A diagram of the Relay Proxy V2 Architecture in HA Mode.

A in-depth diagram of the Relay Proxy V2 Architecture in HA Mode.

HA Mode Example using Docker

In order to run the Proxy in HA mode, you will need to follow these steps:

  1. Configure a ‘Primary’ Proxy.
  2. Configure at least one ‘Replica’ Proxy.
  3. Have a Redis instance running that both your Primary and Replica Proxy can hit.
  4. In HA mode, both the Primary and Replica Proxy use Redis to communicate.

Below is an example docker-compose file that you can use for running the Proxy in HA Mode locally:

version: "3.9"
services:
primary:
image: "harness/ff-proxy:v2-rc0.8"
environment:
- PROXY_KEY=<proxy key>
- REDIS_ADDRESS=redis:6379
- READ_REPLICA=false
- AUTH_SECRET=foobar
ports:
- "7001:7000"

replica-1:
image: "harness/ff-proxy:v2-rc0.8"
environment:
- LOG_LEVEL=INFO
- REDIS_ADDRESS=redis:6379
- READ_REPLICA=true
- AUTH_SECRET=foobar
ports:
- "7002:7000"

replica-2:
image: "harness/ff-proxy:v2-rc0.8"
environment:
- LOG_LEVEL=INFO
- REDIS_ADDRESS=redis:6379
- READ_REPLICA=true
- AUTH_SECRET=foobar
ports:
- "7002:7000"

redis:
image: "redis:latest"
ports:
- "6379:6379"

The example above uses the Docker Image Version v2-rc0.8 but there may be more up-to-date version available. To check for the lastest RC Image, you can go to Feature Flags Proxy Repo on Docker.

Single Mode

When running the Relay Proxy V2 in HA mode, the Primary Proxy starts up and retrieves the configuration from Harness SaaS. It, then, stores it in the cache and opens up a stream with Harness SaaS to listen for changes. Whenever there is an update in Harness SaaS, an event is sent to the Primary Proxy and when the Proxy receives this event, it reaches out to Harness SaaS to fetch the change. The diagram below shows trhe Relay Proxy V2 in Single Proxy Mode:

A diagram of the Relay Proxy V2 Architecture in Single Proxy Mode.

The Proxy Key V2

Creating A Proxy Key

An image of the Account Settings page within the Harness Application.

In order to create a Proxy Key, here are the steps you'll need to follow.

  1. On the Home Page of the Harness Application, head over to Account Settings.
  2. Under Account Settings, an additional menu should appear. Click on Account Resources.
  3. Once loaded, click the key icon labelled as Feature Flags Proxy.
  4. On the top left, Select New Proxy Key. Add a name and description of the key followed by Next.
  5. The next page allws you to select the organisation the key belongs to. Once selected, click Next.
  6. Next, you will associate the proxy key with the Project Environments of your choosing.
  7. Once selected, you can select the environments and if you'd like to select specific environments within each environment (i.e. prod or non-prod), select Specific Environments in the dropdown menu.
  8. Once you are satisfied with your choices, you can go ahead and select Generate Key and save.

Once the key is generated, it should automatically take you back to the Feature Flags Proxy Keys page in your Account Settings.

Rotating a Proxy Key

There are two ways that you can rotate your Proxy Key:

  1. Immediate rotation
  2. Buffered rotation

It’s worth noting that if you use immediate rotation, the old Proxy Key will become invalid and any Proxy’s using that key will be cut off from Harness Saas and unable to receive any updates until you reconfigure it to use the new key value. For this reason you’ll probably only want to use immediate key rotation if you’re concerned that your Proxy Key has been leaked.

If you just want to rotate your Proxy Key as a part of security practices then you’ll want to use the buffered rotation. With buffered rotation we allow the old key value to stay valid for a specified number of hours to give you time to reconfigure and redeploy your Proxy with the new key value. This means that there’s no down time for your Proxy where it loses connection with Harness Saas in between the time you rotate the key in the UI and redeploy your Proxy with the update key value. For example, if I set the buffer time to two hours when I rotate my key, that means my Proxy will be able to use the old key for up to two hours before it’s cut off from Harness Saas.

Key Rotation

The user will be able to easily rotate the key by making request to the Admin API.

A new key will be given and the old key will be rendered invalid. All auth tokens will also be invalidated.

Monitoring the Proxy

To monitor the Proxy, here is an example that users can run locally. It will bring up a Primary Proxy, Read Replica, Prometheus and Grafana using Docker. They can, then, log in to Grafana and view the Harness FF Proxy Dashboard.

You can find this resource to monitor the Proxy over in the Harness Feature Flags Proxy Repo on GitHub on GitHub.

Startup Sequence

Below, you will find a diagram of the Primary Proxy V2 Startup Sequence:

A diagram of the Primary Proxy V2 Startup Sequence.

Here is a diagram of the the Replica Proxy V2 Startuo Sequence:

A diagram of the Replica Proxy V2 Startup Sequence.

Cached Data

Below is a table demonstrating the Cached Data:

KeyTypeUse CaseExample Data
env-envID-feature-configsKey/ValueStores all of the FeatureConfigs in an environment. The Proxy returns this object to SDKs when they make a request to /<environmentID>/feature-configs.
 { "feature": "flagOne", ... // other properties},"feature": "flagTwo",     ... // other properties }]
env-envID-feature-configs-<identifierKey/ValueStores a single flag config
- The Proxy returns this object to SDKs when they make a request to /<environmentID>/feature-configs/<identifier>.
 { "feature": "flagOne", ... // other properties}]
env-envID-segmentsKey/ValueStores all of the TargetSegments in an environment
- The Proxy returns this object to SDKs when they make a request to /<environmentID>/target-segments.
 [{"identifier": "SegmentOne", ... // other properties},{ "identifier": "SegmentTwo", ... // other properties}]
env-envID-segments-<identifier>Key/ValueStores a single TargetSegment config
- The Proxy returns this object to SDKs when they make a request to /environmentID/target-segments/<identifier>.
{ "identifier": "SegmentOne", ... // other properties}
auth-key-<hash>Key/ValueUsed by the Proxy authentication flow to validate SDK keys
- Stores the environmentID as the value so the Proxy can return the SDKs environmentID in the JWT claims.
71716f30-aea0-4271-89b5-cb1c82be4567\
env-envID-api-configsKey/ValueBinds the auth-key-<hash> with the environment it belongs to. This is used so we can invalidate SDK keys
that have been deleted in Harness SaaS.
["auth-key-5e19dff88fb63a8afb76232f8a9b0b8c72c487314e1e497a45614be3c15ea424", "auth-key-8c60733910bb449b5395b7d445cb7562fae5f6a2ec2b83d6bdceca67a115e243", "auth-key-ddd268c12db0ee71c133774239ffa424f9abada5d47d075033eb3940f678c095"]
proxy:sse_eventsStreamUsed by the Primary Proxy to forward SSE events to the Read Replica Proxy.
{"event":"patch","domain":"flag","identifier":"f1","version":20,"environment":"71716f30-aea0-4271-89b5-cb1c82be4567","apiKey":" "
stream:sdk_metricsStreamUsed to forward Metrics from Read Replica Proxy's to Primary Proxy.
- Primary proxy listens on this stream and forwards metrics data to Harness Saas.
{"environment_id":"71716f30-aea0-4271-89b5-cb1c82be4567","metricsData":[{"attributes":[{"key":"featureIdentifier","value":"f1"},{"key":"featureName","value":"f1"},{"key":"variationIdentifier","value":"true"},{"key":"featureValue","value":"true"},{"key":"SDK_TYPE","value":"server"},{"key":"SDK_LANGUAGE","value":"go"},{"key":"SDK_VERSION","value":"1.0.0"},{"key":"target","value":"global"}],"count":2,"metricsType":"FFMETRICS","timestamp":1698669998778}],"targetData":[{"attributes":[],"identifier":"james","name":"james"}]}
ffproxy_saas_stream_healthStreamUsed to store the health status of the Harness Saas through to the Primary Proxy stream.
"{\"state\":\"CONNECTED\",\"since\":1700216614438}"

Inbound Endpoints

This hasn’t changed from Proxy v1 so these docs still apply Inbound endpoints | Harness Developer Hub .

Outbound Endpoints

Below, you will find the endpoints requested by the Primary Relay Proxy when it communicates with Harness SaaS. Remember, 'Read Replica Proxy' only communicates with the Redis cache.

| Basic Startup |

MethodsLinkPurpose
GEThttps://config.ff.harness.io/api/1.0/streamAuthenticates the Proxy Key.
GEThttps://config.ff.harness.io/api/1.0/proxy/configRetrieves the configuration associated with the Proxy Key.
POSThttps://config.ff.harness.io/api/1.0/proxy/authOpens a stream with Harness SaaS to listen for changes.

| Periodic Requests |

MethodsLinkPurpose
GEThttps://config.ff.harness.io/api/1.0/client/env/envID/feature-configsRetrieves the feature config changes that happen in Harness SaaS.
GEThttps://config.ff.harness.io/api/1.0/client/env/envID/target-segmentsRetrieves the target group changes that happen in Harness SaaS.
GEThttps://config.ff.harness.io/api/1.0/proxy/config?environment=envIDRetrieves the environment specific changes that happen in Harness SaaS e.g. a new environment was associated with the Proxy Key.
GEThttps://config.ff.harness.io/api/1.0/proxy/configRetrieves the latest config associated with the Proxy Key. This request is made periodically if the stream between the Primary Proxy and Harness SaaS goes down to make sure the Proxy doesn’t get out of sync.
POSThttps://config.ff.harness.io/api/1.0/metrics/envIDForwards metrics from the SDKs on to the Harness SaaS.

Account Stream

When the Proxy starts assuming that the configuration is correct, it will first attempt to authenticate with the SAAS using the Proxy key configured. If the authentication is successful, the Proxy will receive and store the proxyAuth token to use later to:

  • start the acc level stream,
  • request configs for proxy/environment/features/segments.

A diagram of the Account Stream Architecture.

If the Proxy key is deleted by the user, the event will be sent to the proxy with information to close the stream channel.

Stream Reconnect

If the stream were to disconnect unexpectedly, it will stop itself from connecting and will resume attempting to reconnect after a period of time.

Stream Terminations

SAAS - Proxy

The Proxy is configured to a specific key. Here is a breakdown of what happens when the Stream disconnects.:

  1. If the key was to be deleted by the project admin in the SAAS, a proxyKeyDeleted event is sent by the Account Stream to the proxy followed by a stream close message.
  2. Proxy will then close the stream to the Saas.
  3. Once this happens, the proxy will attempt to clear all the assets assigned to the key in the cache to prevent false positive reading values by the downstream SDKs.
  4. In this case, the SDK should no longer be able to read the actual value of the asset and will go with the default value used by client.

Proxy - SDKs

The termination of the connection between the Proxy and the SDK occurs when Environment or the APIKey are deleted. If that were to happen:

  1. The appropriate event type is sent to the proxy by SAAS.
  2. Similarly, the proxy will update the list of assets in the cache. This will result in either deleting the key or deleting all the assets for delete environment. This will render all existing auth tokens using deleted environment/key invalid. All SDKs subscribed to the environment, or those using deleted APIKey will be sent “end of stream” message and should subsequently close the connection. Normally they would fall back to the pooling mode but because in both cases APIKey no longer exists, SDK will not be able to authenticate using its auth token.

Cache Cleanup

When the proxy begins, it will attempt to fetch the proxy config from the SAAS and populate the cache with inventory of assets for each environment associated with the key which incudes:

  • APIKeys,
  • Features and,
  • Segments.

The Smart Cleanup feature has been implemented to cover a scenario in which assets in cache are off sync with the current state of SAAS.

This could be the case if proxy is off for period of time or it cannot establish connection with SAAS. When the connection is reestablished, or when proxy starts and the cache instance is not empty, Proxy will pull the latest config and scan the existing cache entries. It will then delete all the entries which are not in the latest config to ensure the state is matching.

Cache refresh

To minimise the api requests between Proxy and SAAS, Proxy will fetch a new config when the flag/segment is created or patched. When the asset is deleted, we will handle the cache update without any additional request to the SAAS.

A diagram of the Proxy Key Rotation Structure.

E2E Journey

Below, you will find a diagram of the the End-to-End Journey of the Proxy Rotation.

A diagram of the End to End Journey.

FAQs About Relay Proxy V2

Relay Proxy Version 2 vs Relay Proxy Version 1: What's the difference?

Relay Proxy V2 was developed to fix some of the limitations that came with Relay Proxy V1. The key differences were:

  • that we were unable to configure new environments without restarting the Proxy.
  • Proxy V1 required a restart any time you added new SDK keys to an environment in Harness SaaS and wanted the Proxy to pick them up.
  • Proxy V1 required a config update and restart if you wanted to configure it to use new environments.
  • Proxy V1 embedded the Harness Golang SDK and spun up an instance of this for each environmnet. This meant that there was a stream per environment open between the Relay Proxy and Harness SaaS.
  • No real HA ability.

How does Proxy V2 address these issues?

  • Stream Per Environment -- Instead of embedding the Golang SDK in Proxy V2 and relying on the existing SDK streaming functionality Proxy V2 relies on a new type of Account level stream that’s associated with a Proxy Key. This means that there will only ever be one stream open between your Primary Proxy and Harness SaaS and events for all environments associated with the Proxy key will be sent down this one stream.

  • Unable to configure new environments without restarts -- With the new Account level stream, whenever a new environment is created or assigned to a Proxy Key we now send events down this stream to let the Proxy know that a new environment has been assigned to it. The Proxy will then reach out to Harness SaaS to retrieve this new config and store it in the cache without having to restart.

  • Unable to configure new SDK keys without restarts -- Like with new environments, when a new SDK key is created in an environment that the Proxy is configured to use we send the Proxy an event to let it know an SDK key has been added. The Proxy will then store the hashed SDK key in its cache so that any new SDKs spun up with this SDK key can authenticate with the Proxy.

  • No real HA ability -- With Proxy V2 we’ve made it possible to. configure Proxy’s to run specifically as read replicas or a Primary that communicates with Harness SaaS. This was something that isn’t available with Proxy V1 and if you want to run multiple Proxy’s in V1 they all run as Primary’s.

Why use the Relay Proxy?

In the following cases, you might want to set up Relay Proxy:

  • Air-gap Deployments: You can deploy the proxy in your network if you don't have or can't allow external access to your apps. Local apps connect directly to the proxy, and the proxy has external access to the remote feature flag service to synchronize configuration.
  • Offline Mode: This is identical to air-gapped, except that the proxy does not have a connection to the internet. In that scenario, the configuration must be loaded from the outside using configuration files. Configuration files are used to link your programmes to the proxy.
  • High Availability / Reliability: The feature flag service is extremely reliable. We will fail over to the failover cluster in the event of a major failure. However, in the event of a full network loss, the Relay Proxy ensures that your apps continue to run even after restarts.

If you decide to use the Relay Proxy, make sure it has a good place in your network design. For your app to run, it needs to be able to contact the Relay Proxy, and the architecture differs depending on the type of app. For example, if you want to link the Relay Proxy to any client-side apps, don't put it inside a firewall.

Are there any constraints to the Relay Proxy V2?

At this current time and due to the way Harness implements the authentication tokens, users have a limit of 1000 environments per key.