FeatureHub Team <info@featurehub.io>

Visit us on Github

Feature Hub

Overview

FeatureHub is a Cloud Native platform to help software teams manage their features, from feature flags (also known as feature toggles) to A/B experiments and remote or centralised configuration. It’s an essential ingredient for enabling the feedback loop and feature testing and experimentation in production with real users (see diagram below).

Visit our official web page for more information about the platform here

Building software with feature management encourages DevOps practices like trunk based development, continuous delivery and importantly, separating deployment from release management. Enabling teams to deliver value to customers early and often, whilst maintaining high quality and keeping risk low.

FeatureHub can be used with small startups through to large enterprises with many applications and teams. It has an enterprise grade security and permission model, that’s intuitive and easy to use, so you can be up and running quickly.

FeatureHub is a self-hosted platform so you can run it on your own infrastructure.

Learn

Installation

There are 3 main deployment options for running FeatureHub. As FeatureHub is packaged as a Cloud Native bundle, all parts are Docker images and are intended to be used with that technology (i.e. Docker or Kubernetes).

There is a GitHub repository where you can find all the deployment options.

All of the deployment options mount the database volume separately from the main set of containers, allowing you to upgrade your database and versions of FeatureHub without destroying your database.

FeatureHub runs on the following SQL Databases: PostgreSQL, MySQL, MS SQL Server, Oracle and we provide initialization and migration DDL for each of these databases. Others can be supported, please contact us.

Starting small

If you are just curious to see how FeatureHub works and would like to play with it before deciding which of the 3 installation options are right for you, you can also try it just by running several commands and without cloning this repository. You can watch the video with some instructions here or follow the instructions below.

Start with running this simple line:

docker run -p 8085:80 -v ~/tmp/party:/db featurehub/party-server:latest

where ~/tmp is where you wish to store the database (h2). This will start FeatureHub Admin Console on port 8085 and you can now register as Super Admin, create Portfolio, Application, Feature etc.

Once you have done this, you can then simply run the example app that comes with this docker container, so you don’t have to create sample app and add SDK code yourself. The example project consists of a back-end service (node) and a front-end sample app (React) with some sample features already in place.

Running the example

The example will need to know the SDK URL of your environment (which you can find in the FeatureHub Admin Console), and it will need an IP address that the second docker can get access to. If you know how to use docker networks, you should be able to find this easily, otherwise find your en0 ip address (you can type: ifconfig en0 - choose the inet address, Windows will be slightly different) or similar, do not use localhost as that will not work.

export SDK_URL=default/d8ba747d-7d3c-4454-9c58-130390848412/5EE3vua1NqY0ez6Zd4TXU7XnsZdAPHtR96XaDmhfegitKGiQ9aCdmtmeNUNPubkRZLJLUUpaC7b05ELk
export MY_IP=192.168.XX.XX
docker run -e FEATUREHUB_APP_ENV_URL=http://$MY_IP:8085/features/$SDK_URL -p 5000:5000  featurehub/example_node:0.0.1

This will cause the example to start and you can access it on port 5000. Add a few todo’s in mixed case. If you create a feature flag in the FeatureHub Admin Console called FEATURE_TITLE_TO_UPPERCASE, unlock it and set it to true. Now check your sample front-end app, you will see a "refresh" message appear. If you refresh, it will upper case everything. Experiment!This flag is affecting the backend service as this is where we implemented the feature using one of the SDKs.

Now in the FeatureHub Admin Console, if you create a feature value - a String value called SUBMIT_COLOR_BUTTON and set its value to (say) cyan, you will again see a refresh indicator in the sample front-end app and on refresh the "Add" button will swap to cyan colour. Each time you change the colour, it will recommend you to refresh. It is doing this because it is set in "catch and release" mode, and we recommend you read up on the SDKs for further information on this.

Client SDKs for Feature Hub

The client SDKs for FeatureHub are designed to allow various supported languages to connect to the Edge server and receive updates on the features. Each different SDK is designed to be idiomatic to that language, but also each different SDK is expected to be used for a different purpose, and so capability varies.

SDK Usage

Choose from your development language / framework and follow the links for the implementation details and examples:

Java JavaScript C# Dart Go

Documentation

Java-Jersey

Javascript, Typescript, Node, React, Angular

C#

Dart

Go

Examples

Java-Jersey example

Node server example , React app example

C# Console

Dart Server, Flutter example

Go server

General Run Capabilities for SDKs

This overview seeks to indicate the capabilities of the SDKs and explain what they are and what the do. If you are considering helping us by writing a new SDK for your favourite language, or expand on an existing library, this table of capability indicates what each different language can support and where extra work is helpful.

