Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dictionary-octopus.txt
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ oldthumbprint
oneshot
onlylogs
onmicrosoft
openfeature
openon
operationalize
outfile
Expand Down Expand Up @@ -481,6 +482,7 @@ robocopy
roboto
rocksville
rolename
rollouts
ROOTDIR
rootelement
Rootfs
Expand Down
167 changes: 167 additions & 0 deletions src/pages/docs/feature-flags/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
layout: src/layouts/Default.astro
pubDate: 2026-11-05
modDate: 2026-11-05
title: Getting started with feature flags
sidebarLabel: Getting started
navTitle: Getting started
navSection: Feature Flags
navOrder: 10
icon: fa-solid fa-play
description: Create an Octopus feature flag, connect your application with OpenFeature, evaluate the flag in code, and turn it on for an environment.
subject: feature flags, OpenFeature, client identifier, getting started, feature flag slug
type: guide
audience: [app-dev, devops-eng, new-user]
image:
imageAlt:
---

This page takes you from no feature flags to a flag your application checks at runtime. You'll create a flag in Octopus, connect your application to the Octopus feature flag service, evaluate the flag in code, and turn it on for an environment.

## Create a feature flag

A feature flag lives in an Octopus project. Create one for each feature you want to control independently.

**Before you begin**

You'll need:

- An Octopus project that deploys the application you want to add the flag to.
- [VERIFY: the permission required to create feature flags, for example FeatureToggleEdit — needs: confirmation of the permission name shown in the Octopus UI]

To create a feature flag:

1. From your project, select **Feature Flags**.
2. Select **Add Feature Flag**.
3. Enter a **Name** for the flag.
4. [VERIFY: the label of the button that creates the flag — needs: confirmation from the Add Feature Flag dialog]

The flag appears in the project's feature flag list. Octopus generates a slug from the name, which is how your application refers to the flag.

## Add the Octopus provider to your application

Your application evaluates flags through the OpenFeature SDK, using the Octopus provider to fetch flag values from the Octopus feature flag service. Do this once per application.

To add the Octopus provider:

1. Install the [OpenFeature SDK](https://openfeature.dev/docs/reference/sdks/) for your language.
2. Install the [Octopus provider](/docs/feature-flags/providers) for your language.
3. In your application's startup code, create the Octopus provider with your client identifier and set it as the OpenFeature provider.

For example, in an ASP.NET application:

```cs
// Read the client identifier from configuration
var builder = WebApplication.CreateBuilder(args);
var octopusFeatureFlagsClientId = builder.Configuration["FeatureFlags:ClientId"] ?? "";

// Create the Octopus provider
var octopusProvider = new OctopusFeatureProvider(new OctopusFeatureConfiguration(octopusFeatureFlagsClientId));

// Set Octopus as the OpenFeature provider
await OpenFeature.Api.Instance.SetProviderAsync(octopusProvider);
```

Each provider's README covers setup for that language.

:::div{.warning}
Projects that use feature flag rules need a minimum provider version. See [OpenFeature providers](/docs/feature-flags/providers) for the versions.
:::

Next, give your application its client identifier during deployment.

## Supply the client identifier during deployment

The client identifier is a [JWT](https://jwt.io/introduction) that names the project, environment, and tenant (if applicable) your application belongs to. Octopus provides it in the `Octopus.FeatureFlags.ClientIdentifier` variable, so you can inject the right value for each environment and tenant as you deploy.

**Before you begin**

You'll need:

- A deployment step that can substitute Octopus variables into your application's configuration, such as [structured configuration variables](/docs/projects/steps/configuration-features/structured-configuration-variables-feature) or [substitute variables in templates](/docs/projects/steps/configuration-features/substitute-variables-in-templates).

To supply the client identifier during deployment:

1. In your application's configuration file, add a setting for the client identifier with the value `#{Octopus.FeatureFlags.ClientIdentifier}`.
2. In your deployment process, turn on variable substitution for that configuration file.
3. Deploy a release to the environment.

For example, an `appsettings.json` file could contain:

```json
{
"FeatureFlags": {
"ClientId": "#{Octopus.FeatureFlags.ClientIdentifier}"
}
}
```

The deployed configuration file contains a client identifier for the environment, and tenant if applicable, that you deployed to.

:::div{.hint}
Earlier versions of these docs used the variable `Octopus.FeatureToggles.ClientIdentifier`. It still works as a deprecated alias of `Octopus.FeatureFlags.ClientIdentifier`.
:::

## Get a client identifier for an application Octopus doesn't deploy

If Octopus doesn't deploy your application, or you can't inject the client identifier during deployment, you can generate one in the Octopus Web Portal and add it to your configuration yourself.

To get a client identifier:

1. From your project, select **Feature Flags**.
2. Open the overflow menu and select **Preview Client Identifiers**.
3. Select the **Environment**, and the **Tenant** if your project uses tenants.
4. Copy the client identifier into your application's configuration.

![Client identifier preview menu item](/docs/img/feature-flags/client-identifier-preview-menu-item.png)

:::div{.warning}
A generated client identifier doesn't carry the version of a deployed release, so flags that use a [Version is at least](/docs/feature-flags/rules#rule-conditions) condition won't match for applications that use it.
:::

## Evaluate a feature flag

Your application asks OpenFeature for a flag's value by its slug wherever it needs to decide whether to show the feature.

To evaluate a feature flag:

1. From your project, select **Feature Flags**, then select the flag.
2. Copy the flag's **Slug**.
3. In your application, call the OpenFeature client with the slug and a default value.

For example, to evaluate the flag with the slug `dark-mode` in C#:

```cs
var featureClient = OpenFeature.Api.Instance.GetClient();
var darkModeEnabled = await featureClient.GetBooleanValueAsync("dark-mode", false);
```

The second argument is the default value your code uses if it can't reach the Octopus feature flag service. To learn how it differs from the default value you set in Octopus, see [Default values](/docs/feature-flags/how-evaluation-works#default-values).

## Turn on a feature flag for an environment

A new flag returns its default value everywhere until you add an environment to it. Adding an environment gives the flag a switch for that environment, which turns the flag on for everyone there.

**Before you begin**

You'll need:

- An environment in one of your project's lifecycles.

To turn on a feature flag for an environment:

1. From your project, select **Feature Flags**, then select the flag.
2. In the **Environments** section, select **Add Environment**.
3. Select the environment.
4. Save the flag.

The environment appears in the flag's environment list with its switch on, and applications in that environment get `true` for the flag.

To turn the flag on for only some users in the environment, add rules. See [Targeting users with feature flag rules](/docs/feature-flags/rules).

## Related links

- [Feature flags](/docs/feature-flags)
- [How feature flag evaluation works](/docs/feature-flags/how-evaluation-works)
- [Targeting users with feature flag rules](/docs/feature-flags/rules)
- [OpenFeature providers](/docs/feature-flags/providers)
95 changes: 95 additions & 0 deletions src/pages/docs/feature-flags/how-evaluation-works.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
layout: src/layouts/Default.astro
pubDate: 2026-11-05
modDate: 2026-11-05
title: How feature flag evaluation works
sidebarLabel: How evaluation works
navTitle: How evaluation works
navSection: Feature Flags
navOrder: 20
icon: fa-solid fa-diagram-project
description: Learn how Octopus decides whether a feature flag is on, from environment switches and default values to rules, phases, and percentage rollouts.
subject: feature flags, evaluation, default values, percentage rollout, rules, phases
type: concept
audience: [app-dev, devops-eng]
image:
imageAlt:
---

When your application asks for a feature flag, Octopus works through the flag's configuration for that application's environment and returns `true` or `false`. This page explains each part of that decision, so you can predict what any user will get before you change a flag.

## The evaluation sequence

Every evaluation follows the same sequence, and it stops at the first step that decides the result. Knowing the order tells you which part of a flag's configuration to look at when a user gets a result you didn't expect.

For the environment named in the application's client identifier:

1. If the environment hasn't been added to the flag, the result is the flag's default value.
2. If the environment's switch is off, the result is `false`. [VERIFY: that a switched-off environment returns false rather than the flag's default value — needs: confirmation from the feature flags team]
3. If the environment has no rules, the result is `true`, for everyone.
4. If the environment has phases and none of them is on, the result is `false`.
5. If any rule in a phase that's on matches, the result is `true`. Otherwise, it's `false`.

If the application can't reach the Octopus feature flag service at all, none of this happens, and the application uses the default value in its own code.

<!-- SUGGESTED VISUAL: a flowchart of the evaluation sequence, from "Is the environment added?" through to "Does any rule in an enabled phase match?", with each exit labeled with its result -->

## Rules and conditions

A rule is a set of conditions that together describe a group of users, and the rules on an environment are how a flag reaches some users but not others. Conditions in a rule combine with AND: the rule matches only when every condition matches. Rules combine with OR: the flag is on when at least one rule matches.

For example, an environment with these 2 rules:

- **Internal users**: context attribute `email-domain` is one of `octopus.com`
- **Early adopters**: tenant has tag `Ring/Early adopter` AND 50% of targeting keys

turns the flag on for every internal user, and for half the users of tenants in the early adopter ring.

Because rules combine with OR, a condition only limits the rule it's in. To keep a flag away from someone no matter which rule they'd otherwise match, such as excluding one tenant, add that condition to every rule. For the full list of conditions, see [Rule conditions](/docs/feature-flags/rules#rule-conditions).

## Phases

A phase is a stage in a rollout that holds one or more rules. When a phase is on, its rules join the rules from earlier phases that are already on, so each phase widens the rollout rather than replacing it. When a phase is off, its rules are ignored.

Phases turn on in order. A phase can't be on while a phase before it is off, which keeps the rollout moving in one direction. Turning a phase off rolls the flag back to the users the earlier phases target.

An environment with rules but no visible phases holds all its rules in a single phase that's on. For how phases turn on by themselves, see [Rolling out feature flags in phases](/docs/feature-flags/phased-rollouts).

## Default values {#default-values}

A flag has 2 default values, and each applies in a different situation. Mixing them up is the most common cause of a flag returning something unexpected.

The default value on the flag in Octopus is returned for any environment that hasn't been added to the flag. For example, if a flag's default value is off and only `Staging` and `Production` have been added to it, an application in `Development` gets `false`.

The default value in your code, the second argument to the evaluation call, is used only when the application can't get a value from the Octopus feature flag service, for example during a network outage:

```cs
var darkModeEnabled = await featureClient.GetBooleanValueAsync("dark-mode", false);
```

Set the default value in your code to the result that's safest for your users if Octopus can't be reached. In most cases, that's `false`.

## Percentage rollouts

A percentage condition turns a flag on for a share of tenants or users, such as 20% of tenants. Percentages let you limit how many people a change reaches while you watch for problems, then widen it.

Octopus decides who falls in a percentage by hashing an identifier together with a key that belongs to the flag. For tenants, the identifier is the tenant ID. For users, it's the [targeting key](/docs/feature-flags/rules#evaluation-context) your application supplies. The hash is deterministic, so the same tenant or user always gets the same result for the same flag, and they don't flip between on and off as they use your application.

Because the flag's key is part of the hash, a 20% rollout of one flag reaches a different 20% than a 20% rollout of another flag. This stops the same users from always being the first to get every new feature. When you want related flags to reach the same users, put them in a [rollout group](/docs/feature-flags/rollout-groups), which gives every flag in the group the same key.

[VERIFY: that increasing a percentage keeps everyone already included and only adds new tenants or users — needs: confirmation of the bucketing behavior from the feature flags team]

## Publishing

Octopus doesn't evaluate flags inside your deployments. When you save a change to a flag, Octopus publishes the project's flag configuration to the Octopus feature flag service, which your applications' providers read from. This is why flag changes reach running applications without a redeployment.

If a publish fails, the project's **Feature Flags** page shows a callout, and your applications keep the configuration from the last successful publish. To check recent publishes, see [Check a project's publish history](/docs/feature-flags/managing-flags#check-a-projects-publish-history).

[VERIFY: how long a running application takes to see a published change — needs: the provider refresh interval from the feature flags team]

## Related links

- [Targeting users with feature flag rules](/docs/feature-flags/rules)
- [Rolling out feature flags in phases](/docs/feature-flags/phased-rollouts)
- [Previewing feature flag evaluations](/docs/feature-flags/previewing-evaluations)
- [Managing rollout groups](/docs/feature-flags/rollout-groups)
Loading
Loading