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
varsection 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: trueLogic: {"or" : [ false, false ]}Result: false |
| And | Logic: {"and" : [ true, false ]}Result: falseLogic: {"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: trueLogic: { "==" : [1, "1"] }Result: true |
| Strict equals | Attribute equals the specified value, with strict comparison. | any | Logic: { "===" : [1, 1] }Result: trueLogic: { "===" : [1, "1"] }Result: false |
| Not equals | Attribute doesn't equal the specified value, with type coercion. | any | Logic: { "!=" : [1, 2] }Result: trueLogic: { "!=" : [1, "1"] }Result: false |
| Strict not equal | Attribute doesn't equal the specified value, with strict comparison. | any | Logic: { "!==" : [1, 2] }Result: trueLogic: { "!==" : [1, "1"] }Result: true |
| Exists | Attribute is defined | any | Logic: { "!!": [ "mike" ] }Result: trueLogic: { "!!": [ "" ] }Result: false |
| Not exists | Attribute is not defined | any | Logic: {"!": [ "mike" ] }Result: falseLogic: {"!": [ "" ] }Result: true |
| Greater than | Attribute is greater than the specified value | number | Logic: { ">" : [2, 1] }Result: trueLogic: { ">" : [1, 2] }Result: false |
| Greater than or equals | Attribute is greater or equal to the specified value | number | Logic: { ">=" : [2, 1] }Result: trueLogic: { ">=" : [1, 1] }Result: true |
| Less than | Attribute is less than the specified value | number | Logic: { "<" : [1, 2] }Result: trueLogic: { "<" : [2, 1] }Result: false |
| Less than or equals | Attribute is less or equal to the specified value | number | Logic: { "<=" : [1, 1] }Result: trueLogic: { "<=" : [2, 1] }Result: false |
| Between | Attribute between the specified values | number | Logic: { "<" : [1, 5, 10]}Result: trueLogic: { "<" : [1, 11, 10] }Result: false |
| Between inclusive | Attribute between or equal to the specified values | number | Logic: {"<=" : [1, 1, 10] }Result: trueLogic: {"<=" : [1, 11, 10] }Result: false |
| Contains | Contains string | string | Logic: { "in": ["Spring", "Springfield"] }Result: trueLogic: { "in":["Illinois", "Springfield"] }Result: false |
| Not contains | Does not contain a string | string | Logic: { "!": { "in":["Spring", "Springfield"] } }Result: falseLogic: { "!": { "in":["Illinois", "Springfield"] } }Result: true |
| In | Attribute is in an array of strings | string | Logic: { "in" : [ "Mike", ["Bob", "Mike"]] }Result: trueLogic: { "in":["Todd", ["Bob", "Mike"]] }Result: false |
| Not in | Attribute is not in an array of strings | string | Logic: { "!": { "in" : [ "Mike", ["Bob", "Mike"]] } }Result: falseLogic: { "!": { "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: trueLogic: { "starts_with" : [ "10.0.0.1", "192.168"] }Result: falseAdditional documentation can be found here. |
ends_with |
Attribute ends with the specified value | string | Logic: { "ends_with" : [ "noreply@example.com", "@example.com"] }Result: trueLogic: { ends_with" : [ "noreply@example.com", "@test.com"] }Result: falseAdditional 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: trueAdditional 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.