Runtime Capability Java Javascript1 Go Dart2 C#

Event Streaming

Y

Y

Y

Y

Y

Server Side Rollout Strategies

Y

Y

N

Y

Y

Background Start

Y

Y

Y

Y

Y

Block until Start

N

N

Y

N

N

Readyness Listeners

Y

Y

Y

Y

Y

Feature Listeners

Y

Y

Y

Y

Y

Feature Listener Removal

N

N

Y

Y

Y

Analytics Support

Y

Y

Y

Y

Y

Google Analytics

Y

Y

Y

Y

Y

Feature Overrides

N

Y

N

N

N

Web + Mobile focused capabilities for SDKs

Web + Mobile Support Java Javascript1 Go Dart2 C#

Catch & Release

N

Y

N

Y

N

Development and Test capabilities for SDKs

Dev/Test Capability Java Javascript1 Go Dart2 C#

Test Client

Y

Y

N

Y

Y

Feature Interceptors

Y

Y

N

Y

N

  • (1) Javascript and Typescript are supported via a Typescript library. This is available at the npm repository.

  • (2) Dart and Flutter are supported by Dart libraries available at pub.dev.

  • (3) Java is supported by libraries from Apache Maven Central. You will need to chose an OKHttp or Jersey client.

  • (4) C# and .NET is supported by libraries from nuget. Nuget.org

The following capabilities are focused around general runtime of your application, be it a client or server based application.

Event Streaming

This relates to the primary purpose of the FeatureHub platform, which is a platform by which a client is able to connect and then receive a constant stream of real-time updates to the features as they change. This mechanism is supported via Server Side Events.

Background Start

This relates to the ability for the application to connect to a FeatureHub Edge server in the background and complete the initial transactions and continue listening for updates - all in the background.

Block until Start

This is usually a capability provided instead of readyness listeners, whereby the library can be told to wait until the connection has been successfully established and there is a list of features, or the connection fails for some reason. It is used to ensure a client has a consistent set of features before functioning and is generally best used for server side software.

Readyness Listeners

These perform a similar function to Block until Start, but instead a server can call back or query the readyness status directly and perform the blocking function themselves. The ToDo Java and Typescript examples use this mechanism.

Feature Listeners

This allows client code to listen for changes in the state of a feature, and to trigger some action based on the new state. Generally the whole feature is passed to the listener for it to interrogate.

Feature Listener Removal

Some clients like to, or need to (usually UI related) remove listeners they have created. This allows them to do that.

Analytics Support

This is where the library has a mechanism to log an event, potentially attach metadata. The library captures the state of all of the features at the point in time of the request and will pass it on to any registered Analytics provider. A platform can have analytics support but no analytics providers. We intend over time to support only one, where the data is posted to a backend service which you can then decide where to send and how to send the data.

Google Analytics

This is a client side implementation of the Analytics support. It is designed so you need to specify the User-ID or CID, your UA- id and when logging an event, it will fire off into GA the event - one for each value of non-JSON features.

Web + Mobile Capabilities

The following capabilities are focused on clients that provide a UI to the client and thus you may wish to control the updating of the features.

Catch & Release

Some clients don’t want the feature updates to be immediately triggered in real-time. These are usually those that use Feature Listeners and they want to hold onto the changes until they have informed the user there are changes - via some UI element (e.g. reload for new functionality). Catch and release mode normally includes a flag to set it, an extra callback to indicate new features have come in, and then a release method to indicate the new features should be released (their state changed and the listeners triggered). The Typescript, Javascript and Dart libraries all have examples of this.

If you use catch and release, it is worthwhile considering enabling OpenTracing feature overrides in production. You can configure feature interceptors to not be allowed to override locked features.

Test automation support

Test Client / Feature Updater is designed to allow tests to change the values of features in their environments while they are running.

This will depend on the permissions granted to the service account in the environment that is configured.

Besides READ permission, a typical service account would need UNLOCK and CHANGE_VALUE to allow tests to modify values. Alternatively if features are always unlocked in test environments (which is often the case), CHANGE_VALUE is all that is required, and READ is implicit.

Changes are checked against the latest version of the feature in the cache. Changes that match the current state are simply ignored (and a 200 response given). Changes generally take a second or two to propagate.

For other cases, the FeatureStateUpdate class has three fields.

  • lock - if passed it will change the state of the lock. You need LOCK permission to lock, UNLOCK permission to unlock. If a feature is locked, any attempt to change it will be ignored.

  • value - this is an "object" because it represents all types of values supported. It can be null. If it is null, and you want to ensure this is set to null (which is ignored for feature flags), make sure you set updateValue.

  • updateValue - this is specifically for the situation where you are setting a non feature flag to have a null value. Otherwise passing a value will assume this is true.

