Flag Definitions
Flags
flags
is a required property.
The flags property is a top-level property that contains a collection of individual flags and their corresponding flag configurations.
Flag Definition
flag key
is a required property.
The flag key must uniquely identify a flag so it can be used during flag evaluation.
The flag key should convey the intent of the flag.
Flag properties
A fully configured flag may look like this.
{
"$schema": "https://flagd.dev/schema/v0/flags.json",
"flags": {
"new-welcome-banner": {
"state": "ENABLED",
"variants": {
"on": true,
"off": false
},
"defaultVariant": "off",
"targeting": {
"if": [
{ "ends_with": [{ "var": "email" }, "@example.com"] },
"on",
"off"
]
}
}
}
}
See below for a detailed description of each property.
State
state
is a required property.
Validate states are "ENABLED" or "DISABLED".
When the state is set to "DISABLED", flagd will behave like the flag doesn't exist.
Example:
Variants
variants
is a required property.
It is an object containing the possible variations supported by the flag.
All the values of the object must be the same type (e.g. boolean, numbers, string, JSON).
The type used as the variant value will correspond directly affects how the flag is accessed.
For example, to use a flag configured with boolean values the /flagd.evaluation.v1.Service/ResolveBoolean
path should be used.
If another path, such as /flagd.evaluation.v1.Service/ResolveString
is called, a type mismatch occurs and an error is returned.
Example:
Example:
Example of an invalid configuration:
Default Variant
defaultVariant
is a required property.
The value must match the name of one of the variants defined above.
The default variant is always used unless a targeting rule explicitly overrides it.
Example:
Example:
Example of an invalid configuration:
Targeting Rules
targeting
is an optional property.
A targeting rule must be valid JSON.
Flagd uses a modified version of JsonLogic, as well as some custom pre-processing, to evaluate these rules.
If no targeting rules are defined, the response reason will always be STATIC
, this allows for the flag values to be cached, this behavior is described here.
Variants Returned From Targeting Rules
The output of the targeting rule must match the name of one of the defined variants.
One exception to the above is that rules may return true
or false
which will map to the variant indexed by the equivalent string ("true"
, "false"
).
If a null value is returned by the targeting rule, the defaultVariant
is used.
This can be useful for conditionally "exiting" targeting rules and falling back to the default (in this case the returned reason will be DEFAULT
).
If an invalid variant is returned (not a string, true
, or false
, or a string that is not in the set of variants) the evaluation is considered erroneous.
See Boolean Variant Shorthand.
Evaluation Context
Evaluation context is included as part of the evaluation request. For example, when accessing flagd via HTTP, the POST body may look like this:
The evaluation context can be accessed in targeting rules using the var
operation followed by the evaluation context property name.
Description | Example |
---|---|
Retrieve property from the evaluation context | { "var": "email" } |
Retrieve property from the evaluation context or use a default | { "var": ["email", "noreply@example.com"] } |
Retrieve a nested property from the evaluation context | { "var": "user.email" } |
For more information, see the
var
section in the JsonLogic documentation.
Conditions
Conditions can be used to control the logical flow and grouping of targeting rules.
Conditional | Example |
---|---|
If | Logic: {"if" : [ true, "yes", "no" ]} Result: "yes" Logic: {"if" : [ false, "yes", "no" ]} Result: "no" |
If else | Logic: {"if" : [ false, "yes", false, "no", "maybe" ]} Result: "maybe" Logic: {"if" : [ false, "yes", false, "no", false, "maybe", "who knows" ]} Result: "who knows" |
Or | Logic: {"or" : [ true, false ]} Result: true Logic: {"or" : [ false, false ]} Result: false |
And | Logic: {"and" : [ true, false ]} Result: false Logic: {"and" : [ true, true ]} Result: true |
Operations
Operations are used to take action on or compare properties retrieved from the context. These are provided out-of-the-box by JsonLogic. It's worth noting that JsonLogic operators never throw exceptions or abnormally terminate due to invalid input. As long as a JsonLogic operator is structurally valid, it will return a falsy/nullish value.
Operator | Description | Context attribute type | Example |
---|---|---|---|
Equals | Attribute equals the specified value, with type coercion. | any | Logic: { "==" : [1, 1] } Result: true Logic: { "==" : [1, "1"] } Result: true |
Strict equals | Attribute equals the specified value, with strict comparison. | any | Logic: { "===" : [1, 1] } Result: true Logic: { "===" : [1, "1"] } Result: false |
Not equals | Attribute doesn't equal the specified value, with type coercion. | any | Logic: { "!=" : [1, 2] } Result: true Logic: { "!=" : [1, "1"] } Result: false |
Strict not equal | Attribute doesn't equal the specified value, with strict comparison. | any | Logic: { "!==" : [1, 2] } Result: true Logic: { "!==" : [1, "1"] } Result: true |
Exists | Attribute is defined | any | Logic: { "!!": [ "mike" ] } Result: true Logic: { "!!": [ "" ] } Result: false |
Not exists | Attribute is not defined | any | Logic: {"!": [ "mike" ] } Result: false Logic: {"!": [ "" ] } Result: true |
Greater than | Attribute is greater than the specified value | number | Logic: { ">" : [2, 1] } Result: true Logic: { ">" : [1, 2] } Result: false |
Greater than or equals | Attribute is greater or equal to the specified value | number | Logic: { ">=" : [2, 1] } Result: true Logic: { ">=" : [1, 1] } Result: true |
Less than | Attribute is less than the specified value | number | Logic: { "<" : [1, 2] } Result: true Logic: { "<" : [2, 1] } Result: false |
Less than or equals | Attribute is less or equal to the specified value | number | Logic: { "<=" : [1, 1] } Result: true Logic: { "<=" : [2, 1] } Result: false |
Between | Attribute between the specified values | number | Logic: { "<" : [1, 5, 10]} Result: true Logic: { "<" : [1, 11, 10] } Result: false |
Between inclusive | Attribute between or equal to the specified values | number | Logic: {"<=" : [1, 1, 10] } Result: true Logic: {"<=" : [1, 11, 10] } Result: false |
Contains | Contains string | string | Logic: { "in": ["Spring", "Springfield"] } Result: true Logic: { "in":["Illinois", "Springfield"] } Result: false |
Not contains | Does not contain a string | string | Logic: { "!": { "in":["Spring", "Springfield"] } } Result: false Logic: { "!": { "in":["Illinois", "Springfield"] } } Result: true |
In | Attribute is in an array of strings | string | Logic: { "in" : [ "Mike", ["Bob", "Mike"]] } Result: true Logic: { "in":["Todd", ["Bob", "Mike"]] } Result: false |
Not in | Attribute is not in an array of strings | string | Logic: { "!": { "in" : [ "Mike", ["Bob", "Mike"]] } } Result: false Logic: { "!": { "in":["Todd", ["Bob", "Mike"]] } } Result: true |
Custom Operations
These are custom operations specific to flagd and flagd providers. They are purpose-built extensions to JsonLogic in order to support common feature flag use cases. Consistent with built-in JsonLogic operators, flagd's custom operators return falsy/nullish values with invalid inputs.
Function | Description | Context attribute type | Example |
---|---|---|---|
fractional (available v0.6.4+) |
Deterministic, pseudorandom fractional distribution | string (bucketing value) | Logic: { "fractional" : [ { "var": "email" }, [ "red" , 50], [ "green" , 50 ] ] } Result: Pseudo randomly red or green based on the evaluation context property email .Additional documentation can be found here. |
starts_with |
Attribute starts with the specified value | string | Logic: { "starts_with" : [ "192.168.0.1", "192.168"] } Result: true Logic: { "starts_with" : [ "10.0.0.1", "192.168"] } Result: false Additional documentation can be found here. |
ends_with |
Attribute ends with the specified value | string | Logic: { "ends_with" : [ "noreply@example.com", "@example.com"] } Result: true Logic: { ends_with" : [ "noreply@example.com", "@test.com"] } Result: false Additional documentation can be found here. |
sem_ver |
Attribute matches a semantic versioning condition | string (valid semver) | Logic: {"sem_ver": ["1.1.2", ">=", "1.0.0"]} Result: true Additional documentation can be found here. |
Targeting key
flagd and flagd providers map the targeting key into the "targetingKey"
property of the context used in rules.
For example, if the targeting key for a particular evaluation was set to "5c3d8535-f81a-4478-a6d3-afaa4d51199e"
, the following expression would evaluate to true
:
$flagd properties in the evaluation context
Flagd adds the following properties to the evaluation context that can be used in the targeting rules.
Property | Description | From version |
---|---|---|
$flagd.flagKey |
the identifier for the flag being evaluated | v0.6.4 |
$flagd.timestamp |
a Unix timestamp (in seconds) of the time of evaluation | v0.6.7 |
Shared evaluators
$evaluators
is an optional property.
It's a collection of shared targeting configurations used to reduce the number of duplicated targeting rules.
Example:
{
"$schema": "https://flagd.dev/schema/v0/flags.json",
"flags": {
"fibAlgo": {
"variants": {
"recursive": "recursive",
"memo": "memo",
"loop": "loop",
"binet": "binet"
},
"defaultVariant": "recursive",
"state": "ENABLED",
"targeting": {
"if": [
{
"$ref": "emailWithFaas"
},
"binet",
null
]
}
},
"headerColor": {
"variants": {
"red": "#FF0000",
"blue": "#0000FF",
"green": "#00FF00",
"yellow": "#FFFF00"
},
"defaultVariant": "red",
"state": "ENABLED",
"targeting": {
"if": [
{
"$ref": "emailWithFaas"
},
{
"fractional": [
{ "var": "email" },
["red", 25],
["blue", 25],
["green", 25],
["yellow", 25]
]
},
null
]
}
}
},
"$evaluators": {
"emailWithFaas": {
"in": [
"@faas.com",
{
"var": ["email"]
}
]
}
}
}
Boolean Variant Shorthand
Since rules that return true
or false
map to the variant indexed by the equivalent string ("true"
, "false"
), you can use shorthand for these cases.
For example, this:
{
"$schema": "https://flagd.dev/schema/v0/flags.json",
"flags": {
"new-welcome-banner": {
"state": "ENABLED",
"variants": {
"true": true,
"false": false
},
"defaultVariant": "false",
"targeting": {
"if": [
{ "ends_with": [{ "var": "email" }, "@example.com"] },
"true",
"false"
]
}
}
}
}
can be shortened to this:
{
"$schema": "https://flagd.dev/schema/v0/flags.json",
"flags": {
"new-welcome-banner": {
"state": "ENABLED",
"variants": {
"true": true,
"false": false
},
"defaultVariant": "false",
"targeting": {
"ends_with": [{ "var": "email" }, "@example.com"]
}
}
}
}
Examples
Sample configurations can be found at https://github.com/open-feature/flagd/tree/main/config/samples.