Feature Interceptors

Feature Interceptors are the ability to intercept the request for a feature. They only operate in imperative state, so when code specifically requests the value of a feature, they don’t cause events to trigger. They are designed to function to enable specific kinds of use cases, such as:

  • allowing external storage of features, such as in a text file. This allows developers to override the value of features in their local running infrastructure without having to have a dedicated Environment for themselves or be connected.

  • allow per request overriding of features for example with OpenTracing or OpenTelemetry. Because of the nature of OpenTracing and OpenTelemetry, this allows you to listen to events from message queue systems like NATs, Kafka, ActiveMQ, etc.

It is unlikely you would be using these in production or staging environments as they are designed to make the development and testing of your feature based applications easier. They can however be used in production, and you can tell them that if the feature is locked, their statuses cannot be overridden. So in a test or development environment you should unlock your features and other environments you should lock them.

This prevents bad actors from poking at your apis and turning features on before they are ready.

Licensing

All SDKs are MIT licensed, as they reside in the client codebase. Downstream dependencies are not assured to be so.

Architecture

Key concepts

Portfolios

Portfolios are simply a collection of one or more applications. Typically, portfolios are named to match areas of your business where groups of applications (or application suites) live. Once created these portfolios can be managed by "Portfolio admins". There is no limit to the number of portfolios you can have.

Overview

Portfolio groups

You can create one or more groups of people, these groups can be used to set various permissions on the applications and their environments, within the portfolio. Either use the same groups across applications within the portfolio, or create separate groups for each application. Some example groups might be:

  • Developers (Typically can create features and change feature values in non-production environments)

  • Testers (Typically can change feature values in non-production environments)

  • Operations (Typically can’t create or delete features but can update values in production)

Every Portfolio automatically gets a group called "Administrators", Simply adding people to this group will make them administrators for this portfolio, and they can do anything in any application within that Portfolio.

Applications

Applications are where you create features and environments, they belong inside a portfolio.

Environments

Applications have one or more environments, these typically refer to groups of co-operating deployments of your application in different environments. There are often multiple development environments, testing environments, acceptance testing and customer demo environments depending on the application.

When an application is created there is always an initial environment called Production created. The values of your features are set, per environment.

Every FeatureHub environment has a unique ID, this ID plus a Service Account is what you reference in your application via the SDK when you query for the value of the features.

Features

Features are the main part of FeatureHub, they can be simple feature flags, strings, numbers or more advanced JSON formats intended for forms of configuration.

Feature types

You can create features of the following types:

  • BOOLEAN used for basic feature flags (toggles)

  • NUMBER numerical values

  • STRING string values

  • JSON valid JSON only (typically used for remote configuration, or otherwise overriding internal values of an application)

future support will exist for YAML and JSON-Schema to ensure valid configuration for JSON and YAML types.

Feature key

The feature key is the reference you use in your application, when you use the SDK, you can check the value of a feature, referencing the feature key. It must be unique for your application.

Feature value

When you add a feature flag, this will also automatically create a feature value in each environment. The default feature value will be set to off for boolean type and to null for string, number and json. By default, each feature value will be locked. Essentially feature value is always associated with an application and an environment for that application.

See Feature Permissions for details on the various permission states a feature can have.

Rollout strategies and targeting rules

Rollout strategies

Rollout strategies provide an ability to rollout features to a limited audience based on targeting rules, for example imagine you have a feature flag of type string which controls a "submit button color" that can be in multiple states, e.g green, blue, red etc. With rollout strategies, you can serve a green value to users on iOS devices, blue value to users whose emails ending with gmail.com and red value to users whose location is New Zealand or United States or United Kingdom. You can also use percentage based rollouts and for example, turn your feature "on" only to 50% of the audience.

Rollout strategies are created and added per Feature value. Once you add a strategy you will be able to set a feature value for this strategy, for example "on" or "off" value. A feature will always have "default value", which will be applied for any of your users that do not match rollout strategies rules. You can change the default strategy value at any time (given you have permissions).

You can apply zero or more rollout strategies to a feature. Each rollout strategy can be assigned a different feature value.

Targeting rules

A rollout strategy consists of one or more rules. That rule can consist of any combination of matching criteria, so we refer to them often as targeting rules.

Each additional rule is always applied as an AND condition - the user is using a mobile device that is iOS AND their country is Australia.

Each rule is essentially a key, a condition (equals, includes, etc) and zero or more values. Whereas each targeting rule is an AND condition, each value is an OR condition. For example, if the country is New Zealand OR Indonesia AND the custom field payment_method is equal to credit_card OR direct_debit.

Each rollout strategy can have zero or more rules associated with it. If it has zero rules and no percentage rule the strategy will be ignored. There is no limit on how many rules you can apply. There are 3 main rule types: Preset, Custom and Percentage split

Targeting rule types

Preset

  • Country

  • Device

Available values to match on: browser, mobile, desktop, server, watch, embedded

  • Platform

Available values to match on:

linux, windows, macos, android, ios

  • User Key

For example, can be used to match on email address, partial email address, user id, partial user id or regex.

  • Version

Requires to be in semantic version format, e.g. 1.2.0 - read more about semantic versioning here

Custom

If you cannot find a suitable rule from those listed above, you can create your own rule. When setting up a custom rule you will be required to select a rule type.

Supported custom rules types:

string

number - any valid number

boolean - true and false

semantic version - as per semantic version format. If you are only targeting Java you also get the additional formats supported by Maven and Gradle.

date - international format only - YYYY-MM-DD

date-time - international format only - YYYY-MM-DDTHH:MM:SS.NNN with an optional timezone, UTC is assumed

ip-address - CIDR or specific IP addresses are supported.

If you do not set the value in the client context in the SDK, and the rule indicates to match blank value then this rule will evaluate to true.

Percentage split rule

As well as setting up targeting rules you can also setup percentage split rule. Percentage rules lets you rollout a feature value to an approximate percentage of your user base.

A typical scenario for a flag for example would be a "soft launch". The "default value" of your flag would be off and you set some arbitrary percentage to on (e.g. 20%). Then you would analyse how your feature is performing for those 20%, collect any user feedback, monitor your logging for any issues and if you are happy you will start increasing the rollout to more and more people in your user base, eventually setting it to 100%, changing the default to "on" and removing the strategy. (This is set per environment).

As you can specify one or more split targeting strategies for a feature flag, in case of percentages, the sum of all of them cannot be over 100%. A typical scenario for multiple strategies would be when you operate with non-binary Feature Flag (e.g. string). If you add percentage based rollout strategies that do not add to 100%, then the remainder continues to use the default value.

You can also use percentage rules to perform A-B testing or run experiments, using the on/off of feature flags, or feature values where you can set on numbers or strings. Given FeatureHub provides a GoogleAnalytics connector - you can see the result of your experimentation in the Google Analytics Events dashboard in real time.

Percentage rules can be mixed with other rules, for example a strategy can have a country rule and a percentage rule, e.g. turn on the feature flag to 25% of the audience in New Zealand.

Percentage rule is by default implemented against a single field value provided by the client. By default this is sessionId, if that isn’t provided userKey is used. Otherwise you can provide your own field to base your percentage rollouts on.

It is important to note that the percentages are an approximation, the algorithm works by taking contextual data you provide in SDK in the client side (either a sessionId or a userKey or your own field, ideally consistent for the user across platforms) and it uses an algorithm to spread that across a range giving you control down to four decimal points, but the algorithm is more accurate the greater the number of clients you have. i.e. you can rollout to 0.0001% of your usage base if you wish. If you only have five users, this probably won’t turn it on for anyone, if you have a million it will be more accurate.

Security

Key Security concepts

Administrators

There are two types of administrators, Site Administrators and Portfolio Administrators.

Site Administrators
  • Site Administrators can:

    • Create and manage users of the system

    • Create and manage portfolios

Portfolio Administrators
  • Portfolio Administrators can:

    • Create and manage portfolio groups

    • Create applications

    • Manage access to applications

    • Create Service Accounts

Every Portfolio automatically gets a group called "Administrators", Simply adding people to this group will make them administrators for this portfolio.

Service Accounts

Service accounts are used for programmatic access to the features for an application. A service account will need a minimum of READ access to an environment in order to access a feature value.

Feature Permissions

For each application environment, there are permissions you can assign to portfolio groups or service accounts.

  • READ Can see the value of a feature

  • LOCK Can lock a feature, so it’s value can’t be changed, this gives us a safety net when deploying incomplete code into production. (Typically developers and testers keep features locked until they are finished and ready to be set)

  • UNLOCK Can unlock a feature, so it’s value can be changed

  • CHANGE_VALUE Can change the value of a feature

Groups can also separately be assigned the permission to create, edit and delete entire features.

External Identity

FeatureHub supports external identity providers.

Analytics

Please read the following for information about Analytics

Developer Setup