# Methods Source: https://docs.flipt.io/v1/authentication/methods This document describes the various supported authentication methods. See [Configuration: Authentication Methods](/v1/configuration/authentication#methods) for details on how to configure the various authentication methods. ## Static Token The `token` authentication method supports statically creating authentication tokens. Once enabled, the `/auth/v1/method/token` API prefix is mounted to Flipt's API. This section of the API supports the creation of static tokens. ### Token Management Tokens can be created and deleted via either the UI or API. #### API The following `curl` command creates a static token with no expiration. Given authentication is set to `required` then a prior client token will be required to perform this action. ```console theme={null} curl -X POST localhost:8080/auth/v1/method/token \ -H 'Authorization: Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=' \ -H 'Content-Type: application/json' \ --data '{"name":"access_all_areas","description":"keys to the castle"}' ``` #### UI The UI also supports the creation and deletion of tokens. To access this functionality, navigate to `Settings` from the main menu and see the 'Static Tokens' section. Create Token UI ### Bootstrapping On first startup, Flipt will automatically create a random static token with the name `initial_bootstrap_token` if one doesn't already exist and if `token` authentication is enabled. Bootstrap Token This token is intended to be used to create additional tokens to be then used for subsequent API requests. By default it has no expiration date, therefore it's recommended that this token be deleted once the initial bootstrapping is complete. This token is output to the Flipt logs on startup and can be found by searching for `client_token` in the logs: ```console theme={null} INFO access token created {"server": "grpc", "client_token": "jWLUy8ChnVDs-Llgyj7cMIzB0PfplwbBy-B27a0p23I="} ``` This initial bootstrap process can also be configured to use a known token by setting the `bootstrap.token` value in the configuration file. This is useful if you want to prevent having to search the logs after startup or if Flipt is deployed in an automated fashion, for example, if you are using a configuration management tool. The bootstrap token can also be configured to have an expiration date by setting the `bootstrap.expiration` value in the configuration file. This is useful if you want to ensure that the bootstrap token is only valid for a short time before automatically expiring. See the [Configuration: Method Token](/v1/configuration/overview#authentication-methods-token) documentation for more details. ### Token Expiration Tokens can be created with an optional expiration date. This can be used to ensure that a token is only valid for a short time before automatically expiring. Expired tokens will be automatically deleted by Flipt. The interval and grace period for this cleanup process can be configured via the `token.cleanup.interval` and `token.cleanup.grace_period` values in the configuration. ### Namespaced Tokens Tokens can be created with an optional namespace to allow for more granular control over resource access. Namespaces allow for grouping resources such as flags, segments, etc. To learn more about namespaces, see the [Concepts: Namespaces](/v1/concepts#namespaces) documentation. Namespaced tokens are useful for the scenario when you want to limit the privileges of an integration such as a CI/CD pipeline or internal service. It's important to note that namespaced tokens offer limited access to the Flipt API, as only API requests that can be scoped to a namespace are supported. For example, the `/api/v1/namespaces/{namespace}/flags` endpoint supports a `namespace` parameter, therefore a namespaced token can be used to access this endpoint. However, the `/auth/v1/tokens` endpoint is not associated with a single `namespace`, so a namespaced token cannot be used to access this endpoint. This also means that namespaced tokens themselves cannot be used to create additional tokens. Tokens must be created using a non-namespaced (default) token. ## OpenID Connect [OpenID Connect](https://openid.net/connect/) (OIDC) is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner. Flipt's UI is designed to support this authentication method natively. Meaning, that once enabled, the UI will support login and present each provider as a login button. The rest of this information is mostly academic. It's mainly useful if you want to build your browser application using cookie authentication or understand Flipt's OIDC flow at a lower level. See the [OIDC Configuration](/v1/configuration/authentication#oidc) documentation to learn how to configure your provider(s). The `OIDC` authentication method is primarily designed to support browser-based authentication. However, it can be manually invoked if such a use case presents itself. Once enabled, the `/auth/v1/method/oidc` API prefix is mounted to Flipt's API. This section of the API supports a generic OAuth 2.0 with OIDC flow. Flipt's configuration can be defined with multiple simultaneous OIDC providers. An operator of Flipt chooses a name for each provider and then configures the relevant secrets necessary to authenticate with an OIDC client. Numerous OIDC providers are available. For example, we've tested Flipt with: * Google * Auth0 * GitLab * Dex * Okta * AzureAD * Keycloak Each provider has their own way of establishing clients and acquiring the relevant credentials. You can find further documentation on leveraging providers like these in our [OIDC Configuration](/v1/configuration/authentication#oidc) documentation. For illustration purposes, let us say we've configured a single provider with `Dex` and named it `dex` (lowercase) in our provider configuration. This will lead to the following endpoints being available on Flipt: * `GET /auth/v1/method/oidc/dex/authorize` * `GET /auth/v1/method/oidc/dex/callback` These two endpoints are necessary to support the different legs of the OAuth/OIDC flow. The first can be requested to obtain an authorization URL directed at the configured instance of Dex. The latter is the destination that Dex will redirect the client back to. When using HTTP, this callback endpoint will establish a cookie named `flipt_client_token` and return it via the `Set-Cookie` response header. ## GitHub [GitHub](https://github.com) is an OAuth 2.0 implementation compatible with GitHub. As with OIDC, the GitHub method works natively with the Flipt UI. Once enabled, the UI will support a "Login with GitHub" login option. The `GitHub` authentication method is primarily designed to support browser-based authentication. However, it can be manually invoked if the need arises. Once enabled, the `/auth/v1/method/github` API prefix is mounted to Flipt's API. This section of the API supports GitHub's OAuth 2.0 flow. This will lead to the following endpoints being available on Flipt: * `GET /auth/v1/method/github/authorize` * `GET /auth/v1/method/github/callback` These two endpoints are necessary to support the different legs of the OAuth flow. The first can be requested to obtain an authorization URL directed at GitHub. The latter is the destination that GitHub will redirect the client back to. When using HTTP, this callback endpoint will establish a cookie named `flipt_client_token` and return it via the `Set-Cookie` response header. ### GitHub Enterprise Server Flipt also supports GitHub Enterprise Server as an authentication provider. To configure Flipt to use GitHub Enterprise Server, you will need to provide both the server URL and API URL of your GitHub Enterprise Server instance in the configuration file. ```yaml theme={null} authentication: methods: github: enabled: true server_url: "https://github.example.com" api_url: "https://api.github.example.com" ``` ## Kubernetes This method is designed for automatically authenticating applications with Flipt. The `kubernetes` authentication method supports the ability to exchange [Kubernetes service account](https://kubernetes.io/docs/concepts/security/service-accounts) tokens with Flipt for client tokens. This allows services deployed into the same Kubernetes cluster as Flipt to automatically gain authenticated access to the Flipt API without additional management of static client tokens. Kubernetes Authentication Flow When enabled (see our [Configuration: Method Kubernetes](/v1/configuration/authentication#kubernetes) documentation) a service deployed within Kubernetes can read their service account token from local disk and invoke the verify service account operation on the API. Given the service account is deemed valid for the surrounding cluster this operation will return a valid Flipt client token with a matching expiration as the service account. If your Kubernetes environment has short-lived service account tokens, care will be needed to periodically request a new client token using a newly issued service account token. Kubernetes refreshes service account tokens locally, all that's required is to read the token from the disk again. The client token produced can be used in subsequent API requests with the rest of the Flipt API to gain authenticated access. ### Via the SDK Some of our SDKs support automatic authentication via the Kubernetes authentication method. These clients do not require you to have to manually invoke the verify service account API. Instead, they do this operation for you, and they ensure that the retrieved client token from Flipt is automatically refreshed. The SDKs that currently support this include: * [Go Server SDK](https://pkg.go.dev/go.flipt.io/flipt/sdk/go) ```go sdk.go theme={null} package main import ( http "go.flipt.io/flipt/sdk/go/http" sdk "go.flipt.io/flipt/sdk/go" ) func main() { // The following constructs an instance of the SDK which communicates with // instances of Flipt deployed in the same cluster. // In this example, we assume Flipt is reachable via a k8s service named // `flipt` deployed into the namespace `flipt`. // // The kubernetes provider automatically authenticates the client with this // Flipt service. It also ensures that the credentials are kept up to date // and automatically refreshed before they expire. transport := http.NewTransport("http://flipt.flipt.svc.cluster.local:8080") sdk := sdk.New(transport, sdk.WithAuthenticationProvider( sdk.NewKubernetesAuthenticationProvider(transport), )) } ``` ### Via the API Acquiring a client token via this method can be performed manually from inside a pod. The following uses `curl` to illustrate how a local, valid service account token can be used in this way. ```bash client-token.sh theme={null} # assumes both curl and jq are installed curl -s -X POST http://flipt:8080/auth/v1/method/kubernetes/serviceaccount \ --data "{\"service_account_token\":\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\"}" | \ jq . { "clientToken": "pKkaEik40Nu4lJ7O37l92MNyyD38U8UlaagSmAfJoS0=", "authentication": { "id": "f191babc-57b8-4856-89b1-f324941403d7", "method": "METHOD_KUBERNETES", "expiresAt": "2024-02-20T13:39:14Z", "createdAt": "2023-02-20T14:11:28.962841Z", "updatedAt": "2023-02-20T14:11:28.962841Z", "metadata": { "io.flipt.auth.k8s.namespace": "default", "io.flipt.auth.k8s.pod.name": "someservice-586bfb5b6b-fmh8g", "io.flipt.auth.k8s.pod.uid": "b5217947-aeac-4b35-afd3-23f50d63eae9", "io.flipt.auth.k8s.serviceaccount.name": "default", "io.flipt.auth.k8s.serviceaccount.uid": "8aeb28ad-66f0-4884-bafc-e606e5eda149" } } } ``` The client token found in the body of the response can then be used to authenticate with Flipt as outlined in [Using Client Tokens](/v1/authentication/using-tokens). The expiration can be used to schedule when to next request a new client token. ## JSON Web Tokens [JSON Web Tokens](https://jwt.io/) (JWT) are an open, industry-standard RFC 7519 method for representing claims securely between two parties. Flipt supports the use of externally created and signed JWTs as a method of authentication. JWT authentication is useful for scenarios where you want to integrate Flipt with an existing authentication system, or where you want to perform service to Flipt authentication without the need to manage static client tokens. JWT authentication is **not** supported by the Flipt UI as it is not a session-compatible authentication method. JWT Authentication Flow The JWT issued by the Authorization Server can then be used to authenticate with Flipt as outlined in [Using JSON Web Tokens](/v1/authentication/using-jwts). # Overview Source: https://docs.flipt.io/v1/authentication/overview This document describes how to enable and use authentication with Flipt. Flipt supports the ability to secure its core API routes with authentication. Flipt authentication is **disabled** (not required) by default. Head to the [Configuration: Authentication](/v1/configuration/authentication) section to learn how to enable it. Once enabled, all routes beneath the following API prefixes will require a [client token](#client-tokens) or [JWT](#json-web-tokens) to authenticate requests: * `/api/v1/` * `/auth/v1/` * `/meta/` * `/evaluation/v1/` The following URLs aren't protected by authentication: * `/debug` * `/metrics` * `/health` They're currently unprotected to support backward compatibility. We're exploring ways to support protecting these endpoints going forward. For now, we recommend excluding these API prefixes from your load-balancer. Apart from `/auth/v1/` itself, the rest of the top-level API prefixes can be optionally excluded from authentication. Allowing for sections, such as the evaluations API, to be publicly accessible while still protecting the management and metadata APIs. See the [Configuration: Authentication Exclusions](/v1/configuration/authentication#exclusions) documentation for details. ## Client Tokens Client tokens are the core credential required to authenticate a request. Tokens themselves are acquired via [authentication methods](/v1/authentication/methods). Flipt supports multiple authentication methods for acquiring credentials: 1. [Static Token](/v1/authentication/methods/#static-token) 2. [OIDC](/v1/authentication/methods/#oidc) 3. [GitHub](/v1/authentication/methods/#github) 4. [Kubernetes](/v1/authentication/methods/#kubernetes) Once a `client token` has been acquired, it can be supplied via request metadata dependent on the protocol. Both HTTP and gRPC examples can be found on the [Using Client Tokens](/v1/authentication/using-tokens) page. ## JSON Web Tokens Flipt can also authenticate requests using externally created and signed [JSON Web Tokens](https://jwt.io/). This is useful for integrating existing authentication systems with Flipt. To enable JWT authentication, you will need to configure Flipt with the public key used to verify the JWT signature. See the [Configuration: JWT Authentication](/v1/configuration/authentication#json-web-token) documentation for details. # Using JSON Web Tokens Source: https://docs.flipt.io/v1/authentication/using-jwts This document explains how to handle JSON Web Tokens via both HTTP and gRPC. ## HTTP JSON Web Tokens can only be presented via HTTP requests in the form of an `Authorization` header. ### `Authorization` Header For applications that communicate with Flipt over HTTP, the `Authorization` header is required. It must be provided in the form `Authorization: JWT `. The following examples illustrate this in the context of various programming languages: ```go client.go theme={null} import ( "context" "net/http" ) func main() { req := http.NewRequest("GET", "https://flipt.your.instance/api/v1/flags", nil) req.Header.Set("Authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") resp, err := http.Do(req) // ... } ``` ```typescript client.ts theme={null} import fetch from 'node-fetch'; const headers = { 'Authorization': 'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' } const response = await fetch('https://flipt.your.instance/api/v1/flags', { headers: headers }) ``` ```python client.py theme={null} import requests def doRequest(): headers ={"Authorization": "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"} requests.get("https://flipt.your.instance/api/v1/flags", headers=headers) return ``` ## GRPC For gRPC we use the [Metadata](https://grpc.io/docs/what-is-grpc/core-concepts/#metadata) functionality similar to HTTP Headers. The lower-case `authorization` metadata key should be supplied with a single string `JWT ` to any RPC calls. ### Example The following example authenticates a single gRPC client request: ```go rpc.go theme={null} func DoRequest(ctx context.Context, flagKey string) { ctx := metadata.AppendToOutgoingContext(ctx, "authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") flag, err := flipt.GetFlags(ctx, &flipt.GetFlagRequest{ Key: flagKey, }) //... } ``` This subsequent example demonstrates using a client unary interceptor, which authenticates all outgoing requests: ```go interceptor.go theme={null} func AuthUnaryClientInterceptor(optFuncs ...CallOption) grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") return invoker(ctx, method, req, reply, cc, opts...) } } ``` # Using Client Tokens Source: https://docs.flipt.io/v1/authentication/using-tokens This document explains how to handle client tokens via both HTTP and gRPC. ## HTTP Client tokens can be presented via HTTP requests in two different valid ways. This choice allows us to support two different types of workloads. ### 1. `Authorization` Header For applications that communicate with Flipt over HTTP, the `Authorization` header is most appropriate. It must be provided in the form `Authorization: Bearer `. The following examples illustrate this in the context of various programming languages: ```go client.go theme={null} import ( "context" "net/http" ) func main() { req := http.NewRequest("GET", "https://flipt.your.instance/api/v1/flags", nil) req.Header.Set("Authorization", "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=") resp, err := http.Do(req) // ... } ``` ```typescript client.ts theme={null} import fetch from 'node-fetch'; const headers = { 'Authorization': 'Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=' } const response = await fetch('https://flipt.your.instance/api/v1/flags', { headers: headers }) ``` ```python client.py theme={null} import requests def doRequest(): headers ={"Authorization": "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc="} requests.get("https://flipt.your.instance/api/v1/flags", headers=headers) return ``` ### 2. `Cookie` Header It's important to enable [CSRF](/v1/configuration/authentication#session) prevention in your Flipt configuration when using a "session compatible" authentication method and `Cookie` based authentication in the browser. For browser-based applications (e.g. Flipt's own user interface) we support supplying a client token via a particular `Cookie` called `flipt_client_token`. ```go client.go theme={null} import ( "context" "net/http" ) func main() { req := http.NewRequest("GET", "https://flipt.your.instance/api/v1/flags", nil) req.AddCookie(&http.Cookie{ Name: "flipt_client_token", Value: "gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=", } ) resp, err := http.Do(req) // ... } ``` ```typescript client.ts theme={null} import fetch from "node-fetch"; const headers = { Cookie: "flipt_client_token=gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=", }; const response = await fetch("https://flipt.your.instance/api/v1/flags", { headers: headers, }); ``` ```python client.py theme={null} import requests def doRequest(): headers ={"Cookie": "flipt_client_token=gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc="} requests.get("https://flipt.your.instance/api/v1/flags", headers=headers) return ``` This allows for stateful browser sessions to be established. When using a "session compatible" authentication method (e.g. [OIDC](/v1/authentication/methods#oidc)), Flipt will automatically establish this cookie via a `Set-Cookie` response header during the authentication method exchange. In a browser context this means subsequent API calls will be automatically authenticated given the API requests are invoked with credentials included (cookies are enabled). Flipt's UI leverages this mechanism for its login functionality. ## GRPC For gRPC we use the [Metadata](https://grpc.io/docs/what-is-grpc/core-concepts/#metadata) functionality similar to HTTP Headers. The lower-case `authorization` metadata key should be supplied with a single string `Bearer ` to any RPC calls. ### Example The following example authenticates a single gRPC client request: ```go rpc.go theme={null} func DoRequest(ctx context.Context, flagKey string) { ctx := metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=") flag, err := flipt.GetFlags(ctx, &flipt.GetFlagRequest{ Key: flagKey, }) //... } ``` This subsequent example demonstrates using a client unary interceptor, which authenticates all outgoing requests: ```go interceptor.go theme={null} func AuthUnaryClientInterceptor(optFuncs ...CallOption) grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer gt6P_zIqTnCngfHDCpWb48ob5EBt3PqunUhpofNCNnc=") return invoker(ctx, method, req, reply, cc, opts...) } } ``` # Overview Source: https://docs.flipt.io/v1/authorization/overview This document describes how to enable and use authorization with Flipt. Flipt supports the ability to secure its core API routes with authorization. Flipt authorization is **disabled** (not required) by default. Head to the [Configuration: Authorization](/v1/configuration/authorization) section to learn how to enable it. Once enabled, all routes beneath the Management API prefix will require a [policy](#policies) to be evaluated before the request is allowed to proceed. The policy must evaluate to `allowed == true` for the request to be allowed. * `/api/v1/` ## Open Policy Agent (OPA) [Open Policy Agent (OPA)](https://www.openpolicyagent.org/) is a general-purpose policy engine that can be used to configure and enforce authorization policies. OPA provides a unified toolset and framework for policy across the cloud native stack. Open Policy Agent is a [CNCF](https://www.cncf.io/) project and is used by many organizations to enforce policies across their cloud-native environments. Flipt embeds OPA to evaluate policies that determine whether a request should be allowed or denied. This means that no additional infrastructure or services are required to use OPA with Flipt. Check out our [Role-Based Access Control with Keycloak guide](/v1/guides/operation/authorization/rbac-with-keycloak) for an example on how to configure and use role-based access control (RBAC) with Flipt and Keycloak using OPA. ## Policies Flipt uses OPA to enforce authorization policies for the Management API. The policies are written in [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/), a powerful, declarative policy language. The path to this file is provided as described in the [Configuration: Authorization](/v1/configuration/authorization) section. Part of the power of OPA is that it's extremely flexible as it allows you to define fine-grained policies tailored to your exact needs. Here's an example of a simple policy that checks whether custom claims provided at authentication time include a key `roles` containing a value `admin`: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "admin" in claims.roles } ``` You can find more information on how to write Rego policies in the [OPA documentation](https://www.openpolicyagent.org/docs/latest/policy-language/). OPA has a rich set of built-in functions that can be used to write complex policies. They also provide a [Rego Playground](https://play.openpolicyagent.org/) where you can test your policies before deploying them. It's up to you to define the policies that make sense for your organization. During policy evaluation, Flipt will pass the incoming request context to the built-in Open Policy Agent, which will then evaluate the policy against that context. The context provided to OPA includes the following fields: * `input.authentication`: The authentication information for the request. These are specific to each authentication provider/method and can include things like the user's roles, email, etc. * `input.request`: The incoming request details, such as the `namespace`, `resource`, and `action`. ### Authentication Information Flipt provides the raw authentication information to OPA for evaluation. This information is specific to the authentication method used to authenticate the request. For example, if you're using the [OIDC authentication method](/v1/authentication/methods#openid-connect), the `input.authentication.metadata` field may contain the user's name and email as well as custom claims assigned to the user. Here is an example of the `input.authentication.metadata` field for a request authenticated using an example OIDC provider: ```json theme={null} { "io.flipt.auth.email": "user@email.com", "io.flipt.auth.name": "John Doe", "io.flipt.auth.claims": { "roles": ["admin", "viewer"] } } ``` The `io.flipt.auth.claims` field is a JSON object that contains custom claims provided by the authentication provider. Each authentication provider may provide different claims, so it's up to you to map these claims as needed in your policies. The following fields are available in the `input.authentication` field: * `metadata`: A map of authentication metadata provided by the authentication method. This can include the user's email, name, roles, etc. * `io.flipt.auth.email`: The user's email address. * `io.flipt.auth.name`: The user's name. * `io.flipt.auth.claims`: A map of **all** claims provided by the authentication method. This can include the user's roles, groups, etc. These claims are marshaled into a JSON string before being passed to OPA for evaluation. * `method`: The authentication method used to authenticate the request. ### Helper Functions To make it easier to write policies, Flipt provides a set of helper functions that are available to be used for the `input` field. `flipt.is_auth_method(input, method)` The helper function `flipt.is_auth_method(input, method)` can be used to check if the request was authenticated using the specified method. The `method` parameter is the authentication method name as it is registered in Flipt, e.g. `oidc`, `token`, `kubernetes`, `github`, `jwt`. Example: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { flipt.is_auth_method(input, "jwt") } ``` ### Mapping Identity Each authentication method configurable within Flipt will provide different information depending on the identity. It's up to you to combine identity information (`authentication`) with the requested resource (`request`) to make an authorization decision whether or not the request should be allowed (`allow`). Some authentication methods provide user details such as roles directly, while others may provide a user ID or email that you can use to look up roles in your own system. Many authentication providers support adding custom claims to the JWT token, which can be used to provide additional information about the user. For example, [Okta](https://www.okta.com/) allows you to add custom claims using their groups feature. An example JWT token with custom claims generated by Okta might look like this: ```json theme={null} { "sub": "00uixa271s6x7qt8I0h7", "ver": 1, "iss": "https://{yourOktaDomain}", "aud": "0oaoiuhhch8VRtBnC0h7", "iat": 1574201516, "exp": 1574205116, "jti": "ID.ewMNfSvcpuqyS93OgVeCN3F2LseqROkyYjz7DNb9yhs", "amr": ["pwd", "mfa", "kba"], "idp": "00oixa26ycdNcX0VT0h7", "nonce": "UBGW", "auth_time": 1574201433, "groups": ["Everyone", "IT"] } ``` In this example, the `groups` claim is used to provide the user's organizational groups. You can then write a policy that checks for the presence of specific groups to determine whether the user should be allowed to access a particular resource. ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "IT" in claims.groups } ``` The Rego builtin [`json.unmarshal`](https://www.openpolicyagent.org/docs/latest/policy-reference/#builtin-encoding-jsonunmarshal) function is used to convert the `groups` claim from a string to a JSON object that can be queried in the policy. Flipt encodes the raw authentication claims as a JSON string to pass them to OPA for evaluation. Further documentation on how to configure custom claims and groups in Okta can be found in the [Okta Developer documentation](https://developer.okta.com/docs/guides/customize-tokens-returned-from-okta/main/). Roles or groups are not a requirement for writing policies. You can write policies that check for any information provided by the authentication method, such as the user's email, id, name, etc. Flipt has no notion of users or roles internally, it simply passes the raw authentication information along with other request metadata to OPA for evaluation. ### Request Information The `input.request` field contains information about the incoming request. This includes the `namespace`, `resource`, and `action` of the request. * `namespace`: The [namespace](/v1/concepts#namespaces) in Flipt of the resource being accessed. If no namespace is provided, the default namespace is used, or it is not applicable as the resource is not namespace scoped (e.g. authentication) * `resource`: The resource being accessed. This can be one of: * `namespace`: Access to [namespace](/v1/concepts#namespaces) resources (e.g., listing or creating namespaces). * `flag`: Access to [flag](/v1/concepts#flags) resources and sub-resources (e.g., listing or creating flags, variants, rules or rollouts). * `segment`: Access to [segment](/v1/concepts#segments) resources and sub-resources (e.g., listing or creating segments, constraints or distributions). * `authentication`: Access to authentication resources (e.g., listing or creating client tokens). * `subject`: The (optional) nested subject of the request. This can be one of: * `namespace`: Access to [namespace](/v1/concepts#namespaces) resources. * `flag`: Access to [flag](/v1/concepts#flags) resources. * `variant`: Access to flag [variant](/v1/concepts#variant-flags) resources. * `rule`: Access to flag [rule](/v1/concepts#rules) resources. * `rollout`: Access to flag [rollout](/v1/concepts#rollouts) resources. * `segment`: Access to [segment](/v1/concepts#segments) resources. * `constraint`: Access to segment [constraint](/v1/concepts#constraints) resources. * `distribution`: Access to segment [distribution](/v1/concepts#distributions) resources. * `token`: Access to client token resources. * `action`: The action being performed on the resource. This can be one of: * `create`: Access to create resources. * `read`: Access to list or read resources. * `update`: Access to update resources. * `delete`: Access to delete resources. Here's an example of the `input.request` field for a request to list flags in the default namespace: ```json theme={null} { "namespace": "default", "resource": "flag", "subject": "flag", "action": "read" } ``` Here is an example policy that allows a user to list flags in the default namespace: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { input.request.namespace == "default" input.request.resource == "flag" input.request.action == "read" } ``` Combining the above policy with the user information policy from the previous example, you can create a policy that allows users with the `IT` group to delete flags in the default namespace: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "IT" in claims.groups input.request.namespace == "default" input.request.resource == "flag" input.request.action == "delete" } ``` ## External Data OPA policies can also use external data sources to make decisions. This can be useful when you need to make decisions based on data that is not available in the request context. For example, if your authentication method does not provide user roles, you could use an external data source to map user IDs to roles. Here is an example policy that uses an external data source to check if the user has the `admin` role: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { role := data.roles[input.authentication.metadata["io.flipt.auth.name"]] role == "admin" } ``` And here is an example of the external data source that maps user IDs to roles: ```json data.json theme={null} { "roles": { "user1": "admin", "user2": "viewer" } } ``` Flipt allows you to define external data sources in the configuration file. You can find more information on how to configure external data sources in the [Configuration: Authorization](/v1/configuration/authorization) section. The combination of OPA's flexible policy language and the ability to use external data sources makes it possible to define complex authorization policies that can adapt to your organization's needs. ## Authoring Policies While the examples provided in this document are simple, you can write policies that are as complex as you need. OPA provides a rich set of built-in functions that can be used to write complex policies. Check out our [Role-Based Access Control with Keycloak guide](/v1/guides/operation/authorization/rbac-with-keycloak) for an example on how to configure and use role-based access control (RBAC) with Flipt and Keycloak using OPA. Learning how to write policies in Rego can be challenging at first, but OPA provides extensive documentation on the [Rego Language](https://www.openpolicyagent.org/docs/latest/policy-language/) as well as a [Rego Playground](https://play.openpolicyagent.org/) where you can test your policies before deploying them. OPA also provides a testing framework that you can use to write unit tests for your policies. This can help ensure that your policies are working as expected before deploying them to production. Here are some resources to help you get started with writing and testing policies: * [Rego Language Reference](https://www.openpolicyagent.org/docs/latest/policy-language/) * [Rego Playground](https://play.openpolicyagent.org/) * [Policy Testing](https://www.openpolicyagent.org/docs/latest/policy-testing/) * [Policy Performance](https://www.openpolicyagent.org/docs/latest/policy-performance/) If you have any questions or need help writing policies for Flipt, feel free to reach out to us in our [Discord](https://flipt.io/discord) community. # Product Updates Source: https://docs.flipt.io/v1/changelog/overview Recent updates to Flipt, including new SDKs and other improvements. ## Contains Constraint Operator Added support for the `contains` and `not contains` constraint operators in v1.57.0. These can be used to check if a string or entityID contains (or not contains) a substring. ## Redis Cluster Support Added support for Redis cluster mode in v1.57.0. You can now configure Flipt to use Redis in cluster mode for improved scalability and performance. The feature includes: * Support for both single and cluster modes * Configurable key prefixes and hash tags * OTEL tracing support for Redis operations See the [Caching docs](/v1/configuration/caching) for more information. ## Consolidated JavaScript Client-Side SDK The JavaScript browser and Node.js SDKs have been consolidated into a single package. See the [Integration docs](/v1/integration/client) for more information. ## Model Context Protocol (MCP) Flipt now supports the [Model Context Protocol (MCP)](/v1/tooling/model-context-protocol) which allows AI assistants and LLMs to directly interact with your feature flags, segments, and evaluations through a standardized interface. See the [Model Context Protocol docs](/v1/tooling/model-context-protocol) for more information. ## Android Client-Side SDK Just released the Android SDK client for client-side flag evaluation. See the [Integration docs](/v1/integration/client) for more information. ## OpenFeature Python Provider Just released the OpenFeature Python Provider for Flipt. See the [OpenFeature docs](/v1/integration/openfeature) for more information. ## Flag Metadata Added support for metadata on flags in the Flipt UI. Flag Metadata Example ## Prometheus Analytics Storage Added support for Prometheus as an [analytics storage backend](/v1/configuration/analytics#prometheus). ## UI Improvements Changed the UI for flags and segments list views to use a more modern look and feel. ## Swift Client-Side SDK Just released the Swift SDK client for client-side flag evaluation. See the [Integration docs](/v1/integration/client) for more information. ## C# Client-Side SDK Just released the C# SDK client for client-side flag evaluation. See the [Integration docs](/v1/integration/client) for more information. # bundle build Source: https://docs.flipt.io/v1/cli/commands/bundle/build Build a new bundle ``` flipt bundle build [flags] ``` This command builds a new bundle containing feature files identified via Flipt's feature index (see: [Locating flag state](/v1/configuration/storage#locating-flag-state)). Given the files are all valid the command should successfully create a new (local) OCI feature bundle, and its resulting SHA digest is printed. Bundles are named via the provided `name` argument. This argument supports an optional `tag` suffix. ### Examples ``` $ flipt bundle build mybundle sha256:0e500a47bc26afcc91a1cea7abb39f55566bb99b709449a1752eea65000a663c $ flipt bundle build mybundle:latest sha256:0e500a47bc26afcc91a1cea7abb39f55566bb99b709449a1752eea65000a663c ``` ### Options ``` -h, --help help for build ``` # bundle list Source: https://docs.flipt.io/v1/cli/commands/bundle/list List all bundles ``` flipt bundle list [flags] ``` This command lists out named bundles previously built or pulled locally. Each bundle is listed with its digest, name, created timestamp and optional tag. ### Examples ``` $ flipt bundle list DIGEST REPO TAG CREATED 8a70b2c mybundle latest 2023-11-13 13:51:20 +0000 UTC 9388e73 mybundle 2023-11-10 12:02:04 +0000 UTC 3e628b6 mybundle 2023-11-03 15:54:54 +0000 UTC ``` ### Options ``` -h, --help help for list ``` # bundle pull Source: https://docs.flipt.io/v1/cli/commands/bundle/pull Pull a remote bundle ``` flipt bundle pull [flags] ``` This command fetches a bundle from a target remote locally with the same name. ### Examples ``` $ flipt bundle pull ghcr.io/flipt-io/flipt/mybundle:latest sha256:0e500a47bc26afcc91a1cea7abb39f55566bb99b709449a1752eea65000a663c $ flipt bundle list 0e500a4 mybundle latest 2023-11-13 13:53:52 +0000 UTC 8a70b2c mybundle 2023-11-13 13:51:20 +0000 UTC ``` ### Options ``` -h, --help help for pull ``` # bundle push Source: https://docs.flipt.io/v1/cli/commands/bundle/push Push local bundle to remote ``` flipt bundle push [flags] ``` This command pushes a bundle located at `from` to the target `to`. More commonly this is used to push a local bundle to an upstream registry. ### Examples ``` flipt bundle push mybundle:latest ghcr.io/flipt-io/flipt/mybundle:latest sha256:0e500a47bc26afcc91a1cea7abb39f55566bb99b709449a1752eea65000a663c ``` ### Options ``` -h, --help help for push ``` # config edit Source: https://docs.flipt.io/v1/cli/commands/config/edit Edit Flipt configuration ``` flipt config edit [flags] ``` ### Options ``` -h, --help help for edit ``` ### Inherited Options ``` --config string path to config file ``` ### More Info See the [configuration](/v1/configuration) section of the documentation for more information. # config init Source: https://docs.flipt.io/v1/cli/commands/config/init Initialize Flipt configuration ``` flipt config init [flags] ``` ### Options ``` -y, --force Overwrite existing configuration file -h, --help help for init ``` ### Inherited Options ``` --config string path to config file ``` ### More Info See the [configuration](/v1/configuration) section of the documentation for more information. # evaluate Source: https://docs.flipt.io/v1/cli/commands/evaluate Evaluate a flag with Flipt. ``` flipt evaluate [flagKey] [flags] ``` ### Options ``` -a, --address string address of Flipt instance. (default "http://localhost:8080") -c, --context stringArray evaluation request context as key=value. -e, --entity-id string evaluation request entity id. (default "${uuid}") -h, --help help for evaluate -i, --interval duration interval between requests in watch mode. (default 1s) -n, --namespace string flag namespace. (default "default") -r, --request-id string evaluation request id. -t, --token string client token used to authenticate access to Flipt instance. -w, --watch enable watch mode. ``` ### Examples ``` $ flipt evaluate chat-enabled --context test=foo {"flag_key":"chat-enabled","enabled":true,"reason":"DEFAULT_EVALUATION_REASON","request_id":"73d12ea1-65d7-401d-b0c7-f7a6b3d41dd6","request_duration_millis":0.894792,"timestamp":"2024-01-23T17:37:13.484716964Z"} ``` # export Source: https://docs.flipt.io/v1/cli/commands/export Export Flipt data to file/stdout ``` flipt export [flags] ``` ### Options ``` -a, --address string address of remote Flipt instance to export from (defaults to direct DB export if not supplied) --all-namespaces export all namespaces. (mutually exclusive with --namespaces) --config string path to config file -h, --help help for export --namespaces string comma-delimited list of namespaces to export from. (mutually exclusive with --all-namespaces) (default "default") -o, --output string export to filename (default STDOUT) --sort-by-key sort exported resources by key. (flags, flag variants and segments. namespaces will be sorted with --all-namespaces) -t, --token string client token used to authenticate access to remote Flipt instance when exporting. ``` ### More Info See the [import/export](/v1/operations/import-export) section of the documentation for more information. # import Source: https://docs.flipt.io/v1/cli/commands/import Import Flipt data from file/stdin ``` flipt import [flags] ``` ### Options ``` -a, --address string address of remote Flipt instance to import into (defaults to direct DB import if not supplied) --config string path to config file --drop drop database before import -h, --help help for import --skip-existing only import new data --stdin import from STDIN -t, --token string client token used to authenticate access to remote Flipt instance when importing. ``` ### More Info See the [import/export](/v1/operations/import-export) section of the documentation for more information. # migrate Source: https://docs.flipt.io/v1/cli/commands/migrate Run pending database migrations ``` flipt migrate [flags] ``` ### Options ``` --config string path to config file --database string string to denote which database type to migrate (default "default") -h, --help help for migrate ``` ### More Info See the [migrations](/v1/configuration/storage#migrations) section of the documentation for more information. # validate Source: https://docs.flipt.io/v1/cli/commands/validate Validate Flipt flag state (.yaml, .yml) files ``` flipt validate [flags] ``` ### Options ``` -e, --extra-schema string path to extra schema constraints -F, --format string output format: json, text (default "text") -h, --help help for validate --issue-exit-code int exit code to use when issues are found (default 1) -d, --work-dir set the working directory ``` ### Behavior This command validates Flipt's declarative feature configuration files. It looks for feature flag definitions in the same way as Flipt's declarative backends. Checkout the documentation on [locating flag state](/v1/configuration/storage#locating-flag-state) to learn more about this process. ### Extra Schema The flag `--extra-schema` (short form `-e`) can be used to pass additional constraints via a [CUE](https://cuelang.org/) schema file. This file will be unified with the base schema used within `flipt validate` to ensure the format of Flipt files. You can find the base schema [here](https://github.com/flipt-io/flipt/blob/main/internal/cue/flipt.cue). As an example, take the following flipt `features.yaml` file: ```yaml theme={null} flags: - key: someFeature name: Some Feature ``` Running validate will succeed when provided with a path to this file. ```console theme={null} ➜ flipt validate ➜ echo $? 0 ``` By default, the flag `description` field is not required. However, imagine that you want to ensure this field is always provided with a non-empty string. You can do this via the `--extra-schema` flag and a CUE definition. In this instance we're going to create a CUE file named `extended.cue`. Within this file we will add a constraint to the `#Flag` CUE definition, which ensures our desired behavior. ```cue theme={null} #Flag: { description: =~"^.+$" } ``` This definition ensures that description is both supplied and that the value matches the regular expression. The regular expression in this example ensures a string with a length of at least 1 character. Now when invoking the validate sub-command, we pass the path to this extra CUE definition: ```console theme={null} ➜ flipt validate -e extended.cue Validation failed! - Message : flags.0.description: incomplete value =~"^.+$" File : features.yaml Line : 2 ``` Here we see that our additional constraint on description is being validated and described in the output. ### More Info See the [flag state](/v1/configuration/storage#flag-state-configuration) section of the documentation for more information. # Overview Source: https://docs.flipt.io/v1/cli/overview Overview of the Flipt CLI The `flipt` CLI is a command line interface for managing Flipt. It's useful for configuring your Flipt instance, running migrations, validating `.features.yml` files, and more. You can use it in various environments, including your local machine, CI/CD, and more. ### Installation ```console Homebrew theme={null} brew install flipt-io/brew/flipt ``` ```console Binary theme={null} curl -fsSL https://get.flipt.io/install | sh ``` ### Usage ``` flipt [flags] ``` `flipt` with no arguments will run the Flipt server. It will look for a configuration file as described in the [configuration](/v1/configuration/overview#configuration-file) documentation. You can specify a different configuration file with the `--config` flag. ### Examples ``` $ flipt $ flipt config init $ flipt --config /path/to/config.yml migrate ``` ### Options ``` --config string path to config file -h, --help help for flipt ``` # Concepts Source: https://docs.flipt.io/v1/concepts This document describes the basic concepts of Flipt. More information on how to use Flipt is noted in the [Getting Started](/v1/introduction) documentation. ## Namespaces Namespaces are the recommended way to organize all resources such as Flags, Segments, Rules, etc within Flipt. Namespaces allow you to separate all data within Flipt for use in different environments such as Development, Staging, Production, etc. Namespaces Settings Another common use-case of Namespaces is to separate Flipt data by internal team or organization. All data created in one namespace is only accessible within that namespace, meaning flags/segments/etc must be created in each namespace in which they're to be used. If a namespace isn't selected then the 'Default' namespace is used. Namespaces Settings Namespaces can be managed within the `Settings` section of the Flipt UI: Namespaces Settings ## Flags Flags are the basic unit in the Flipt ecosystem. Flags represent experiments or features that you want to be able to enable or disable for users of your applications. For example, a flag named `new-contact-page` could be used to determine whether or not a given user sees the latest version of a 'Contact Us' page that you are working on when they visit your homepage. Flags can be used as simple on/off toggles or with variants and rules to support more elaborate use cases. Flags Example There are two types of flags: * **Variant** which allows you to return a single variant for a given flag given a set of evaluation rules. This is the default flag type. * **Boolean** which allows you to return a boolean value for a given flag. ### Variant Flags Variants are options for flags. For example, if you have a flag `colorscheme` that determines which main colors your users see when they login to your application, then possible variants could include `dark`, `light` or `auto`. #### Variant Attachments Variants can also have JSON attachments. This allows you to store additional data about a variant that can be used in your application at runtime. Variant attachments are not used for evaluation, they are only used for runtime configuration. The attachment size is limited to **1MB**. Variant Flags Example ### Boolean Flags Boolean flags are a special type of flag that allow you to return a boolean value for a given flag. You can use boolean flags to determine if a feature is enabled or disabled for a given entity (user, device, etc) by returning `true` or `false` respectively. Boolean flags work well for simple use cases where you don't need to return multiple variants. Boolean flags can be configured with [rollout](#rollouts) rules to determine which entities receive `true` or `false` for a given flag. Boolean Flags Example ### Metadata All flags can have metadata associated with them. This metadata is stored in the Flipt backend and can be used to add additional information about a flag. Metadata is stored as a JSON object and is not used for evaluation. You can retrieve flag metadata using the [Get Flag](/v1/reference/flags/get-flag) API. In the Flipt UI, metadata is displayed in the flag details section. The UI allows you to add, edit, and delete metadata and provides a more user-friendly interface for managing metadata by specifying key-value pairs and their data types. Currently, the following data types are supported: * Primitive types: `String`, `Number`, `Boolean` * Complex types: `Array`, `Object` Flag Metadata Example ## Segments Segments allow you to split your user base or audience up into predefined slices. This is a powerful feature that enables targeting groups to determine if a flag or variant applies to them. An example segment could be `new-users`. Segments Example Segments are global within a Flipt namespace. ### Match Types When configuring a segment you can choose a `Match Type` of either: * **Match All** which requires ALL constraints to match for the segment to apply for evaluation. * **Match Any** which requires AT LEAST ONE constraint to match for the segment to apply for evaluation. ### Constraints Constraints allow you to determine which segment a given entity is a part of. For example, for a user to fall into the above `new-users` segment, you may want to check their `finished_onboarding` property. Constraints Example All constraints have a *property*, *type*, *operator* and optionally a *value*. #### Constraint Types Currently 5 constraint types are available: * **String** which allows you to check a string property of an entity * **Number** which allows you to check a number property of an entity (integer or float) * **Boolean** which allows you to check a boolean property of an entity such as `true` or `false` * **DateTime** which allows you to check a date or datetime property of an entity such as `2020-01-01` or `2020-01-01T00:00:00Z` ([RFC3339](https://datatracker.ietf.org/doc/html/rfc3339)) * **Entity** which allows you to check the `entityId` that was sent in the body of the `Variant` or `Boolean` request Constraint Types The constraint value is represented as a string in transit and in the database, however it's coerced into the appropriate type for evaluation. ## Rules Rules allow you to tie your flags, variants and segments together by specifying which segments are targeted by which variants. Rules can be as simple as `IF IN segment THEN RETURN variant_a` or they can be richer by using distribution logic to roll out features on a percentage basis. Continuing our previous example, we may want to return the flag variant `dark` for all entities in the `new-users` segment. This would be configured like so: Rules Example Rules are evaluated in order per their rank from 1-N. The first rule that matches wins. Once created, rules can be re-ordered to change how they're evaluated. ### Default Rule Default Rules are available since v1.47.0 of Flipt. If no rules match for a given flag, the default rule value is returned. This value is optional and can be set to any variant that exists for the flag. Default Rule Example ### Distributions Distributions allow you to return different variants of your flag to different percentages of your user base based on your rules. Let's say that instead of always showing the `dark` variant to your `new-users` segment, you want to show `dark` to **10%** of `new-users`, `light` to **30%**, and `auto` to the remaining **60%**. You would accomplish this using rules with distributions: Distributions Example The ability to manage distributions, as illustrated in the image above, is an extremely powerful feature of Flipt that can help you seamlessly deploy new features of your applications to your users while also limiting the reach of potential bugs. ## Rollouts Rollouts allow you to potentially change the result of a boolean flag value at request time. Rollouts are a sequence of conditions which when one is matched for a request context, overrides the default rollout property. Current rollout types include: * **Threshold** which allows you to return `true` or `false` for a given percentage of entities. * **Segments Match** which allows you to return `true` or `false` if an entity matches a given segment. Rollouts Example Rollouts work similar to [Rules](#rules) in that they're evaluated in order per their rank from 1-N. The first rollout that matches wins. Once created, rollouts can be re-ordered to change how they're evaluated. ### Default Rollout If no rollouts match for a given flag, the default rollout value is returned. This value is the same as the 'enabled' value for the flag for backward compatibility reasons. ## Evaluation Evaluation is the process of sending requests to the Flipt server to process and determine if that request matches any of your segments and if so which variant or boolean value to return depending on flag type. In the above example involving colors, evaluation is where you send information about your current user to determine if they're a `new-user`, and which color (`dark`, `auto`, or `light`) that they should see for their main color scheme. Evaluation Example ### Entities Evaluation works by uniquely identifying each *thing* that you want to compare against your segments and flags. We call this an `entity` in the Flipt ecosystem. More often than not this will be a user, but we didn't want to make any assumptions about how your application works, which is why `entity` was chosen. **Entity** What you want to test against in your application For Flipt to successfully determine which *bucket* your entities fall into, it must have a way to uniquely identify them. This is the `entityId` and it's a simple string. It's up to you what that `entityId` is. It could be a: * email address * userID * IP address * physical address * etc Anything that's unique enough for your application and its requirements. ### Context The final piece of the puzzle is context. Context allows Flipt to determine which segment your entity falls into by comparing it to all the possible constraints that you defined. **Context** Metadata associated with your entity used to determine which if any segments that entity is a member of Examples of context include: ``` - isAdmin - favoriteColor - country - freeUser ``` Think of these as pieces of information that are usually not unique, but that can be used to split your entities into your segments. You can include as much or as little context for each entity as you want, however, the more context that you provide, the more likely it's that an entity will match one of your segments. In Flipt, `context` is a simple map of key-value pairs where the key is the property to match against all constraints, and the value is what's compared. ### Bucketing Bucketing is the process of determining which variant to return for a given evaluation request. Flipt uses a hashing algorithm to determine which variant to return for a given `flagKey`, `entityID` and `context`. This is what allows Flipt to return the same variant every time (also sometimes referred to as **stickiness**). Flipt never persists any information about your entities or context or which variant was returned for a given evaluation request. This is all done at runtime and is ephemeral. This allows Flipt to be used in a wide variety of applications and use cases without having to worry about inadvertently storing personally identifiable information (PII) or other privacy concerns. **Let's look at how it works:** 1. Flipt takes the `flagKey` and `entityID` and concatenates them together to form a string that looks like `flagKey:entityID`. This is called the key. 2. Flipt then takes this new key and uses a hashing algorithm ([CRC-32 ChecksumIEEE](https://pkg.go.dev/hash/crc32#ChecksumIEEE)) to create a 32-bit integer called the hash. 3. Flipt then creates a set of buckets from 0‐999 (1000 total buckets), mapping them with a sorted set of the [distributions](#distributions) for the flag. 4. Finally, Flipt takes the hash and uses the modulo operator to determine which bucket the hashed value falls into. The distribution that maps to that bucket is then returned. **Consider an example:** Imagine that you have a flag with two [distributions](#distributions) `A` and `B`. If `distribution A` has a 30% 'rollout', then it would 'take up' buckets 0‐299 (out of the 1000 buckets). `Distribution B` would take up the remaining buckets 300‐999. The `flagKey/entityID` hashed value is a 32bit integer on which Flipt performs a [modulo](https://en.wikipedia.org/wiki/Modulo) operation (% 1000) so that it 's guaranteed to return a number between 0‐999. The result of the modulo operation is then used to determine which distribution to return via the bucket mapping. If the result is between 0‐299, then `distribution A` is returned, otherwise `distribution B` is returned. # Analytics Source: https://docs.flipt.io/v1/configuration/analytics This document describes various configuration mechanisms for controlling analytics for Flipt. ## Analytics Flipt includes functionality for reporting analytical data to a configurable storage engine. Currently, Flipt has support for collecting data into the following storage engines: * [ClickHouse](https://clickhouse.com/) * [Prometheus](https://prometheus.io/) The data that gets collected currently includes: * Flag Evaluation Count Once a storage engine is configured, these analytics are viewable in the UI allowing users to visualize up to 24 hours of data for each metric. UI For Analytics The image above shows the past 30 minutes of the flag `flag1` evaluation counts. ### Origin Analytics are currently only collected as they pass through the evaluation server. This means that analytics will be captured if you are using the REST or GRPC APIs via one of our [Server SDKs](/v1/integration/server/rest) or [GRPC SDKs](/v1/integration/server/grpc) for evaluations. We have plans to support collecting analytics for [Client-Side](/v1/integration/client) evaluations in the future. ## ClickHouse You can use a self-hosted ClickHouse instance or a [managed instance](https://clickhouse.com/cloud/) to store your analytics data. We highly **recommend** using a separate database for analytics produced by Flipt. This ensures that Flipt analytic data can be logically isolated from the rest of your Clickhouse data. The analytics database must be created before Flipt will be able to write analytical data and run any migrations. See our [migration](/v1/configuration/storage#migrations) section for more info. To create a database for Flipt analytics, you can use the following SQL: ```sql theme={null} CREATE DATABASE IF NOT EXISTS flipt_analytics; ``` See the [ClickHouse documentation](https://clickhouse.com/docs) for more information on how to get started with ClickHouse. ### Configuration To configure Flipt to use ClickHouse for analytics, you will need to add the following configuration to your `config.yml` file or environment variables: ```bash theme={null} FLIPT_ANALYTICS_STORAGE_CLICKHOUSE_ENABLED=true FLIPT_ANALYTICS_STORAGE_CLICKHOUSE_URL=clickhouse://clickhouse:9000/flipt_analytics ``` ```yaml theme={null} analytics: storage: clickhouse: enabled: true url: clickhouse://clickhouse:9000/flipt_analytics ``` ## Prometheus You can use any [Prometheus](https://prometheus.io/docs/introduction/overview/) server to store your analytics data. ### Configuration To configure Flipt to use Prometheus for analytics, you will need to add the following configuration to your `config.yml` file or environment variables: ```bash theme={null} FLIPT_ANALYTICS_STORAGE_PROMETHEUS_ENABLED=true FLIPT_ANALYTICS_STORAGE_PROMETHEUS_URL=http://prometheus:9090 ``` ```yaml theme={null} analytics: storage: prometheus: enabled: true url: http://prometheus:9090 ``` ### Custom Headers You can also add custom headers to the Prometheus requests by setting the `analytics.storage.prometheus.headers` configuration property. This can be useful if you are using a proxy or need to add additional authentication headers. ```yaml theme={null} analytics: storage: prometheus: headers: "Authorization": "Bearer " ``` # Overview Source: https://docs.flipt.io/v1/configuration/auditing/overview This document describes Flipt's auditing capabilities. Audit Events are pieces of data that describe a particular thing that has happened in a system. Flipt provides the functionality of processing and batching these audit events and an abstraction for sending these audit events to a sink. ## Events Flipt supports sending audit events to configured sinks. Audit events have the following structure: ```json theme={null} { "version": "0.2", "type": "flag", "action": "created", "status": "success", "metadata": { "actor": { "authentication": "none", "ip": "172.17.0.1" } }, "payload": { "description": "flipt flag", "enabled": true, "key": "flipt", "name": "flipt", "namespace_key": "default" }, "timestamp": "1970-01-01T00:00:00Z" } ``` * `version` : the version of the audit event structure. * `type` : the type of the entity being acted upon (flag, variant, constraint, etc.) * `action` : the action taken upon the entity (created, deleted, updated, etc.) * `metadata` : extra information related to the audit event as a whole. The `actor` field will always be present containing some identity information of the source which initiated the audit event * `payload` : the actual payload used to interact with the `Flipt` server for certain auditable events * `timestamp`: the time the event was created * `status`: the status of the event (success, denied, etc.) Currently, we support the following sinks for audit events: * [Log](/v1/configuration/overview#audit-events-log): the audit events are output as either `json` or `console` depending on configuration. The default output is to STDOUT, however, the log sink can also be output to a file. * [Webhook](/v1/configuration/overview#audit-events-webhook): the audit events are sent to a URL of your choice. * [Kafka](/v1/configuration/overview#audit-events-kafka): the audit events are sent to a Kafka topic of your choice. You can find [examples](https://github.com/flipt-io/flipt/tree/main/examples/audit) in the main GitHub repository on how to enable audit events and how to tune configuration for it. ## Event Filtering You can specify configuration for which events you would like to receive on your audit sink. An always up to date list of events supported is available in our [GitHub repository](https://github.com/flipt-io/flipt/blob/main/internal/server/audit/README.md). Events are specified in the format of `noun:verb`. You can also specify a wild card for either the noun or the verb. For instance `*:created` corresponds to all `created` events for every entity. Furthermore, `flag:*` corresponds to all `flag` events, and `*:*` corresponds to every single event. Examples of configuring events include: ``` flag:created namespace:created flag:* rollout:deleted rule:deleted *:updated ``` ## Authentication / Authorization If [authentication](/v1/authentication) is enabled, the actor field will contain the identity information of the source which initiated the audit event. This information may contain the user's email, IP address, and other relevant information. If [authorization](/v1/authorization) is enabled, the audit event will contain the result of the authorization check in the `status` field. The status field will be set to `success` if the authorization check passed, and `denied` if the check failed. This information can be used to determine if an unauthorized user attempted to perform an action. # Webhooks Source: https://docs.flipt.io/v1/configuration/auditing/webhooks This document describes Flipt's webhook support. You can opt to receive audit events as an HTTP POST to a configured webhook. Below is an example HTTP POST request made to a webhook URL: ```console theme={null} POST / HTTP/1.1 Content-Length: 275 Accept-Encoding: gzip Content-Type: application/json X-Forwarded-For: 136.54.97.144 X-Forwarded-Proto: https { "version": "0.1", "type": "flag", "action": "updated", "metadata": { "actor": { "authentication": "none", "ip": "127.0.0.1" } }, "payload": { "description": "", "enabled": true, "key": "maintenance-mode", "name": "Maintenance Mode", "namespace_key": "default" }, "timestamp": "2023-09-13T13:05:18-04:00" } ``` ## Automatic Retries If the webhook server returns a non-200 response, Flipt will retry sending the request using an exponential backoff strategy until a maximum elapsed duration. The default maximum elapsed duration is 15 seconds. You can configure the maximum duration using the following configuration: ```yaml theme={null} audit: sinks: webhook: max_backoff_duration: 15s ``` See the [Audit Events - Webhook](/v1/configuration/overview#audit-events-webhook) section of the configuration documentation for more details. ## Security You may provide a signing secret for requests to your webhook. If you specify a signing secret, you will receive a request with the `X-Flipt-Webhook-Signature` header populated. This value can be set in the [Audit Events - Webhook](/v1/configuration/overview#audit-events-webhook) section of the Flipt server configuration. The value in the `X-Flipt-Webhook-Signature` header is the request body HMAC SHA256 signed with the signing secret you specified. On the webhook server, you can validate the signature by using the same signing secret. It's *strongly recommended* that you do this to prevent requests to your webhook server that are from invalid origins. ## Templates You can specify a template for the body of an Audit Event Webhook request. This allows you to customize the body of the request to your webhook server. A sample configuration can look something like this: ```yaml theme={null} audit: sinks: webhook: enabled: true templates: - url: https://example.com headers: Content-Type: application/json Authorization: Bearer body: | { "type": "{{ .Type }}", "action": "{{ .Action }}" "payload": {{ toJson .Payload }} } ``` The Go template contains a `toJson` utility function that will transform an input into JSON if it fits the structure. This configuration tells Flipt to send a `POST` request when events need to be emitted to the URL `https://example.com` with the HTTP headers, `Content-Type` and `Authorization`, and the body which is a [Go template](https://pkg.go.dev/text/template) that will be executed when an event comes in. The event structure looks like this: ```go theme={null} type Event struct { Version string `json:"version"` Type Type `json:"type"` Action Action `json:"action"` Metadata Metadata `json:"metadata"` Payload interface{} `json:"payload"` Timestamp string `json:"timestamp"` } ``` Any of the values that are [exposed](https://github.com/flipt-io/flipt/blob/v1.28.0/internal/server/audit/audit.go#L51-L61) by Flipt are available for inclusion in your HTTP body template. ### Example: Slack Below is an example of a Slack webhook integration that uses the templating feature to send a Slack message when a flag is updated. ````yaml theme={null} audit: sinks: webhook: enabled: true templates: - url: "https://hooks.slack.com/services/xxxxx" headers: Content-Type: "application/json" body: | { "text": "Flipt Event: {{ .Type }}/{{ .Action }}\n\n```{{ .Payload }}```" } ```` The above configuration will send a Slack message that looks like this: Slack Message You can find more information about Slack webhooks [here](https://api.slack.com/messaging/webhooks). You can also use the [Slack Block Kit Builder](https://app.slack.com/block-kit-builder) to build more complex messages. # Authentication Source: https://docs.flipt.io/v1/configuration/authentication This document describes how to configure Flipt's authentication mechanisms. Once authentication has been set to `required: true` all API routes will require a client token to be present. The UI will require a session-compatible authentication method (e.g. [OIDC](#method-oidc)) to be enabled. Flipt supports the ability to secure its core API routes by setting the `required` field to `true` on the `authentication` configuration object. ```yaml config.yaml theme={null} authentication: required: true ``` When authentication is set to `required`, the API will ensure valid credentials are present on all API requests. See the [Authentication: Overview](/v1/authentication/overview) documentation for more details on Flipt's API authentication handling. ## Exclusions Exclusions allow you to disable authentication for sections of the API. The Flipt API is made up of several top-level API sections, each with its own unique prefix. For example: * `/api/v1` is the core feature flag state management section * `/evaluate/v1` is the application facing flag state evaluation API Several of these API sections can be optionally omitted from requiring authentication. A common use case is to allow the evaluation API to be publicly accessible while still requiring authenticated users to manage feature-flag configuration and state. By default, when authentication is configured as `required: true`, the effective configuration for the exclusions looks like this: ```yaml config.yaml theme={null} authentication: required: true exclude: management: false evaluation: false ``` This means every part of the Flipt API is required for authentication. However, taking the example from before, we could skip authentication for the evaluation section of the Flipt API like so: ```yaml config.yaml theme={null} authentication: required: true exclude: evaluation: true ``` ## Session This section contains common properties for establishing browser sessions via a "session compatible" authentication method. Session-compatible methods enable support for login in the UI. The methods below state whether or not they're session compatible (e.g. [OIDC](#method-oidc) is session compatible). In order to establish a browser session over HTTP (via a `Cookie` header) some configuration is required. ```yaml config.yaml theme={null} authentication: required: true session: domain: "flipt.yourorg.com" secure: true csrf: key: "some_secret_string" ``` When a "session compatible" authentication method is enabled the `domain` property is **required**. It should be configured with the public domain your Flipt instance is hosted on. The other properties aren't required to be explicitly configured. To best secure your instance of Flipt, we advise that you run Flipt with `secure: true`. This will require you to expose Flipt over HTTPS. Additionally, we advise that you configure a `csrf.key` with a 32 or 64-byte random string of data. ``` openssl rand -base64 64 ``` ## Methods Each key within the `methods` section is a particular authentication method. These methods are disabled (`enabled: false`) by default. Enabling and configuring a method allows for different ways to establish client token credentials within Flipt. ### Static Token The `token` method provides the ability to create client tokens statically, with optional expiry constraints. ```yaml config.yaml theme={null} authentication: required: true methods: token: enabled: true bootstrap: expiration: 24h ``` Once enabled, static tokens can be created via the [CreateToken](/v1/reference/authentication/create-token) operation in the API. Further explanation for using this method can be found in the [Authentication: Static Token](/v1/authentication/methods#static-token) documentation. ### OIDC The `OIDC` method is a `session compatible` authentication method. Read our [Login with Google](/v1/guides/operation/authentication/login-with-google) guide for a more in-depth walk-through setting up an OIDC provider. The `oidc` method provides the ability to establish client tokens via OAuth 2.0 with OIDC flow. Once enabled and configured, the UI will automatically leverage it and present any configured providers as login options. ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true email_matches: - ^.*@flipt.io$ providers: some_provider: # insert your provider name issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" scopes: - email - profile ``` Multiple providers can be configured simultaneously. Each provider will result in a login option being presented in the UI, along with a configured endpoint to support the provider flow. "OIDC Login" Flipt has been tested with each of the following providers: * [Google](https://developers.google.com/identity/openid-connect/openid-connect) * [Auth0](https://auth0.com/docs/get-started/applications/application-settings) * [GitLab](https://docs.gitlab.com/ee/integration/openid_connect_provider.html) * [Dex](https://dexidp.io/docs/openid-connect/) * [Okta](https://developer.okta.com/docs/concepts/oauth-openid/#oauth-2-0) * [AzureAD](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc) * [Keycloak](https://www.keycloak.org/docs/latest/server_admin/index.html#_identity_broker_oidc) Though the intention is that it should work with all OIDC providers, these are just the handful the Flipt team has validated. Following any of the links above should take you to the relevant documentation for each of these providers' OIDC client setups. You can use the credentials and client configuration obtained using those steps as configuration for your Flipt instance. #### Callback URL When configuring your OIDC provider, you will need to provide a callback URL for the provider to redirect back to Flipt after a successful login. The callback URL will be in the form of `https://your.flipt.instance.url.com/auth/v1/method/oidc/{provider}/callback`. You can find the callback URL for each provider that you configure in your Flipt instance by querying the API. ```bash theme={null} curl --request GET \ --url https://your.flipt.instance.url.com/auth/v1/method \ --header 'Accept: application/json' ``` ```json theme={null} { "methods": [ { "method": "METHOD_TOKEN", "enabled": true, "sessionCompatible": false, "metadata": null }, { "method": "METHOD_OIDC", "enabled": true, "sessionCompatible": true, "metadata": { "providers": { "google": { "authorize_url": "/auth/v1/method/oidc/google/authorize", "callback_url": "/auth/v1/method/oidc/google/callback" } } } } ] } ``` #### Email Matches Flipt operators may wish to lock down access to the Flipt API and UI to a specific group of users within their organization behind OIDC. Since OIDC has the ability to retrieve email addresses, Flipt also provides a configuration option of using `email_matches` which are [regular expressions](https://github.com/google/re2/wiki/Syntax) that can be used to match against the OIDC email. You must request the `email` scope from your OIDC provider in order for this feature to work. You can see an example of that above in the [sample configuration](#method-oidc). #### PKCE A good amount of OIDC providers support the PKCE (Proof Key for Code Exchange) flow and the implicit OAuth flow. Flipt allows for a configuration to enable PKCE for all the legs of the OIDC authentication flow. To enable this, you must set the [`use_pkce`](/v1/configuration/overview#authentication-methods-oidc) property to `true` for each provider you would like to leverage PKCE with. #### Example: OIDC With Google Checkout our [Login with Google](/v1/guides/operation/authentication/login-with-google) guide for an in-depth look into configuring Google as an OIDC provider. Given we're running our instance of Flipt on the public internet at `https://flipt.myorg.com`. Using Google as an example and the documentation linked above, we obtained the following credentials for a Google OAuth client: ```yaml theme={null} client_id: "CyJcdvQMadOjSEx7ArArom0ytrbIHWd2Fb3N59oh8NQ=" client_secret: "WGgJmfQqN7cf17dFyZKXDL5S445/qhp+hfDAC0Mnl7oBrxgdAgiMyuwCkPiwfgQy" ``` We could create a provider definition in our configuration like so: ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true providers: google: issuer_url: "https://accounts.google.com" client_id: "CyJcdvQMadOjSEx7ArArom0ytrbIHWd2Fb3N59oh8NQ=" client_secret: "WGgJmfQqN7cf17dFyZKXDL5S445/qhp+hfDAC0Mnl7oBrxgdAgiMyuwCkPiwfgQy" redirect_address: "https://flipt.myorg.com" scopes: - email - profile ``` The redirect URL for this provider would be `https://flipt.myorg.com/auth/v1/method/oidc/google/callback`. Additional `scopes` such as `profile` aren't 100% necessary, however, adding them will result in Flipt being able to identify more details about your users such as personalized greeting messages and user profile pictures in the UI. Once this configuration has been enabled a `Login with Google` option will be presented in the UI. Clicking this button will navigate the user to a Google consent screen. Once the user has authenticated with Google, they will be redirected to the address defined in the `redirect_address` section of the provider configuration. Google's consent screen can be configured to only accept accounts that are within your Google Workspace organization. Other providers have similar mechanisms for attenuating who can leverage this authentication flow. ### GitHub The `GitHub` method is a `session compatible` authentication method. Read our [Login with Github](/v1/guides/operation/authentication/login-with-github) guide for a more in-depth walk-through. The `github` method provides the ability to establish client tokens via OAuth 2.0 with GitHub as the identity provider. Once enabled and configured, the UI will automatically leverage it and present a "Login with GitHub" button. ```yaml config.yaml theme={null} authentication: required: true methods: github: enabled: true client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" scopes: - user:email ``` "GitHub Login" #### Allowed Organizations The GitHub authentication method supports the ability to restrict access to a set of GitHub organizations. This is important if you want to limit access to Flipt to only members of a specific organization as opposed to all GitHub users. To enable this feature, set the `github.allowed_organizations` configuration value to a list of GitHub organizations. For example: ```yaml config.yaml theme={null} authentication: required: true methods: github: enabled: true scopes: - read:org allowed_organizations: - my-org - my-other-org ``` The `read:org` scope is required to retrieve the list of organizations that the user is a member of. #### Allowed Teams The GitHub authentication method also supports the ability to restrict access to a set of GitHub teams. This is important if you want to limit access to Flipt to only members of a specific team within an organization as opposed to all members of the organization. To enable this feature, set the `github.allowed_teams` configuration value to a list of GitHub teams within existing allowed organizations. For example: ```yaml config.yaml theme={null} authentication: required: true methods: github: enabled: true scopes: - read:org allowed_organizations: - my-org - my-other-org allowed_teams: my-org: - my-team my-other-org: - my-other-team ``` The organizations to check for team membership must be included in the `allowed_organizations` list. ### Kubernetes The `kubernetes` method provides the ability to exchange Kubernetes service account tokens for client tokens. ```yaml config.yaml theme={null} authentication: required: true methods: kubernetes: enabled: true discovery_url: https://kubernetes.default.svc.cluster.local ca_path: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt service_account_token_path: /var/run/secrets/kubernetes.io/serviceaccount/token ``` Once enabled, client tokens can be retrieved by sending a Kubernetes pod's service account token to the `VerifyServiceAccount` operation in the API. Further explanation for using this method can be found in the [Authentication: Kubernetes](/v1/authentication/methods#kubernetes) documentation. #### Troubleshooting **verifying service account: failed to verify signature: fetching keys oidc** In some managed Kubernetes cluster environments, the default cluster OIDC provider is replaced with the platform's managed alternative. For example, EKS clusters leverage this so that they can issue service account tokens which can assume the capabilities of AWS IAM roles. In this situation, the default OIDC discovery URL isn't appropriate for fetching key material from. Instead, you should locate your clusters OIDC URL and use that instead. Your cluster's OIDC URL will vary between Kubernetes providers. For example, here is some documentation which should help for EKS: [EKS troubleshoot OIDC and IRSA](https://repost.aws/knowledge-center/eks-troubleshoot-oidc-and-irsa). It's also important to note that custom OIDC providers likely will use HTTPS which has been signed with certificates not authorized by the cluster TLS certificate authority. In this situation, you can override the `kubernetes` auth providers `ca_path` field with relevant key material. The `flipt` distributed Docker image has valid and trusted certificates in `/etc/ssl/certs/ca-certificates.crt`, which can be appropriate if your OIDC provider has certificates granted by a valid public certificate authority. ```yaml example-config-for-eks.yaml theme={null} authentication: required: true methods: kubernetes: enabled: true discovery_url: https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E # note: yours will be different ca_path: /etc/ssl/certs/ca-certificates.crt # this can be enough if your OIDC provider TLS certificates have been signed by a public certificate authority ``` See [this issue](https://github.com/flipt-io/flipt/issues/2942) for more context. ### JSON Web Token The `jwt` method provides the ability to authenticate with Flipt using an externally issued JSON Web Token. This method is useful for integrating with other authentication systems that can issue JWTs (e.g. [Auth0](https://auth0.com/docs/tokens/json-web-tokens)) or by generating your own signed JWTs on the fly. Flipt supports asymmetrically signed JWTs using the following algorithms: * RS256 * RS512 * ES256 * ES512 * EdDSA This means that the JWT must be signed using a private key leveraging one of these algorithms and Flipt must be configured with the corresponding public key. Flipt supports key verification using the following methods: * [JWKS](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) URL (JSON Web Key Set URL) * PEM (Privacy Enhanced Mail) encoded public key These methods are mutually exclusive, meaning that only one of them can be configured at a time. #### JWKS URL The `jwks_url` configuration value is a URL that points to a JWKS (JSON Web Key Set) endpoint. This endpoint must return a JSON object that contains a list of public keys that can be used to verify the JWT signature. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true jwks_url: https://auth0.com/.well-known/jwks.json ``` #### PEM Encoded Public Key The `public_key_file` configuration value is the path to a PEM encoded public key that can be used to verify the JWT signature. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true public_key_file: /path/to/public_key.pem ``` #### Claim Validation Flipt supports validating the following claims: * `iss` (issuer) * `aud` (audience) * `sub` (subject) * `exp` (expiration time) * `nbf` (not before) * `iat` (issued at) The `exp`, `nbf`, and `iat` claims are validated by default. To enable claim validation, configure the values in the `validate_claims` configuration option to the expected values. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true validate_claims: issuer: https://auth0.com/ subject: user@domain.com audiences: https://flipt.io/, https://flipt.com/ # at least one audience must match ``` ### Common Properties: Cleanup Each authentication method contains a nested `cleanup` configuration object. This object configures the periodic deletion of *expired* authentications created with the associated method. ```yaml config.yaml theme={null} authentication: required: true methods: : cleanup: interval: 10m grace_period: 24h ``` The cleanup object currently contains two keys `interval` and `grace_period`. The `interval` is used to configure how frequently a delete *expired* tokens action is performed. Whereas, `grace_period` is used to ensure that *expired* tokens are preserved for at least this configured duration. This allows you to keep authentications around for auditing purposes after expiration. Expired tokens are instances where the `expires_at` timestamp occurs before the current time. The grace period is added onto this timestamp as a predicate when the delete operation is made. Tokens that have expired (`expires_at` is before `now()`) will begin immediately failing authentication when presented as a credential to the API. The `grace_period` is simply for the cleanup process. ## Reverse Proxy You can secure Flipt simply by running it behind a reverse proxy in your own trusted environment. An example of this can be found in [authentication examples](https://github.com/flipt-io/flipt/tree/main/examples/authentication) in the Flipt repository. # Authorization Source: https://docs.flipt.io/v1/configuration/authorization This document describes how to configure Flipt's authorization mechanisms. Once authorization has been set to `required: true` all management API routes will require a valid authentication session as well. The UI will require a session-compatible authentication method (e.g. [OIDC](/v1/authentication/methods#openid-connect)) to be enabled. Flipt supports the ability to secure its core API routes by setting the `required` field to `true` on the `authorization` configuration object. ```yaml config.yaml theme={null} authorization: required: true ``` When authorization is set to `required`, the API will ensure valid credentials are present on all management API requests. See the [Authorization: Overview](/v1/authorization/overview) documentation for more details on Flipt's API authorization handling. ## Backends Flipt uses [Open Policy Agent (OPA)](https://www.openpolicyagent.org/) to enforce authorization policies. OPA is a general-purpose policy engine that can be used to enforce policies across the stack. Flipt supports sourcing policies and external data from various backends. Currently, Flipt supports the following backends: * [Local](#local) * [Bundle](#bundle) * [Object Store](#object) ## Local Flipt supports loading policy and external data from the local filesystem. ### Policies For configuring policies, the files must be valid [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) files. You can specify the path to the policy file in the `policy` object in the `authorization` configuration object. ```yaml theme={null} authorization: required: true backend: local local: policy: path: "policy.rego" ``` The policy **must** have the following package declaration: ```rego policy.rego theme={null} package flipt.authz.v1 ``` You can learn more about policies in our [Authorization: Overview](/v1/authorization/overview#policies) documentation. #### Polling Interval Flipt will poll the policy file for changes at a regular interval. By default, Flipt will poll the policy file every 5 minutes. You can adjust this interval by setting the `poll_interval` field in the `policy` object. ```yaml theme={null} authorization: required: true backend: local local: policy: path: "policy.rego" poll_interval: "1m" ``` ### External Data In addition to policies that can be used to enforce authorization rules, Flipt also provides a way to pass external data to the policy evaluation from the local filesystem. These data objects **must be valid JSON objects**. This can be done by setting the `data` object in the `authorization` configuration object. ```yaml theme={null} authorization: required: true backend: local local: policy: path: "policy.rego" data: path: "data.json" ``` You can learn more about using data with policies in our [Authorization: Overview](/v1/authorization/overview#external-data) documentation. #### Polling Interval Like policies, Flipt will poll data files for changes at a regular interval. By default, Flipt will poll the data file every 30 seconds. You can adjust this interval by setting the `poll_interval` field in the `data` object. ```yaml theme={null} authorization: required: true backend: local local: data: path: "data.json" poll_interval: "1m" ``` ## Bundle Flipt supports loading policy and external data from OPA bundles. Bundles are a way to package policy and data files together as a single unit. You can read more about creating and using OPA bundles in the [OPA documentation](https://www.openpolicyagent.org/docs/latest/management-bundles/). Bundles can be hosted on a remote server and downloaded by Flipt at regular intervals. Some of the services that OPA bundles support out of the box include: * [HTTP](https://www.openpolicyagent.org/docs/latest/management-bundles/#bundle-service-api) * [S3](https://www.openpolicyagent.org/docs/latest/management-bundles/#amazon-s3) * [Azure Blob Storage](https://www.openpolicyagent.org/docs/latest/management-bundles/#azure-blob-storage) * [Google Cloud Storage](https://www.openpolicyagent.org/docs/latest/management-bundles/#google-cloud-storage) * [OCI Registry](https://www.openpolicyagent.org/docs/latest/management-bundles/#oci-registry) Bundle support is enabled by setting the `backend` field to `bundle` in the `authorization` configuration object. The `bundle` backend requires a valid `configuration` object to be set. This configuration definition is the same as the OPA bundle [service configuration](https://www.openpolicyagent.org/docs/latest/configuration/). ```yaml theme={null} authorization: required: true backend: bundle bundle: configuration: | services: - name: acmecorp url: https://example.com/service/v1 credentials: bearer: token: "bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm" bundles: authz: service: acmecorp resource: somedir/bundle.tar.gz polling: min_delay_seconds: 10 max_delay_seconds: 20 ``` ## Object Similar to our [object storage](/v1/configuration/storage#object) support for Flipt flag data, Flipt also supports loading policy and external data from object storage. Technically, this is a subset of the bundle backend, but it is useful for those who want to provide a simplified configuration for loading policy and data from object storage, without the need to configure the bundle service directly. The `object` backend requires a valid `type` to be configured. This is similar to the object storage configuration for Flipt flag data as it also requires valid credentials to access the object storage service. The credentials are read from environment variables at Flipt start time. ```bash theme={null} AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... ``` ```yaml theme={null} authorization: required: true backend: object object: type: s3 s3: region: us-east-1 bucket: flipt_policy_bundles # optional: bucket prefix for locating bundle files prefix: production # optional: for non-AWS hosted S3 endpoint: http://localhost:9009 ``` Currently, Flipt only supports the `s3` object storage type directly. If you require support for other object storage types, please [let us know](https://github.com/flipt-io/flipt/issues/new). Alternatively, as a workaround, you can use the bundle backend to load policy and data from other object storage types. Follow the [OPA bundle documentation](https://www.openpolicyagent.org/docs/latest/management-bundles/) for more information. # Caching Source: https://docs.flipt.io/v1/configuration/caching This document describes how to configure Flipt's caching mechanisms. ## Caching Flipt supports both in-memory cache as well as [Redis](https://redis.io/) to enable faster reads and evaluations. Enabling caching has been shown to speed up read performance by several orders of magnitude if you are using a relational database. Enabling in-memory caching when running more than one instance of Flipt isn't advised as it may lead to unpredictable results. It's recommended to use Redis instead if you are running more than one instance of Flipt. Caching works as follows: * All flag reads and evaluation requests go through the cache * Flag cache entries are purged whenever a write to a flag or its variants occur or the TTL expires * Cache entries are purged after the TTL expires only * A cache miss will fetch the item from the database and add the item to the cache for the next read * A cache hit will simply return the item from the cache, not interacting with the database See the [Cache](/v1/configuration/overview#cache) section for how to configure caching. ### Expiration/Eviction You can also configure an optional duration at which items in the cache are marked as expired. For example, if you set the cache TTL to `5m`, items that have been in the cache for longer than 5 minutes will be marked as expired, meaning the next read for that item will hit the database. Setting an eviction interval (in-memory cache only) will automatically remove expired items from your cache at a defined period. The combination of cache expiration and eviction can help lessen the amount of memory your cache uses, as infrequently accessed items will be removed over time. To tune the expiration and eviction interval of the cache set the following in your configuration: ```yaml theme={null} cache: enabled: true backend: memory ttl: 5m # items older than 5 minutes will be marked as expired memory: eviction_interval: 2m # expired items will be evicted from the cache every 2 minutes ``` ### Redis #### Key Prefix When using Redis as your cache backend, you can configure a prefix that will be added to all Redis cache keys. This is useful when: * Multiple Flipt instances share the same Redis instance * You want to namespace your cache keys to avoid conflicts * You need to identify or manage Flipt's cache keys separately from other applications To configure a key prefix, set the following in your configuration: ```yaml theme={null} cache: enabled: true backend: redis redis: prefix: "flipt" # all cache keys will be prefixed with "flipt:" Note: this is the default value ``` #### Clustering Considerations Flipt supports Redis in both single and cluster modes as of v1.57.0. The default mode is single. To configure Flipt to use Redis in cluster mode, set the following in your configuration: ```yaml theme={null} cache: enabled: true backend: redis redis: url: "{address}:{port}" # the address and port of your Redis cluster mode: cluster ``` **Key Hash Slots** In Redis Cluster, keys that need to be part of the same operation (like transactions) must be in the same hash slot. Redis uses a CRC16 hash of the key modulo 16384 to determine which slot a key belongs to. However, you can influence this behavior using hash tags. **Hash Tags** Hash tags are parts of the key name enclosed in curly braces `{}`. When a key contains a hash tag, Redis will only use the part within the braces to calculate the hash slot. This allows you to ensure related keys are stored in the same slot. For example, if you're using Redis Cluster with Flipt and need to ensure certain related keys are on the same node, you can configure your key prefix to include a hash tag: ```yaml theme={null} cache: enabled: true backend: redis redis: mode: cluster prefix: "{flipt}" # ensures all Flipt cache keys are in the same hash slot ``` For more information about Redis Cluster and key management, see the [Redis Clustering Best Practices With Keys](https://redis.io/blog/redis-clustering-best-practices-with-keys/) documentation. # Experimental Source: https://docs.flipt.io/v1/configuration/experimental This document describes our current experimental features and how to enable them. ## Introduction From time to time, we may introduce new features that are not yet ready for general availability. These features are considered experimental and may change or be removed in future releases. We encourage you to try these features and provide feedback to help us improve them. ## Enabling Experimental Features These features are disabled by default. To enable them, you can set the `experimental.{feature}.enabled` configuration option to `true` in your Flipt [configuration file](/v1/configuration/overview#configuration-file). For example to enable the `foo` experimental feature: ```yaml config.yaml theme={null} experimental: foo: enabled: true ``` You can also enable experimental features using [environment variables](/v1/configuration/overview#environment-variables). For example, to enable the `foo` experimental feature, you can set the `FLIPT_EXPERIMENTAL_FOO_ENABLED` environment variable to `true`. ## Current Experimental Features The following is a list of our current experimental features and a brief description of each. Make sure you have the [latest version](https://github.com/flipt-io/flipt/releases/latest) of the Flipt CLI installed on your local machine. ## Deprecations Once an experimental feature is promoted to a stable feature or is removed, it will move to a deprecated status. Depending on the feature, you may need to take action to migrate to the new stable feature or remove the deprecated feature from your configuration. If an enabled experimental feature has been deprecated, you will see a warning message in the CLI output when you start the Flipt server, such as: ```bash theme={null} Warning: 'experimental.filesystem_storage' has been deprecated and will be removed in a future release. ``` # Observability Source: https://docs.flipt.io/v1/configuration/observability This document describes how to configure Flipt's observability mechanisms including metrics, logging, and tracing. ## Metrics ### Prometheus Flipt exposes [Prometheus](https://prometheus.io/) metrics by default at the `/metrics` HTTP endpoint. To see which metrics are currently supported, point your browser to `FLIPT_HOST/metrics` (ex: `localhost:8080/metrics`). You should see a bunch of metrics being recorded such as: ```yaml theme={null} flipt_cache_hit_total{cache="memory",type="flag"} 1 flipt_cache_miss_total{cache="memory",type="flag"} 1 --- go_gc_duration_seconds{quantile="0"} 8.641e-06 go_gc_duration_seconds{quantile="0.25"} 2.499e-05 go_gc_duration_seconds{quantile="0.5"} 3.5359e-05 go_gc_duration_seconds{quantile="0.75"} 6.6594e-05 go_gc_duration_seconds{quantile="1"} 0.00026651 go_gc_duration_seconds_sum 0.000402094 go_gc_duration_seconds_count 5 ``` An [example](https://github.com/flipt-io/flipt/tree/main/examples/metrics) showing how to set up Flipt with Prometheus can be found in the GitHub repository. You can disable the Prometheus metrics collection by setting the `metrics.enabled` configuration option to `false`. ### OTLP Flipt supports sending metrics to an [OTLP](https://opentelemetry.io/docs/concepts/data-collection/) collector. OTLP supports additional configuration such as specifying the protocol to use (gRPC or HTTP) as well as providing custom headers to send with the request. Custom headers can be used to provide authentication information to the collector which may be required if you are using a hosted collector such as [NewRelic](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/), [DataDog](https://docs.datadoghq.com/opentelemetry/otlp_ingest_in_the_agent/?tab=host), or [Honeycomb](https://docs.honeycomb.io/getting-data-in/opentelemetry-overview/#instrumenting-with-opentelemetry). These can be configured via the `metrics.otlp` configuration section. ```yaml theme={null} metrics: enabled: true exporter: "otlp" otlp: endpoint: "https://{your-collector-url}" headers: "X-Some-Header": "some-value" ``` ### Dashboards Grafana Dashboard We provide a set of [Grafana](https://grafana.com/) dashboards that you can use to visualize the metrics collected by Flipt, including both server health and flag evaluation metrics. You can find the dashboards in our [grafana-dashboards](https://github.com/flipt-io/grafana-dashboards) repository. ## Logging Flipt writes logs to STDOUT in two formats: * [JSON](#json) * [Console](#console) The format can be configured via the `log.encoding` configuration option. ```yaml theme={null} log: encoding: json ``` For production deployments, we recommend using the JSON format as it's easier to parse and ingest into log aggregation systems such as Elasticsearch, Splunk, Loki, or Datadog. We've prepared an [example](https://github.com/flipt-io/flipt/tree/main/examples/audit/log) showing how to set up Flipt with Grafana Loki and Promtail to ingest and query logs. ### JSON ```json theme={null} { "L": "INFO", "T": "2024-01-20T21:59:49-05:00", "M": "finished unary call with code OK", "server": "grpc", "grpc.start_time": "2024-01-20T21:59:49-05:00", "system": "grpc", "span.kind": "server", "grpc.service": "flipt.evaluation.EvaluationService", "grpc.method": "Boolean", "peer.address": "127.0.0.1:52635", "grpc.code": "OK", "grpc.time_ms": 0.146 } ``` #### Log Key Descriptions * `L`: Level (log level). Possible values include: debug, info, warn, error, fatal, and panic. * `T`: Timestamp. The timestamp is in ISO 8601 format, widely used for representing date and time. It includes the date, time, and time zone information. For example, "2024-01-20T21:59:49-05:00" represents the date and time in the Eastern Time Zone (UTC-5). * `M`: Message. The message describes the log event. It can include information about the operation, errors encountered, or other relevant details. ### Console ```text theme={null} 2024-01-20T22:04:18-05:00 INFO finished unary call with code OK {"server": "grpc", "grpc.start_time": "2024-01-20T22:04:18-05:00", "system": "grpc", "span.kind": "server", "grpc.service": "flipt.evaluation.EvaluationService", "grpc.method": "Boolean", "peer.address": "127.0.0.1:53714", "grpc.code": "OK", "grpc.time_ms": 0.373} ``` More information about the available configuration options can be found in the [Logging configuration](/v1/configuration/overview#logging) section. ## Tracing Flipt supports distributed tracing via the [OpenTelemetry](https://opentelemetry.io/) project. Currently, we support the following tracing backends: * [Jaeger](https://www.jaegertracing.io/) * [Zipkin](https://zipkin.io/) * [OTLP](https://opentelemetry.io/docs/reference/specification/protocol/) Enable tracing via the values described in the [Tracing configuration](/v1/configuration/overview#tracing) and point Flipt to your configured collector to record spans. [Examples](https://github.com/flipt-io/flipt/tree/main/examples/tracing) showing how to set up Flipt with each of the supported tracing backends can be found in the main GitHub repository . ### OTLP Datadog OTLP OTLP supports additional configuration such as specifying the protocol to use (gRPC or HTTP) as well as providing custom headers to send with the request. Custom headers can be used to provide authentication information to the collector which may be required if you are using a hosted collector such as [NewRelic](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/), [Datadog](https://docs.datadoghq.com/opentelemetry/otlp_ingest_in_the_agent/?tab=host), or [Honeycomb](https://docs.honeycomb.io/getting-data-in/opentelemetry-overview/#instrumenting-with-opentelemetry). These can be configured via the `tracing.otlp` configuration section. ```yaml theme={null} tracing: enabled: true exporter: "otlp" otlp: endpoint: "https://{your-collector-url}" headers: "X-Some-Header": "some-value" ``` #### Environment Variables Flipt supports OTLP specific resource environment variables that are part of the [OTLP spec](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/). The following environment variables are supported: * `OTEL_SERVICE_NAME` - Sets the value of the `service.name` resource attribute (default: `flipt`) * `OTEL_RESOURCE_ATTRIBUTES` - Key-value pairs to be used as [resource attributes](https://opentelemetry.io/docs/specs/semconv/resource/#semantic-attributes-with-dedicated-environment-variable). # Overview Source: https://docs.flipt.io/v1/configuration/overview This document describes how to configure the Flipt server. Flipt server can be configured in two ways. Configuration precedence is as follows: 1. [Environment Variables](#environment-variables) 2. [Configuration File](#configuration-file) ## Configuration File The default way that Flipt is configured is with the use of a configuration file [default.yml](https://github.com/flipt-io/flipt/blob/main/config/default.yml). This file is read when Flipt starts up and configures several important properties for the server. You can generate a default configuration file by running `flipt config init`. The server will check in a few different locations for server configuration (in order): 1. `--config` flag as an override 2. `{{ USER_CONFIG_DIR }}/flipt/config.yml` (the `USER_CONFIG_DIR` value is based on your architecture and specified in the [Go documentation](https://pkg.go.dev/os#UserConfigDir)) 3. `/etc/flipt/config/default.yml` We provide both a [JSON schema](https://raw.githubusercontent.com/flipt-io/flipt/main/config/flipt.schema.json) and a [Cue schema](https://raw.githubusercontent.com/flipt-io/flipt/main/config/flipt.schema.cue) that you can use to validate your configuration file and its properties. You can edit any of these properties to your liking, and on restart, Flipt will pick up the new changes. ### Environment Substitution The configuration file also supports environment variable substitution as of `v1.45.0`. This allows you to use environment variables in your configuration file. For example, you can use the `FLIPT_CUSTOM_DB_URL` environment variable in the configuration file like this: ```yaml theme={null} db: url: ${FLIPT_CUSTOM_DB_URL} ``` This will replace `${FLIPT_CUSTOM_DB_URL}` with the value of the `FLIPT_CUSTOM_DB_URL` environment variable. The format for environment variable substitution is `${ENV_VAR}`. This can be used to provide sensitive information to Flipt without storing it in the configuration file. For example, you can use environment variables to store the database URL, API keys, or other sensitive information without having to conform to the pre-defined Flipt [environment variable format](#environment-variables). ### Remote Configuration Flipt supports fetching configuration from a remote source. This is useful for managing configuration across multiple instances of Flipt. The remote configuration source can be a URL to a configuration file stored in one of the following object storage services: * S3 (e.g.: `s3://bucket-name/path/to/config.yml`) * Azure Blob Storage (e.g.: `azblob://container-name/path/to/config.yml`) * Google Cloud Storage (e.g.: `googlecloud://bucket-name/path/to/config.yml`) To load Flipt configuration from a remote source, replace the `config.yml` file with the URL to the remote configuration file in the `--config` flag when starting Flipt. ```console theme={null} flipt --config s3://bucket-name/path/to/config.yml ``` For authenticating with the object storage service, you can use the following environment variables depending on the service: * `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` * `AZURE_STORAGE_ACCOUNT` and `AZURE_STORAGE_KEY` or `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_CLIENT_SECRET` * `GOOGLE_APPLICATION_CREDENTIALS` These environment variables are used by the underlying object storage client libraries to authenticate with the object storage service and are the same values used in our [object storage configuration](/v1/configuration/storage#object). ## Environment Variables All options in the configuration file can be overridden using environment variables using the syntax: ```yaml theme={null} FLIPT__ ``` Environment variables **MUST** have `FLIPT_` prefix and be in `UPPER_SNAKE_CASE` format. Using environment variables to override defaults is especially helpful when running with Docker as described in the [Docker](/v1/installation/docker) documentation. Keys should be uppercase and `.` should be replaced by `_`. For example, given these configuration settings: ```yaml theme={null} server: grpc_port: 9000 db: url: file:/var/opt/flipt/flipt.db ``` You can override them using: ```console theme={null} export FLIPT_SERVER_GRPC_PORT=9001 export FLIPT_DB_URL="postgres://postgres@localhost:5432/flipt?sslmode=disable" ``` ### Multiple Values Some configuration options can have a list of values. For example, the `cors.allowed_origins` option can have multiple origins. In this case, you can use a space separated list of values for the environment variable override: ```console theme={null} export FLIPT_CORS_ALLOWED_ORIGINS="http://localhost:3000 http://localhost:3001" ``` ## Configuration Parameters | Property | Description | Default | Since | | ----------------------------- | ------------------------------------------------------------- | -------------------- | ------- | | cors.enabled | Enable CORS support | false | v0.7.0 | | cors.allowed\_origins | Sets Access-Control-Allow-Origin header on server | "\*" (all domains) | v0.7.0 | | meta.check\_for\_updates | Enable check for newer versions of Flipt on startup | true | v0.17.0 | | meta.telemetry\_enabled | Enable anonymous telemetry data (see [Telemetry](#telemetry)) | true | v1.8.0 | | meta.state\_directory | Directory on the host to store local state | \$HOME/.config/flipt | v1.8.0 | | diagnostics.profiling.enabled | Enable profiling endpoints for pprof | true | v1.29.0 | ### User Interface | Property | Description | Default | Since | | ----------------- | ---------------------------------------------- | ------- | ------- | | ui.default\_theme | Sets the default UI theme for users | system | v1.27.0 | | ui.topbar.color | Sets the color of the top menu bar (hex value) | | v1.44.0 | ### Logging | Property | Description | Default | Since | | ---------------- | -------------------------------------------------------------------------------- | ------- | ------- | | log.level | Level at which messages are logged (debug, info, warn, error, fatal, panic) | info | | | log.grpc\_level | Level at which gRPC messages are logged (debug, info, warn, error, fatal, panic) | error | v1.12.0 | | log.file | File to log to instead of STDOUT | | v0.10.0 | | log.encoding | Encoding to use for logging (json, console) | console | v1.12.0 | | log.keys.time | Structured logging key used when outputting log timestamp | T | v1.18.1 | | log.keys.level | Structured logging key used when outputting log level | L | v1.18.1 | | log.keys.message | Structured logging key used when outputting log message | M | v1.18.1 | ### Server | Property | Description | Default | Since | | ---------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------- | ------- | | server.protocol | http or https | http | v0.8.0 | | server.host | The host address on which to serve the Flipt application | 0.0.0.0 | | | server.http\_port | The HTTP port on which to serve the Flipt REST API and UI | 8080 | | | server.https\_port | The HTTPS port on which to serve the Flipt REST API and UI | 443 | v0.8.0 | | server.grpc\_port | The port on which to serve the Flipt GRPC server | 9000 | | | server.grpc\_conn\_max\_idle\_time | Maximum amount of time a GRPC connection can be idle | unlimited | v1.35.0 | | server.grpc\_conn\_max\_age | Maximum amount of time a GRPC connection can live | unlimited | v1.35.0 | | server.grpc\_conn\_max\_age\_grace | Maximum amount of time a GRPC connection can live for outstanding RPCs after exceeding `grpc_conn_max_age ` | unlimited | v1.35.0 | | server.cert\_file | Path to the certificate file (if protocol is set to https) | | v0.8.0 | | server.cert\_key | Path to the certificate key file (if protocol is set to https) | | v0.8.0 | ### Authentication | Property | Description | Default | Since | | -------------------------------------- | ------------------------------------------------------------- | ------- | ------- | | authentication.required | Enable or disable authentication validation on requests | false | v1.15.0 | | authentication.exclude.management | Exclude authentication for /api/v1 API prefix | false | v1.24.0 | | authentication.exclude.metadata | Exclude authentication for /meta API prefix | false | v1.24.0 | | authentication.exclude.evaluation | Exclude authentication for /evaluation/v1 API prefix | false | v1.24.0 | | authentication.exclude.ofrep | Exclude authentication for /ofrep API prefix | false | v1.46.0 | | authentication.session.domain | Public domain on which Flipt instance is hosted | | v1.17.0 | | authentication.session.secure | Configures the `Secure` property on created session cookies | false | v1.17.0 | | authentication.session.token\_lifetime | Configures the lifetime of the session token (login duration) | 24h | v1.17.0 | | authentication.session.state\_lifetime | Configures the lifetime of state parameters during OAuth flow | 10m | v1.17.0 | | authentication.session.csrf.key | Secret credential used to sign CSRF prevention tokens | | v1.17.0 | | authentication.session.csrf.secure | Enable secure CSRF token enforcement | false | v1.58.6 | #### Authentication Methods: Token | Property | Description | Default | Since | | -------------------------------------------------- | ---------------------------------------------------------------- | ------- | ------- | | authentication.methods.token.enabled | Enable static token creation | false | v1.15.0 | | authentication.methods.token.cleanup.interval | Interval between deletion of expired tokens | 1h | v1.16.0 | | authentication.methods.token.cleanup.grace\_period | How long an expired token can exist until considered deletable | 30m | v1.16.0 | | authentication.methods.token.bootstrap.token | The static token to use for bootstrapping | | v1.19.0 | | authentication.methods.token.bootstrap.expiration | How long after creation until the static bootstrap token expires | | v1.19.0 | #### Authentication Methods: OIDC | Property | Description | Default | Since | | ------------------------------------------------------------------- | ---------------------------------------------------------------- | ------- | ------- | | authentication.methods.oidc.enabled | Enable OIDC authentication | false | v1.17.0 | | authentication.methods.oidc.cleanup.interval | Interval between deletion of expired tokens | 1h | v1.17.0 | | authentication.methods.oidc.cleanup.grace\_period | How long an expired token can exist until considered deletable | 30m | v1.17.0 | | authentication.methods.oidc.providers.\[provider].issuer\_url | Provider specific OIDC issuer URL (see your providers docs) | | v1.17.0 | | authentication.methods.oidc.providers.\[provider].client\_id | Provider specific OIDC client ID (see your providers docs) | | v1.17.0 | | authentication.methods.oidc.providers.\[provider].client\_secret | Provider specific OIDC client secret (see your providers docs) | | v1.17.0 | | authentication.methods.oidc.providers.\[provider].redirect\_address | Public URL on which this Flipt instance is reachable | | v1.17.0 | | authentication.methods.oidc.providers.\[provider].scopes | Scopes to request from the provider | | v1.17.0 | | authentication.methods.oidc.providers.\[provider].use\_pkce | Option for enabling PKCE for OIDC authentication flow | false | v1.26.0 | | authentication.methods.oidc.email\_matches | List of email addresses (regex) of users allowed to authenticate | | v1.24.0 | #### Authentication Methods: GitHub | Property | Description | Default | Since | | ---------------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------ | ------- | | authentication.methods.github.enabled | Enable GitHub authentication | false | v1.26.0 | | authentication.methods.github.cleanup.interval | Interval between deletion of expired tokens | 1h | v1.26.0 | | authentication.methods.github.cleanup.grace\_period | How long an expired token can exist until considered deletable | 30m | v1.26.0 | | authentication.methods.github.client\_id | GitHub client ID | | v1.26.0 | | authentication.methods.github.client\_secret | GitHub client secret | | v1.26.0 | | authentication.methods.github.redirect\_address | Public URL on which this Flipt instance is reachable | | v1.26.0 | | authentication.methods.github.scopes | Scopes to request from GitHub | | v1.26.0 | | authentication.methods.github.allowed\_organizations | List of GitHub organizations allowed to authenticate | | v1.33.0 | | authentication.methods.github.allowed\_teams | Map of GitHub organizations to teams that users must be members of | | v1.39.0 | | authentication.methods.github.server\_url | GitHub Server URL (to support GHES) | [https://github.com](https://github.com) | v1.43.0 | | authentication.methods.github.api\_url | GitHub API URL (to support GHES) | [https://api.github.com](https://api.github.com) | v1.43.0 | #### Authentication Methods: Kubernetes | Property | Description | Default | Since | | --------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------- | | authentication.methods.kubernetes.enabled | Enable Kubernetes service account token authentication | false | v1.19.0 | | authentication.methods.kubernetes.cleanup.interval | Interval between deletion of expired tokens | 1h | v1.19.0 | | authentication.methods.kubernetes.cleanup.grace\_period | How long an expired token can exist until considered deletable | 30m | v1.19.0 | | authentication.methods.kubernetes.discovery\_url | Kubernetes API server URL for OIDC configuration discovery | [https://kubernetes.default.svc.cluster.local](https://kubernetes.default.svc.cluster.local) | v1.19.0 | | authentication.methods.kubernetes.ca\_path | Kubernetes API CA certification path | /var/run/secrets/kubernetes.io/serviceaccount/ca.crt | v1.19.0 | | authentication.methods.kubernetes.service\_account\_token\_path | Path to Flipt service account token | /var/run/secrets/kubernetes.io/serviceaccount/token | v1.19.0 | #### Authentication Methods: JWT | Property | Description | Default | Since | | ----------------------------------------------------- | --------------------------------------------------- | ------- | ------- | | authentication.methods.jwt.enabled | Enable JWT authentication | false | v1.35.0 | | authentication.methods.jwt.jwks\_url | URL to retrieve JWKS for JWT validation | | v1.35.0 | | authentication.methods.jwt.public\_key\_file | Path to public key file for JWT validation | | v1.35.0 | | authentication.methods.jwt.validate\_claims.issuer | The issuer claim to validate on JWT tokens | | v1.35.0 | | authentication.methods.jwt.validate\_claims.audiences | The audience claim (list) to validate on JWT tokens | | v1.35.0 | | authentication.methods.jwt.validate\_claims.subject | The subject claim to validate on JWT tokens | | v1.41.0 | ### Authorization | Property | Description | Default | Since | | ---------------------- | --------------------------------------------------------------------- | ------- | ------- | | authorization.required | Enable or disable authorization validation on requests | false | v1.43.0 | | authorization.backend | The backend to use for authorization policies (local, bundle, object) | local | v1.45.0 | #### Authorization Backend: Local | Property | Description | Default | Since | | ----------------------------------------- | -------------------------------------------- | ------- | ------- | | authorization.local.policy.path | Path to the local policy file | | v1.45.0 | | authorization.local.policy.poll\_interval | Interval to poll the policy file for changes | 5m | v1.45.0 | | authorization.local.data.path | Path to the local data file | | v1.45.0 | | authorization.local.data.poll\_interval | Interval to poll the data file for changes | 30s | v1.45.0 | #### Authorization Backend: Bundle | Property | Description | Default | Since | | ---------------------------------- | ------------------------------------ | ------- | ------- | | authorization.bundle.configuration | Configuration for the bundle service | | v1.45.0 | #### Authorization Backend: Object | Property | Description | Default | Since | | ------------------------- | ----------------------------- | ------- | ------- | | authorization.object.type | The type of object store (s3) | s3 | v1.45.0 | ##### Authorization Backend Object: S3 | Property | Description | Default | Since | | -------------------------------- | ------------------------------------------- | ------- | ------- | | authorization.object.s3.region | The AWS region to use for S3 object storage | | v1.45.0 | | authorization.object.s3.bucket | The S3 bucket to use for object storage | | v1.45.0 | | authorization.object.s3.prefix | The S3 prefix to use for object storage | | v1.45.0 | | authorization.object.s3.endpoint | The S3 endpoint to use for object storage | | v1.45.0 | ### Database | Property | Description | Default | Since | | -------------------------------- | ------------------------------------------------------------------- | ----------------------------------- | ---------------------- | | db.url | URL to access Flipt database | file:/(OS Dependent)/flipt/flipt.db | v1.26.0 \*OS Dependent | | db.protocol | Protocol for Flipt database (URL takes precedence) | | v0.18.0 | | db.host | Host to access Flipt database (URL takes precedence) | | v0.18.0 | | db.port | Port to access Flipt database (URL takes precedence) | | v0.18.0 | | db.name | Name of Flipt database (URL takes precedence) | | v0.18.0 | | db.user | User to access Flipt database (URL takes precedence) | | v0.18.0 | | db.password | Password to access Flipt database (URL takes precedence) | | v0.18.0 | | db.max\_idle\_conn | The maximum number of connections in the idle connection pool | 2 | v0.17.0 | | db.max\_open\_conn | The maximum number of open connections to the database | unlimited | v0.17.0 | | db.conn\_max\_lifetime | Sets the maximum amount of time in which a connection can be reused | unlimited | v0.17.0 | | db.prepared\_statements\_enabled | Enable or disable prepared statements for database queries | true | v1.23.1 | ### Storage | Property | Description | Default | Since | | ------------------ | --------------------------------------------------------- | -------- | ------- | | storage.type | The type of storage to use (database, local, git, object) | database | v1.25.0 | | storage.read\_only | Enable read-only mode for storage | false | v1.25.0 | #### Storage Local | Property | Description | Default | Since | | ------------------ | --------------------------------------- | ------- | ------- | | storage.local.path | The path to the local storage directory | | v1.25.0 | #### Storage Git | Property | Description | Default | Since | | ---------------------------------------------------------- | ---------------------------------------------------------------------- | ------- | ------- | | storage.git.repository | The URL of the git repository to use | | v1.25.0 | | storage.git.ref | The git ref to use | main | v1.25.0 | | storage.git.ref\_type | How to parse the git ref (static, semver) | static | v1.41.0 | | storage.git.poll\_interval | The interval to poll the git repository and ref for changes | 30s | v1.25.0 | | storage.git.directory | The root directory to search in the repository | | v1.40.0 | | storage.git.authentication.basic.username | The username to use for basic authentication | | v1.25.0 | | storage.git.authentication.basic.password | The password to use for basic authentication | | v1.25.0 | | storage.git.authentication.token.access\_token | The access token to use for authentication | | v1.25.0 | | storage.git.authentication.ssh.password | Password used to generate the SSH key pair | | v1.30.0 | | storage.git.authentication.ssh.private\_key\_path | Path to private key on the filesystem | | v1.30.0 | | storage.git.authentication.ssh.private\_key\_bytes | (Alternative) Raw private key bytes | | v1.30.0 | | storage.git.authentication.ssh.insecure\_ignore\_host\_key | Skip verifying the known hosts key (avoid in production) | false | v1.30.0 | | storage.git.backend.type | The backend to use for git repository storage (options: memory, local) | memory | v1.43.0 | | storage.git.backend.path | The path to the local storage directory for git backend | | v1.43.0 | #### Storage Object | Property | Description | Default | Since | | ------------------- | ------------------------------------------------------------ | ------- | ------- | | storage.object.type | The type of object storage to use (s3, azblob, googlecloud ) | s3 | v1.25.0 | ##### Storage Object: S3 | Property | Description | Default | Since | | -------------------------------- | ------------------------------------------- | ------- | ------- | | storage.object.s3.region | The AWS region to use for S3 object storage | | v1.25.0 | | storage.object.s3.bucket | The S3 bucket to use for object storage | | v1.25.0 | | storage.object.s3.prefix | The S3 prefix to use for object storage | | v1.25.0 | | storage.object.s3.endpoint | The S3 endpoint to use for object storage | | v1.25.0 | | storage.object.s3.poll\_interval | The interval to poll S3 for changes | 30s | v1.25.0 | ##### Storage Object: Azure Blob | Property | Description | Default | Since | | ------------------------------------ | -------------------------------------------------------- | ------- | ------- | | storage.object.azblob.endpoint | The Azure Blob Store endpoint to use for object storage | | v1.34.0 | | storage.object.azblob.container | The Azure Blob Store container to use for object storage | | v1.34.0 | | storage.object.azblob.poll\_interval | The interval to poll Azure Blob Store for changes | 30s | v1.34.0 | ##### Storage Object: Google Cloud Storage | Property | Description | Default | Since | | ----------------------------------------- | --------------------------------------------------------- | ------- | ------- | | storage.object.googlecloud.bucket | The Google Cloud Storage bucket to use for object storage | | v1.35.0 | | storage.object.googlecloud.prefix | The Google Cloud Storage prefix to use for object storage | | v1.35.0 | | storage.object.googlecloud.poll\_interval | The interval to poll Google Cloud Storage for changes | 30s | v1.35.0 | #### Storage OCI | Property | Description | Default | Since | | ----------------------------------- | ----------------------------------------------------- | ---------------------- | ------- | | storage.oci.repository | The target bundle repository (with optional registry) | | v1.31.0 | | storage.oci.authentication.username | The username to use for authentication | | v1.31.0 | | storage.oci.authentication.password | The password to use for authentication | | v1.31.0 | | storage.oci.bundles\_directory | The directory in which to store local bundles | \$config/flipt/bundles | v1.31.0 | | storage.oci.poll\_interval | The interval to poll the registry for changes | 30s | v1.31.0 | | storage.oci.manifest\_verison | The OCI manifest version to use | 1.1 | v1.39.1 | | storage.oci.authentication.type | The type to use for authentication | static | v1.40.0 | ### Cache | Property | Description | Default | Since | | ------------- | ------------------------------------------------------- | ------- | ------- | | cache.enabled | Enable caching of data | false | v1.10.0 | | cache.ttl | Time to live for cached data | 60s | v1.10.0 | | cache.backend | The backend to use for caching (options: memory, redis) | memory | v1.10.0 | #### Cache: Memory | Property | Description | Default | Since | | ------------------------------- | -------------------------------------------------------------------- | ------- | ------- | | cache.memory.eviction\_interval | Interval at which expired items are evicted from the in-memory cache | 5m | v0.12.0 | #### Cache: Redis | Property | Description | Default | Since | | --------------------------------- | ------------------------------------------------------------------- | --------- | ------- | | cache.redis.host | Host to access the Redis database | localhost | v1.10.0 | | cache.redis.port | Port to access the Redis database | 6379 | v1.10.0 | | cache.redis.db | Redis database to use | 0 | v1.10.0 | | cache.redis.username | Username to access the Redis database | | v1.40.1 | | cache.redis.password | Password to access the Redis database | | v1.10.0 | | cache.redis.mode | Redis mode (single, cluster) | single | v1.57.0 | | cache.redis.prefix | Prefix to add to all Redis cache keys | "flipt" | v1.57.0 | | cache.redis.require\_tls | Require TLS to access the Redis database | false | v1.25.0 | | cache.redis.pool\_size | Max number of socket connections per CPU | 10 | v1.25.0 | | cache.redis.min\_idle\_conn | Minimum number of idle connections in the pool | 0 | v1.25.0 | | cache.redis.conn\_max\_idle\_time | Maximum amount of time a connection can be idle | 30m | v1.25.0 | | cache.redis.net\_timeout | Network timeout for Redis connections | 0 | v1.25.0 | | cache.redis.ca\_cert\_path | Path to custom certificate authority (CA) certificate | | v1.43.0 | | cache.redis.ca\_cert\_bytes | (Alternative) Raw certificate authority (CA) certificate bytes | | v1.43.0 | | cache.redis.insecure\_skip\_tls | Skip verifying the server's certificate chain (avoid in production) | false | v1.43.0 | ### Audit Events | Property | Description | Default | Since | | -------------------------- | -------------------------------------------------- | -------- | ------- | | audit.buffer.capacity | Max capacity of buffer to send events to sinks | 2 | v1.21.0 | | audit.buffer.flush\_period | Duration to wait before sending events to sinks | 2m | v1.21.0 | | audit.events | Type of events user would like to receive on sinks | \["*:*"] | v1.27.0 | #### Audit Events: Log | Property | Description | Default | Since | | ------------------------ | ---------------------------------------------------- | ------- | ------- | | audit.sinks.log.enabled | Enable log sink | false | v1.21.0 | | audit.sinks.log.file | File path to write audit events to instead of STDOUT | | v1.21.0 | | audit.sinks.log.encoding | Encoding to use for logging (json, console) | inherit | v1.44.0 | #### Audit Events: Webhook | Property | Description | Default | Since | | ------------------------------------------ | ------------------------------------------------------------------ | ------- | ------- | | audit.sinks.webhook.enabled | Enable webhook sink | false | v1.27.0 | | audit.sinks.webhook.url | URL to send audit events to | | v1.27.0 | | audit.sinks.webhook.signing\_secret | Signing secret to use for verification of origin on webhook server | | v1.27.0 | | audit.sinks.webhook.max\_backoff\_duration | Max exponential backoff duration for sending webhook upon failure | 15s | v1.27.0 | | audit.sinks.webhook.templates\[] | List of webhook templates for Flipt to send audit events to | | v1.28.0 | #### Audit Events: Kafka | Property | Description | Default | Since | | ----------------------------------------- | ---------------------------------------------------- | -------- | ------- | | audit.sinks.kafka.enabled | Enable Kafka sink | false | v1.46.0 | | audit.sinks.kafka.topic | Kafka topic to send audit events to | | v1.46.0 | | audit.sinks.kafka.bootstrap\_servers | Kafka bootstrap servers | | v1.46.0 | | audit.sinks.kafka.encoding | Encoding to use for events in Kafka (protobuf, avro) | protobuf | v1.46.0 | | audit.sinks.kafka.schema\_registry.url | URL to the schema registry for encoding | | v1.46.0 | | audit.sinks.kafka.require\_tls | Require TLS to access the Kafka broker | false | v1.46.0 | | audit.sinks.kafka.insecure\_skip\_tls | Skip verifying the server's certificate chain | false | v1.46.0 | | audit.sinks.kafka.authentication.username | SASL/SCRAM username to access the Kafka broker | | v1.46.0 | | audit.sinks.kafka.authentication.password | SASL/SCRAM password to access the Kafka broker | | v1.46.0 | ### Analytics | Property | Description | Default | Since | | ------------------------------ | ----------------------------------------------- | ------- | ------- | | analytics.buffer.flush\_period | Duration to wait before sending events to sinks | 10s | v1.37.0 | #### Analytics: Clickhouse | Property | Description | Default | Since | | ------------------------------------ | ----------------------------------- | ------- | ------- | | analytics.storage.clickhouse.enabled | Enable Clickhouse support | false | v1.37.0 | | analytics.storage.clickhouse.url | URL to connect to clickhouse server | | v1.37.0 | #### Analytics: Prometheus | Property | Description | Default | Since | | ------------------------------------ | ------------------------------------------------------------------------ | ------- | ------- | | analytics.storage.prometheus.enabled | Enable Prometheus support | false | v1.52.0 | | analytics.storage.prometheus.url | URL to connect to prometheus server | | v1.52.0 | | analytics.storage.prometheus.headers | Additional headers to send with Prometheus requests (map\[string]string) | | v1.52.1 | ### Metrics | Property | Description | Default | Since | | ---------------- | -------------------------------------- | ---------- | ------- | | metrics.enabled | Enable metrics support | true | v1.41.0 | | metrics.exporter | The exporter to use (prometheus, otlp) | prometheus | v1.41.0 | #### Metrics: OTLP | Property | Description | Default | Since | | --------------------- | ------------------------------------------------------------------ | --------------------- | ------- | | metrics.otlp.endpoint | The OTLP receiver address (supports: grpc, http, https) | grpc://localhost:4317 | v1.41.0 | | metrics.otlp.headers | Additional headers to send with OTLP requests (map\[string]string) | | v1.41.0 | ### Tracing | Property | Description | Default | Since | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- | | tracing.enabled | Enable tracing support | false | v1.18.2 | | tracing.exporter | The exporter to use (jaeger, zipkin, otlp) | jaeger | v1.18.2 | | tracing.sampling\_ratio | The sampling ratio to use for exporting spans | 1.0 | v1.41.0 | | tracing.propagators | The [propagators](https://opentelemetry.io/docs/specs/otel/context/api-propagators/) to use for tracing (tracecontext, b3, jaeger, etc) | tracecontext, baggage | v1.41.0 | #### Tracing: Jaeger | Property | Description | Default | Since | | ------------------- | ---------------------------------------- | --------- | ------- | | tracing.jaeger.host | The UDP host destination to report spans | localhost | v0.17.0 | | tracing.jaeger.port | The UDP port destination to report spans | 6831 | v0.17.0 | #### Tracing: Zipkin | Property | Description | Default | Since | | ----------------------- | --------------------------------------- | ------------------------------------------------------------------------ | ------- | | tracing.zipkin.endpoint | The Zipkin API endpoint to report spans | [http://localhost:9411/api/v2/spans](http://localhost:9411/api/v2/spans) | v1.18.2 | #### Tracing: OTLP | Property | Description | Default | Since | | --------------------- | ------------------------------------------------------------------ | --------------------- | ------- | | tracing.otlp.endpoint | The OTLP receiver address (supports: grpc, http, https) | grpc://localhost:4317 | v1.18.2 | | tracing.otlp.headers | Additional headers to send with OTLP requests (map\[string]string) | | v1.28.0 | ## Deprecations From time to time configuration options will need to be deprecated and eventually removed. Deprecated configuration options will be removed after \~6 months from the time they were deprecated. All deprecated configuration options will be removed from the documentation, however, they will still work as expected until they're removed. A warning will be logged in the Flipt logs when a deprecated configuration option is used. All deprecated options are listed in the [DEPRECATIONS](https://github.com/flipt-io/flipt/blob/main/DEPRECATIONS.md) file in the Flipt repository as well as the [CHANGELOG](https://github.com/flipt-io/flipt/blob/main/CHANGELOG.md). ## Experiments From time to time, Flipt may introduce new features that are not considered fully supported. These features are considered experimental and may change or be removed in future releases. We put experimental features behind a configuration setting that can be enabled in the configuration file. To enable experimental features, set the `experimental.{feature}.enabled` configuration option to `true`. ```yaml theme={null} experimental: foo: enabled: true ``` See the [Experimental](/v1/configuration/experimental) documentation for more information on the current experimental features and how to enable them. # Storage Source: https://docs.flipt.io/v1/configuration/storage This document describes how to configure Flipt's storage backend mechanisms. ## Relational Database Flipt supports the following relational databases: * [SQLite](https://www.sqlite.org/index.html) * [PostgreSQL](https://www.postgresql.org/) * [CockroachDB](https://www.cockroachlabs.com/) * [MySQL](https://dev.mysql.com/) * [LibSQL/Turso](https://turso.tech/) SQLite is enabled by default for simplicity, however, you should use PostgreSQL, MySQL, or CockroachDB if you intend to run multiple copies of Flipt in a high availability configuration. The database connection can be configured as follows: ### SQLite The default location of the SQLite database is `/var/opt/flipt/flipt.db` on Linux and `~/Library/Application Support/flipt/flipt.db` on macOS. ```bash theme={null} FLIPT_DB_URL="file:/var/opt/flipt/flipt.db" ``` ```yaml theme={null} db: # file: informs flipt to use SQLite url: file:/var/opt/flipt/flipt.db ``` ### LibSQL See our [libSQL Example](https://github.com/flipt-io/flipt/blob/main/examples/database/libsql) for a working example of how to use libSQL with Flipt. #### Local ```bash theme={null} FLIPT_DB_URL="libsql://file:/var/opt/flipt/flipt.db" ``` ```yaml theme={null} db: # libsql: informs flipt to use libSQL url: libsql://file:/var/opt/flipt/flipt.db ``` #### Remote If using [Turso](https://turso.tech/) you must use a [database auth token](https://docs.turso.tech/reference/turso-cli#creating-a-database-token) to access the database. ```bash theme={null} FLIPT_DB_URL="https://db-[your-github-name].turso.io?authToken=[your-auth-token]" ``` ```yaml theme={null} db: # http(s): informs flipt to use libSQL over HTTP(s) via sqld/Turso url: https://db-[your-github-name].turso.io?authToken=[your-auth-token] ``` ### PostgreSQL ```bash theme={null} FLIPT_DB_URL="postgres://postgres@localhost:5432/flipt?sslmode=disable" ``` ```yaml theme={null} db: url: postgres://postgres@localhost:5432/flipt?sslmode=disable ``` ### CockroachDB ```bash theme={null} FLIPT_DB_URL="cockroach://root@localhost:26257/flipt?sslmode=disable" ``` ```yaml theme={null} db: url: cockroach://root@localhost:26257/flipt?sslmode=disable ``` ### MySQL ```bash theme={null} FLIPT_DB_URL="mysql://mysql@localhost:3306/flipt" ``` ```yaml theme={null} db: url: mysql://mysql@localhost:3306/flipt ``` ### Migrations From time to time the Flipt database must be updated with new schema. To accomplish this, Flipt includes a `migrate` command that will run any pending database migrations for you. By default Flipt will run your application data migrations. You can run migrations on your [analytical](/v1/configuration/analytics) databases by specifying the `--database=analytics` flag to the migrate command. If Flipt is started and there are pending migrations, you will see the following error in the console: ```yaml theme={null} migrations pending, please backup your database and run `flipt migrate` ``` If it's your first run of Flipt, all migrations will automatically be run before starting the Flipt server. You should backup your database before running `flipt migrate` to ensure that no data is lost if an error occurs during migration. If running Flipt via Docker, you can run the migrations in a separate container before starting Flipt by running: ```yaml theme={null} docker run -it -v $HOME/flipt:/var/opt/flipt flipt/flipt:latest /bin/sh -c './flipt migrate' ``` `$HOME/flipt` is just used as an example, you can use any directory you would like on the host. If you don't use mounted volumes to persist your data, your data will be lost when the migration container exits, having no effect on your Flipt instance! ## Declarative The following backend types are designed to support declarative management of feature flag state via a well-known file format. In particular, they're designed to support GitOps practices with minimal external dependencies. The current four declarative backend types include: * [Local](#local-2) * [Git](#git) * [Object](#object) * [OCI](#oci) The `local` backend has been primarily developed to support a local development experience, whereas, the `git`, `object` and `oci` backends are intended for production use. ### Read Only Mode Read Only Mode Once enabled, all declarative backends put the Flipt API and UI into a `read-only` mode that prevents Flipt from writing to the backend. This is useful for production environments where you want to ensure that flag state is only managed via the configured backend. You can also put Flipt into `read-only` mode by setting the `FLIPT_STORAGE_READ_ONLY` environment variable to `true`, or setting `storage.read_only` to `true` in your configuration. ### Local The purpose of this backend type is to support serving Flipt flag state directly from your local filesystem. You can simply specify a relative or absolute directory in order to start a local Flipt instance and serve flag state. This is particularly useful for local development and validation of flag state changes. Flipt will periodically rebuild its state from the local disk every 10 seconds. ```bash theme={null} FLIPT_STORAGE_TYPE="local" FLIPT_STORAGE_LOCAL_PATH="." ``` ```yaml theme={null} storage: type: local local: path: "." ``` ### Git The `git` type backend is used to configure a target Git repository and Git reference to source feature flag state. The configuration contains fields for addressing the repository, configuring the target reference as well as adding authentication credentials. Once a target repository and reference are configured, Flipt will poll the source repository on a periodic cadence. This cadence is also configurable and defaults to 30 seconds. Flipt will follow the configured [reference](https://git-scm.com/book/en/v2/Git-Internals-Git-References) and keep up to date with new changes. Flipt supports the following reference types: * `static` (default): Flipt will use the reference provided in the configuration. * `semver`: Flipt will use the latest reference that matches the [semver](https://semver.org/) pattern (e.g. `v1.0.*`). ```bash theme={null} FLIPT_STORAGE_TYPE="git" FLIPT_STORAGE_GIT_REPOSITORY="https://github.com/predictab.le/config.git" FLIPT_STORAGE_GIT_REF="main" FLIPT_STORAGE_GIT_POLL_INTERVAL="30s" # for private repository access FLIPT_STORAGE_GIT_AUTHENTICATION_BASIC_USERNAME=... FLIPT_STORAGE_GIT_AUTHENTICATION_BASIC_PASSWORD=... ``` ```yaml theme={null} storage: type: git git: repository: "https://github.com/predictab.le/config.git" ref: "main" poll_interval: "30s" authentication: basic: username: ... password: ... token: access_token: ... ``` #### Authentication Authentication enables the ability to leverage private Git repositories as flag state backends. The `git` type backend supports both `basic`, `token` and `ssh` based authentication schemes. **GitHub** When using GitHub and their [PATs (Personal Access Tokens)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens), `basic` authentication should be used. GitHub expects you to supply a valid `username` and provide your PAT as the `password` parameter. ```yaml theme={null} storage: type: git git: repository: "https://github.com/predictab.le/config.git" ref: "main" poll_interval: "30s" authentication: basic: username: < username > password: < github-personal-access-token > ``` **SSH** In order to configure Flipt with SSH, you will need to generate an SSH key-pair and configure your repository provider with the public key. GitHub has some excellent documentation regarding how to generate and install you credentials [here](https://docs.github.com/en/authentication/connecting-to-github-with-ssh). Once you have your private key credentials you will need to configure Flipt to use them. This can be done via the `storage.git.authentication.ssh` configuration section: ```yaml theme={null} storage: type: git git: repository: git@github.com:flipt-io/some-private-repo.git authentication: ssh: password: flipt private_key_path: private-key.pem # private_key_bytes: # alternatively pass the raw bytes inline insecure_ignore_host_key: true ``` `insecure_ignore_host_key` is not encouraged for production use, and is `false` by default. Instead, you are advised to put the key fingerprint in the known hosts file where you are running Flipt. For example, for GitHub you can do `ssh-keyscan github.com >> ~/.ssh/known_hosts` on the Flipt host. *Container Deployment*: When running Flipt in containers, mount the known\_hosts file to the system-wide SSH path instead of a user directory. For example, with Docker ```yaml theme={null} volumes: - /path/to/your/known_hosts:/etc/ssh/ssh_known_hosts:ro ``` See our [GitOps Guide](/v1/guides/user/get-going-with-gitops) for an example of how to set up a GitHub repository as a flag state backend. #### Repository Storage The `git` backend also supports configuring where the Git repository is cloned to. By default, Flipt will clone the repository to an in-memory filesystem, but you can configure a local directory to clone the repository to which is useful for relieving memory pressure especially for large repositories. ```yaml theme={null} storage: type: git git: repository: git@github.com:flipt-io/some-private-repo.git backend: type: local path: /var/opt/flipt/git ``` ### Object The object storage type supports using a hosted object storage service as the source of truth for Flipt state configuration. Currently, Flipt supports the following object store providers: * [AWS S3](https://aws.amazon.com/s3/) * [Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/) * [Google Cloud Storage](https://cloud.google.com/storage) #### Contents The contents of a target object storage bucket must contain Flipt state configuration files. As with the `git` and `local` backend types, the same rules apply with regard to how Flipt will locate feature flag state in your target bucket. See the section below on [Flag State Configuration](#flag-state-configuration) for how Flipt decides which files in a target are considered for serving flag state. With the object storage backend, Flipt will respect a file at the root of the target with the name `.flipt.yml` to serve as an index for locating flag state configuration in the bucket. It will also use the same default strategy when the index isn't supplied (e.g. file name `features.yml` or `*.features.yml`). #### Amazon S3 The AWS S3 backend can be configured to serve state from a single bucket from a target S3-compatible API. This means that both AWS S3 and open-source alternatives such as [Minio](https://github.com/minio/minio) can be used. The following is an example of how to configure Flipt to leverage this backend type: ```bash theme={null} FLIPT_STORAGE_TYPE="object" FLIPT_STORAGE_OBJECT_TYPE="s3" FLIPT_STORAGE_OBJECT_S3_REGION="us-east-1" FLIPT_STORAGE_OBJECT_S3_BUCKET="flipt_feature_flags" FLIPT_STORAGE_OBJECT_S3_POLL_INTERVAL="1m" # optional: bucket prefix for locating flag state files FLIPT_STORAGE_OBJECT_S3_PREFIX="production" # optional: for non-AWS hosted S3 FLIPT_STORAGE_OBJECT_S3_ENDPOINT=http://localhost:9009 ``` ```yaml theme={null} storage: type: object object: type: s3 s3: region: us-east-1 bucket: flipt_feature_flags poll_interval: "30s" # optional: bucket prefix for locating flag state files prefix: production # optional: for non-AWS hosted S3 endpoint: http://localhost:9009 ``` In addition to these Flipt configuration parameters, valid credentials will also be required for Flipt to authenticate with the target object store. These should be provided as environment variables to the Flipt server process: ```bash theme={null} AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... ``` #### Azure Blob Storage The Azure Blob Storage backend can be configured to serve state from a single container from a target Azure Blob Storage account. The following is an example of how to configure Flipt to leverage this backend type: ```bash theme={null} FLIPT_STORAGE_TYPE="object" FLIPT_STORAGE_OBJECT_TYPE="azblob" FLIPT_STORAGE_OBJECT_AZBLOB_CONTAINER="flipt-feature-flags" FLIPT_STORAGE_OBJECT_AZBLOB_POLL_INTERVAL="1m" # optional: for customizing Azure blob storage endpoint FLIPT_STORAGE_OBJECT_AZBLOB_ENDPOINT=http://localhost:10000 ``` ```yaml theme={null} storage: type: object object: type: azblob azblob: container: flipt-feature-flags # optional: for customizing Azure blob storage endpoint endpoint: https//devaccount.blob.core.windows.net poll_interval: "30s" ``` In addition to these Flipt configuration parameters, valid credentials will also be required for Flipt to authenticate with the target object store. These should be provided as environment variables to the Flipt server process. There are 2 options supported for authentication: * Using [Azure Credentials](https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication?tabs=bash#2-authenticate-with-azure) ```bash theme={null} AZURE_CLIENT_ID=... # application ID of an Azure service principal AZURE_TENANT_ID=... # ID of the application's Microsoft Entra tenant AZURE_CLIENT_SECRET=... # password of the Azure service principal ``` * Using Azure Blob [Storage Account Keys](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal) ```bash theme={null} AZURE_STORAGE_ACCOUNT=... AZURE_STORAGE_KEY=... ``` #### Google Cloud Storage The Google Cloud Storage backend can be configured to serve state from a single bucket from a target Google Cloud Storage account. The following is an example of how to configure Flipt to leverage this backend type: ```bash theme={null} FLIPT_STORAGE_TYPE="object" FLIPT_STORAGE_OBJECT_TYPE="googlecloud" FLIPT_STORAGE_OBJECT_GOOGLECLOUD_BUCKET="flipt-feature-flags" FLIPT_STORAGE_OBJECT_GOOGLECLOUD_POLL_INTERVAL="1m" # optional: bucket prefix for locating flag state files FLIPT_STORAGE_OBJECT_GOOGLECLOUD_PREFIX="production" ``` ```yaml theme={null} storage: type: object object: type: googlecloud googlecloud: bucket: flipt-feature-flags poll_interval: "30s" ``` In addition to these Flipt configuration parameters, valid credentials will also be required for Flipt to authenticate with the target object store. If running in a Google Cloud environment, you can use [Application Default Credentials](https://cloud.google.com/docs/authentication/production) to authenticate with Google Cloud Storage. Alternatively, you can use a [Service Account](https://cloud.google.com/iam/docs/creating-managing-service-accounts) to authenticate with Google Cloud Storage and provide the service account key file to Flipt. This should be provided as an environment variable to the Flipt server process: ```bash theme={null} GOOGLE_APPLICATION_CREDENTIALS=... # path to a service account key file ``` ### OCI Since `v1.31.0`, Flipt supports using any [OCI](https://opencontainers.org/) compatible registry as a declarative backend source. Flipt has its own custom OCI manifest format (we call them `bundles`), which can be built and managed using the [Flipt CLI](/v1/cli/commands/bundle). ```bash theme={null} FLIPT_STORAGE_TYPE="oci" FLIPT_STORAGE_OCI_REPOSITORY="some.oci.registry/repository/image:tag" FLIPT_STORAGE_OCI_POLL_INTERVAL="30s" # authentication credentials FLIPT_STORAGE_OCI_AUTHENTICATION_USERNAME="username" FLIPT_STORAGE_OCI_AUTHENTICATION_PASSWORD="password" # location used for storing local bundles FLIPT_STORAGE_OCI_BUNDLES_DIRECTORY="/flipt/bundles" FLIPT_STORAGE_OCI_MANIFEST_VERSION="1.1" ``` ```yaml theme={null} storage: type: "oci" oci: repository: "some.oci.registry/repository/image:tag" poll_interval: "30s" authentication: username: "username" password: "password" bundles_directory: "/flipt/bundles" manifest_version: "1.1" ``` Certain OCI registries may require setting the OCI manifest version to something other than the default (`1.1`) to work correctly. In this case, you can set the `FLIPT_STORAGE_OCI_MANIFEST_VERSION` environment variable or `storage.oci.manifest_version` configuration property to the desired version (e.g. `1.0`). See [this issue](https://github.com/flipt-io/flipt/issues/2907) for more information. #### Authentication Starting from version `1.40.0`, Flipt offers two authentication methods: * **Static**: This is the default method that uses a username and password for authentication. * **AWS ECR**: If you're using Flipt on AWS with a private ECR repository, you can configure authentication differently. Set either the `FLIPT_STORAGE_OCI_AUTHENTICATION_TYPE` environment variable or the `storage.oci.authentication.type` configuration property to `aws-ecr`. Additionally, make sure your compute instance or container has a role with permissions to pull from ECR. See [this issue](https://github.com/flipt-io/flipt/issues/2938) for more information. ### Flag State Configuration Each of Flipt's filesystem backends expects you to represent your feature flag configuration via a set of YAML files. These files declaratively define what flags, segments, variants, etc. exist and in what configuration. #### Locating Flag State Flipt's filesystem backends allow you to define feature flags alongside other configurations in a shared directory, repository, or object storage bucket. Flipt uses a naming scheme to index which files are flag state files. By default, Flipt will look for the following filename patterns to attempt to parse as Flipt state: * `**/features.yaml` * `**/features.yml` * `**/*.features.yaml` * `**/*.features.yml` Any file named `features.yaml`, `features.yml`, or with either extension `.features.yaml` or `.features.yml` is considered recursively from the root of your target. If this naming convention doesn't work for you, it can be overridden by creating a file named `.flipt.yml` in the root of your target directory tree. This file will be used to instruct Flipt on how to index your directory tree and find flag state files: ```yaml theme={null} version: "1.0" include: - "**/features.yaml" - "**/features.yml" - "**/*.features.yaml" - "**/*.features.yml" exclude: [] ``` The index file contains two lists `include` and `exclude`. These can contain specific paths or glob-matching patterns. The indexing process first matches the `include` section and then filters that are set by the `exclude` section. #### Defining Flag State Flipt flag state file format has been taken directly from Flipt's existing [import and export](/v1/operations/import-export) flag state format. You can run `flipt export` on your existing Flipt instance, and then add/commit the result to a directory, object storage, or Git repository to get started. This can be used to migrate from a relational database-backed instance of Flipt to a filesystem-backed deployment with ease. ```yaml features.yaml theme={null} namespace: backend flags: - key: awesomeNewFeature name: Awesome New Feature enabled: true variants: - key: enabled name: Enabled - key: disabled name: Disabled rules: - segment: internal-users distributions: - variant: enabled rollout: 100 - segment: all-users distributions: - variant: enabled rollout: 20 - variant: disabled rollout: 80 segments: - key: internal-users name: Internal Users constraints: - type: STRING_COMPARISON_TYPE property: organization operator: eq value: internal match_type: ALL_MATCH_TYPE - key: all-users name: All Users match_type: ALL_MATCH_TYPE ``` Each file identified for use by Flipt represents the contents of a single namespace. Multiple namespaces can be defined across multiple files. You can organize these files however you like in your target directory. By defining different namespaces in different directories, you can leverage features such as GitHub's Codeowners. This gives you authorization mechanisms for managing contributions to Flipt state. The file format currently consists of four top-level keys: ```yaml theme={null} version: "1.0" # a version for this file format namespace: default # string identifying the resources collective namespace flags: [] # [Flag] list of Flag definitions segments: [] # [Segment] list of Segment definitions ``` # Telemetry Source: https://docs.flipt.io/v1/configuration/telemetry This document describes how to configure Flipt's telemetry outputs as well as what data is captured. ## Telemetry Flipt developers rely on anonymous usage data to help prioritize new features and improve the product. The information collected is completely anonymous, never shared with external entities, and you can opt-out at any time. The telemetry data is collected by default, but you can disable it by following the instructions below. Telemetry is only collected when Flipt is running, **once at startup** and then every **4 hours**. ### What Kind of Data is Collected? * Flipt version (i.e.: v1.21.0) * Database backend (i.e.: Postgres) * Cache backend (i.e.: Redis) * Authentication methods (i.e.: OIDC) We use [Jitsu](https://jitsu.com/) to collect the data. Only the Flipt team has access to the raw data. Here is an example of the telemetry data sent to Jitsu: ```json theme={null} { "version": "1.1", "uuid": "1545d8a8-7a66-4d8d-a158-0a1c576c68a6", "lastTimestamp": "2023-04-25T01:01:51Z", "flipt": { "version": "v1.21.1", "os": "linux", "arch": "amd64", "storage": { "database": "postgres", "cache": "redis" }, "authentication": { "methods": "oidc" } } } ``` You can always view the current schema of the telemetry data and see how it's collected on [GitHub](https://github.com/flipt-io/flipt/blob/main/internal/telemetry/telemetry.go). ### How To Disable Telemetry Telemetry collection can be disabled in several ways: #### Configuration File ```yaml theme={null} meta: telemetry_enabled: false ``` #### Environment Variables ```shell theme={null} export FLIPT_META_TELEMETRY_ENABLED=false ``` Telemetry can also be disabled by setting the [DO\_NOT\_TRACK](https://consoledonottrack.com/) environment variable to `true` or `1`: ```shell theme={null} export DO_NOT_TRACK=true ``` # Switching from LaunchDarkly to Flipt Source: https://docs.flipt.io/v1/guides/migration/launchdarkly/flipt Install Flipt and migrate your flags from LaunchDarkly to Flipt The rest of this guide will cover the remaining steps required to migrate from LaunchDarkly to Flipt. ## Adding the Flipt OpenFeature Provider Flipt supports the OpenFeature standard which makes it easy to switch from LaunchDarkly to Flipt. Continuing with the Node.js example from the previous section, you can replace the LaunchDarkly provider with the [Flipt provider](https://github.com/open-feature/js-sdk-contrib/tree/main/libs/providers/flipt) in your codebase: ```javascript theme={null} import { FliptProvider } from "@openfeature/flipt"; const provider = new FliptProvider("default", { url: "http://your.flipt.host", }); OpenFeature.setProvider(provider); const client = OpenFeature.getClient(); ``` ## Installing Flipt Flipt is a single binary that can be run on any Linux or macOS (arm64) host. You can install and try out Flipt in a few different ways: ```console Binary theme={null} curl -fsSL https://get.flipt.io/install | sh ``` ```console Docker theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:latest ``` ```console Kubernetes/Helm theme={null} helm repo add flipt https://helm.flipt.io helm install flipt flipt/flipt ``` ```console Homebrew theme={null} brew install flipt-io/brew/flipt ``` For more details, see our [installation documentation](/v1/installation/overview). ## Migrate State from LaunchDarkly to Flipt Generally speaking, it’s preferable to open up new flags individually when migrating to a new feature flagging platform. This allows you to test each flag in isolation and ensure that the new platform is working as expected. If you need assistance with migrating your flags from LaunchDarkly to Flipt, join our [Discord community](https://flipt.io/discord) and ask for help in the #migration channel. Flipt offers flag state migration services for any paid user of our [Managed Cloud](#) offering. # Migrating from LaunchDarkly SDK to OpenFeature SDK Source: https://docs.flipt.io/v1/guides/migration/launchdarkly/openfeature Migrate a Node.js application from LaunchDarkly SDK to OpenFeature SDK This guide is focused on migrating a Node.js application from LaunchDarkly SDK to OpenFeature SDK. The process is similar for other programming languages, but the specifics of the SDKs and the APIs they provide may differ. Feature flagging is a useful modern practice that lets you update the configuration of your application without redeploying it, setting your feature rollouts free from your deployment schedule. Feature flagging is used to roll out features gradually, enable different features for different groups of users, or test in production. It also saves you from sleepless nights by enabling rolling features back if they turn out to be degrading your application's production performance. There are lots of feature flagging service providers out there, and [LaunchDarkly](https://launchdarkly.com/) is one of the leaders in the space. While it's great to have burgeoning competition, it also introduces a bit of chaos into the customer experience. What if your existing feature flagging service goes out of market or raises pricing through the roof because its investors feel like getting their money back? Since every feature flagging service comes with its own bespoke SDK, you would need to allocate substantial development time each time you need to switch providers. Enter [OpenFeature](https://openfeature.dev/): an open specification that defines a vendor-agnostic API for feature flagging that works with a wide array of feature flag management tools. Every tool vendor creates an OpenFeature-compliant provider library for each supported programming language or technology. For instance, [OpenFeature providers for Node.js](https://openfeature.dev/ecosystem/?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider\&instant_search%5BrefinementList%5D%5Bcategory%5D%5B0%5D=Server\&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=JavaScript) are currently available from the following vendors: CloudBees, ConfigCat, DevCycle, FeatBit, flagd, Flipt, Go Feature Flag, LaunchDarkly, PostHog, and Split. When you use an OpenFeature SDK to implement feature flagging in your application, you get the freedom to switch between feature flagging vendors quickly and easily. All it takes is installing and importing a new vendor's OpenFeature provider, and replacing usages of your old vendor's provider with the new one. Let's say you're maintaining a Node.js application that uses feature flagging from LaunchDarkly via their [Node server SDK](https://docs.launchdarkly.com/sdk/server-side/node-js). You want to minimize feature flagging vendor lock-in in case LaunchDarkly changes its pricing model to something that will be hard for your team to afford. To do that, you'd need to switch from LaunchDarkly's own SDK to the [OpenFeature Node.js SDK](https://openfeature.dev/docs/reference/technologies/server/javascript/) and use LaunchDarkly's OpenFeature provider. How hard would it be for you to make this switch? Read on to find out. ## Types of Feature Flags in LaunchDarkly LaunchDarkly supports the following types of feature flags: * **Boolean flags**. This is the most common type of feature flag and the default type when you create a new flag in LaunchDarkly. These are useful for enabling and disabling a specific feature, helping target specific users or groups, or perform a progressive rollout of a feature. * **String flags**. These are helpful for multivariate testing of configuration values or text content. You can set as many string variations as you need. * **Number flags** are also used for multivariate testing like string flags, but variation values are numeric. * **JSON flags**. These are useful for testing groups of configuration values, as an alternative to putting all values in individual flags dependent on each other. All these types of flags are covered by the OpenFeature spec and available in OpenFeature's Node.js SDK. Let's see what you'd need to do specifically to perform the migration. ## Finding Usages of LaunchDarkly SDK APIs First, you need to find where in your code base the LaunchDarkly SDK is used. You can do this in three steps. First, perform a textual search for `node-server-sdk` across your project. Ignore search results in *package.json* and package manager lock files. What you're looking for are usages in import or require statements inside your .js and .ts files, such as this: ```javascript theme={null} import LaunchDarkly from "@launchdarkly/node-server-sdk"; ``` Next, search for references of the `LaunchDarkly` import inside every file where this import is present. You're looking for a statement that creates a LaunchDarkly client: ```javascript theme={null} const ldClient = LaunchDarkly.init(sdkKey); ``` Finally, search for references of the LaunchDarkly client instance: in our example, `ldClient`. This will give you the list of all LaunchDarkly client API calls that are responsible for getting values of specific feature flags. For example, this is what you'd see if you invoke JetBrains WebStorm's *Show Usages* command on `ldClient`: Searching for usages of LaunchDarkly client instance in JetBrains WebStorm If you're using VS Code, this is what you'd see after calling *Go to References* on `ldClient`: Searching for usages of LaunchDarkly client instance in VS Code ### Optional: Use FlagLint For larger JavaScript and TypeScript codebases, you can use [FlagLint](https://flaglint.dev/) to analyze supported direct LaunchDarkly Node.js SDK usages with AST analysis: ```bash theme={null} # List detected call sites npx flaglint scan ./src # Summarize migration risk and readiness npx flaglint audit ./src # Preview safe OpenFeature call-site rewrites without changing files npx flaglint migrate ./src --dry-run ``` The migration preview skips usages that FlagLint cannot safely rewrite. FlagLint analyzes application call sites but does not migrate flag definitions, targeting rules, environment configuration, backend state, or provider setup. ## Installing and Importing OpenFeature Packages When you're using LaunchDarkly's own SDK, your application declares this package as a dependency: ```json theme={null} "@launchdarkly/node-server-sdk": "^9.4.1" ``` To make use of the OpenFeature Node.js SDK and LaunchDarkly's OpenFeature provider instead, you need to install the following two packages: ```json theme={null} "@launchdarkly/openfeature-node-server": "0.5.1", "@openfeature/server-sdk": "^1.6.3", ``` The next step is to go through the files in your project that import from LaunchDarkly's own SDK, and add new import statements to these files: ```javascript theme={null} import { OpenFeature } from "@openfeature/server-sdk"; import { LaunchDarklyProvider } from "@launchdarkly/openfeature-node-server"; ``` ## Keys and Context The way you load the LaunchDarkly SDK key and feature flag keys stays the same when you're migrating to the OpenFeature SDK. For example, this code would not change for the purposes of migration: ```javascript theme={null} import credentials from "../credentials.json" assert { type: "json" }; const sdkKey = credentials.launchDarkly.sdkKey; const featureFlags = { booleanFlag: { key: "boolean-flag", type: "boolean", }, stringFlag: { key: "string-flag", type: "string", }, numberFlag: { key: "number-flag", type: "number", }, jsonFlag: { key: "json-flag", type: "object", }, }; ``` However, there's a subtle difference in setting up the context when you migrate to OpenFeature. Whereas with LaunchDarkly SDK you'd use the `key` property in the context object, you need to use `targetingKey` with the OpenFeature SDK. LaunchDarkly SDK: ```javascript theme={null} const context = { kind: "user", key: "example-user-key", name: "Sandy", }; ``` OpenFeature SDK: ```javascript theme={null} const context = { kind: "user", targetingKey: "example-user-key", // Note the change in property name name: "Sandy", }; ``` ## Client Initialization The way you initialize the feature flag provider's client is going to be quite different. With LaunchDarkly SDK, you create a client instance first and then fire a `waitForInitialization()` call: ```javascript theme={null} const ldClient = LaunchDarkly.init(sdkKey); await ldClient.waitForInitialization(); ``` When migrating to the OpenFeature SDK, this is when you're actually starting to use OpenFeature APIs. Also, the order of operations flips around: you start by making a call that sets a specific vendor provider, in this case the LaunchDarkly provider, and waits for its initialization. The second call gives you an instance of a client that you'll be using from now on: ```javascript theme={null} await OpenFeature.setProviderAndWait(new LaunchDarklyProvider(sdkKey)); const client = OpenFeature.getClient(); ``` ## Migrating Boolean Flags In the LaunchDarkly SDK, here's how you fetch the value of a boolean flag: ```javascript theme={null} const booleanFlagValue = await ldClient.boolVariation( featureFlags.booleanFlag.key, context, false ); doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, booleanFlagValue ); ``` If you're not a fan of the async/await syntax, you might as well resolve the promise returned by the `boolVariation()` call using a `then()` call: ```javascript theme={null} ldClient .boolVariation(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` In addition to `boolVariation()`, there are two more LaunchDarkly client functions that you may be using with boolean flags: `variation()` and `boolVariationDetail()`. `variation()` is just a more generic function that you can use to get flag values of any type: ```javascript theme={null} ldClient .variation(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` `boolVariationDetail()` is a function that returns an object that contains both the flag value and additional metadata: the reason of the flag being in a particular value and the variation index: ```javascript theme={null} ldClient .boolVariationDetail(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` Now, when you're migrating to the OpenFeature SDK, it provides two client functions instead of three: `getBooleanValue()` and `getBooleanDetails()`. Note that it doesn't provide the equivalent of LaunchDarkly SDKs general-purpose `variation()` function. This means that when migrating, you'll need to choose a function corresponding to the specific type of flag you're using. To sum it up, below are code snippets representing the usage of the three LaunchDarkly SDKs functions that you can use to get boolean flag values, along with the OpenFeature SDK code that you'd end up with after migration. When migrating a `boolVariation()` call, ```javascript theme={null} ldClient .boolVariation(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getBooleanValue(featureFlags.booleanFlag.key, false, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` When migrating a `variation()` call, ```javascript theme={null} ldClient .variation(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getBooleanValue(featureFlags.booleanFlag.key, false, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` Finally, when migrating a `boolVariationDetail()` call, ```javascript theme={null} ldClient .boolVariationDetail(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getBooleanDetails(featureFlags.booleanFlag.key, false, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); ``` Note that functions in the two SDKs take arguments in a different order: * In LaunchDarkly SDK, the key goes first, followed by the context, and then by the default value. * In OpenFeature SDK, the key also goes first, but the default value goes in the second position, followed by the context as the third argument. OpenFeature SDK functions also take the fourth argument, `FlagEvaluationOptions`, but it's optional and for the purposes of migration, you should just omit it. ## Migrating String Flags In the LaunchDarkly SDK, you fetch the value of a string flag as follows: ```javascript theme={null} ldClient .stringVariation(featureFlags.stringFlag.key, context, "red") .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` or, using the async/await syntax: ```javascript theme={null} const stringFlagValue = await ldClient.stringVariation( featureFlags.stringFlag.key, context, "red" ); doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, stringFlagValue ); ``` Similar to boolean flags, with the LaunchDarkly SDK, you can also fetch values of string flags using the general-purpose `variation()` function, or fetch string flags along with their associated details using `stringVariationDetail()`. When migrating a `stringVariation()` call, ```javascript theme={null} ldClient .stringVariation(featureFlags.stringFlag.key, context, "red") .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getStringValue(featureFlags.stringFlag.key, "red", context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` When migrating a `variation()` call, ```javascript theme={null} ldClient .variation(featureFlags.stringFlag.key, context, "red") .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getStringValue(featureFlags.stringFlag.key, "red", context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` When migrating a `stringVariationDetail()` call, ```javascript theme={null} ldClient .stringVariationDetail(featureFlags.stringFlag.key, context, "red") .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getStringDetails(featureFlags.stringFlag.key, "red", context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.stringFlag.key, flagValue ) ); ``` ## Migrating Number Flags In the LaunchDarkly SDK, you fetch the value of a number flag with the following promise chain syntax: ```javascript theme={null} ldClient .numberVariation(featureFlags.numberFlag.key, context, 50) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` or using the async/await syntax: ```javascript theme={null} const numberFlagValue = await ldClient.numberVariation( featureFlags.numberFlag.key, context, 50 ); doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, numberFlagValue ); ``` The general-purpose `variation()` function is also available for fetching number flags, as well as the `numberVariationDetail()` function for fetching number flag details. When migrating a `numberVariation()` call, ```javascript theme={null} ldClient .numberVariation(featureFlags.numberFlag.key, context, 50) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getNumberValue(featureFlags.numberFlag.key, 50, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` When migrating a `variation()` call, ```javascript theme={null} ldClient .variation(featureFlags.numberFlag.key, context, 50) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getNumberValue(featureFlags.numberFlag.key, 50, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` When migrating a `numberVariationDetail()` call, ```javascript theme={null} ldClient .numberVariationDetail(featureFlags.numberFlag.key, context, 50) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` becomes ```javascript theme={null} client .getNumberDetails(featureFlags.numberFlag.key, 50, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.numberFlag.key, flagValue ) ); ``` ## Migrating JSON Flags If you have read this far, it should come as no surprise to you that the LaunchDarkly SDK provides three functions for working with JSON flags: 1. `jsonVariation()`, a specialized function for fetching JSON flags. 2. `variation()`, a general-purpose function that can be used to fetch all types of flags, including JSON flags. 3. `jsonVariationDetail()`, a function that fetches JSON flags along with their associated metadata. You can call each of these functions with a promise call chain: ```javascript theme={null} ldClient .jsonVariation(featureFlags.jsonFlag.key, context, {}) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` or using the async/await syntax: ```javascript theme={null} const jsonFlagValue = await ldClient.jsonVariation( featureFlags.jsonFlag.key, context, {} ); doSomethingDependingOnFeatureFlagValue( featureFlags.jsonFlag.key, jsonFlagValue ); ``` When migrating a `jsonVariation()` call to the OpenFeature SDK, ```javascript theme={null} ldClient .jsonVariation(featureFlags.jsonFlag.key, context, {}) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` becomes ```javascript theme={null} client .getObjectValue(featureFlags.jsonFlag.key, {}, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` When migrating a `variation()` call, ```javascript theme={null} ldClient .variation(featureFlags.jsonFlag.key, context, {}) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` also becomes ```javascript theme={null} client .getObjectValue(featureFlags.jsonFlag.key, {}, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` Finally, when migrating a `jsonVariationDetail()` call, ```javascript theme={null} ldClient .jsonVariationDetail(featureFlags.jsonFlag.key, context, {}) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` becomes ```javascript theme={null} client .getObjectDetails(featureFlags.jsonFlag.key, {}, context) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(featureFlags.jsonFlag.key, flagValue) ); ``` ## Migrating Event Listeners Apart from migrating functions that get values of flags, you may also want to migrate your event listening and handling code. This is especially important if during the lifetime of your application, you want to react to flag value changes that occur in LaunchDarkly. This wouldn't make too much sense for full-stack web applications where you can just get the current flag value on every page load, but it does make sense for APIs and other kinds of long-running processes. LaunchDarkly's Node server SDK allows you to listen to and handle events using the `on()` method that you call on the client instance, like this: ```javascript theme={null} ldClient.on("event_name", (eventInfo) => handleEvent(eventInfo)); ``` There are [five event types](https://launchdarkly.github.io/js-core/packages/sdk/server-node/docs/interfaces/LDClient.html#on) that you can listen to: `ready`, `failed`, `error`, `update`, and `update:key`. ### Initialization and Client Error Events The `ready` and `failed` events are only fired once, as a result of the client initialization. You can wrap the `await ldClient.waitForInitialization()` call in a try/catch block instead of listening to these two events. However, if you are listening to them explicitly, then your `ready` listener when using the LaunchDarkly SDK looks like this: ```javascript theme={null} ldClient.on("ready", () => { console.log("We're connected to LaunchDarkly :)"); }); ``` If so, the following is the equivalent listener using the OpenFeature SDK: ```javascript theme={null} OpenFeature.addHandler(ProviderEvents.Ready, () => { console.log("We're connected to LaunchDarkly through OpenFeature :)"); }); ``` When you start using OpenFeature's `addHandler()` function for event listening, don't forget to extend your OpenFeature SDK import statement to include the `ProviderEvents` enum: ```javascript theme={null} import { OpenFeature, ProviderEvents } from "@openfeature/server-sdk"; ``` Here's LaunchDarkly's `failed` event listener: ```javascript theme={null} ldClient.on("failed", () => { console.log("Failed to connect to LaunchDarkly :("); }); ``` OpenFeature SDK doesn't provide the equivalent of LaunchDarkly's `failed` event, so if you want to handle a permanent client error in connecting to LaunchDarkly, you should do it in the catch clause of the try/catch block around the OpenFeature client initialization call: ```javascript theme={null} try { await OpenFeature.setProviderAndWait(new LaunchDarklyProvider(sdkKey)); const client = OpenFeature.getClient(); // More code } catch (error) { console.log( `Failed to connect to LaunchDarkly :( Here's what the error says: ${JSON.stringify( error )}` ); } ``` LaunchDarkly also allows listening to the `error` event that signals an abnormal condition when the client is working: ```javascript theme={null} ldClient.on("error", (error) => { console.log( `The LaunchDarkly client has encountered an error. Here are the details: ${JSON.stringify( error )}` ); }); ``` In OpenFeature SDK terms, the equivalent listener looks like this: ```javascript theme={null} OpenFeature.addHandler(ProviderEvents.Error, (error) => { console.log( `The OpenFeature client for LaunchDarkly has encountered an error. Here are the details: ${JSON.stringify( error )}` ); }); ``` ### Feature Flag Configuration Update Events The two most significant event listeners in the LaunchDarkly SDK are `update` and `update:key`. The former enables listening to configuration changes affecting any flag: ```javascript theme={null} ldClient.on("update", (keyObject) => { console.log(`Configuration of flag ${keyObject.key} has changed`); ldClient .variation(keyObject.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue(keyObject.key, flagValue) ); }); ``` The `update:key` listener is more specific and serves to receive configuration updates affecting a single flag that you identify by its key: ```javascript theme={null} ldClient.on(`update:${featureFlags.booleanFlag.key}`, () => { console.log( `Configuration of flag ${featureFlags.booleanFlag.key} has changed` ); ldClient .variation(featureFlags.booleanFlag.key, context, false) .then((flagValue) => doSomethingDependingOnFeatureFlagValue( featureFlags.booleanFlag.key, flagValue ) ); }); ``` In the OpenFeature SDK, there's no equivalent to `update:key`. You can only listen to configuration changes affecting any flags, and here's how you do it: ```javascript theme={null} OpenFeature.addHandler( ProviderEvents.ConfigurationChanged, async (_eventDetails) => { // your event handling code } ); ``` There's a tricky part about this event handler. As we've seen above, OpenFeature SDK doesn't provide a general-purpose API to get the value of a flag irrespective of its type. You need to use functions that are specific to a feature flag type: `client.getStringValue()`, `client.getBooleanValue()`, etc. This doesn't play well with the fact that OpenFeature SDK only provides a generic event update listener. When you receive an updated configuration event, you need to look up its type by key, and depending on the result, call a type-specific function. Here's what this may look like in practice: ```javascript theme={null} OpenFeature.addHandler( ProviderEvents.ConfigurationChanged, async (_eventDetails) => { const changedFlag = _eventDetails.flagsChanged[0]; console.log(`Configuration of flag ${changedFlag} has changed`); const flagType = Object.values(featureFlags).find( (x) => x.key === changedFlag ).type; let flagValue; if (flagType === "boolean") { flagValue = await client.getBooleanValue(changedFlag, false, context); } else if (flagType === "string") { flagValue = await client.getStringValue(changedFlag, "red", context); } else if (flagType === "number") { flagValue = await client.getNumberValue(changedFlag, 50, context); } else if (flagType === "object") { flagValue = await client.getObjectValue(changedFlag, null, context); } else { console.log( "Something went awry: we don't know the type of the updated flag" ); } doSomethingDependingOnFeatureFlagValue(changedFlag, flagValue); } ); ``` ## Cleaning Up As soon as you have migrated all feature flag calls and event listeners from LaunchDarkly's own SDK to the OpenFeature Node.js SDK, remember to delete all code coming from LaunchDarkly's SDK, as well as the corresponding import/require statements. After this, you'll be able to uninstall LaunchDarkly's SDK package —`@launchdarkly/node-server-sdk`—by removing it from *package.json* and running your package manager's install command. ## Summary After reading this guide, you know what OpenFeature is and why using the OpenFeature SDK with your feature flagging logic instead of a particular vendor's SDK can benefit your team in the long run by reducing the vendor lock-in. As you can see, the APIs provided by LaunchDarkly's Node server SDK map well to those available in the OpenFeature Node.js SDK, and migrating from one to another shouldn't be hard should you decide to do so. Happy feature rollouts with feature flags no matter which vendor you're using! # Migrating from LaunchDarkly Source: https://docs.flipt.io/v1/guides/migration/launchdarkly/overview Migrate from LaunchDarkly to Flipt in 4 simple steps If you're already a LaunchDarkly user, migrating from LaunchDarkly to Flipt is a simple, 4-step process. We suggest you follow the steps one after the other, in the order they're listed. This will allow you to rollback changes easily, in case of a migration error. 1. [**Migrating from LaunchDarkly SDK to OpenFeature SDK**](/v1/guides/migration/launchdarkly/openfeature) First, we'll identify all flag instances in your codebase, and migrate them from the traditional LaunchDarkly SDK to the OpenFeature SDK. This will enable us to make as little modifications as possible to your codebase, and allow you to replace feature flagging vendors with ease. 2. [**Adding the Flipt OpenFeature Provider**](/v1/guides/migration/launchdarkly/flipt#adding-the-flipt-openfeature-provider) Since Flipt supports OpenFeature, migrating to Flipt is as easy as changing the LaunchDarkly OpenFeature provider to the Flipt OpenFeature provider. 3. [**Installing Flipt**](/v1/guides/migration/launchdarkly/flipt#installing-flipt) In order to use Flipt, you will need to install it in your infrastructure. If you want us to handle the running and maintenance of Flipt, you can leverage our [Cloud](#) offering. 4. [**Migrate State from LaunchDarkly to Flipt**](/v1/guides/migration/launchdarkly/flipt#migrate-state-from-launchdarkly-to-flipt) The last part is to migrate all of your existing flags from the LaunchDarkly interface to your Flipt instance. Flipt has a new [Cloud](#) offering that allows you to scale your feature management platform without worrying about the underlying infrastructure. We'll assist you in LaunchDarkly to Flipt migration services for free, for all of our paying users. # Login with GitHub Source: https://docs.flipt.io/v1/guides/operation/authentication/login-with-github Configuring Flipt to enable login with GitHub via OAuth 2.0 If you've read the [Login With Google guide](/v1/guides/operation/authentication/login-with-google), you would have learned that Flipt supports many methods of authentication for users to control who has access to Flipt. Alongside the support for generic OIDC login, Flipt has launched support for login with GitHub in version [v1.26.0](https://github.com/flipt-io/flipt/releases/tag/v1.26.0), through their OAuth 2.0 flow. This guide will serve as a walk-through on how to set this flow up for users of Flipt in your organization. ## Prerequisites * [Docker](https://www.docker.com/) * [GitHub](https://github.com/) ## Brief Explanation of OAuth 2.0 OAuth 2.0 is an authentication standard whose goal is to allow 3rd party applications to access authorized resources from a provider. It relies on the user explicitly granting access to the 3rd party application to issue a token on behalf of the OAuth 2.0 provider for authorized use. OAuth 2.0 Flow Diagram Unlike OIDC, OAuth 2.0 does not have a standardized identity layer, which means the process of retrieving identity information varies between providers. Users should consult their OAuth 2.0 provider's documentation to understand the specific methods for retrieving identity information. ## Creating a GitHub OAuth 2.0 Application 1. Navigate to your GitHub account, and click on `Settings` under the menu of your Profile icon 2. At the bottom of the menu on the left, click on the menu option titled `Developer Settings` 3. This should bring you to a page that has `OAuth Apps` as a menu option on the left, click on that and click `New OAuth App` to start creating the application 4. You should be brought to a page that looks like the image below, and can start filling out the information: OAuth 2.0 App Creation * `Application Name`: Give your application a meaningful name * `Homepage URL`: Usually Flipt will be used internally by organizations, so this value depends on how you plan to expose Flipt. When in doubt you can just use the URL to your organization's home page * `Authorization callback URL`: For this value, you'll need your Flipt URL followed by `/auth/v1/method/github/callback`. Since we will be running Flipt in a Docker container locally, we will use `http://localhost:8080/auth/v1/method/github/callback` instead of actual Flipt URL. We're using `localhost:8080` here for illustration purposes. In a production setting, you would use whichever accessible domain name you have configured for your Flipt deployment. These values can always be changed later after the creation of the application. 5. Retrieve the `Client ID` and `Client Secret` from the created OAuth 2.0 app The Client ID should already be provided to you. You will have to generate a client secret. Click on the `Generate a new client secret` button (it may ask you to authenticate again with GitHub). ## Running Flipt ### 1. Define a Flipt `config.yml` Flipt relies on configuration that the user provides for many bits of functionality. To enable the Login With GitHub feature, you must define a configuration file `config.yml` with certain fields and values. The [configuration documentation](https://www.flipt.io/docs/configuration/overview) gives a complete list of all configuration values available for how to configure Flipt. The [Authentication Methods: GitHub](/v1/configuration/overview#authentication-methods-github) section of the configuration documentation describes the values needed to enable the Login with GitHub functionality. It should look similar to the following: ```yaml theme={null} version: "1.0" log: level: DEBUG authentication: required: true session: domain: localhost:8080 methods: github: enabled: true client_id: "< client ID from GitHub >" client_secret: "< client secret from GitHub >" redirect_address: "< Flipt URL with no path >" scopes: - "user:email" ``` The `client_id` and `client_secret` are going to be the values from your GitHub OAuth application. The `redirect_address` will be `http://localhost:8080`. The `scopes` are entirely dependent on what level of access you would like the returned GitHub access token to have. The [GitHub documentation](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps) describes a list of valid scopes. The last bit of configuration is the session details. In order for the browser to establish a session to communicate with Flipt in an authenticated way, you must provide access details in an HTTP cookie whose value is a static token created by Flipt. This static token is created during the GitHub OAuth 2.0 flow, and associated with the GitHub metadata retrieved from the GitHub API with the access token. The `domain` value will specify which host can receive the cookie. ### 2. Run Flipt as a Docker container ```bash theme={null} docker run -it --rm \ -p 8080:8080 \ -v "$(pwd)/config.yml:/config.yml" \ flipt/flipt:latest ./flipt --config /config.yml ``` This will mount the `config.yml` as a volume in the container, and Flipt will use that configuration as it's provided as a command line flag option. ### 3. Navigate to the Flipt UI Access the Flipt UI by typing in the `http://localhost:8080` URL in the address bar of a browser. You should see the following screen: Login With GitHub Click the button to Login With GitHub, and it should take you to the GitHub domain to complete the authentication flow with the following screen: GitHub Authorization Click on the green `Authorize {username}` button to allow completion of the OAuth 2.0 flow ## Conclusion After completion of the flow you should be taken to the normal Flipt homepage and start using Flipt normally as before. If you have a profile picture on GitHub, it should show in the top right corner. Flipt Dashboard This guide shows the basics of getting Flipt running with GitHub OAuth 2.0 authentication in a development environment. Now that you know the basics, you can tailor the configuration pieces to fit your exact use cases. For instance, you would not use `localhost:8080` in a production setting, but rather a custom domain. If you have a custom domain, you can modify the `Authorization Callback URL` value on the GitHub OAuth application page, the `redirect_address`, and `domain` configuration values for the Flipt configuration. # Login with Google Source: https://docs.flipt.io/v1/guides/operation/authentication/login-with-google Configuring Flipt to enable login with Google via OIDC Flipt UI presenting login with Google button In a production environment it's often important to control who has access to your systems and feature flagging is no different. Flipt ships with built-in mechanisms and configuration for service-to-Flipt and user-to-Flipt authentication. For service-to-Flipt authentication, Flipt supports static token and Kubernetes-based authentication methods. However, neither of these methods is appropriate for browser sessions and the UI. To solve this, Flipt supports [OpenID Connect](/v1/authentication/methods#openid-connect) (OIDC) as a session-compatible authentication method. OIDC is an open standard supported by many existing platforms such as Google, Okta, Auth0, GitLab, and many more. ## What You'll Learn In this guide, you will learn how to configure Google as an OIDC provider for Flipt. By the end of this guide, we will have: * 🔒 Run Flipt and configured it to `require` authentication * 🔑 Created an OAuth consent screen and client in your Google workspace * 🔐 Configured Google as an OIDC provider for Flipt ## Prerequisites For this guide you're going to need the following: * [Docker](https://www.docker.com/) * [Google Cloud Account](https://cloud.google.com) ## Brief Explanation of OIDC OIDC is an extension on top of the OAuth standard for delegated authentication. OAuth allows Flipt to delegate authentication to an external provider of your choice. The OIDC extension provides the **Relying Party** (Flipt in this case) with a well-known protocol for requesting identity from an **Identity Provider** (IdP) (Google in this example). It ensures that we can support a multitude of IdPs through a standard set of configuration parameters. This means we don't have to add more code to Flipt each time we want to support an additional identity provider. As long as the provider conforms to the OIDC standard, Flipt can be configured to leverage it. It also gives Flipt the option to obtain and present user profile pictures and email addresses in the UI. ## Running Flipt For the purpose of this guide, we will start by configuring and running Flipt with a minimal configuration file. ### 1. Define a Flipt `config.yml` We're going to create a configuration file named `config.yml` in the current directory. This file will tell Flipt to increase its logging level to the maximum to aid in debugging. It will also set authentication as `required = true`. This is needed to ensure that Flipt enforces its APIs and must be provided with a credential of some sort to gain access. ```yaml config.yml theme={null} version: "1.0" log: level: DEBUG authentication: required: true ``` ### 2. Run Flipt as a Docker container In this step, we run Flipt and mount our local `config.yml` file into the running container. This will start Flipt as a process in the foreground of your current terminal session. You can stop Flipt by entering `ctrl+C`. This particular command forwards your localhost port `8080` into the container's localhost port `8080`. The `8080` port is the default for Flipt's HTTP service and can be changed via the `server` configuration parameter. ```sh theme={null} docker run -it --rm \ -p 8080:8080 \ -v "$(pwd)/config.yml:/config.yml" \ flipt/flipt:latest ./flipt --config /config.yml ``` ### 3. Navigate to the Flipt UI Once you visit Flipt's UI, you should be greeted by a message stating that there are no login providers configured. As mentioned before, once authentication is required, a session-compatible method is needed to enable login. We're now going to do that by configuring Google as an OIDC provider for Flipt. UI presenting a no providers error message ## Creating a Google OAuth Client In order to get Google setup as our IdP, we need: 1. A Google Cloud account 2. To configure our [OAuth consent screen](https://developers.google.com/workspace/guides/configure-oauth-consent) 3. To create a set of [Google OAuth client ID credentials](https://developers.google.com/workspace/guides/create-credentials#oauth-client-id) Google's documentation will always be the most up-to-date source for how to achieve this. However, we will go over some of the details and strive to keep this guide up to date. ### 1. Configure your [OAuth Consent Screen](https://developers.google.com/workspace/guides/configure-oauth-consent) Your consent screen is the page you're navigated to when attempting to login via Google. This is where you need to configure your consent application name and the *scopes* Flipt can request. **Flipt requires the scope `openid`.** You can additionally choose to support both: * `https://www.googleapis.com/auth/userinfo.email` * `https://www.googleapis.com/auth/userinfo.profile` Doing so will allow Flipt to identify the caller in your audit logs by their email address. As well enabling the UI to present your users Google profile picture. You will have the option to create your OAuth application as `internal` or `external`. We recommend `internal` as that way only your internal Google workspace users can access Flipt. Make sure to configure the consent screen as per Google's instructions and set the scopes accordingly. ### 2. Create your OAuth Client Credentials 1. Navigate to [Google Console Credentials](https://console.cloud.google.com/apis/credentials). 2. Click `+ Create Credentials`. This presents us with a few options for credential types: * API Key * OAuth client ID * Service Account Google cloud create credentials popover Select the `OAuth client ID` type and you will be taken to an input form (like the one below). Select the `Web application` option when prompted to select an `Application type`. Once selected you will be presented with more input options. Google cloud create oauth client ID form 3. Configure the client's name and redirect URL. As shown in the screenshot, we'll want to enter the following values for the inputs: * Application type: `Web application` * Name: `Flipt` (something to identify the purpose of the credentials) Under the **Authorized redirect URIs** heading select `+ ADD URI`. > Don't get this confused with *Authorized JavaScript origins* This will present us with an input box which we will populate with the following value: ```url theme={null} http://localhost:8080/auth/v1/method/oidc/google/callback ``` The URL `http://localhost:8080/auth/v1/method/oidc/google/callback` is the redirect URL for your local running instance. In a production environment, you would replace the domain part of the URI with the public address of your Flipt instance. 4. Click `Create`. This should create your credentials if all your inputs validate correctly. You should be presented with a modal containing your new client credentials. Example modal containing Google OAuth client credentials You will need to take note of these values, as you're going to use them in the next step. ## Configuring Flipt With OIDC Credentials Now that we've an OAuth client configured in our Google Cloud account, we can begin configuring Flipt to leverage it. ### 1. Add `google` provider to `config.yml` Open your `config.yml` we created in the [beginning of the guide](#1-define-a-flipt-config-yml). Now we're going to update your configuration with the details we obtained from Google. The configuration below does the following for Flipt: * Enables the OIDC method * Configures the session domain * Defines an OIDC provider called `google` * Adds the specific configuration and credentials for the Google OIDC provider Your configuration should look something like the following: ```yaml config.yml theme={null} version: "1.0" log: level: DEBUG authentication: required: true session: domain: localhost:8080 methods: oidc: enabled: true providers: google: issuer_url: "https://accounts.google.com" client_id: "< client ID from Google >" client_secret: "< client secret from Google >" redirect_address: "http://localhost:8080" scopes: - email - profile ``` The session domain is required for session-compatible authentication methods. It's used by Flipt as the domain for storing authentication cookies. Note that we've enabled the `oidc` method, and it has a section called `providers`. Each key beneath the `providers` section is unique and can be whatever you want. However, the name is important as it affects the `redirect_url` generated for the particular provider. If you change this provider name from `google` to something else, then you will need to update your [OAuth client details](#3-configure-the-oauth-client) in Google Cloud. For example, changing it from `google` to `gcp` would result in the redirect URI changing like so: ```diff theme={null} - http://localhost:8080/auth/v1/method/oidc/google/callback + http://localhost:8080/auth/v1/method/oidc/gcp/callback ``` Each provider section has a consistent structure. You're required to provide the `issuer_url`, `client_id`, `client_secret` and `redirect_address`. The `scopes` section is optional, and allows Flipt the opportunity to obtain additional details on the authenticating caller (e.g. email and profile picture). ### 2. Restart Flipt You can now stop and start your Flipt instance using the Docker command we described in Section 1. Once Flipt has restarted you can navigate your browser to the [UI](http://localhost:8080) and attempt a login with Google. When you click `Login with Google` you should be navigated away to your Google consent screen. Once you grant consent, you should return to Flipt and be logged into Flipt. ## Production and Beyond 🎉 Congratulations, you've successfully run Flipt and enabled login with Google as the OIDC provider. You're now equipped with everything you need to get this working in a production environment. To help you across the finishing line, here are some tips and considerations to keep in mind. ### 1. Custom Flipt Domain In reality, you're not going to run Flipt on `localhost`. You're going to host it on some domain name on the public internet or within a VPN. A few touch points will need to be updated with your new domain. For example, consider the domain `https://flipt.internal.dev`. 1. Update your Google OAuth Client You will need to update the **redirect URI** of your OAuth client in Google with this domain. ```diff theme={null} - http://localhost:8080/auth/v1/method/oidc/google/callback + https://flipt.internal.dev/auth/v1/method/oidc/google/callback ``` 2. Session `domain` and provider `redirect_address` Now that we're hosting under a new domain, we need to instruct Flipt where to store cookies and what our redirect address is going to be. ```diff config.yml theme={null} version: "1.0" log: level: DEBUG authentication: required: true session: - domain: localhost:8080 + domain: flipt.internal.dev methods: oidc: enabled: true providers: google: issuer_url: "https://accounts.google.com" client_id: "< client ID from Google >" client_secret: "< client secret from Google >" - redirect_address: "http://localhost:8080" + redirect_address: "https://flipt.internal.dev" scopes: - email - profile ``` ### 2. Securing Flipt 1. Enable CSRF protection Using browser session based authentication puts applications at risk of cross-site request forgery attacks. Flipt supports automatic CSRF prevention via signed token strings, using a shared signing key. Check out our [Configuration: Session](/v1/configuration/authentication#session) documentation for details on how to configure this. 2. Move credentials to environment variables Sometimes for security purposes you don't want to be inserting your sensitive credentials (such as provider `client_secret` or your CSRF `key`) into a configuration file. Flipt supports defining configuration in its YAML file and as environment variables. Check out our [Configuration: Environment Variables](/v1/configuration/overview#environment-variables) section for details on how to provide configuration as environment variables. As a quick example, both the Google provider `client_secret` and the CSRF signing `key` can be presented to Flipt like so: ```sh theme={null} FLIPT_AUTHENTICATION_METHODS_OIDC_PROVIDERS_GOOGLE_CLIENT_SECRET=< oauth client secret > FLIPT_AUTHENTICATION_SESSION_CSRF_KEY=< CSRF token signing key > ``` # Login with Keycloak Source: https://docs.flipt.io/v1/guides/operation/authentication/login-with-keycloak Configuring Flipt to enable login with Keycloak via OIDC Flipt UI presenting login with Keycloak button If you've read the [Login With Google guide](/v1/guides/operation/authentication/login-with-google), you would have learned that Flipt supports many methods of authentication for users to control who has access to Flipt. [Keycloak](https://www.keycloak.org/) is an open-source identity and access management solution that supports OpenID Connect (OIDC). This guide will serve as a walk-through on how to set up Keycloak for authentication of users of Flipt in your organization. ## What You'll Learn In this guide, you will learn how to configure Keycloak as an OIDC provider for Flipt. By the end of this guide, we will have: * ⚙️ Setup Keycloak by creating a realm, user, and client * 🔒 Configured Keycloak as an OIDC provider for Flipt ## Prerequisites For this guide you're going to need the following: * [Docker](https://www.docker.com/) * Read the [Login With Google guide](/v1/guides/operation/authentication/login-with-google) ## Setting Up Keycloak To set up Keycloak for authentication, you will need to create a new realm, client, and user. This section of the guide is a simplified version of the [Keycloak: Getting Started Docker Guide](https://www.keycloak.org/getting-started/getting-started-docker). ### 1. Start Keycloak Start Keycloak using Docker: ```bash theme={null} docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:24.0.4 start-dev ``` ### 2. Access Keycloak Access Keycloak at [http://localhost:8080](http://localhost:8080) and log in with the admin credentials (`admin`/`admin`). ### 3. Create a Realm Create a new realm called `flipt`: 1. Click on `Keycloak` in the top-left corner. 2. Click on the `Create realm` button. 3. Enter `flipt` as the realm name. 4. Click on the `Create` button. Keycloak create realm form ### 4. Create a User Create a new user called `user`: 1. Click on the `Users` tab. 2. Click on the `Create new user` button. 3. Fill in the user details and click on the `Create` button. 4. Set the user's password by clicking on the `Credentials` tab and click `Set Password`. 5. Enter a password and confirm the password. 6. Toggle `Temporary` to `OFF` so that the user does not need to change their password on the first login. 7. Click `Save`. Keycloak create user ### 5. Create a Client Create a new client called `flipt`: 1. Click on the `Clients` tab. 2. Click on the `Create Client` button. 3. Ensure `OpenID Connect` is selected as the client type. 4. Enter `flipt` as the client ID and click on `Next`. 5. Ensure the `Standard flow` and `Direct access grants` are enabled and click on `Next`. 6. Set the `Valid Redirect URIs` to `http://localhost:8081/auth/v1/method/oidc/keycloak/callback`. 7. Set the `Web Origins` to `http://localhost:8081`. 8. Ensure `Client authentication` is set to `ON`. 9. Click on `Save`. Keycloak create client ### 6. Copy Client ID and Secret 1. From the `flipt` client, click on the `Credentials` tab. 2. The client ID will be displayed at the top of the page (e.g., `flipt`). Copy this value and save it for later. 3. Click on the copy icon next to the `Client Secret` field to copy the client secret. Save this value for later. ### 7. Get Required URLs 1. In another browser tab, paste the following URL into the address bar: ``` http://localhost:8080/realms/flipt/.well-known/openid-configuration ``` 2. Copy the `issuer` URL from the JSON response. This will be used as the `issuer_url` in the Flipt configuration. Keycloak OIDC configuration ## Running Flipt Now that we have an OIDC client configured in our Keycloak instance, we can begin configuring Flipt to leverage it. ### 1. Define a Flipt `config.yml` We're going to create a configuration file named `config.yml` in the current directory. This file will tell Flipt to increase its logging level to the maximum to aid in debugging. We will also set the HTTP port to `8081` to avoid conflicts with Keycloak. It will also set authentication as `required = true`. This is needed to ensure that Flipt enforces its APIs and must be provided with a credential of some sort to gain access. ```yaml config.yml theme={null} version: "1.0" log: level: DEBUG server: http_port: 8081 authentication: required: true ``` ### 2. Add `keycloak` provider to `config.yml` In your `config.yml` file, add the following configuration in the `authentication` section to enable the OIDC method and configure the Keycloak provider: ```yaml config.yml theme={null} authentication: required: true session: domain: localhost:8081 methods: oidc: enabled: true providers: keycloak: issuer_url: "< issuer URL from Keycloak >" client_id: "< client ID from Keycloak (e.g., `flipt`) >" client_secret: "< client secret from Keycloak >" redirect_address: "http://localhost:8081" ``` The session domain is required for session-compatible authentication methods. It's used by Flipt as the domain for storing authentication cookies. Note that we've enabled the `oidc` method, and it has a section called `providers`. Each key beneath the `providers` section is unique and can be whatever you want. However, the name is important as it affects the `redirect_url` generated for the particular provider. Each provider section has a consistent structure. You're required to provide the `issuer_url`, `client_id`, `client_secret` and `redirect_address`. The `scopes` section is optional, and allows Flipt the opportunity to obtain additional details on the authenticating caller (e.g. email and profile picture). ### 3. Start Flipt You can now start your Flipt instance using the following command: ```sh theme={null} docker run -it --rm \ -p 8080:8080 \ -v "$(pwd)/config.yml:/config.yml" \ flipt/flipt:latest ./flipt --config /config.yml ``` Once Flipt has started you can to navigate your browser to the [UI](http://localhost:8081) and attempt a login with Keycloak. When you click `Login with Keycloak` you should be navigated away to your Keycloak instance to complete the authentication flow. Keycloak login screen Once you successfully authenticate with the username/password you created earlier, you should return to Flipt and be logged in. Flipt dashboard ## Conclusion 🎉 Congratulations, you've successfully run Flipt and enabled login with Keycloak as the OIDC provider. Many of the same production considerations from the [Login With Google guide](/v1/guides/operation/authentication/login-with-google) apply here. You should follow the same steps to secure your Flipt instance and ensure that only authorized users can access it. Next, you might want to consider enabling authorization and setting up policies to control who can access what in Flipt. You can learn more about this in the [Role-Based Access Control with Keycloak guide](/v1/guides/operation/authorization/rbac-with-keycloak). # Role-Based Access Control with Keycloak Source: https://docs.flipt.io/v1/guides/operation/authorization/rbac-with-keycloak Configure and use role-based access control (RBAC) with Flipt, Keycloak, and OPA. As described in the [Authorization Overview](/v1/authorization/overview), Flipt supports the ability to secure its core API routes with authorization in a flexible and extensible way. This guide will cover how to configure and use role-based access control (RBAC) with Flipt with a Rego policy configured for an imaginary organization using Keycloak for authentication. Role-based access control (RBAC) is not a feature of Flipt itself but rather a pattern that can be implemented using Flipt's authorization system via OPA. ## What You'll Learn * 🔒 How to set up Keycloak for authorization * 🔑 How to create a Rego policy for RBAC with Flipt * ⚙️ How to configure Flipt to use the policy for authorization ## Prerequisites For this guide, you will need: * [Docker](https://www.docker.com/) * Follow the [Login with Keycloak guide](/v1/guides/operation/authentication/login-with-keycloak) to set up Keycloak for authentication ## Setting Up Keycloak To set up Keycloak for authorization, you'll first need to create a new realm, client, and user. ### 1. Follow the Login with Keycloak Guide Follow the [Login with Keycloak guide](/v1/guides/operation/authentication/login-with-keycloak) to set up Keycloak for authentication. This guide will walk you through setting up Keycloak and creating a realm, client, and user that you will use for this guide. Flipt UI presenting login with Keycloak button ### 2. Create a Realm Role 1. Login to Keycloak as an admin user. 2. Click on the `Realm Roles` tab. 3. Click `Create Role`. 4. Enter `developer` as the role name and description and click `Save`. Create Role ### 3. Assign the Role to a User 1. Click on the `Users` tab. 2. Click on the `user` user. 3. Click on the `Role Mappings` tab. 4. Click `Assign Role`. 5. Select the `developer` role and click `Assign`. Assign Role ### 4. Map Client Scopes Map the `roles` scope to the `flipt` client: 1. Click on the `Clients Scopes` tab. 2. Click on `roles` in the list of client scopes. 3. Click on the `Mappers` tab. 4. Click on `realm roles` in the list of mappers. Map Client Scopes 5. Set the `Token Claim Name` field to something short like `roles`. 6. Set the `Claim JSON Type` field to `String`. 7. Toggle on `Add to ID token`. 8. Click `Save`. Customize Role Mapper ## Configuring RBAC in Flipt To configure RBAC with Flipt, you will need to define a Rego policy that enforces the roles and permissions for your organization. Here's an example of a simple policy that checks whether a user has the `developer` role: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "developer" in claims.roles } ``` In this example, the policy checks if the user has the `developer` role. If the user has the `developer` role, the policy will allow the request. Otherwise, the request will be denied. The `authentication` input is provided by Flipt to OPA and contains the authentication information for the request. This information is specific to the authentication method used to authenticate the request. More complex policies can be defined to enforce fine-grained access control based on your organization's requirements. For example, you could define policies that check for specific roles and permissions for different resources or actions. An example policy that allows users with the `developer` role to have full access to the Management API and users with the `viewer` role to have read-only access might look like this: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "developer" in claims.roles } allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "viewer" in claims.roles input.request.verb = "read" } ``` ### 1. Write the Rego Policy 1. Create a new file called `policy.rego` with the following content: ```rego policy.rego theme={null} package flipt.authz.v1 import rego.v1 default allow := false allow if { claims := json.unmarshal(input.authentication.metadata["io.flipt.auth.claims"]) "developer" in claims.roles } ``` ### 2. Configure Flipt to Use the Policy Update the `flipt.yaml` configuration file from the [Login with Keycloak guide](/v1/guides/operation/authentication/login-with-keycloak) to enable authorization and specify the path to the Rego policy file: ```yaml flipt.yaml theme={null} authentication: required: true session: domain: localhost:8081 methods: oidc: enabled: true providers: keycloak: issuer_url: "< issuer URL from Keycloak >" client_id: "< client ID from Keycloak (e.g., `flipt`) >" client_secret: "< client secret from Keycloak >" redirect_address: "http://localhost:8081" authorization: required: true backend: local local: policy: path: "policy.rego" ``` ### 3. Run Flipt You can now start your Flipt instance using the following command: ```sh theme={null} docker run -it --rm \ -p 8080:8080 \ -v "$(pwd)/config.yml:/config.yml" \ -v "$(pwd)/policy.rego:/policy.rego" \ flipt/flipt:latest ./flipt --config /config.yml ``` ## Testing the Policy To test the policy, login to Flipt using the user you created in Keycloak. If the user has the `developer` role, they should be able to access the Flipt Management API. You can create a new user in Keycloak that does not have the `developer` role to test that the policy is working as expected. If the user does not have the `developer` role, they should receive an error message in the UI or API response. Unauthorized Access ## Conclusion In this guide, you learned how to configure and use role-based access control (RBAC) with Flipt using a Rego policy and Keycloak for authentication. By defining a Rego policy that enforces the roles and permissions for your organization, you can secure your Flipt instance and control access to your feature data with fine-grained permissions and infinite flexibility. For more information on Flipt's authorization system and how to configure and use it, see the [Authorization Overview](/v1/authorization/overview). In the future, we plan to provide more examples and best practices for using Flipt's authorization system with different authentication providers and use cases. If you have any feedback or suggestions for how we can improve this guide, please let us know! # Deploy to Fly.io Source: https://docs.flipt.io/v1/guides/operation/deployment/deploy-to-flyio Deploy Flipt to Fly.io with Postgres [Fly.io](https://fly.io) is a platform for running applications close to users. This guide will show you how to deploy Flipt to Fly.io and configure Flipt to use a Postgres database, also managed by Fly.io. ## What You'll Learn In this guide, you will learn how to deploy Flipt to Fly.io with Postgres. You'll also learn how to configure Flipt with environment variables. By the end of this guide, we will have: * 🚀 Successfully deployed Flipt to Fly.io * 🐘 Configured Flipt with environment variables to use Fly.io's managed Postgres service ## Prerequisites * A Fly.io account (Sign up: [https://fly.io](https://fly.io)) * `flyctl` CLI installed on your local machine (Installation guide: [https://fly.io/docs/getting-started/installing-flyctl/](https://fly.io/docs/getting-started/installing-flyctl/)) ## Deployment Steps 1. Ensure you can log in to your Fly.io account with `fly auth login`. 2. Create and `cd` into a new directory for your Flipt deployment. (e.g. `mkdir flipt-test && cd flipt-test`) 3. Begin the launch process to deploy Flipt on Fly.io using their CLI, selecting mainly the defaults and Postgres when prompted: We specify the ghcr.io/flipt-io/flipt:latest image, which is the latest stable release of Flipt. You can also use a specific version of Flipt by replacing latest with a specific version tag (e.g. ghcr.io/flipt-io/flipt:v1.23.0). ```console theme={null} $ fly launch -i ghcr.io/flipt-io/flipt:latest ? App Name (leave blank to use an auto-generated name) flipt-test Automatically selected personal organization: ... ? Would you like to set up a Postgresql database now? Yes ``` Note the Postgres database connection string that's printed during the launch process. You will need this to configure Flipt. 4. After the launch process completes, it will write a `fly.toml` file to your current directory. You can configure the number of instances, memory, and CPU allocated to your Flipt deployment. You can also set environment variables to customize Flipt's configuration. For more information, refer to the [Fly.io documentation](https://fly.io/docs/reference/configuration/) and the [Flipt documentation](/v1/configuration/overview). 5. Before deploying Flipt, we'll need to set the `FLIPT_DB_URL` secret to point to your newly configured Postgres database. You can do this with the following command, replacing `` with the connection string from the launch process and appending the db name (postgres) and `?sslmode=disable`: ```console theme={null} fly secrets set FLIPT_DB_URL=/postgres?sslmode=disable ``` 6. Finally, deploy Flipt to Fly.io with `fly deploy`. ```console theme={null} $ fly deploy Deploying flipt-test ==> Validating App Configuration ``` ## Verifying the Deployment After deployment, you can verify if Flipt is running correctly by accessing the Flipt UI on the provided Fly.io URL or issue the command `fly open` in the CLI to open your newly deployed Flipt instance in the browser. ```console theme={null} $ fly open opening https://flipt-test.fly.dev/ ... ``` Flipt UI ## Configuration You can configure Flipt with [environment variables](/v1/configuration/overview#environment-variables) in the `fly.toml` file. For example, to configure Flipt to use a custom port and enable DEBUG logging you can add the following to the `fly.toml` file: ```toml fly.toml theme={null} # See https://fly.io/docs/reference/configuration/ for information # about how to use this file. app = "flipt-test" primary_region = "iad" [build] image = "ghcr.io/flipt-io/flipt:latest" [http_service] internal_port = 9090 force_https = true [env] FLIPT_SERVER_HTTP_PORT = 9090 FLIPT_LOG_LEVEL = "debug" ``` After making changes to the `fly.toml` file, you can deploy the changes with `fly deploy`. ```console theme={null} $ fly deploy Deploying flipt-test ==> Validating App Configuration ``` ## Troubleshooting If you encounter any issues during the deployment, check the logs on Fly.io for any error messages: ```console theme={null} fly logs ``` Enabling DEBUG logging as shown above can be helpful for troubleshooting any issues during Flipt startup. ## Conclusion Deploying Flipt to Fly.io allows you to get up and running with Flipt quickly. For production deployments however, you'll likely want to configure Flipt with [authentication](/v1/configuration/authentication) as well as consider configuring [caching](/v1/configuration/storage#caching), [observability](/v1/configuration/observability), and using a [read replica](https://fly.io/docs/postgres/advanced-guides/high-availability-and-global-replication/) for your database. For more information on production deployments, refer to the [Deployment](/v1/operations/deployment) section of the documentation. # Deploy to Kubernetes Source: https://docs.flipt.io/v1/guides/operation/deployment/deploy-to-kubernetes Deploy Flipt to Kubernetes using our Helm chart ## What You'll Learn In this guide, you will learn how to deploy Flipt to a local Kubernetes cluster (via [Kind](https://kind.sigs.k8s.io/)) using our official Helm chart. You'll also learn how to override the default Flipt configuration by providing a `values.yaml` file. By the end of this guide, we will have: * 🚢 Created a Kind cluster locally using Docker * 📦 Installed Flipt into your cluster via Helm * ⚙️ Configured Flipt log level and other settings via a `values.yaml` file ## Prerequisites * Docker installed ([Download](https://www.docker.com/products/docker-desktop)) * Helm v3.x installed ([Installation guide](https://helm.sh/docs/intro/install/)) * Kind installed ([Installation guide](https://kind.sigs.k8s.io/docs/user/quick-start/)) ## Deploying Flipt ### 1. Create a Local Kubernetes Cluster Using Kind First, we need to create a local Kubernetes cluster. We'll use [Kind](https://kind.sigs.k8s.io/) to accomplish this. Open a terminal and run the following command: ```bash theme={null} kind create cluster --name flipt ``` This command will create a new Kubernetes cluster named `flipt`. Wait for the command to complete and ensure the cluster is correctly set up. ### 2. Add the Flipt Helm Repository Next, we'll add the [Flipt Helm repository](https://helm.flipt.io/) which hosts the Flipt Helm charts. Run the following command: ```bash theme={null} helm repo add flipt https://helm.flipt.io/ ``` After running this command, Helm will fetch shared information about the new repository. ### 3. Update Helm Repositories To ensure that Helm has the latest information about the charts from the Flipt Helm repository, update the repositories: ```bash theme={null} helm repo update ``` ### 4. Install Flipt with Custom Configuration Before installing Flipt, you should create a `values.yaml` file to customize the deployment according to your preferences. For example, to set a specific configuration value, you could add the following to your `values.yaml` file: ```yaml theme={null} flipt: config: log: level: WARN cache: enabled: true backend: memory ``` This example sets the Flipt server log level to 'WARN' and also enables our in-memory cache. You can adjust this file to include any configuration values you need. Once you have your `values.yaml` file, you can use it when installing Flipt with Helm by using the `-f` or `--values` flag: ```bash theme={null} helm install flipt flipt/flipt -f values.yaml ``` This command installs the Flipt Helm chart into your Kubernetes cluster using the configuration options specified in your `values.yaml` file merged with the default values from Flipt. The `values.yaml` file allows you to customize many aspects of the deployment, including resource limits and requests, service types, replica counts, and more. Be sure to consult the [Flipt documentation](https://www.flipt.io/docs/configuration/overview) and the default `values.yaml` in the Flipt Helm chart for more information on what can be configured. ### 5. Forward the Port to Access Flipt After successfully installing Flipt via the Helm chart, you should see instructions on how to access Flipt in your terminal. The instructions will look something like this: ```bash theme={null} You have successfully deployed Flipt. export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=flipt,app.kubernetes.io/instance=flipt" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT ``` Execute the commands in your terminal to forward the port and access Flipt. You should now be able to access Flipt at `http://localhost:8080`. ### 6. Verify the Installation and Configuration To ensure that Flipt has been correctly deployed to your Kubernetes cluster, you can check the running pods: ```bash theme={null} kubectl get pods ``` You should see the Flipt pod in the list with a status of `Running`. ```console theme={null} NAME READY STATUS RESTARTS AGE flipt-6d64f856d7-4l5qn 1/1 Running 0 32m ``` To verify that your configuration changes were applied, you can `curl` Flipt's `/meta/config` endpoint: ```bash theme={null} curl --silent http://localhost:8080/meta/config | jq ``` In the output of this command, you should see the configuration values you set in your `values.yaml` file. ```json theme={null} "log": { "level": "WARN", ... }, "cache": { "enabled": true, "backend": "memory", ... }, ``` ## Next Steps Congratulations! You've successfully deployed Flipt to a local Kubernetes cluster using our Helm chart. You've also learned how to override the default Flipt configuration by providing a `values.yaml` file. You should be able to take the knowledge you've gained in this guide and deploy Flipt in to a real Kubernetes cluster. Please refer to the [Flipt Helm chart repository](https://github.com/flipt-io/helm-charts) for more information on how to configure Flipt using the Helm chart. Additionally, you should checkout our documentation on our native [Kubernetes authentication method](/v1/authentication/methods#kubernetes). This method can be leveraged to automatically authenticate clients, without the need to manually manage credentials, for applications deployed into the same Kubernetes cluster as Flipt. # Get Going with GitOps Source: https://docs.flipt.io/v1/guides/user/get-going-with-gitops Configuring Flipt for a GitOps workflow ## Why GitOps? GitOps is a set of practices centered around storing your application and infrastructure configuration in Git. The goal being to leverage the capabilities of version-control for your entire systems configuration. If you're already embracing GitOps practices for your other configuration, then aligning your feature flags with these same practices can complete the experience. No more correlating what changed in Git, with what changed in your feature flag system to understand the entire state of the world. Git is the single source of truth as GitOps intended. So how do we achieve this with Flipt? ## What You'll Learn In this guide you will: * 🏁 Add a feature flag to an existing codebase * 📝 Define the flag via Flipt's configuration format * 🌲 Add, commit, and push the change to a production-serving branch * 🎯 Adjust our configuration to target an internal group of users in our organization * 🌓 Progressively enable the flag for proportions of the user base ## Setting the Scene Our guide starts with an imaginary organization with a single web application defined in Go and committed to a GitHub repository. We as the developer, have been tasked to experiment with a new sorting algorithm on an endpoint for our application. Our application handles requests from authenticated users. These users also happen to be grouped into organizations. We will use this information in our targeting rules later on. This endpoint happens to list out a bunch of strings in a JSON array. The sorting algorithm previously used was slow (Bubble Sort), and we want to try something new (Quicksort). While we feel confident in our implementation, we're going to practice caution and release the change behind a feature flag. ### Structure If you want to follow along you can fork our [gitops guide repository](https://github.com/flipt-io/guides). ```bash theme={null} . ├── go.mod ├── go.sum ├── main.go └── pkg └── server └── words.go ``` Our application lives in a directory committed to a Git repository. For the example's sake, we assume the repository will be hosted on GitHub at `https://github.com/organization/repository.git`. The target of our change is a `http.HandlerFunc` definition (in the file `pkg/server/words.go`) with the name `ListWords`. Currently, the function uses a sorting function `bubblesort` and we're going to swap this for the `quicksort` function. ```go pkg/server/words.go theme={null} func (s *Server) ListWords(w http.ResponseWriter, r *http.Request) { words, err := getWords(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } bubblesort(words) if err := json.NewEncoder(w).Encode(words); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } ``` ### Calling Flipt Instead of calling `bubblesort` directly, we're going to use the [Flipt Go SDK](https://github.com/flipt-io/flipt/blob/main/sdk/go) to switch this call based on the feature flag `use-quicksort-algorithm`. This flag is going to be a **boolean** type flag, and so we use the `sdk.Evaluation().Boolean()` call to evaluate the `enabled` property of our flag. We provide this evaluation call with a request containing the flags key, an entity ID and a context map. ```diff diff.go theme={null} func (s *Server) ListWords(w http.ResponseWriter, r *http.Request) { words, err := getWords(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - bubbleSort(words) * flag, err := s.flipt.Evaluation().Boolean(r.Context(), &evaluation.EvaluationRequest{ * FlagKey: "use-quicksort-algorithm", * EntityId: getUser(r.Context()), * Context: map[string]string{ * "organization": getOrganization(r.Context()), * }, * }) * * if flag.Enabled { * quicksort(words) * } else { * bubblesort(words) * } if err := json.NewEncoder(w).Encode(words); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } ``` ```go pkg/server/words.go theme={null} func (s *Server) ListWords(w http.ResponseWriter, r *http.Request) { words, err := getWords(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } flag, err := s.flipt.Evaluation().Boolean(r.Context(), &evaluation.EvaluationRequest{ FlagKey: "use-quicksort-algorithm", EntityId: getUser(r.Context()), Context: map[string]string{ "organization": getOrganization(r.Context()), }, }) if flag.Enabled { quicksort(words) } else { bubblesort(words) } if err := json.NewEncoder(w).Encode(words); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } ``` The entity ID used here is going to be an identifier for the requests authenticated user. This is returned by the call to `getUser(r.Context())`. Our context map is going to contain a single key `organization`, which is populated by a call to `getOrganization(r.Context())`. This will also return an identifier, only this time for the requesting user's organization. ## Flipt's Declarative Backends The focus of this guide is to leverage Flipt's new "declarative backends" to enable a GitOps workflow. The name comes from the fact that the backend for Flipt is modeled around configuration files in a directory structure. These configuration files can coexist in a directory alongside other content (application code or other configuration code). There currently exist four top-level declarative backend types: * `local` (local directory) * `git` (remote Git repository and branch) * `object` (object storage, AWS S3 or Azure Blob Storage or Google Cloud Storage) * `oci` (OCI registry storage) In this guide we will explore both the `local` and `git` backend types. ### Defining Flag State Locally In order for our application to work, it now depends on communicating with an instance of Flipt. We're going to configure our instance using a `features.yml` file in the root of our existing project. Then we will configure Flipt to serve directly from our local directory. You don't have to call your file `features.yml` and you can spread your flag definitions across multiple files. Checkout our docs on [locating flag state](/v1/configuration/storage#locating-flag-state) to learn more. ```diff theme={null} . +├── features.yml ├── go.mod ├── go.sum ├── main.go └── pkg └── server └── words.go ``` The contents of this file is going to start out with the definition of the `use-quicksort-algorithm` flag. This flag will be a *boolean* type flag and be in a disabled (`enabled = false`) state. ```yaml features.yml theme={null} version: "1.2" namespace: default flags: - key: use-quicksort-algorithm name: Use Quicksort Algorithm type: BOOLEAN_FLAG_TYPE enabled: false ``` ### Running Flipt Locally Now the flag is defined in the current directory, we can run Flipt and configure the directory as the source of truth. This is useful for validating behaviour locally, before committing and pushing flag state to a production tracked Git repository. The following command runs Flipt in Docker, with the local directory mounted and Flipt configured appropriately. ```bash theme={null} docker run -it --rm \ -p 8080:8080 \ -p 9000:9000 \ -v "$(pwd):/data" \ -e FLIPT_STORAGE_TYPE=local \ -e FLIPT_STORAGE_LOCAL_PATH=/data \ flipt/flipt:latest ``` Flipt instance showing flag in disabled state > This image demonstrates what can be seen in the Flipt UI with the configuration file we defined being served. Now that Flipt is running locally, our application can also be run and configured to target our local instance of Flipt available at both `http://localhost:8080` and `grpc://localhost:9000` (depending on your protocol of choice). The UI is also available on port `8080`, however, it's running in **read-only mode** since flag state is configured via the configuration file we defined before. ### Running Flipt Over Git The `local` backend is useful for experimenting and exploring flag state in your development environment. However, in a production setting, both the `git` and the `object` storage types are more appropriate. Focussing on `git`, the following command runs Flipt with a remote Git repository hosted on GitHub and tracking the `main` branch. ```bash theme={null} docker run -it --rm \ -p 8080:8080 \ -p 9000:9000 \ -e FLIPT_STORAGE_TYPE=git \ -e FLIPT_STORAGE_GIT_REPOSITORY=https://github.com/organization/repository.git \ -e FLIPT_STORAGE_GIT_REF=main \ -e FLIPT_STORAGE_GIT_AUTHENTICATION_BASIC_USERNAME=username \ -e FLIPT_STORAGE_GIT_AUTHENTICATION_BASIC_PASSWORD=github-personal-access-token \ flipt/flipt:latest ``` In this example, Flipt has been configured to serve directly from our pretend repository with our application code in it. Flipt will track the HEAD of this repository's `main` branch. Changes will eventually propagate into our running instance of Flipt. Head to [Configuration: Storage: Declarative Backends](/v1/configuration/storage#declarative) to learn more about configuring these backend types for Flipt. ### Pushing Our New Flag To Production For sake of this demonstration, we're going to assume Flipt has been deployed and configured in this way for our production environment. Our production deployment of our words endpoint will also have been configured to connect to this running instance of Flipt. Given our repository is now being tracked and served by Flipt, we can add, commit, and push both our changes to our endpoint, as well as our new `features.yml` file to our branch `main`. ```bash theme={null} git add pkg/server/words.go git add features.yml git commit -m "feat: define the use-quicksort-algorithm flag" git push origin main ``` Once Flipt has received the updated reference, our flag should be available through Flipt's API. The code change we added can now safely reference the present flag, which is currently in a `disabled` state. You can use `curl` to ensure the service is still behaving as expected: ```bash theme={null} # the -w option prints timing output at the end curl -w "\nTotal: %{time_total}s\n" "http://localhost:8000/words" ``` Next we will begin to enable the flag under different conditions. ## Targeting and Rollouts Now that our application is deployed with our code change and is referencing our new flag, we can adjust the state via the configuration file and push the changes to Git. We will start by checking out a new branch, as we're going to propose our change as a pull request and get review from a colleague. ```bash theme={null} git checkout -b enable-flag-for-internal-organization ``` ### Internal Users We open the `features.yml` file and update the definition with a new segment and add a rollout rule on our flag which returns `enable = true` when the request matches our new segment. ```diff features.diff theme={null} version: "1.2" namespace: default flags: - key: use-quicksort-algorithm name: Use Quicksort Algorithm type: BOOLEAN_FLAG_TYPE enabled: false + rollouts: + - segment: + key: internal-users + value: true +segments: +- key: internal-users + name: Internal Users + match_type: ANY_MATCH_TYPE + constraints: + - property: organization + operator: eq + value: internal + type: STRING_COMPARISON_TYPE ``` ```yaml features.yml theme={null} version: "1.2" namespace: default flags: - key: use-quicksort-algorithm name: Use Quicksort Algorithm type: BOOLEAN_FLAG_TYPE enabled: false rollouts: - segment: key: internal-users value: true segments: - key: internal-users name: Internal Users match_type: ANY_MATCH_TYPE constraints: - property: organization operator: eq value: internal type: STRING_COMPARISON_TYPE ``` Breaking this change down we've got: #### The `internal-users` Segment ```yaml features.yml theme={null} # ... segments: - key: internal-users name: Internal Users match_type: ANY_MATCH_TYPE constraints: - property: organization operator: eq value: internal type: STRING_COMPARISON_TYPE ``` This [segment](/v1/concepts#segments) definition matches any evaluation request where there exists a key `organization` on the context, with a value `internal`. Remember we added the key `organization` earlier when defining the flag in code. We used a value derived from the request (`getOrganization(r.Context())`). This got the organization identifier for the calling user. Now, when the user happens to be associated with the `internal` organization, it will match the `internal-users` segment in Flipt. #### A New Segment Rollout Rule ```yaml features.yml theme={null} flags: - key: use-quicksort-algorithm # ... rollouts: - segment: key: internal-users value: true ``` Finally, we add a [rollout rule](/v1/concepts#rollouts) to our boolean flag. This rule allows us to override the `enabled` property of the flag under certain conditions. In this instance, we're using the `segment` type rule to say when the request matches the `internal-users` segment, return the value `true`. Now our flag is configured to target internal users and enable the Quicksort algorithm for those users instead. #### Proposing and Integrating Our Change Next, we add, commit, and push the change to our branch. ```bash theme={null} git add features.yml git commit -m "feat: enable use-quicksort-algorithm for internal-users" git push enable-flag-for-internal-organization ``` From here, we can open a pull-request and get feedback from our team. Once approval has been given, we can merge the PR and the change goes live. When the change has been merged into `main`, Flipt will eventually start serving this new configuration change. We can now request our application as an authenticated user. Users inside the `internal` organization should get results sorted with the new Quicksort algorithm. Whereas, the rest of users should still be served using the old Bubble Sort algorithm. Validating the change before exposing it to a wider audience is your opportunity to identify and fix any issues. Perhaps the algorithm is incorrect, maybe the order has reversed or has become unstable for some entries. You can fix those changes now before targeting more users. ```bash theme={null} curl -w "\nTotal: %{time_total}s\n" "http://localhost:8000/words?org=internal-users" ``` ### Proportional Rollout Once we're confident our change is working as expected, since we've validated the change in production for `internal` users, we can start to roll it out to external users. The `flipt` binary has the sub-command `flipt validate`. This can be used to statically validate your Flipt feature configuration files. You can install this to run during a CI step and catch bugs before merging changes into `main`. For GitHub, try our pre-built [Flipt Setup Action](https://github.com/marketplace/actions/flipt-setup-action). We could enable the flag for all users at once, but there is always a chance we've missed something during manual validation. Everyone has the best intentions, however. things get missed. So instead we're going to start slow and gradually enable it for percentages of our user base. This will give the change time to bake with your audience. If anything is wrong, we've minimized the effected users to a small subset. Once again we're going to checkout a branch. ```bash theme={null} git checkout -b enable-flag-for-20-percent ``` Then we're going to edit `features.yml` and add a threshold percentage rule. ```diff features.diff theme={null} version: "1.2" namespace: default flags: - key: use-quicksort-algorithm name: Use Quicksort Algorithm type: BOOLEAN_FLAG_TYPE enabled: false rollouts: - segment: key: internal-users value: true + - threshold: + percentage: 20 + value: true segments: - key: internal-users name: Internal Users match_type: ANY_MATCH_TYPE constraints: - property: organization operator: eq value: internal type: STRING_COMPARISON_TYPE ``` ```yaml features.yaml theme={null} version: "1.2" namespace: default flags: - key: use-quicksort-algorithm name: Use Quicksort Algorithm type: BOOLEAN_FLAG_TYPE enabled: false rollouts: - segment: key: internal-users value: true - threshold: percentage: 20 value: true segments: - key: internal-users name: Internal Users match_type: ANY_MATCH_TYPE constraints: - property: organization operator: eq value: internal type: STRING_COMPARISON_TYPE ``` Again, breaking this change down: #### A New Threshold Rollout Rule Here we're adding a new, different rollout rule type to our existing flag. Note that we've left our segment targeting rule intact. This means our flag will remain enabled for internal users. Rollout rules are evaluated on each request in order. The first rule to match will result in the flags enabled property returning the configured `value`. If no rules match, then the flags top-level `enabled` property is used as the final default return value. ```yaml features.yml theme={null} flags: - key: use-quicksort-algorithm # ... - segment: key: internal-users value: true - threshold: percentage: 20 value: true ``` This threshold percentage is set to `20`, meaning roughly `20%` of entity IDs will match and cause the flag to return `enabled = true`. Head to [Concepts: Bucketing](/v1/concepts#bucketing) to learn how this mechanism is actually achieved. #### Proposing and Integrating Our Change Once again, we add, commit, and push the change to our branch. ```bash theme={null} git add features.yml git commit -m "feat: enable use-quicksort-algorithm for 20% of users" git push enable-flag-for-20-percent ``` From here, we can open a pull-request and get feedback from our team. Once we've got approval, we can merge the PR and the change goes live. ### Closing the Loop This process can be repeated, each time increasing the `percentage` property of this newly added `threshold` rollout rule. Once we get to the stage of enabling the flag for 100% of users, we can either set the percentage to `100` or we can remove the targeting rules altogether and set the `enabled` property to `true`. ```yaml features.yml theme={null} version: "1.2" namespace: default flags: - key: use-quicksort-algorithm name: Use Quicksort Algorithm type: BOOLEAN_FLAG_TYPE enabled: true ``` Beyond this, we can further close the loop by removing the feature flag call from our application code and simply use the new `quicksort` function. ```go pkg/server/words.go theme={null} func (s *Server) ListWords(w http.ResponseWriter, r *http.Request) { words, err := getWords(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } quicksort(words) if err := json.NewEncoder(w).Encode(words); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } ``` ## Recap We've successfully rolled a feature out to production using GitOps practices via Flipt's declarative feature flag configuration files and declarative backends. Along the way, we had the opportunity to use Git to understand the current state of the world. At each commit, we could've fully recreated the configuration of our entire application, including the state of Flipt itself. ### Further Considerations Now you have all the tools necessary to practice GitOps with your feature flags. You might want to consider the `object` or the `oci` backend if your source Git repositories are too large (we're working on a guide for that now). The declarative storage backends currently mandate that the UI is **read-only**. We've thoughts on how this could change in the future, but for now, this is a limitation. You always have your editor, Git and the SCMs (GitHub, Gitlab etc) for state management in the meantime. Each of these backends work by polling their sources (git, oci, local directory or object store) and the interval can be configured. Checkout the [Configuration: Storage: Declarative](/v1/configuration/storage#declarative) for details on adjusting these intervals. # Evaluating with References Source: https://docs.flipt.io/v1/guides/user/using-references Leveraging Flipt evaluation references for preview environments. ## What are References in Flipt? References are a way to pass additional information to Flipt during an evaluation request. This allows you to serve different flag states based on the reference when using our [Git backend](/v1/configuration/storage#git). References are especially useful when using Flipt in preview environments. You can use references to serve a different Git branch for each preview environment keeping your main branch safe from untested configurations. ## What Are Preview Environments? Preview environments are a way to create a temporary environment for a pull request. This allows you to test your changes in a production-like environment before merging your code. This is especially useful for testing changes that require a full build and deploy cycle. In this guide, we're going to demonstrate how to leverage Flipt in preview environments to test changes in a production-like environment, without affecting your production users. ## What You'll Learn In this guide you will learn how to: * 🏁 Setup Flipt to work in a preview environment * 🚀 Create a preview environment for a pull request that modifies a feature flag in our [declarative format](/v1/configuration/storage#flag-state-configuration) * 🌲 Add, commit, and push the change to a preview branch * 🧪 Test the change in the preview environment * 🎉 Merge the pull request and deploy the change to production ## Our Example Application We're going to be making a change to our internal organization sales dashboard. This dashboard is made up of a simple [React](https://reactjs.org/) frontend and a Go backend. The frontend is a single-page application that makes API calls to the backend to fetch data. The backend is a **new** API that returns a list of sales performance data. The frontend will use this data to render a graph of our company's sales performance. Because this API is new and we're not sure how it will perform, we want to test it in a production-like environment before we merge it into our main branch. Our example application without our new graph We already use Flipt in our production environment, and we want to use the same instance without having to deploy a new Flipt specifically for our preview environments. We also make use of Flipt's GitOps integration to manage our feature flags in our Git repository. This allows us to manage our feature flags in a declarative format, and have them automatically synced to Flipt in the background. If you're not familiar with Flipt's GitOps integration, check out our GitOps guide for more information. ### Structure Our application lives in a directory committed to a Git repository. For the example's sake, we assume the repository will be hosted on GitHub at `https://github.com/organization/repository.git`. The application is made up of three directories: * `cmd/api` - contains our Go backend API and loads the UI * `ui` - contains our React frontend * `pkg/performance` - contains our Flipt feature flag definition If you want to follow along you can fork our [guide repository](https://github.com/flipt-io/guides). For this guide, we'll mainly focus on the Go backend and the Flipt feature flag definition file. ### Go Backend The purpose of our Go backend is two-fold: 1. Serve our React frontend 2. Serve our new API Our new API is a simple HTTP endpoint that returns a list of sales performance data. Because we're good engineers, we want to make sure that our new API is performant before we merge it into our main branch. To do this, we're going to use Flipt to control access to our new API. The main bit of code that we want to guard is where we mount the `/api/performance` endpoint: ```go cmd/api/main.go theme={null} http.HandleFunc("/api/performance", func(w http.ResponseWriter, r *http.Request) { logger := slog.With( slog.String("namespace", "performance"), slog.String("flag", "showPerformanceHistory"), ) // evaluate the showPerformanceHistory features flag result, err := flipt.Evaluation().Boolean(r.Context(), &evaluation.EvaluationRequest{ NamespaceKey: "performance", FlagKey: "showPerformanceHistory", EntityId: fmt.Sprintf("%x", rand.Intn(1000)), Reference: os.Getenv("FLIPT_CLIENT_REFERENCE"), }) if err != nil { logger.Error("evaluating flag", "error", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // if the flag is disabled we return that the endpoint cannot be found if !result.Enabled { logger.Debug("flag disabled") http.Error(w, "path not found", http.StatusNotFound) return } if err := json.NewEncoder(w).Encode(&history); err != nil { logger.Error("parsing json", "error", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } }) ``` Here you can see that we're using Flipt's Go client to evaluate the `showPerformanceHistory` feature flag. If the flag is enabled, we return the sales performance data. Also of note, we're using the `FLIPT_CLIENT_REFERENCE` environment variable to pass in the reference to Flipt in the evaluation call. This is used to serve a different Git branch for each preview environment. We'll talk more about this later. ### Flipt Feature Flag Definition Our feature flag definition is stored in the `pkg/performance` directory. This directory contains a single file called `features.yml`. This file contains the definition of our `showPerformanceHistory` feature flag. ```yaml pkg/performance/features.yml theme={null} namespace: performance flags: - key: showPerformanceHistory name: Show Performance History Graph type: BOOLEAN_FLAG_TYPE enabled: false ``` You don't have to call your file `features.yml` and you can spread your flag definitions across multiple files. Check out our docs on [locating flag state](/v1/configuration/storage#locating-flag-state) to learn more. ## Creating Preview Environments For this guide, we're going to use [GitHub Actions](https://github.com/features/actions) to deploy our preview environments to [Koyeb](https://www.koyeb.com/). Koyeb has a nice tutorial on how to deploy a preview environment using GitHub Actions. You can find it [here](https://www.koyeb.com/tutorials/deploy-preview-environments-on-koyeb-for-github-pull-requests). To get our preview environments working with Flipt, we'll need some way of passing the Git branch name to Flipt. We can do this by setting the `FLIPT_CLIENT_REFERENCE` environment variable to the Git branch name. This will allow us to serve a different Git branch for each preview environment. To do this, we'll need to add a step to our GitHub Actions workflow that sets the `FLIPT_CLIENT_REFERENCE` environment variable to the Git branch name. ```yaml theme={null} - name: Deploy the application to Koyeb uses: koyeb/action-git-deploy@v1 with: app-name: "dashboard-app-preview-${{ github.head_ref }}" service-name: ${{ github.head_ref }} service-ports: "8081:http" service-routes: "/:8081" service-env: "FLIPT_CLIENT_REFERENCE=${{ github.head_ref }},FLIPT_ADDRESS=${{ secrets.FLIPT_ADDRESS }}" docker: ghcr.io/flipt-io/dashboard-app:latest ``` Here we're also setting the `FLIPT_ADDRESS` environment variable to the address of our Flipt instance. This could also be configured in your application via a config file. ## Enabling the Flag and Pushing to a Preview Branch Now that we have our preview environments setup, we can enable our feature flag and push our changes to a preview branch. To enable our feature flag, we'll need to update our `features.yml` file to set the `enabled` field to `true`. ```yaml pkg/performance/features.yml theme={null} namespace: performance flags: - key: showPerformanceHistory name: Show Performance History Graph type: BOOLEAN_FLAG_TYPE enabled: true ``` Now we can add, commit, and push our changes to a preview branch. ```bash theme={null} git checkout -b feature/enable-performance-history git add pkg/performance/features.yml git commit -m "Enable performance history" git push origin feature/enable-performance-history ``` We'll also need to create a pull request for our preview branch. This will trigger our GitHub Actions workflow and deploy our preview environment. ## Testing the Change Before checking on our preview environment, let's take a look at our Flipt instance. We can see that our feature flag is still showing as disabled in the UI. Flipt is configured to track the `main` branch of our Git repository by default, which is what it continues to show in the UI. Our feature flag is still disabled in the UI In an upcoming release, we'll be adding the ability to switch between references in the UI. This will allow you to see the state of your feature flags in each Git branch. Now that our preview environment is deployed, we can test our new API. We can view our application deployed to Koyeb from the Koyeb dashboard. You can also view the application settings and see that the `FLIPT_CLIENT_REFERENCE` environment variable is set to the Git branch name. Our application settings in Koyeb Now we can click on the application URL to view our application. We can see that our new API is working and our graph is being rendered. 🎉 This means our feature flag is enabled successfully in our preview environment. Our example application with our new graph ## Merging the Pull Request Now that we've tested our new API in our preview environment, we can merge our pull request and deploy our changed flag definition to production. Note that we don't have to make any code changes in our production application. This is because our Flipt is already configured to track the HEAD of the `main` Git branch. This means that when we merge our pull request, our application will automatically start using the new flag state. Our feature flag is now enabled in the UI ## Recap In this guide, we learned how to use Flipt's GitOps integration and references to test changes in a production-like environment without affecting our production users. Using references allowed us to serve a different Git branch for each preview environment. This means that each of our developers can test their feature flag changes in a production-like environment without affecting other developers. There are likely many other ways to use references with Flipt. We'd love to hear how you're using references in your organization. ### Further Considerations References are available for all of our GET API endpoints, (e.g. [`GET /api/v1/flags`](/v1/reference/flags/list-flags)) as well as all of our evaluation endpoints (e.g. [`POST /evaluate/v1/boolean`](/v1/reference/evaluation/boolean-evaluation)). We've also added support for references in all of our [server side REST SDKs](/v1/integration/server/rest) and our [client side SDKs](/v1/integration/client). References currently only work with Git, and our `git` backend, like all of the declarative storage backends, mandates that the UI is **read-only**. We have thoughts on how this could change in the future, but for now, this is a limitation. You always have your editor, Git and the SCMs (GitHub, GitLab etc) for state management in the meantime. Flipt will automatically sync your feature flag definitions to Flipt in the background. Each of these backends work by polling their sources (git, oci, local directory or object store) and the interval can be configured. Check out the [Configuration: Storage: Declarative](/v1/configuration/storage#declarative) for details on adjusting these intervals. # Docker Source: https://docs.flipt.io/v1/installation/docker Running Flipt in a Docker container The simplest way to run Flipt is via Docker. This streamlines the installation and configuration by using a reliable runtime. ### Prerequisites Docker installation is required on the host, see the [official installation docs](https://docs.docker.com/install/). Flipt requires Docker Engine version [20.10](https://docs.docker.com/engine/release-notes/20.10/) or higher. ### Running ```console theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:latest ``` This will download the image and start a Flipt container and publish ports needed to access the UI and backend server. All persistent Flipt data will be stored in `$HOME/flipt`. `$HOME/flipt` is just used as an example, you can use any directory you would like on the host. The Flipt container uses host-mounted volumes to persist data: | Host location | Container location | Purpose | | ------------- | ------------------ | ---------------------------- | | \$HOME/flipt | /var/opt/flipt | For storing application data | This allows data to persist between Docker container restarts. If you don't use mounted volumes to persist your data, your data will be lost when the container exits! After starting the container you can visit [http://127.0.0.1:8080](http://127.0.0.1:8080) to view the application. Flipt runs without the root user in the Docker container. ### Configuration A default configuration file is included within the image. To supply a custom configuration, update the `docker run` command to mount your local configuration into the container: ```console theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ -v $HOME/flipt/config.yaml:/etc/flipt/config/default.yml \ docker.flipt.io/flipt/flipt:latest ``` # Kubernetes Source: https://docs.flipt.io/v1/installation/kubernetes Deploy Flipt to Kubernetes using the Helm chart The chart is hosted in the [Flipt Helm repository](https://helm.flipt.io) and is open source. Check out our [Deploy to Kubernetes](/v1/guides/operation/deployment/deploy-to-kubernetes) guide for an in-depth look into deploying Flipt to Kubernetes using our Helm chart. Any issues or suggestions on how to improve the Flipt Helm chart are welcome in the [chart repository](https://github.com/flipt-io/helm-charts). ### Prerequisites [Helm](https://helm.sh) must be installed to use the chart. Please refer to Helm's [documentation](https://helm.sh/docs/) to get started. Once Helm is set up properly, add the Flipt Helm repository as follows: ```console theme={null} helm repo add flipt https://helm.flipt.io ``` ### Installing You can install the Flipt Helm chart with the following command: ```console theme={null} helm install flipt flipt/flipt ``` # Overview Source: https://docs.flipt.io/v1/installation/overview Multiple ways to install and run Flipt on your own infrastructure Flipt is a single binary that can be run on any Linux or macOS (arm64) host. You can install and try out Flipt in a few different ways: ```console Binary theme={null} curl -fsSL https://get.flipt.io/install | sh ``` ```console Docker theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:latest ``` ```console Kubernetes/Helm theme={null} helm repo add flipt https://helm.flipt.io helm install flipt flipt/flipt ``` ```console Homebrew theme={null} brew install flipt-io/brew/flipt ``` For more details on each installation method, see the sections below. * [Docker](/v1/installation/docker) * [Kubernetes](/v1/installation/kubernetes) * [Homebrew](#homebrew) * [Binary](#binary) ## Homebrew You can install Flipt using [Homebrew](https://brew.sh/) on macOS and Linux. Flipt runs as a service and is managed by [Homebrew Services](https://github.com/Homebrew/homebrew-services). This means you can start and stop Flipt using the `brew services` command. ### Installing ```console theme={null} brew install flipt-io/brew/flipt ``` ### Running ```console theme={null} brew services start flipt ``` Alternatively, you can start Flipt in the foreground using: ```console theme={null} flipt ``` ## Binary You can always download the latest release archive of Flipt from the [Releases](https://github.com/flipt-io/flipt/releases) section on GitHub. ### Installing You can use the following script to download and install the latest Flipt binary: ```console theme={null} curl -fsSL https://get.flipt.io/install | sh ``` This will install Flipt to `/usr/local/bin/flipt` on Mac and Linux systems. View the [install.sh](https://github.com/flipt-io/flipt/blob/main/install.sh) source for more details. ### Running Run the Flipt binary with: ```console theme={null} flipt [--config OPTIONAL_PATH_TO_YOUR_CONFIG] ``` Flipt will check in a few different locations for server configuration (in order): 1. `--config` flag as an override 2. `{{ USER_CONFIG_DIR }}/flipt/config.yml` (the `USER_CONFIG_DIR` value is based on your architecture and specified in the [Go documentation](https://pkg.go.dev/os#UserConfigDir)) 3. `/etc/flipt/config/default.yml` See the [Configuration](/v1/configuration) section for more details. ## Supported Architectures Flipt is built for the following architectures/os: * **x86-64** / **Linux** * **ARM64** / **Linux** * **x86-64** / **Darwin/MacOS** * **ARM64** / **Darwin/MacOS** You can find the binaries for each architecture in the [Latest Release](https://github.com/flipt-io/flipt/releases/latest) assets section on GitHub. The [Docker image](https://hub.docker.com/r/flipt/flipt/tags) for Flipt is multi-arch and supports both **x86-64** and **ARM64** architectures on **Linux**. If you need a different architecture, please open an issue on the [GitHub repository](https://github.com/flipt-io/flipt/issues) and we will try to accommodate your request. # Client-Side SDKs Source: https://docs.flipt.io/v1/integration/client An overview of the client-side SDKs available for integrating with Flipt. Not sure which SDK to use? Check out our [Integration Overview](/v1/integration/overview) documentation. For a more detailed overview of how the client-side SDKs work, check out our announcement blog post: [Client-Side SDKs for Flipt](https://blog.flipt.io/new-client-side-evaluation). ## Overview Flipt provides a number of client-side SDKs to help you integrate with Flipt in your application. The SDKs are available in a number of languages: Evaluate flags client-side in your Node.js or browser-based applications Evaluate flags client-side in your React applications Evaluate flags client-side in your Python applications Evaluate flags client-side in your Go applications Evaluate flags client-side in your Java applications Evaluate flags client-side in your Ruby applications Evaluate flags client-side in your Dart/Flutter applications Evaluate flags client-side in your C# applications Evaluate flags client-side in your Swift applications Evaluate flags client-side in your Android applications > Need a client in another language? Let us know! ## Polling vs Streaming By default, the SDKs will use a polling mechanism to sync the state of the flags with the Flipt server. You can set the polling interval using the `updateInterval` option in the SDK's configuration. Flipt v2 offers `streaming` mode for real-time flag updates via its new streaming API that allows you to subscribe to changes. # Examples Source: https://docs.flipt.io/v1/integration/examples Examples on how Flipt can be integrated into various applications, frameworks, and tools. All of our examples are available on [GitHub](https://github.com/flipt-io/flipt/tree/main/examples). Here are some hand-picked examples to get you started. ## Applications Examples on how to integrate Flipt into various applications and frameworks. How to integrate Flipt into your Go applications with GRPC How to integrate Flipt into your Next.js applications using both server-side and client-side rendering ## Configuration Examples on how to configure Flipt to fit your needs. How to setup OIDC authentication with Flipt Configure Flipt to use a PostgreSQL, MySQL or CockroachDB databases Configure Flipt to use an external Redis cache for improved performance ## Tooling Examples on how to integrate Flipt with various third-party tools. Integrate Flipt with ClickHouse or Prometheus to collect and display evaluation data Integrate Flipt with OpenTelemetry to trace requests with feature flag evaluations Integrate Flipt with Prometheus and Grafana to collect metrics on your feature flag usage Setup audit logging and webhooks for Flipt to track changes within the system # OpenFeature Source: https://docs.flipt.io/v1/integration/openfeature An overview of OpenFeature and Flipt OpenFeature integrations. [OpenFeature](https://openfeature.dev/) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool. OpenFeature allows you to use the same feature flagging API across multiple feature flag management tools. This means that you can switch between feature flag management tools without having to change your code. OpenFeature is a CNCF Sandbox project. You can learn more about OpenFeature on the [OpenFeature website](https://openfeature.dev/). ## Providers As a feature flag management tool, Flipt provides our own OpenFeature integrations (providers). This means that you can use the OpenFeature API with Flipt. From the [OpenFeature Specification](https://docs.openfeature.dev/docs/specification/sections/providers): > Providers are the "translator" between the flag evaluation calls made in application code, and the flag management system that stores flags and in some cases evaluates flags. We currently provide the following OpenFeature providers: The official Flipt OpenFeature Provider using the OpenFeature Node SDK. The official Flipt OpenFeature Provider using the OpenFeature Web SDK. The official Flipt OpenFeature Provider using the OpenFeature Go SDK. The official Flipt OpenFeature Provider using the OpenFeature Java SDK. The official Flipt OpenFeature Provider using the OpenFeature C# SDK. The official Flipt OpenFeature Provider using the OpenFeature Python SDK. The official Flipt OpenFeature Provider using the OpenFeature Ruby SDK. > Need a client in another language? Let us know! ## Remote Evaluation Protocol The OpenFeature Remote Evaluation Protocol (OFREP) is an API specification for feature flagging that allows the use of generic providers to connect to any feature flag management systems that support the protocol. Flipt is one of the early adopters of the OFREP protocol and has implemented the protocol in its API. The OFREP protocol is still in the early stages of development, so the specification is subject to change. The API documentation for the OFREP protocol implementation in Flipt is available in the [OpenFeature Remote Evaluation](/v1/reference/openfeature/overview) API documentation. For more information on the OFREP protocol, see the [OpenFeature Remote Evaluation Protocol](https://github.com/open-feature/protocol) repository on GitHub. # Overview Source: https://docs.flipt.io/v1/integration/overview This document describes how to integrate Flipt in your existing applications. To learn how to install and run Flipt, see the [Installation](/v1/installation) documentation. Once you have the Flipt server up and running within your infrastructure or local development environment, the next step is to integrate the Flipt client(s) with your applications for evaluating your feature flags. There are two main ways to evaluate feature flags with Flipt: 1. [Server-Side Evaluation](#server-side-evaluation) 2. [Client-Side Evaluation](#client-side-evaluation) ## Server-Side Evaluation Server-side evaluation is the most common way to evaluate feature flags. This is where your application makes a request to Flipt to evaluate a feature flag and Flipt responds with the result of the evaluation. Flipt exposes two different APIs for performing server-side evaluation: 1. [REST API](#rest-api) 2. [GRPC API](#grpc-api) The choice of which API to use is up to you. Both APIs are fully supported and are functionally equivalent. The REST API is easier to get started with, but the GRPC API is more performant. ### REST API Flipt comes equipped with a fully functional REST API. The Flipt UI is completely backed by this same API. This means that anything that can be done in the Flipt UI can also be done via the REST API. The Flipt REST API can also be used with any language that can make HTTP requests. This means you don't need to use one of our official clients to integrate your application with Flipt. The latest version of the REST API is fully documented using the [OpenAPI v3 specification](https://github.com/flipt-io/flipt-openapi) as well as the above [API Reference](/v1/reference/overview). See all official REST SDKs as well as how to generate your own in the [REST SDK](/v1/integration/server/rest) section. ### GRPC API Since Flipt is a [GRPC](https://grpc.io/) enabled application, you can connect to it using the GRPC protocol. This means that you can use any language that has a GRPC client implementation to integrate with Flipt. GRPC requires HTTP/2 in your environment. An example [Go application](https://github.com/flipt-io/flipt/tree/main/examples/basic) is available, showing how you would integrate with Flipt using the Go GRPC client. In the [GRPC SDK](/v1/integration/server/grpc) section, you can find all official GRPC SDKs and instructions for generating your own. ## Client-Side Evaluation Client-side evaluation is another way Flipt supports evaluating feature flags. This is where your application has a local copy of the feature flag rules and evaluates them locally. Client-side evaluation is much more performant than server-side evaluation, but it comes with some tradeoffs. The main tradeoff is that you need to keep your feature flag rules in sync with Flipt. This means that you will need to periodically fetch the feature flag rules from Flipt and update your local copy. Our client-side SDKs provide a way to do this automatically. Reasons for using client-side evaluation include: * You want to reduce the number of requests your application makes to Flipt for feature flag evaluations * You want to reduce the latency of feature flag evaluations See all official client-side SDKs in the [Client-Side SDKs](/v1/integration/client) section. # GRPC SDKs Source: https://docs.flipt.io/v1/integration/server/grpc An overview of the GRPC server-side SDKs available for integrating with Flipt. Not sure which SDK to use? Check out our [Integration Overview](/v1/integration/overview) documentation. ## Overview For server-side applications, Flipt provides a GRPC API for evaluating flags. The GRPC API SDKs are available in the following languages: Evaluate flags in your Go applications with GRPC Evaluate flags in your Ruby applications with GRPC Evaluate flags in your .NET applications with GRPC > Need a client in another language? Let us know! If your language isn't listed, please see the section below on how to generate a native GRPC client manually. If you choose to open-source this client, please submit a pull request so that we can add it to the docs. ## Generate If a GRPC client in your language isn't available for download, you can easily generate it yourself using the existing [protobuf definition](https://github.com/flipt-io/flipt/blob/main/rpc/flipt/flipt.proto). The [GRPC documentation](https://grpc.io/docs/) has extensive examples of how to generate GRPC clients in each supported language. GRPC generates both client implementation and server interfaces. To use Flipt you only need the GRPC client implementation and can ignore the server code as this is implemented by Flipt itself. Below are two examples of how to generate Flipt clients in both Go and Ruby. **Go Example** 1. Follow the [setup instructions](https://grpc.io/docs/quickstart/go/) on the GRPC website. 2. Generate using protoc to desired location: ```console theme={null} protoc -I ./rpc --go_out=plugins=grpc:/tmp/flipt/go ./rpc/flipt.proto cd /tmp/flipt/go/flipt ls flipt.pb.go flipt_pb.rb flipt_services_pb. ``` **Ruby Example** 1. Follow the [setup instructions](https://grpc.io/docs/quickstart/ruby/) on the GRPC website. 2. Generate using protoc to the desired location: ```console theme={null} grpc_tools_ruby_protoc -I ./rpc --ruby_out=/tmp/flipt/ruby --grpc_out=/tmp/flipt/ruby ./rpc/flipt.proto cd /tmp/flipt/ruby ls flipt_pb.rb flipt_services_pb.rb ``` # REST SDKs Source: https://docs.flipt.io/v1/integration/server/rest An overview of the REST server-side SDKs available for integrating with Flipt. Not sure which SDK to use? Check out our [Integration Overview](/v1/integration/overview) documentation. ## Overview For server-side applications, Flipt provides a REST API for evaluating flags. The REST API SDKs are available in the following languages: Evaluate flags in your Node applications Evaluate flags in your Python applications Evaluate flags in your Go applications Evaluate flags in your Rust applications Evaluate flags in your Java applications Evaluate flags in your PHP applications Evaluate flags in your C# applications > Need a client in another language? Let us know! ## Generate You can use [openapi-generator](https://openapi-generator.tech/) to generate client code in your preferred language from the [Flipt OpenAPI v3 specification](https://github.com/flipt-io/flipt-openapi). While generating clients is outside of the scope of this documentation, an example of generating a Java client with the `openapi-generator` is below. **Java Example** 1. Install [`openapi-generator`](https://openapi-generator.tech/docs/installation) 2. Generate using `openapi-generator-cli` to desired location: ``` openapi-generator generate -i openapi.yml -g java -o /tmp/flipt/java ``` # Getting Started Source: https://docs.flipt.io/v1/introduction This document describes how to get started with Flipt. This document will walk you through creating your first flag, segment, set of rules, and finally using the evaluation console to simulate an evaluation request from your applications. For more information on any of the concepts described, please see the [Concepts](/v1/concepts) documentation. ## Setup Before getting started, make sure the Flipt server is up and running on your host on your chosen ports. See [Installation](/v1/installation) for more. ```console Binary theme={null} curl -fsSL https://get.flipt.io/install | sh ``` ```console Docker theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:latest ``` ```console Kubernetes/Helm theme={null} helm repo add flipt https://helm.flipt.io helm install flipt flipt/flipt ``` ```console Homebrew theme={null} brew install flipt-io/brew/flipt ``` In this example, we'll use the default location of [http://localhost:8080](http://localhost:8080). ## Flags and Variants First, we'll create a flag and variants that we will use to evaluate against. ### Create a Flag A flag is the basic entity in Flipt. Flags can represent features in your applications that you want to enable/disable for your users. To create a flag: 1. Open the UI at [http://localhost:8080](http://localhost:8080). 2. Click `New Flag`. 3. Populate the details of the flag as shown. 4. Click `Enabled` so the flag will be enabled once created. 5. Click `Create`. "Create Flag" ### Create Variants Variants allow you to return different values for your flags based on rules that you define. To create a variant: 1. On the Flag Details page for the new flag you created, click `New Variant`. 2. Populate the details of the variant as shown. 3. Click `Create`. 4. Create one more variant populating the information as you wish. "Create Variant" Click `Flags` in the navigation menu and you should now see your newly created flag in the list. ## Segments and Constraints Next, we'll create a segment with a constraint that will be used to determine the reach of your flag. ### Create a Segment Segments are used to split your user base into subsets. To create a segment: 1. From the navigation click `Segments`. 2. Click `New Segment`. 3. Populate the details of the segment as shown. 4. Click `Create`. "Create Segment" ### Create a Constraint Constraints are used to target a specific segment. Constraints aren't required to match a segment. A segment with no constraints will match every request by default. To create a constraint: 1. On the Segment Details page for the new segment you created, click `New Constraint`. 2. Populate the details of the constraint as shown. 3. Click `Create`. "Create Constraint" Click `Segments` in the navigation menu and you should now see your newly created segment in the list. ## Rules and Distributions Finally, we'll create a rule defining a distribution for your flag and variants. Rules allow you to define which variant gets returned when you evaluate a specific flag that falls into a given segment. ### Create a Rule To create a rule: 1. Go back to the flag you created at the beginning. 2. Scroll down and click the `Rules` tab. 3. Click `New Rule`. 4. Next to `Segment` choose or search for the segment you created earlier. 5. Next to `Type` choose `Multi-Variate`. 6. You should see the two variants that you created earlier, with a percentage of `50%` each. 7. Click `Create`. "Create" A distribution is a way of assigning a percentage for which entities evaluated get a specific variant. The higher the percentage assigned, the more likely it is that any entity will get that specific variant. You could just as easily have picked `Single Variant` instead of `Multi-Variate` when setting up your rule. This would effectively mean you have a single distribution, a variant with `100%` chance of being returned. ## Evaluation Console After creating the above flag, segment and targeting rule, you're now ready to test how this would work in your application. The Flipt UI contains an Evaluation Console to allow you to experiment with different requests to see how they would be evaluated. The main ideas behind how evaluation works are described in more detail in the [Concepts](/v1/concepts#evaluation) documentation. To test evaluation: 1. Navigate to the `Console` page from the main navigation. 2. Select or search for the flag you created earlier. 3. Notice that the `Entity ID` field is pre-populated with a random UUID. This represents the ID that you would use to uniquely identify entities (ex: users) that you want to test against your flags. 4. Click `Evaluate`. 5. Note the pane to the right has been populated with the evaluation response from the server, informing you that this request would match the segment that you created earlier, and return one of the variants defined. 6. Experiment with different values for the `Request Context` and `Entity ID` fields. "Evaluation Console" That's it! You're now ready to integrate Flipt into your applications and start defining your flags and segments that will enable you to seamlessly rollout new features to your users while reducing risk. # Architecture Source: https://docs.flipt.io/v1/operations/architecture The overall Flipt server architecture is shown in this diagram
Flipt Architecture
Flipt Architecture
The Flipt application is made up of three main components: * Flipt Backend Service * Flipt REST API * Flipt Web UI All three of these components run side by side in a single binary. The UI and REST API are served on the same port (`8080` by default) and the GRPC Backend Service is served on `9000` by default. ## Backend The Flipt Backend service is the main entry point to the application and implements all of the business logic for Flipt. This is what users of the gRPC client SDKs will communicate with, allowing for fast, efficient communication with your applications. ### REST API The Flipt REST API is implemented on top of the Backend Service using gRPC Gateway (described below). The REST API is served under `/api/v1` and allows all actions that the client SDKs allow. ### Web UI The Flipt Web UI is a modern, minimalist UI to allow you to easily set up and monitor your feature flags and experiments. It's served as a JavaScript Single Page Application (SPA) and communicates with the Flipt Backend Service through the REST API. A guide to using the UI for the first time can be found in the [Getting Started](/v1/introduction) documentation. ## Storage Flipt can be run with a multitude of different databases and storage backends including non-traditional data stores like Git, OCI, S3, Azure, and Google Cloud Storage. See our [Storage](/v1/configuration/storage) documentation for more information on all of the available storage backends. ## Technologies Flipt is built using several amazing open-source technologies including: * [Go Programming Language](https://golang.org/) * [gRPC](https://grpc.io/) * [gRPC Gateway](https://github.com/grpc-ecosystem/grpc-gateway/) * [ReactJS](https://reactjs.org/) * [TailwindCSS](https://tailwindcss.com/) ### Go From the [Go](https://golang.org/) documentation: > Go makes it easy to build simple, reliable and efficient software. These are all goals that Flipt also aspires to. Flipt was written in Go mainly because of its ability to produce bulletproof systems software as a single binary for multiple architectures. This allows Flipt to easily be deployed in almost any environment since it's as simple as copying a compiled binary. ### GRPC [gRPC](https://grpc.io/) is a high-performance, open-source RPC framework created by Google. gRPC allows Flipt to be performant by eliminating much of the overhead incurred by using standard HTTP for communication. gRPC also has the benefit of being able to generate client SDKs in many different languages from a single [Protobuf](https://github.com/flipt-io/flipt/blob/main/rpc/flipt/flipt.proto) file. This allows you easily integrate your services with Flipt regardless of the language that they're written in. ### GRPC Gateway While awesome, gRPC might not be for everyone. [gRPC Gateway](https://github.com/grpc-ecosystem/grpc-gateway/) is a reverse-proxy server which translates a RESTful JSON API into gRPC. This allows Flipt to implement a REST API as well as the gRPC API described above. This means that the REST API follows the same code paths as the gRPC service that Flipt implements, allowing for reduced bugs and a simpler architecture. The Flipt UI is also built on top of the REST API provided by gRPC gateway. # Deployment Source: https://docs.flipt.io/v1/operations/deployment Details on various ways to deploy Flipt. Flipt is built and delivered as a single standalone binary. Head to the [Installation](/v1/installation/overview) section for more details. Running Flipt with the default configuration is a great way to get to grips with using it. However, the default settings have some limitations which might make it impractical in a production environment. This guide explores some deployment configurations for increased scalability and reliability. ## Defaults By default, Flipt runs as a single instance process backed by SQLite. Additionally, all API interactions go directly to this database.
Flipt single replica deployment
Flipt single replica deployment
However, Flipt can be run in front of an externally managed relational database (e.g. PostgreSQL, MySQL or CockroachDB), allowing operators to run multiple instances. Caching can also be configured: both in-memory or shared via a distributed solution such as Redis. Enabling caching will reduce the number of interactions required on the database, making reads significantly faster.
Flipt multiple instance configuration diagram
Flipt multiple instance configuration diagram
## Horizontal Scalability As mentioned, Flipt runs on top of SQLite by default. SQLite is an embedded relational database, backed by a single file on disk. Access to the database is limited to a single writing process on the same machine. Using SQLite in this way means Flipt can only be run as a single instance. In many scenarios, it's advantageous to run multiple instances of a service like Flipt. Doing so can provide redundancy during critical failures. It also allows an operator to scale the number of instances to meet throughput demands. An externally hosted relational database is required to scale Flipt horizontally (run multiple instances with a shared backend). PostgreSQL, MySQL, and CockroachDB are the currently supported relational backends. Check out [Configuration: Storage](/v1/configuration/storage) for more details on how to configure Flipt's available storage backends. Once configured with one of these databases, you can run multiple instances safely. Flipt takes care of schema management and some state management operations (e.g. automated deletion of expired API client tokens). To run multiple instances of Flipt you will need to do so behind a load-balancer. Nginx, Caddy, and Envoy are examples of suitable load-balancer choices. ## Caching Flipt supports both in-memory caching and the ability to use an external system such as Redis. Caching allows Flipt to reuse computed results made in a short period. This reduces the number of requests to the backing database and minimizes waste caused by excess evaluation. In-memory caching can be enabled via the "caching" section of the configuration file and requires no external dependencies. Details on these configuration options can be found in the [Configuration: Cache](/v1/configuration/overview#cache) section. However, there is a limitation when multiple instances of Flipt are run in parallel. Since each instance of Flipt has an isolated in-memory cache, the benefits diminish the more instances of Flipt you run. Using a remote system such as [Redis](https://redis.io/) to store the cache data, the same cache instance between multiple Flipt replicas can be shared. A single (logical) shared instance of Redis is required to see the benefits of this kind of caching. Redis is currently the only caching backend. We're considering adding more viable options (such as [Memcached](https://memcached.org/)) in the future. Please [open an issue](https://github.com/flipt-io/flipt/issues/new/) if you have a specific caching backend you would like to see supported. ## Health Checks Flipt exposes health check endpoints for both HTTP and gRPC. These endpoints are useful for orchestrators such as Kubernetes to determine if a Flipt instance is healthy and ready to serve traffic. Health checks are not only useful in a Kubernetes environment but can be used in any environment where you need to determine the health of a Flipt instance. ### HTTP Flipt exposes a health check endpoint at `/health` which can be used to determine the health of a Flipt instance. The endpoint returns a `200` status code and a JSON body with a `status` field if the instance is healthy and ready to serve traffic. ```bash theme={null} $ curl -v http://localhost:8080/health > GET /health HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/8.1.2 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: application/json < Content-Length: 21 < {"status":"SERVING"} ``` ### gRPC Flipt exposes a health check endpoint at `/grpc.health.v1.Health/Check` which can be used to determine the health of a Flipt instance. The endpoint returns a `SERVING` status code if the instance is healthy and ready to serve traffic. ```bash theme={null} $ grpcurl -plaintext localhost:9000 grpc.health.v1.Health/Check { "status": "SERVING" } ``` Read more about the [gRPC Health Checking Protocol](https://grpc.io/docs/guides/health-checking/) for more details. ## Kubernetes Flipt already supports running as a [Docker container](/v1/installation/docker), so the lift to run within a Kubernetes environment proves to be quite simple. The easiest way to get started is to use our official [Helm chart](/v1/installation/kubernetes). The chart provisions a Kubernetes Deployment of Flipt along with a Kubernetes Service. If you are already familiar with Kubernetes, you can get started by using the `flipt:latest` image (or pin to a specific version). ### Sidecar Deployment We published a [blog post](https://blog.flipt.io/flipt-as-a-sidecar) that explores an efficient way to run Flipt as a sidecar.
Flipt sidecar deployment configuration
Flipt sidecar deployment configuration
The `Flipt (master)` is the source of truth of all feature flag state where Flipt users make edits through the UI. The `Flipt Exporter` is a [Kubernetes CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) which uses the [flipt export](/v1/cli/commands/export) command to upload potential changed state to a S3 bucket. Several instances of Flipt can then be run using the S3 bucket as a source of truth. One such example is the `Flipt Sidecar` in the diagram which is collocated with a main process (in the same Kubernetes pod) that uses a Flipt client. The overall idea is for the main process to achieve faster evaluations going over "localhost" rather than through a central Flipt process which could be running anywhere in a distributed sense. ## Further Considerations Flipt primarily relies on the backing database to achieve scalability. It offers caching to minimize the dependence on the backing store and avoid re-work. However, attention should be paid to the health and performance of the backing database and the interactions between Flipt and storage. Feature flag systems are primarily read-often and written infrequently. This allows some affordance to how such a system can be deployed and operated. When deployed against a remote database, Flipt operates as a stateless system, allowing operators to deploy multiple instances of Flipt in various configurations. A more advanced deployment scenario might see Flipt run in two alternate tiers, one for servicing your application's flag evaluations (read-tier) and another for the Flipt dashboard and making flag state changes (write-tier). This has the potential for multiple benefits: * Failures in either read or write tiers can be isolated from one another. A failure in the tier serving the dashboard wouldn't necessarily affect flag evaluations. * Reads can be configured with access to the cache, where writes can be isolated from the caching tier. This may have benefits to the number of connections required on your caching layer. * Reads can be deployed in front of read-only replicas of a database, with the write-tier connecting directly to the primary, allowing more potential for scale in the database layer.
Flipt separate read/write tier deployment configuration
Flipt separate read/write tier deployment configuration
Flipt ships with metrics, logging, and tracing around both behavior and system performance metrics. These pieces of telemetry can be useful for understanding the constraints within your setup of Flipt. We recommend reading the [Configuration: Observability](/v1/configuration/observability) section to understand more about how to extract these measurements. # Import/Export Source: https://docs.flipt.io/v1/operations/import-export Importing and exporting data to and from Flipt Importing is only supported for database backed Flipt instances. Both `flipt import` and `flipt export` support the `--address` and `--token` flags to enable transferring data to and from Flipt instances via the API instead of requiring a direct database connection. ``` flipt import --address http://flipt.my.org --token static-api-token flipt export --address grpc://flipt.my.org:9000 ``` Both `HTTP` and `gRPC` are supported by the `--address` flag. ## Import To import data into Flipt, use the `flipt import` command. You can either import from a file or from STDIN. To import from STDIN, Flipt requires the `--stdin` flag: ```yaml theme={null} cat flipt.yaml | flipt import --stdin ``` If not importing using `--stdin`, Flipt requires the file to be imported as an argument: ```yaml theme={null} flipt import flipt.yaml ``` Namespaces are inferred from the YAML documents themselves. If a namespace your document refers to doesn't exist in the database, it will be created. This command supports the `--drop` flag that will drop all data in your Flipt database tables before importing. This is to ensure that no data collisions occur during the import. Be careful when using the `--drop` flag as it will immediately drop all data and there is no undo. It's recommended to first backup your database before running this command just to be safe. See the [CLI reference](/v1/cli/commands/import) for more information on the `import` command. ## Export To export Flipt data, use the `flipt export` command. By default, `export` will output to STDOUT: ```yaml theme={null} $ flipt export flags: - key: new-contact-page name: New Contact Page description: Show users our Beta contact page enabled: true variants: - key: blue name: Blue - key: green name: Green ``` You can also export to a file using the `-o filename` or `--output filename` flags: ```yaml theme={null} flipt export -o flipt.yaml ``` By default, Flipt will export from the `default` namespace. Use the flag `--namespaces` to export from a different namespace or multiple namespaces. ```yaml theme={null} flipt export --namespaces production ``` The `--all-namespaces` flag is a boolean flag that tells export to export all namespaces. By default, Flipt exports resources in the *natural* order of the selected storage type. While the output is typically consistent within the same storage type, import/export operations can yield varying results across different storage types. To enhance consistency during export, the `--sort-by-key` flag can be used. ```yaml theme={null} flipt export --sort-by-key --all-namespaces ``` See the [CLI reference](/v1/cli/commands/export) for more information on the `export` command. # Production Source: https://docs.flipt.io/v1/operations/production This document describes recommended configuration options for operating Flipt in Production. Flipt's default setup is designed to help you get up and running quickly. To run Flipt successfully in a production environment, you will likely need to modify a few configuration options. Some of the configuration options and tips to consider when operating Flipt in production are as follows: ## Database Connection Limits By default, the Go `database/sql` client will have `MaxOpenConn` equal to 0 (unlimited), and `MaxIdleConn` equal to 2. With the databases that listen over a network (MySQL, Postgres, CockroachDB), there are default server limits for the number of open connections it supports. In high burst traffic scenarios, this can lead to the `too many open connections` error server side. You should tweak that number to be above 0, and to whatever fits your use case. This can be altered either via the Flipt configuration file or environment variables: ```bash theme={null} FLIPT_DB_MAX_OPEN_CONN=5 ``` ```yaml theme={null} db: max_open_conn: 5 ``` The [Go documentation](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns) states: ``` If MaxOpenConns is greater than 0 but less than the new MaxIdleConns, then the new MaxIdleConns will be reduced to match the MaxOpenConns limit. ``` Keep in mind that tuning `MaxOpenConn` may lead to tuning `MaxIdleConn` as well. ```bash theme={null} FLIPT_DB_MAX_IDLE_CONN=5 ``` ```yaml theme={null} db: max_idle_conn: 5 ``` ## Prepared Statements By default, all queries are run as prepared statements. This could pose a problem in some environments. For instance, PGBouncer doesn't support prepared statements in its [transaction pooling mode](https://www.pgbouncer.org/faq.html#how-to-use-prepared-statements-with-transaction-pooling). You can disable prepared statements for the database client using: ```bash theme={null} FLIPT_DB_PREPARED_STATEMENTS_ENABLED=false ``` ```yaml theme={null} db: prepared_statements_enabled: false ``` ## Debug Logging Debug logging can be useful if you are actively developing or trying to fix problems in an environment, but can have the adverse effect of eating up CPU time under load. Enabling debug logging can end up mixing useful logs with non-useful ones. It's recommended to disable Flipt's debug logging in a production environment by increasing the log level: ```bash theme={null} FLIPT_LOG_LEVEL=info ``` ```yaml theme={null} log: level: info ``` ## Profiling Flipt exposes profiling endpoints (`/debug/pprof`) that can be useful for debugging and troubleshooting. However, these endpoints can be a security risk if exposed to the public internet. You can disable these endpoints by setting the following configuration options: ```bash theme={null} FLIPT_DIAGNOSTICS_PROFILING_ENABLED=false ``` ```yaml theme={null} diagnostics: profiling: enabled: false ``` ## Prometheus Metrics If your instance uses Prometheus as the storage engine for analytical data, Flipt will expose a metrics endpoint (`/metrics`) that can be scraped by Prometheus. Ensure that this endpoint is not publicly accessible, for example, by configuring your Istio Ingress setup appropriately. # Upgrading Source: https://docs.flipt.io/v1/operations/upgrading This document describes how to upgrade Flipt. Flipt aims to provide an upgrade process which requires zero downtime with minimal steps. Currently, Flipt supports four relational database backends and uses a migration process to manage their schema. Each new release of Flipt might include updates to database migrations. The release notes on GitHub for each Flipt release should signify whether it does or not. You can find the releases and release notes on [GitHub](https://github.com/flipt-io/flipt/releases). Before upgrading your Flipt instances to a new version, you may need to run the `flipt migrate` command against your database. The Flipt binary is self-contained and has all necessary migrations baked in. You should use the version of Flipt you're attempting to upgrade to. If you attempt to upgrade to a new version of Flipt before running migrations, then Flipt will fail fast on startup with a message like the following. ``` migrations pending, please backup your database and run `flipt migrate` ``` ## Upgrade Process We **strongly recommend** that you perform a backup of your Flipt database before doing any migrations. While we strive to ensure that Flipt is error free and production ready, we can't guarantee perfection. First, run `flipt -v` to see the version you have installed. You want this to be the version you're attempting to upgrade to. ```sh theme={null} $ flipt -v _____ _ _ _ | ___| (_)_ __ | |_ | |_ | | | '_ \| __| | _| | | | |_) | |_ |_| |_|_| .__/ \__| |_| Version: 1.20.0 Commit: 5badad98844061a15c05bd6b21accde44ea7fcb5 Build Date: 2023-04-11T15:39:19Z Go Version: go1.20.3 ``` Once you have identified the version you have installed is the target version you are upgrading to, you can run `flipt migrate` (In this instance I am upgrading to Flipt v1.20.0). ```sh theme={null} $ flipt migrate 2023-04-13T15:35:17Z DEBUG using driver {"driver": "sqlite3"} 2023-04-13T15:35:17Z DEBUG migrations complete ``` Now you can update your running instance(s) of Flipt to match the same version. We design our migrations to be compatible with older Flipt server versions, so it's safe for you to keep running Flipt while the migrations are run and after they have finished. ## Downgrade Process As previously mentioned, we recommend you backup your database before performing any upgrades. Flipt doesn't currently come with any built-in downgrade tooling. Our suggestion, if you need to revert to an previous version of Flipt, is to restore your database using a backup from when it was backing the target older version. # Create Token Source: https://docs.flipt.io/v1/reference/authentication/create-token POST /auth/v1/method/token ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/auth/v1/method/token \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer ' \ --data '{ "description": "", "name": "" }' ``` # Delete Token Source: https://docs.flipt.io/v1/reference/authentication/delete-token DELETE /auth/v1/tokens/{id} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/auth/v1/tokens/{id} \ --header 'Authorization: Bearer {token}' ``` # Expire Self Source: https://docs.flipt.io/v1/reference/authentication/expire-self PUT /auth/v1/self/expire ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/auth/v1/self/expire \ --header 'Authorization: Bearer ' ``` # Get Self Source: https://docs.flipt.io/v1/reference/authentication/get-self GET /auth/v1/self ```bash cURL theme={null} curl --request GET \ --url https://try.flipt.io/auth/v1/self \ --header 'Accept: application/json' \ --header 'Authorization: Bearer ' ``` # Get Token Source: https://docs.flipt.io/v1/reference/authentication/get-token GET /auth/v1/tokens/{id} ```bash cURL theme={null} curl --url https://try.flipt.io/auth/v1/tokens/{id} \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {token}' ``` # List Tokens Source: https://docs.flipt.io/v1/reference/authentication/list-tokens GET /auth/v1/tokens ```bash cURL theme={null} curl --url https://try.flipt.io/auth/v1/tokens \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {token}' ``` # Create Constraint Source: https://docs.flipt.io/v1/reference/constraints/create-constraint POST /api/v1/namespaces/{namespaceKey}/segments/{segmentKey}/constraints ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/segments/{segmentKey}/constraints \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "operator": "", "property": "", "type": "" }' ``` # Delete Constraint Source: https://docs.flipt.io/v1/reference/constraints/delete-constraint DELETE /api/v1/namespaces/{namespaceKey}/segments/{segmentKey}/constraints/{id} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/segments/{segmentKey}/constraints/{id} ``` # Update Constraint Source: https://docs.flipt.io/v1/reference/constraints/update-constraint PUT /api/v1/namespaces/{namespaceKey}/segments/{segmentKey}/constraints/{id} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/segments/{segmentKey}/constraints/{id} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "operator": "", "property": "", "type": "" }' ``` # Create Distribution Source: https://docs.flipt.io/v1/reference/distributions/create-distribution POST /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/{ruleId}/distributions ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules/{ruleId}/distributions \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "rollout": 0, "variantId": "" }' ``` # Delete Distribution Source: https://docs.flipt.io/v1/reference/distributions/delete-distribution DELETE /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/{ruleId}/distributions/{id} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules/{ruleId}/distributions/{id} ``` # Update Distribution Source: https://docs.flipt.io/v1/reference/distributions/update-distribution PUT /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/{ruleId}/distributions/{id} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules/{ruleId}/distributions/{id} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "rollout": 0, "variantId": "" }' ``` # Batch Evaluation Source: https://docs.flipt.io/v1/reference/evaluation/batch-evaluation POST /evaluate/v1/batch ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/evaluate/v1/batch \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "requests": [ { "context": {}, "entityId": "", "flagKey": "", "namespaceKey": "" } ] }' ``` # Boolean Evaluation Source: https://docs.flipt.io/v1/reference/evaluation/boolean-evaluation POST /evaluate/v1/boolean ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/evaluate/v1/boolean \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "context": {}, "entityId": "", "flagKey": "", "namespaceKey": "" }' ``` # Variant Evaluation Source: https://docs.flipt.io/v1/reference/evaluation/variant-evaluation POST /evaluate/v1/variant ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/evaluate/v1/variant \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "context": {}, "entityId": "", "flagKey": "", "namespaceKey": "" }' ``` # Create Flag Source: https://docs.flipt.io/v1/reference/flags/create-flag POST /api/v1/namespaces/{namespaceKey}/flags ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/flags \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "key": "", "name": "", "description": "", "enabled": true }' ``` # Delete Flag Source: https://docs.flipt.io/v1/reference/flags/delete-flag DELETE /api/v1/namespaces/{namespaceKey}/flags/{key} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{key} ``` # Get Flag Source: https://docs.flipt.io/v1/reference/flags/get-flag GET /api/v1/namespaces/{namespaceKey}/flags/{key} ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/default/flags/{key} \ --header 'Accept: application/json' ``` # List Flags Source: https://docs.flipt.io/v1/reference/flags/list-flags GET /api/v1/namespaces/{namespaceKey}/flags ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/default/flags \ --header 'Accept: application/json' ``` # Update Flag Source: https://docs.flipt.io/v1/reference/flags/update-flag PUT /api/v1/namespaces/{namespaceKey}/flags/{key} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{key} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "name": "", "description": "", "enabled": false, }' ``` # Create Namespace Source: https://docs.flipt.io/v1/reference/namespaces/create-namespace POST /api/v1/namespaces ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "key": "", "name": "" }' ``` # Delete Namespace Source: https://docs.flipt.io/v1/reference/namespaces/delete-namespace DELETE /api/v1/namespaces/{key} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/{key} ``` # Get Namespace Source: https://docs.flipt.io/v1/reference/namespaces/get-namespace GET /api/v1/namespaces/{key} ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/{key} \ --header 'Accept: application/json' ``` # List Namespaces Source: https://docs.flipt.io/v1/reference/namespaces/list-namespaces GET /api/v1/namespaces ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces \ --header 'Accept: application/json' ``` # Update Namespace Source: https://docs.flipt.io/v1/reference/namespaces/update-namespace PUT /api/v1/namespaces/{key} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/{key} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "name": "", "description": "" }' ``` # Bulk Evaluation Source: https://docs.flipt.io/v1/reference/openfeature/bulk-evaluation POST /ofrep/v1/evaluate/flags OFREP bulk flag evaluation ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/ofrep/v1/evaluate/flags \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'X-Flipt-Namespace: ' \ --data '{ "context": { "flags": ["flagKey1", "flagKey2", "flagKey3"], "targetingKey": "targetingKey1" }, }' ``` # Configuration Source: https://docs.flipt.io/v1/reference/openfeature/configuration GET /ofrep/v1/configuration OFREP provider configuration ```bash cURL theme={null} curl --url https://try.flipt.io/ofrep/v1/configuration \ --header 'Accept: application/json' ``` # Flag Evaluation Source: https://docs.flipt.io/v1/reference/openfeature/flag-evaluation POST /ofrep/v1/evaluate/flags/{key} OFREP single flag evaluation ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/ofrep/v1/evaluate/flags/ \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'X-Flipt-Namespace: ' \ --data '{ "context": { "targetingKey": "targetingKey1" }, }' ``` # Overview Source: https://docs.flipt.io/v1/reference/openfeature/overview OpenFeature Remote Evaluation Protocol (OFREP) is an API specification for feature flagging that allows the use of generic providers to connect to any feature flag management systems that supports the protocol. Currently, OFREP is still in the early stages of development so the specification is subject to change. Flipt is one of the early adopters of the OFREP protocol and has implemented the protocol in its API. For more information on the OFREP protocol, see the [OpenFeature Remote Evaluation Protocol](https://github.com/open-feature/protocol) repository on GitHub. ## Endpoints The OFREP protocol is implemented in the Flipt API. The following endpoints are available: * [Configuration](/v1/reference/openfeature/configuration) - Supplies information about the remote flag management system to set up the OpenFeature SDK providers. * [Single Flag Evaluation](/v1/reference/openfeature/flag-evaluation) - Called by the server providers to perform single flag evaluation. * [Bulk Evaluation](/v1/reference/openfeature/bulk-evaluation) - Called by the server providers to perform bulk evaluation of multiple flags. ## Providers Providers are the entities that implement the OFREP protocol from the caller. Providers are responsible for evaluating feature flags and returning the results to the client. Current providers include: * [Go](https://github.com/open-feature/go-sdk-contrib/tree/main/providers/ofrep) * [JS Server](https://github.com/open-feature/js-sdk-contrib/tree/main/libs/providers/ofrep) * [JS Web](https://github.com/open-feature/js-sdk-contrib/tree/main/libs/providers/ofrep-web) # API Overview Source: https://docs.flipt.io/v1/reference/overview Flipt's API is the primary way to interact with Flipt Open Source outside of the UI. It's used to create, update, and delete entities such as namespaces, flags, segments, rules, and also to evaluate flags. The Flipt UI is completely backed by this same API. This means that anything that can be done in the Flipt UI can also be done via the REST API. The Flipt REST API can also be used with any language that can make HTTP requests. The latest version of the REST API is fully documented using the [OpenAPI v3 specification](https://raw.githubusercontent.com/flipt-io/flipt/main/openapi.yaml). ## Authentication Flipt authentication is **disabled** (not required) by default. Head to the [Configuration: Authentication](/v1/configuration#authentication) section to enable it. Flipt supports two types of authentication for the API: * **Client Token Authentication** - This method uses tokens stored by Flipt to authenticate the request. See the [Using Client Tokens](/v1/authentication/using-tokens) section for more information. * **JSON Web Token (JWT) Authentication** - This method uses a JWT token, created and signed externally from Flipt to authenticate the request. See the [Using JWT Tokens](/v1/authentication/using-jwts) section for more information. See the [Authentication](/v1/authentication) documentation for more information on all supported authentication methods. ## SDKs We're adding new SDKs all the time. To see the current list of official REST SDKs, head to the [REST SDKs](/v1/integration/server/rest) documentation. ## Backward Compatibility We take great care to ensure that the Flipt REST API is backward compatible. This means that you can safely upgrade to a newer version of Flipt without having to change your API calls. From time to time we may need to make large changes to the API as we introduce additional features, however we will continue to make sure that we preserve backward compatibility. We will describe any major changes in the section below. ## API Changes ### v1.24.0 Version [v1.24.0](https://github.com/flipt-io/flipt/releases/tag/v1.24.0) of Flipt introduced the concept of [boolean flag types](/v1/concepts#boolean-flags) as well as [Rollouts](/v1/concepts#rollouts) to override a flag's `enabled` state via a set of rules. We also introduced a new `/evaluate/v1` set of API endpoints to evaluate both `boolean` and `variant` flags. The previous `/api/v1/evaluate` endpoints for evaluation are still available and will continue to work as before, however they will only work for `variant` type flags and should be considered deprecated. ### v1.20.0 Version [v1.20.0](https://github.com/flipt-io/flipt/releases/tag/v1.20.0) of Flipt introduced the concept of [Namespaces](/v1/concepts#namespaces) as root objects nested under the `/namespaces` route (i.e.: `/api/v1/namespace/{namespaceKey}/flags`). All previous endpoints without the `/namespaces` prefix still work as before (i.e.: `/api/v1/flags`), they simply resolve to using the **default** namespace. See the [Concepts: Namespaces](/v1/concepts#namespaces) section for more information. # Create Rollout Source: https://docs.flipt.io/v1/reference/rollouts/create-rollout POST /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rollouts ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rollouts \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "rank": 1, "threshold": { "percentage": 50.0, "value": true }, } }' ``` # Delete Rollout Source: https://docs.flipt.io/v1/reference/rollouts/delete-rollout DELETE /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rollouts/{id} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rollouts/{id} ``` # Get Rollout Source: https://docs.flipt.io/v1/reference/rollouts/get-rollout GET /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rollouts/{id} ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rollouts/{id} \ --header 'Accept: application/json' ``` # List Rollout Source: https://docs.flipt.io/v1/reference/rollouts/list-rollouts GET /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rollouts ```bash cURL theme={null} curl --request GET \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rollouts \ --header 'Accept: application/json' ``` # Order Rollouts Source: https://docs.flipt.io/v1/reference/rollouts/order-rollouts PUT /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rollouts/order ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{key}/rollouts/order \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "rolloutIds": [] }' ``` # Update Rollout Source: https://docs.flipt.io/v1/reference/rollouts/update-rollout PUT /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rollouts/{id} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rollouts \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "threshold": { "percentage": 70.0, "value": false }, } }' ``` # Create Rule Source: https://docs.flipt.io/v1/reference/rules/create-rule POST /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "rank": 1, "segmentKey": "" }' ``` # Delete Rule Source: https://docs.flipt.io/v1/reference/rules/delete-rule DELETE /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/{id} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules/{id} ``` # Get Rule Source: https://docs.flipt.io/v1/reference/rules/get-rule GET /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/{id} ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules/{id} \ --header 'Accept: application/json' ``` # List Rules Source: https://docs.flipt.io/v1/reference/rules/list-rules GET /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules ```bash cURL theme={null} curl --request GET \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules \ --header 'Accept: application/json' ``` # Order Rules Source: https://docs.flipt.io/v1/reference/rules/order-rules PUT /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/order ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{key}/rules/order \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "ruleIds": [] }' ``` # Update Rule Source: https://docs.flipt.io/v1/reference/rules/update-rule PUT /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/rules/{id} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/rules/{id} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "segmentKey": "" }' ``` # Create Segment Source: https://docs.flipt.io/v1/reference/segments/create-segment POST /api/v1/namespaces/{namespaceKey}/segments ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/segments \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "description": "", "key": "", "matchType": "", "name": "" }' ``` # Delete Segment Source: https://docs.flipt.io/v1/reference/segments/delete-segment DELETE /api/v1/namespaces/{namespaceKey}/segments/{key} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/segments/{key} ``` # Get Segment Source: https://docs.flipt.io/v1/reference/segments/get-segment GET /api/v1/namespaces/{namespaceKey}/segments/{key} ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/default/segments/{key} \ --header 'Accept: application/json' ``` # List Segments Source: https://docs.flipt.io/v1/reference/segments/list-segment GET /api/v1/namespaces/{namespaceKey}/segments ```bash cURL theme={null} curl --url https://try.flipt.io/api/v1/namespaces/default/segments \ --header 'Accept: application/json' ``` # Update Segment Source: https://docs.flipt.io/v1/reference/segments/update-segment PUT /api/v1/namespaces/{namespaceKey}/segments/{key} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/segments/{key} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "name": "", "description": "", }' ``` # Create Variant Source: https://docs.flipt.io/v1/reference/variants/create-variant POST /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/variants ```bash cURL theme={null} curl --request POST \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/variants \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "key": "", "name": "", "description": "", "attachment": "" }' ``` # Delete Variant Source: https://docs.flipt.io/v1/reference/variants/delete-variant DELETE /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/variants/{id} ```bash cURL theme={null} curl --request DELETE \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/variants/{id} ``` # Update Variant Source: https://docs.flipt.io/v1/reference/variants/update-variant PUT /api/v1/namespaces/{namespaceKey}/flags/{flagKey}/variants/{id} ```bash cURL theme={null} curl --request PUT \ --url https://try.flipt.io/api/v1/namespaces/default/flags/{flagKey}/variants/{id} \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "name": "", "description": "", "attachment": "" }' ``` # GitHub Actions Source: https://docs.flipt.io/v1/tooling/github-actions How to use our GitHub Actions to automate your workflows. ## Setup Flipt Flipt Setup Action The [flipt-setup-action](https://github.com/marketplace/actions/flipt-setup-action) can be used to setup Flipt v1 in your GitHub workflow. Once setup, you can then use any of the [CLI commands](/v1/cli/overview) that Flipt provides in your workflow. ### Usage The following example demonstrates how to use the action in a GitHub workflow which runs the [flipt validate](/v1/cli/commands/validate) command. ```yaml theme={null} validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: flipt-io/setup-action@v0.5.0 with: version: v1 # Installs the latest v1 release # Optional, additional arguments to pass to the `flipt` command # args: # Optional, the directory to run Flipt against, defaults to the repository root # working-directory: - run: flipt validate ``` # Model Context Protocol (MCP) Source: https://docs.flipt.io/v1/tooling/model-context-protocol Use Flipt's MCP server to enable AI assistants to interact with your feature flags ## Overview The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open protocol that standardizes how applications provide context to Large Language Models (LLMs). Think of MCP like a USB-C port for AI applications - it provides a standardized way to connect AI models to different data sources and tools. [Flipt's MCP server](https://github.com/flipt-io/mcp-server-flipt/tree/main/packages/mcp-server-flipt) allows AI assistants and LLMs to directly interact with your feature flags, segments, and evaluations through a standardized interface. This enables powerful AI-driven workflows and integrations with tools that support the MCP protocol. Using Flipt v2? See the [v2 MCP server documentation](/v2/tooling/model-context-protocol) instead. MCP Server ## Use Cases ### AI-Enabled IDEs When using AI-enabled IDEs like Cursor that support MCP, your AI assistant can: * Check feature flag states while reviewing code * Help toggle features on/off during development * Assist in creating and managing feature flags * Evaluate flags for specific users/entities * Help debug feature flag logic and rules For example, you could ask your AI assistant: * "What's the current state of the 'dark-mode' flag?" * "Enable the 'beta-features' flag for all users in the 'internal' segment" * "Create a new feature flag for our upcoming notification system" ### AI Agents and Workflows The Flipt MCP server can be integrated into broader AI agent workflows to: * Automate feature flag management based on system metrics * Coordinate feature rollouts across multiple services * Generate reports on feature usage and impact * Manage complex feature flag rules and segments ## Getting Started Check out the [Flipt MCP server repository](https://github.com/flipt-io/mcp-server-flipt/tree/main/packages/mcp-server-flipt) for the most up to date information on how to use the MCP server. ### Cursor To use the Flipt MCP server with Cursor, you need to configure Cursor to use the MCP server. The Cursor docs have a [guide on how to configure Cursor](https://docs.cursor.com/context/model-context-protocol#configuring-mcp-servers) to use a MCP server. For Flipt, you can use the following configuration: ```json theme={null} { "mcpServers": { "flipt": { "command": "npx", "args": ["-y", "@flipt-io/mcp-server-flipt"] } } } ``` ### Configuration The server can be configured using environment variables: ```bash theme={null} # The URL of your Flipt instance FLIPT_URL=http://localhost:8080 # Optional API key for authentication FLIPT_API_KEY= ``` ## Available Operations The Flipt MCP server provides tools for: * **Namespace Management**: Create, list, update, and delete namespaces * **Flag Operations**: Create, toggle, and manage feature flags * **Segment Management**: Define and update user segments * **Flag Evaluation**: Evaluate flags for specific entities * **Constraints & Rules**: Manage targeting rules and constraints * **Variants & Distributions**: Configure feature variants and rollout distributions # CloudNative Source: https://docs.flipt.io/v1/usecases/cloudnative This document describes how Flipt thrives in a CloudNative environment. ## Overview Flipt is a CloudNative feature flag solution. While Flipt can run in almost any environment, it is especially well suited for CloudNative environments. CloudNative means different things to different people. We define CloudNative as an environment that is: * **Containerized** - Flipt is distributed as a container image and can be deployed to any container orchestration platform. * **Dynamic** - Flipt is designed to be deployed and updated with minimal downtime. * **Scalable** - Flipt is designed to scale horizontally and vertically. * **Observable** - Flipt is designed to be observable. It exposes Prometheus metrics and logs in a structured format. * **Stateless** - Flipt is designed to be stateless. It supports multiple storage backends, including cloud object storage and SQL databases. ## Kubernetes and Helm Flipt is mainly distributed as a container image. While it is a single binary and can run easily on bare metal, most users choose to deploy Flipt to a container orchestration platform such as Kubernetes. To deploy Flipt to Kubernetes, use our Helm chart as described in our [Kubernetes](/v1/installation/kubernetes) documentation. Flipt also integrates directly with Kubernetes service account tokens for authentication. This allows services deployed into the same Kubernetes cluster as Flipt to automatically gain authenticated access to the Flipt API without additional management of static client tokens. See our [Kubernetes Authentication](/v1/authentication/methods#kubernetes) documentation for more information on how to configure Kubernetes service account authentication. ## Metrics and Observability ### Metrics Flipt exposes Prometheus metrics on the `/metrics` endpoint. These metrics are designed to be scraped by Prometheus and visualized in external tools such as Grafana. See the [Metrics Configuration](/v1/configuration/observability#metrics) documentation for more information on the metrics exposed by Flipt and how to configure them. ### Logging Flipt writes structured logs in JSON format. These logs are designed to be ingested by external log aggregation tools such as Elasticsearch, Splunk, and Grafana Loki. For more information on the logs exposed by Flipt and how to configure them, see the [Logging Configuration](/v1/configuration/observability#logging) documentation. ### Tracing Flipt exposes tracing information in the OpenTelemetry format. This allows you to trace requests through Flipt and into your application. Flipt also annotates the traces with information such as the feature flag and variant that was evaluated. For more information on the tracing exposed by Flipt and how to configure it, see the [Tracing Configuration](/v1/configuration/observability#tracing) documentation. ## Storage Flipt is designed to be stateless. It supports multiple storage backends, including cloud object storage, git, OCI, and SQL databases. Our [Declarative Storage](/v1/configuration/storage#declarative) also allows you to easily migrate between storage backends. For example, you can start with a local SQLite database and migrate to a cloud object storage backend as your usage grows. ## Security and Performance ### Security Flipt supports multiple authentication methods, including static tokens, Kubernetes service account tokens, JWT, and OIDC. See our [Authentication](/v1/authentication) documentation for more information on the authentication methods supported by Flipt. ### Performance Flipt is written in Go and is designed to be performant. It's horizontally scalable and can be deployed to multiple replicas to handle increased load. Flipt also supports caching of feature flag evaluations. This allows you to cache the results of feature flag evaluations in memory to reduce the load on your storage backend. Finally, Flipt's GRPC API is meant to be used in a cloud environment such as Kubernetes. This allows you to deploy Flipt in the same Kubernetes cluster as your applications and take advantage of the low latency and high throughput of the Kubernetes network. See our [Architecture](/v1/operations/architecture) and [Deployment](/v1/operations/deployment) documentation for more information on how to deploy Flipt for performance and scalability. # Edge/IoT Source: https://docs.flipt.io/v1/usecases/edge This document describes how Flipt can be used in edge and IoT computing environments. ## Overview Flipt is designed to be able to be used in an edge computing environment. This means that Flipt can be deployed to a device that's close to the end user. This is in contrast to a centralized computing environment where the application is deployed to a data center that's far away from the end user, such as a cloud provider. Because of Flipt's small footprint and single binary deployment, it's well suited for edge computing environments. Also, since the Flipt server is stateless, it can be deployed in a highly available configuration. This means that multiple Flipt servers can be deployed to the edge and requests can be load balanced across them, providing a highly available service to the end user. Our [Deployment](/v1/operations/deployment) documentation provides more information on how to deploy Flipt in a highly available configuration. ## Storage Flipt supports a variety of storage backends, allowing it to be deployed to a variety of edge computing environments. ### Edge-Compatible Databases Flipt's pluggable data store architecture allows it to be deployed to a variety of edge computing environments without requiring traditional server-based relational databases. Specifically, Flipt's support for SQLite, [LibSQL](https://turso.tech/libsql), and [Turso](https://turso.tech/) allow it to run in environments where a traditional database is not available. See the [Database Support](/v1/configuration/storage##relational-database) section for more information on Flipt's relational database support. ### Declarative Storage Flipt's declarative storage backends allow it to run without a database at all. Flipt can be configured to load its feature flag data in the following ways: * From a file on the local filesystem * From a remote git repository * From an OCI compliant container image registry * From any of the 3 major cloud computing object storage services (AWS, Google Cloud, and Azure) These backends allow you to deploy Flipt to the edge and evaluate feature flags close to your end user. See the [Declarative Storage](/v1/configuration/storage#declarative) section for more information on Flipt's declarative storage backends. ## GRPC API GRPC is a high performance, open source, universal RPC framework. Flipt's GRPC API allows it to run in environments where HTTP isn't available or practical. This is especially useful in environments that require low latency and high throughput, such as IoT devices. See our [Architecture](/v1/operations/architecture) section for more information on Flipt's GRPC API and overall architecture. ## Client Side Evaluation Flipt's client-side evaluation SDKs allow feature flag evaluation to be performed directly from edge clients, without the need of making evaluation requests to the central Flipt server. This is especially useful in environments where the edge client isn't always connected to the internet, such as IoT devices. Client side evaluation has shown to be up to 1000x faster than traditional server side evaluation, and as such greatly decreases the number of network requests required. This is especially useful in environments where network bandwidth is limited (such as IoT devices), where there is sensitivity to latency (e.g. high throughput services), or on critical paths where transient failures must be avoided at all costs (e.g. during transaction processing). See our [Client Side Integration](/v1/integration/client) documentation for more information. # GitOps Source: https://docs.flipt.io/v1/usecases/gitops This document describes how Flipt can be used with GitOps workflows ## Overview GitOps is a way to do Continuous Delivery, and it works by using Git as a single source of truth for declarative infrastructure and applications. With Git at the center of your delivery pipelines, developers can make pull requests to accelerate and simplify application deployments. Flipt is uniquely suited to work with GitOps workflows because of its declarative backends and ability to be configured completely via YAML, or JSON. We believe that feature flags are a form of configuration and should be treated as such. This means that feature flags should be able to be stored in the same repository as the code that uses them. This allows developers to make changes to both the code and the feature flags in the same pull request. This also allows developers to use the same GitOps tooling to deploy both their code and their feature flags to production. ## Git Backend Flipt's declarative storage backends allow it to run without a database at all. Flipt can be configured to load its feature flag data in the following ways: * From a file on the local filesystem * From a remote **git repository** * From an OCI compliant container image registry * From any of the 3 major cloud computing object storage services (AWS, Google Cloud, and Azure) Our git support enables you to evaluate feature flags across different branches and tags. This allows developers to test feature flags in a staging environment before merging them into production, or leverage preview environments to test feature flags in isolation. Read our [Get Going with GitOps](https://docs.flipt.io/v1/guides/user/get-going-with-gitops#get-going-with-gitops) guide to learn how to get started with GitOps and Flipt. ## CI/CD Integration Our [GitHub Action](/v1/tooling/github-actions) allows you to easily integrate Flipt into your CI/CD pipelines. This allows you to install Flipt into your CI pipeline and run tests against your feature flags before deploying your code to production. You can either import your feature flag data from your repository into Flipt using our [Import Command](/v1/cli/commands/import) or run Flipt over your repository directly using our [Local Storage](/v1/configuration/storage#local-2) backend. This allows you to import your feature flag data into Flipt before running your tests. ## Validation Flipt's [Validate Command](/v1/cli/commands/validate) allows you to validate your feature flag data against a schema. This allows you to ensure that your feature flag data is valid before deploying it to production. This is especially useful when using Flipt with GitOps workflows because it allows you to catch errors in your configuration in the CI stage. You can also add your own custom validation rules to the schema to ensure that your feature flag data is valid for your specific use case. # Overview Source: https://docs.flipt.io/v1/usecases/overview This document describes some of the general use cases for Flipt and feature flags. For more specific use cases that Flipt is suited for, see the following sections: * [CloudNative](/v1/usecases/cloudnative/) * [Edge/IoT](/v1/usecases/edge/) * [GitOps](/v1/usecases/gitops/) ## Enhanced Development Experience Feature flags are extremely versatile and can quickly become an important tool in a developer’s toolbox. Some of the ways they can be used to enhance the development experience include: * Enabling trunk-based development workflows * Testing new features internally during development before releasing them fully in production * Ensuring overall system safety by guarding new releases with unknown performance implications with an emergency kill switch * Gating certain features for different permission levels, allowing you to control who sees what * Enabling continuous configuration by changing values during runtime ## Enabling Trunk-Based Development A common development workflow is to have a “trunk” branch that represents the latest version of your application in production. You can use feature flags to control which features are enabled on your trunk, allowing engineers to test new features without disrupting your live users. This method of development is largely referred to as [trunk-based development](https://trunkbaseddevelopment.com/) and is often preferable to branch-based deployment workflow because it’s a lot easier to manage. Feature flag-driven trunk-based development allows you to keep your code base clean and well-organized, while still enabling engineers to iterate quickly. ## Testing New Features Internally Feature flags provide a powerful mechanism for testing new features internally during their development. By using feature flags, you can enable new features for specific groups of users, such as internal employees, in order to test and validate their functionality in a controlled and safe environment. This approach allows for the early detection of bugs and other issues that may not have been discovered through traditional testing methods, helping to ensure that new features are thoroughly vetted and optimized for release. ## Gating Features for Different Permissions Using feature flags can be a powerful way to manage permissions and control access to new features, without requiring a full-fledged permission model in the codebase. By leveraging feature flags, you can limit access to new features by selectively enabling them for certain groups of users or under specific conditions. This allows for a more flexible and responsive approach to permissions management, without the need to hard-code complex permission logic into the codebase. Instead, the logic for enabling or disabling features can be managed remotely through the feature flags configuration, enabling rapid experimentation and iteration. ## Ensuring System Safety Feature flags provide a powerful tool to mitigate the risk of code changes impacting the system's stability or negatively impacting customers. This is especially important when working on complex and large projects that are difficult to test in isolation, such as those that require updates to database schema, ETL data migrations, or running background jobs. By utilizing feature flags, you can gradually roll out code, monitor its impact, and quickly disable it if necessary. ## Enabling Continuous Configuration Feature flags can be utilized for continuous configuration management. This allows for dynamic changes to be made in real-time to elements (e.g.: changing rate limits for service-to-service communication), without the need to update the codebase or configuration files, or deploy every time a change is required. By using feature flags, these values can be modified and managed remotely, offering greater flexibility and responsiveness. ## Learn More These are just some of the many use cases for Flipt and feature flags for developers. Reach out to our team on [Discord](https://flipt.io/discord) or [GitHub](https://git.new/flipt) to find out how Flipt can support your specific use case. # config edit Source: https://docs.flipt.io/v2/cli/commands/config/edit Edit Flipt configuration ``` flipt config edit [flags] ``` ## Synopsis Opens the Flipt configuration file in your default editor for making changes. ## Options ``` -h, --help help for edit ``` ### Options inherited from parent commands ``` --config string path to config file ``` ## Examples ```bash theme={null} flipt config edit flipt config edit --config /path/to/config.yml ``` ## More Info See the [Configuration](/v2/configuration/overview) section of the documentation for more information. # config init Source: https://docs.flipt.io/v2/cli/commands/config/init Initialize Flipt configuration ``` flipt config init [flags] ``` ## Synopsis Creates a new Flipt configuration file with default settings. ## Options ``` -y, --force Overwrite existing configuration file -h, --help help for init ``` ### Options inherited from parent commands ``` --config string path to config file ``` ## Examples ```bash theme={null} flipt config init flipt config init --force ``` ## More Info See the [Configuration](/v2/configuration/overview) section of the documentation for more information. # evaluate Source: https://docs.flipt.io/v2/cli/commands/evaluate Evaluate a flag ``` flipt evaluate [flagKey] [flags] ``` ## Synopsis Evaluates a feature flag against the Flipt instance and returns the evaluation result. Supports watch mode for continuous evaluation. ## Options ``` -a, --address string address of Flipt instance. (default "http://localhost:8080") -c, --context stringArray evaluation request context as key=value. -e, --entity-id string evaluation request entity id. (default "a910380a-2948-4da6-9d07-1238fc1042a5") --environment string flag environment (default "default") -h, --help help for evaluate -i, --interval duration interval between requests in watch mode. (default 1s) -n, --namespace string flag namespace. (default "default") -r, --request-id string evaluation request id. -t, --token string client token used to authenticate access to Flipt instance. -w, --watch enable watch mode. ``` ## Examples ```bash theme={null} flipt evaluate chat-enabled --context test=foo {"flag_key":"chat-enabled","enabled":true,"reason":"DEFAULT_EVALUATION_REASON","request_id":"73d12ea1-65d7-401d-b0c7-f7a6b3d41dd6","request_duration_millis":0.894792,"timestamp":"2024-01-23T17:37:13.484716964Z"} ``` ## More Info See the [Evaluation](/v2/concepts#evaluation) concepts section of the documentation for more information. # license activate Source: https://docs.flipt.io/v2/cli/commands/license/activate Activate a new Flipt Pro license ``` flipt license activate [flags] ``` ## Synopsis Interactive wizard for activating a new Flipt Pro license. Run this command when you first receive a license key or need to update your license configuration. The `activate` command provides a guided, text-based user interface that: * Supports both Pro Monthly and Pro Annual license types * Handles online and offline license configurations * Automatically updates your Flipt configuration file * Validates the license with the licensing service * Provides clear step-by-step guidance through the activation process ## Options ``` --config string path to config file -h, --help help for activate ``` ## Examples ```bash theme={null} flipt license activate flipt license activate --config /path/to/config.yml ``` ## More Info See the [Licensing](/v2/licensing) and [Flipt Pro](/v2/pro) documentation for more information about Pro features and licensing options. # license check Source: https://docs.flipt.io/v2/cli/commands/license/check Validate your Flipt Pro license ``` flipt license check [flags] ``` ## Synopsis Validates your current license configuration and displays license status information. Use this command to verify your license is properly configured before deploying to production, or to troubleshoot licensing issues. The `check` command: * Validates the license configuration in your Flipt config file * Connects to the licensing service to verify license validity * Displays your current license status and expiration * Shows which Pro features are available with your license * Provides guidance for unlicensed users ## Options ``` --config string path to config file -h, --help help for check ``` ## Examples ```bash theme={null} flipt license check flipt license check --config /path/to/config.yml ``` ## More Info See the [Licensing](/v2/licensing) and [Flipt Pro](/v2/pro) documentation for more information about Pro features and licensing options. # migrate Source: https://docs.flipt.io/v2/cli/commands/migrate Run pending analytics database migrations ``` flipt migrate [flags] ``` ## Synopsis This currently only supports Clickhouse analytics database migrations. Runs pending analytics database migrations. ## Options ``` --config string path to config file -h, --help help for migrate ``` ## Examples ```bash theme={null} flipt migrate flipt migrate --config /path/to/config.yml ``` ## More Info See the [Analytics](/v2/configuration/analytics) section of the documentation for more information. # quickstart Source: https://docs.flipt.io/v2/cli/commands/quickstart Interactive setup wizard for Flipt Git storage ``` flipt quickstart [flags] ``` ## Synopsis The `quickstart` command provides an interactive, text-based user interface wizard to help you configure Flipt v2 with Git storage and SCM integration. The wizard guides you through: * Selecting your SCM provider (GitHub, GitLab, Bitbucket, Azure DevOps, Gitea) * Configuring Git repository storage settings * Setting up authentication (Personal Access Token) * Automatically updating your Flipt configuration file ## Options ``` --config string path to config file -h, --help help for quickstart ``` ## Examples ```bash theme={null} flipt quickstart flipt quickstart --config /path/to/config.yml ``` ## More Info See the [Quickstart](/v2/quickstart) section of the documentation for more information about getting started with Flipt v2. # server Source: https://docs.flipt.io/v2/cli/commands/server Run the Flipt server ``` flipt server [flags] ``` ## Synopsis Starts the Flipt server. ## Options ``` --config string path to config file -h, --help help for server ``` ## Examples ```bash theme={null} flipt server flipt server --config /path/to/config.yml ``` # validate Source: https://docs.flipt.io/v2/cli/commands/validate Validate Flipt flag state (.yaml, .yml) files ``` flipt validate [flags] ``` ## Synopsis Validates Flipt flag state files (`.yaml`, `.yml`) for syntax errors and schema compliance. ## Options ``` -e, --extra-schema string path to extra schema constraints -F, --format string output format: json, text (default "text") -h, --help help for validate --issue-exit-code int exit code to use when issues are found (default 1) -d, --work-dir string set the working directory (default ".") ``` ## Examples ```bash theme={null} flipt validate flipt validate --work-dir /path/to/flags flipt validate --format json flipt validate --extra-schema /path/to/schema.json ``` # Overview Source: https://docs.flipt.io/v2/cli/overview Overview of the Flipt v2 CLI The `flipt` CLI is a command line interface for managing Flipt v2. It's useful for configuring your Flipt instance, running the server, and more. You can use it in various environments, including your local machine and CI/CD pipelines. ### Installation ```console Binary theme={null} curl -fsSL https://get.flipt.io/v2 | sh ``` ### Usage ``` flipt [flags] ``` ### Examples ``` $ flipt --help $ flipt server $ flipt server --config /path/to/config.yml ``` ### Options ``` -h, --help help for flipt ``` # Concepts Source: https://docs.flipt.io/v2/concepts This document describes the basic concepts of Flipt v2. More information on how to use Flipt is noted in the [Quickstart](/v2/quickstart) documentation. ## Environments Environments are a new concept in Flipt v2. They are a way to organize your namespaces, feature flags and configurations and keep them separate from each other. By default, Flipt v2 will create a single environment called `default` along with the `default` namespace. Environments Environments are managed via configuration files as they are also coupled to how you store your configuration data. See the [Environments](/v2/configuration/environments) documentation for more. All data created in one environment is only accessible within that environment, meaning namespaces, flags, segments, etc must be created in each environment in which they're to be used. If an environment isn't selected then the 'Default' environment is used. You can create as many environments as you want. Each environment can have its own namespaces, feature flags and configurations. ## Branches Branches are a way to create a copy of an environment. This allows you to test changes to your feature flags and configurations in a separate branch without affecting your users in production. Branches are created from an existing environment. Branches copy the base environment data and are completely independent of each other after creation. Branches You can create as many branches as you want from a base environment, however you cannot branch from a branch. ## Namespaces Namespaces are a way to organize your feature flags and configurations within an environment. One common use-case of Namespaces is to separate Flipt data by internal team. All data created in one namespace is only accessible within that namespace, meaning flags, segments, etc must be created in each namespace in which they're to be used. If a namespace isn't selected then the 'Default' namespace is used. Namespaces can be managed within the `Settings` section of the Flipt UI: Namespaces ## Flags Flags are the basic unit in the Flipt ecosystem. Flags represent experiments or features that you want to be able to enable or disable for users of your applications. For example, a flag named `New Contact Page` could be used to determine whether or not a given user sees the latest version of a 'Contact Us' page that you are working on when they visit your homepage. Flags can be used as simple on/off toggles or with variants and rules to support more elaborate use cases. Flags There are two types of flags: * **Variant** which allows you to return a single variant for a given flag given a set of evaluation rules. This is the default flag type. * **Boolean** which allows you to return a boolean value for a given flag. ### Variant Flags Variants are options for flags. For example, if you have a flag `Proceed to Checkout Color` that determines which color your users see when they proceed to checkout, then possible variants could include `blue`, `red` or `green`. Variant Flags #### Variant Attachments Variants can also have JSON attachments. This allows you to store additional data about a variant that can be used in your application at runtime. Variant attachments are not used for evaluation, they are only used for runtime configuration. The attachment size is limited to **1MB**. ### Boolean Flags Boolean flags are a special type of flag that allow you to return a boolean value for a given flag. You can use boolean flags to determine if a feature is enabled or disabled for a given entity (user, device, etc) by returning `true` or `false` respectively. Boolean flags work well for simple use cases where you don't need to return multiple variants. Boolean flags can be configured with [rollout](#rollouts) rules to determine which entities receive `true` or `false` for a given flag. Boolean Flags ### Metadata All flags can have metadata associated with them. This metadata is stored in the Flipt backend and can be used to add additional information about a flag. Metadata is stored as a JSON object and is not used for evaluation. You can retrieve flag metadata using the [Get Flag](/v1/reference/flags/get-flag) API. By default, ListFlags responses omit flag metadata. To include metadata in ListFlags responses, set [`evaluation.include_flag_metadata`](/v2/configuration/overview#evaluation) to `true`. In the Flipt UI, metadata is displayed in the flag details section. The UI allows you to add, edit, and delete metadata and provides a more user-friendly interface for managing metadata by specifying key-value pairs and their data types. Currently, the following data types are supported: * Primitive types: `String`, `Number`, `Boolean` * Complex types: `Array`, `Object` Flag Metadata ## Segments Segments allow you to split your user base or audience up into predefined slices. This is a powerful feature that enables targeting groups to determine if a flag or variant applies to them. An example segment could be `beta-users`. Segments Segments are global within a Flipt namespace. ### Match Types When configuring a segment you can choose a `Match Type` of either: * **Match All** which requires ALL constraints to match for the segment to apply for evaluation. * **Match Any** which requires AT LEAST ONE constraint to match for the segment to apply for evaluation. ### Constraints Constraints allow you to determine which segment a given entity is a part of. For example, for a user to fall into the above `beta-users` segment, you may want to check their `finished_onboarding` property. Constraints All constraints have a *property*, *type*, *operator* and optionally a *value*. #### Constraint Types Currently 5 constraint types are available: * **String** which allows you to check a string property of an entity * **Number** which allows you to check a number property of an entity (integer or float) * **Boolean** which allows you to check a boolean property of an entity such as `true` or `false` * **DateTime** which allows you to check a date or datetime property of an entity such as `2020-01-01` or `2020-01-01T00:00:00Z` ([RFC3339](https://datatracker.ietf.org/doc/html/rfc3339)) * **Entity** which allows you to check the `entityId` that was sent in the body of the `Variant` or `Boolean` request The constraint value is represented as a string in transit and in storage, however it's coerced into the appropriate type for evaluation. ## Rules Rules allow you to tie your flags, variants and segments together by specifying which segments are targeted by which variants. Rules can be as simple as `IF IN segment THEN RETURN variant_a` or they can be richer by using distribution logic to roll out features on a percentage basis. Continuing our previous example, we may want to return the flag variant `green` for all entities in the `beta-users` segment. This would be configured like so: Rules Rules are evaluated in order per their rank from 1-N. The first rule that matches wins. Once created, rules can be re-ordered to change how they're evaluated. ### Default Rule If no rules match for a given flag, the default rule value is returned. This value is optional and can be set to any variant that exists for the flag. ### Distributions Distributions allow you to return different variants of your flag to different percentages of your user base based on your rules. Let's say that instead of always showing the `green` variant to your `beta-users` segment, you want to show `green` to **10%** of `beta-users`, `blue` to **30%**, and `red` to the remaining **60%**. You would accomplish this using rules with distributions: Distributions The ability to manage distributions, as illustrated in the image above, is an extremely powerful feature of Flipt that can help you seamlessly deploy new features of your applications to your users while also limiting the reach of potential bugs. ## Rollouts Rollouts allow you to potentially change the result of a boolean flag value at request time. Rollouts are a sequence of conditions which when one is matched for a request context, overrides the default rollout property. Current rollout types include: * **Threshold** which allows you to return `true` or `false` for a given percentage of entities. * **Segments Match** which allows you to return `true` or `false` if an entity matches a given segment. Rollouts Rollouts work similar to [Rules](#rules) in that they're evaluated in order per their rank from 1-N. The first rollout that matches wins. Once created, rollouts can be re-ordered to change how they're evaluated. ### Default Rollout If no rollouts match for a given flag, the default rollout value is returned. This value is the same as the 'enabled' value for the flag for backward compatibility reasons. ## Evaluation Evaluation is the process of sending requests to the Flipt server to process and determine if that request matches any of your segments and if so which variant or boolean value to return depending on flag type. In the above example involving checkout colors, evaluation is where you send information about your current user to determine if they're a `beta-user`, and which color (`green`, `blue`, or `red`) that they should see for their checkout color. Evaluation ### Entities Evaluation works by uniquely identifying each *thing* that you want to compare against your segments and flags. We call this an `entity` in the Flipt ecosystem. More often than not this will be a user, but we didn't want to make any assumptions about how your application works, which is why `entity` was chosen. **Entity** What you want to test against in your application For Flipt to successfully determine which *bucket* your entities fall into, it must have a way to uniquely identify them. This is the `entityId` and it's a simple string. It's up to you what that `entityId` is. It could be a: * email address * userID * IP address * physical address * etc Anything that's unique enough for your application and its requirements. ### Context The final piece of the puzzle is context. Context allows Flipt to determine which segment your entity falls into by comparing it to all the possible constraints that you defined. **Context** Metadata associated with your entity used to determine which if any segments that entity is a member of Examples of context include: ``` - isAdmin - favoriteColor - country - freeUser ``` Think of these as pieces of information that are usually not unique, but that can be used to split your entities into your segments. You can include as much or as little context for each entity as you want, however, the more context that you provide, the more likely it's that an entity will match one of your segments. In Flipt, `context` is a simple map of key-value pairs where the key is the property to match against all constraints, and the value is what's compared. ### Bucketing Bucketing is the process of determining which variant to return for a given evaluation request. Flipt uses a hashing algorithm to determine which variant to return for a given `flagKey`, `entityID` and `context`. This is what allows Flipt to return the same variant every time (also sometimes referred to as **stickiness**). Flipt never persists any information about your entities or context or which variant was returned for a given evaluation request. This is all done at runtime and is ephemeral. This allows Flipt to be used in a wide variety of applications and use cases without having to worry about inadvertently storing personally identifiable information (PII) or other privacy concerns. **Let's look at how it works:** 1. Flipt takes the `flagKey` and `entityID` and concatenates them together to form a string that looks like `flagKey:entityID`. This is called the key. 2. Flipt then takes this new key and uses a hashing algorithm ([CRC-32 ChecksumIEEE](https://pkg.go.dev/hash/crc32#ChecksumIEEE)) to create a 32-bit integer called the hash. 3. Flipt then creates a set of buckets from 0‐999 (1000 total buckets), mapping them with a sorted set of the [distributions](#distributions) for the flag. 4. Finally, Flipt takes the hash and uses the modulo operator to determine which bucket the hashed value falls into. The distribution that maps to that bucket is then returned. **Consider an example:** Imagine that you have a flag with two [distributions](#distributions) `A` and `B`. If `distribution A` has a 30% 'rollout', then it would 'take up' buckets 0‐299 (out of the 1000 buckets). `Distribution B` would take up the remaining buckets 300‐999. The `flagKey/entityID` hashed value is a 32bit integer on which Flipt performs a [modulo](https://en.wikipedia.org/wiki/Modulo) operation (% 1000) so that it 's guaranteed to return a number between 0‐999. The result of the modulo operation is then used to determine which distribution to return via the bucket mapping. If the result is between 0‐299, then `distribution A` is returned, otherwise `distribution B` is returned. # Analytics Source: https://docs.flipt.io/v2/configuration/analytics This document describes various configuration mechanisms for controlling analytics for Flipt v2. ## Analytics Flipt includes functionality for reporting analytical data to a configurable storage engine. Currently, Flipt has support for collecting data into the following storage engines: * [ClickHouse](https://clickhouse.com/) * [Prometheus](https://prometheus.io/) The data that gets collected currently includes: * Flag Evaluation Count Once a storage engine is configured, these analytics are viewable in the UI allowing users to visualize up to 24 hours of data for each metric. Analytics Dashboard The image above shows the past 30 minutes of the flag `summer-sale` evaluation counts. ### Origin Analytics are currently only collected as they pass through the evaluation server. This means that analytics will be captured if you are using the REST or GRPC APIs via one of our [Server SDKs](/v2/integration/server/rest) or [GRPC SDKs](/v1/integration/server/grpc) for evaluations. We have plans to support collecting analytics for [Client-Side](/v2/integration/client) evaluations in the future. ## ClickHouse You can use a self-hosted ClickHouse instance or a [managed instance](https://clickhouse.com/cloud/) to store your analytics data. We highly **recommend** using a separate database for analytics produced by Flipt. This ensures that Flipt analytic data can be logically isolated from the rest of your Clickhouse data. The analytics database must be created before Flipt will be able to write analytical data and run any migrations. See our [migrate](/v2/cli/commands/migrate) command for more info. To create a database for Flipt analytics, you can use the following SQL: ```sql theme={null} CREATE DATABASE IF NOT EXISTS flipt_analytics_v2; ``` See the [ClickHouse documentation](https://clickhouse.com/docs) for more information on how to get started with ClickHouse. ### Configuration To configure Flipt to use ClickHouse for analytics, you will need to add the following configuration to your `config.yml` file or environment variables: ```bash theme={null} FLIPT_ANALYTICS_STORAGE_CLICKHOUSE_ENABLED=true FLIPT_ANALYTICS_STORAGE_CLICKHOUSE_URL=clickhouse://clickhouse:9000/flipt_analytics_v2 ``` ```yaml theme={null} analytics: storage: clickhouse: enabled: true url: clickhouse://clickhouse:9000/flipt_analytics_v2 ``` ## Prometheus You can use any [Prometheus](https://prometheus.io/docs/introduction/overview/) server to store your analytics data. ### Configuration To configure Flipt to use Prometheus for analytics, you will need to add the following configuration to your `config.yml` file or environment variables: ```bash theme={null} FLIPT_ANALYTICS_STORAGE_PROMETHEUS_ENABLED=true FLIPT_ANALYTICS_STORAGE_PROMETHEUS_URL=http://prometheus:9090 ``` ```yaml theme={null} analytics: storage: prometheus: enabled: true url: http://prometheus:9090 ``` ### Custom Headers You can also add custom headers to the Prometheus requests by setting the `analytics.storage.prometheus.headers` configuration property. This can be useful if you are using a proxy or need to add additional authentication headers. ```yaml theme={null} analytics: storage: prometheus: headers: "Authorization": "Bearer " ``` ### AWS SigV4 Authentication If you are using [Amazon Managed Service for Prometheus (AMP)](https://aws.amazon.com/prometheus/), you can configure Flipt to authenticate requests using [AWS Signature Version 4 (SigV4)](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). ```yaml theme={null} analytics: storage: prometheus: enabled: true url: https://aps-workspaces.us-east-1.amazonaws.com/workspaces/ sigv4: enabled: true ``` ```bash theme={null} FLIPT_ANALYTICS_STORAGE_PROMETHEUS_ENABLED=true FLIPT_ANALYTICS_STORAGE_PROMETHEUS_URL=https://aps-workspaces.us-east-1.amazonaws.com/workspaces/ FLIPT_ANALYTICS_STORAGE_PROMETHEUS_SIGV4_ENABLED=true FLIPT_ANALYTICS_STORAGE_PROMETHEUS_SIGV4_REGION=us-east-1 FLIPT_ANALYTICS_STORAGE_PROMETHEUS_SIGV4_ACCESS_KEY= FLIPT_ANALYTICS_STORAGE_PROMETHEUS_SIGV4_SECRET_KEY= ``` If `access_key` and `secret_key` are not provided, Flipt falls back to the [default AWS credential chain](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials) (environment variables, shared credentials file, IAM instance profile, etc.). You can also assume an IAM role by specifying `role_arn`: ```yaml theme={null} analytics: storage: prometheus: enabled: true url: https://aps-workspaces.us-east-1.amazonaws.com/workspaces/ sigv4: enabled: true region: us-east-1 role_arn: arn:aws:iam:::role/ ``` | Property | Description | Default | | ---------------------------------------------- | ----------------------------------------------- | ------- | | analytics.storage.prometheus.sigv4.enabled | Enable Prometheus SigV4 support | false | | analytics.storage.prometheus.sigv4.region | AWS region for SigV4 signing | | | analytics.storage.prometheus.sigv4.access\_key | AWS access key ID | | | analytics.storage.prometheus.sigv4.secret\_key | AWS secret access key | | | analytics.storage.prometheus.sigv4.profile | AWS credentials profile name | | | analytics.storage.prometheus.sigv4.role\_arn | ARN of an IAM role to assume for authentication | | # Authentication Source: https://docs.flipt.io/v2/configuration/authentication This document describes how to configure the authentication mechanisms for Flipt v2. Flipt supports the ability to secure its core API routes by setting the `required` field to `true` on the `authentication` configuration object. ```yaml config.yaml theme={null} authentication: required: true ``` When authentication is set to `required`, the API will ensure valid credentials are present on all API requests. Once authentication has been set to `required: true` all API routes will require a client token to be present. The UI will require a session-compatible authentication method (e.g. [OIDC](#method-oidc)) to be enabled. ## Exclusions Exclusions allow you to disable authentication for sections of the API. The Flipt API is made up of several top-level API sections, each with its own unique prefix. For example: * `/evaluate/v1` is the application facing flag state evaluation API Several of these API sections can be optionally omitted from requiring authentication. A common use case is to allow the evaluation API to be publicly accessible while still requiring authenticated users to manage feature-flag configuration and state. By default, when authentication is configured as `required: true`, the effective configuration for the exclusions looks like this: ```yaml config.yaml theme={null} authentication: required: true exclude: evaluation: false ``` This means every part of the Flipt API is required for authentication. However, taking the example from before, we could skip authentication for the evaluation section of the Flipt API like so: ```yaml config.yaml theme={null} authentication: required: true exclude: evaluation: true ``` ## Session This section contains common properties for establishing browser sessions via a "session compatible" authentication method. Session-compatible methods enable support for login in the UI. The methods below state whether or not they're session compatible (e.g. [OIDC](#method-oidc) is session compatible). Session Login In order to establish a browser session over HTTP (via a `Cookie` header) some configuration is required. ```yaml config.yaml theme={null} authentication: required: true session: domain: "flipt.yourorg.com" secure: true csrf: key: "some_secret_string" ``` When a "session compatible" authentication method is enabled the `domain` property is **required**. It should be configured with the public domain your Flipt instance is hosted on. The other properties aren't required to be explicitly configured. To best secure your instance of Flipt, we advise that you run Flipt with `secure: true`. This will require you to expose Flipt over HTTPS. Additionally, we advise that you configure a `csrf.key` with a 32 or 64-byte random string of data. ``` openssl rand -base64 64 ``` ### Session Storage Session storage allows you to configure where the session data is stored. All session enabled authentication methods will use the same configured session storage backend. Currently, Flipt v2 supports the following session storage backends: * `memory` * `redis` #### Memory The `memory` backend is the default and will store session data in memory. This means that the session data will be lost when the Flipt server restarts. ```yaml config.yaml theme={null} authentication: required: true session: storage: type: memory ``` #### Redis The `redis` backend will store session data in a Redis instance. This means that the session data will be persisted across Flipt server restarts and can be shared across multiple Flipt servers. ```yaml config.yaml theme={null} authentication: required: true session: storage: type: redis redis: mode: single # Required: either "single" or "cluster" host: localhost port: 6379 db: 0 password: password ``` The `mode` parameter is **required** and must be set to either: * `single` - For standalone Redis instances (most common) * `cluster` - For Redis cluster setups ##### Redis Cluster Example For Redis cluster configurations, use `mode: cluster`: ```yaml config.yaml theme={null} authentication: required: true session: storage: type: redis redis: mode: cluster host: localhost port: 6379 db: 0 password: password ``` ### Session Cleanup Session cleanup is a feature that allows you to configure the periodic deletion of *expired* authentications created with the associated method. ```yaml config.yaml theme={null} authentication: required: true session: cleanup: grace_period: 24h ``` `grace_period` is used to ensure that *expired* tokens are preserved for at least this configured duration. This allows you to keep authentications around for auditing purposes after expiration. Expired tokens are instances where the `expires_at` timestamp occurs before the current time. The grace period is added onto this timestamp as a predicate when the delete operation is made. Tokens that have expired (`expires_at` is before `now()`) will begin immediately failing authentication when presented as a credential to the API. The `grace_period` is simply for the cleanup process. ## Methods Each key within the `methods` section is a particular authentication method. These methods are disabled (`enabled: false`) by default. Enabling and configuring a method allows for different ways to establish client token credentials within Flipt. ### Static Token The `token` method is NOT a `session compatible` authentication method. The `token` method provides the ability to create client tokens statically, defined in the configuration file. ```yaml config.yaml theme={null} authentication: required: true methods: token: enabled: true storage: tokens: "some_token_id": credential: "some_token_credential" metadata: some_key: "some_value" ``` #### Using Secret References To avoid storing token values directly in your configuration file, you can use [secret references](/v2/configuration/overview#secret-references) with a configured [secret provider](/v2/configuration/secrets). Using the [file provider](/v2/configuration/secrets#file-provider): ```yaml config.yaml theme={null} authentication: required: true methods: token: enabled: true storage: tokens: "ci_token": credential: "${secret:file:ci-token}" # References /etc/flipt/secrets/ci-token metadata: name: "CI Pipeline Token" "dev_token": credential: "${secret:file:dev-token}" # References /etc/flipt/secrets/dev-token metadata: name: "Development Token" ``` Using the [HashiCorp Vault provider](/v2/configuration/secrets#hashicorp-vault-provider): ```yaml config.yaml theme={null} authentication: required: true methods: token: enabled: true storage: tokens: "ci_token": credential: "${secret:vault:flipt/tokens:ci-token}" # References flipt/tokens secret, key: ci-token metadata: name: "CI Pipeline Token" "dev_token": credential: "${secret:vault:flipt/tokens:dev-token}" # References flipt/tokens secret, key: dev-token metadata: name: "Development Token" ``` Using a cloud provider ([AWS](/v2/configuration/secrets#aws-secrets-manager-provider), [GCP](/v2/configuration/secrets#gcp-secret-manager-provider), or [Azure](/v2/configuration/secrets#azure-key-vault-provider)): ```yaml config.yaml theme={null} authentication: required: true methods: token: enabled: true storage: tokens: "ci_token": credential: "${secret:aws:ci-token}" # AWS Secrets Manager metadata: name: "CI Pipeline Token" "dev_token": credential: "${secret:gcp:dev-token}" # GCP Secret Manager metadata: name: "Development Token" ``` See [Secrets](/v2/configuration/secrets) for details on configuring secret providers. ### OIDC The `OIDC` method is a `session compatible` authentication method. The `oidc` method provides the ability to establish client tokens via OAuth 2.0 with OIDC flow. Once enabled and configured, the UI will automatically leverage it and present any configured providers as login options. ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true email_matches: - ^.*@flipt\.io$ providers: some_provider: # insert your provider name issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" scopes: - email - profile ``` Multiple providers can be configured simultaneously. Each provider will result in a login option being presented in the UI, along with a configured endpoint to support the provider flow. Flipt v2 has been tested with each of the following providers: * [Google](https://developers.google.com/identity/openid-connect/openid-connect) * [Auth0](https://auth0.com/docs/get-started/applications/application-settings) * [GitLab](https://docs.gitlab.com/ee/integration/openid_connect_provider.html) * [Dex](https://dexidp.io/docs/openid-connect/) * [Okta](https://developer.okta.com/docs/concepts/oauth-openid/#oauth-2-0) * [AzureAD](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc) * [Keycloak](https://www.keycloak.org/docs/latest/server_admin/index.html#_identity_broker_oidc) Though the intention is that it should work with all OIDC providers, these are just the handful the Flipt team has validated. Following any of the links above should take you to the relevant documentation for each of these providers' OIDC client setups. You can use the credentials and client configuration obtained using those steps as configuration for your Flipt instance. #### Callback URL When configuring your OIDC provider, you will need to provide a callback URL for the provider to redirect back to Flipt after a successful login. The callback URL will be in the form of `https://your.flipt.instance.url.com/auth/v1/method/oidc/{provider}/callback`. You can find the callback URL for each provider that you configure in your Flipt instance by querying the API. ```bash theme={null} curl --request GET \ --url https://your.flipt.instance.url.com/auth/v1/method \ --header 'Accept: application/json' ``` ```json theme={null} { "methods": [ { "method": "METHOD_TOKEN", "enabled": true, "sessionCompatible": false, "metadata": null }, { "method": "METHOD_OIDC", "enabled": true, "sessionCompatible": true, "metadata": { "providers": { "google": { "authorize_url": "/auth/v1/method/oidc/google/authorize", "callback_url": "/auth/v1/method/oidc/google/callback" } } } } ] } ``` #### Email Matches Flipt operators may wish to lock down access to the Flipt API and UI to a specific group of users within their organization behind OIDC. Since OIDC has the ability to retrieve email addresses, Flipt also provides a configuration option of using `email_matches` which are [regular expressions](https://github.com/google/re2/wiki/Syntax) that can be used to match against the OIDC email. You must request the `email` scope from your OIDC provider in order for this feature to work. You can see an example of that above in the [sample configuration](#method-oidc). #### Algorithms By default, Flipt expects OIDC ID tokens to be signed with the `RS256` algorithm. Some identity providers sign tokens with other algorithms (for example, `ES256` or `PS256`). You can configure the accepted signing algorithms per provider using the `algorithms` field. Supported algorithms: `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`, `PS384`, `PS512`. ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true providers: some_provider: issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" algorithms: - ES256 ``` If not specified, the default is `["RS256"]`. #### UserInfo Claims Some OIDC providers keep ID token claims minimal and require calling the UserInfo endpoint to obtain additional attributes such as email, display name, or group membership. This is especially common for providers that omit or truncate group claims in the ID token. You can enable fetching additional claims from the provider's UserInfo endpoint by setting `fetch_extra_user_info` to `true`. When enabled, Flipt calls the UserInfo endpoint during the login callback and merges the returned claims into the session. ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true providers: some_provider: issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" fetch_extra_user_info: true ``` If not specified, the default is `false`. #### Custom Authorize Parameters Some OIDC providers require extra query parameters on the authorization request. For example, Auth0 can use an `audience` parameter to request API access, and some providers use parameters such as `domain_hint`, `connection`, or `idp` to route users to the correct identity provider. Configure these values with the `authorize_parameters` map on the provider. Flipt appends each key-value pair to the OIDC authorize URL during login. ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true providers: some_provider: issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" authorize_parameters: audience: "https://api.example.com" prompt: "login" domain_hint: "example.com" ``` If not specified, the default is an empty map. #### Single Logout (SLO) Single Logout (SLO) allows you to terminate a user's session across Flipt and the OIDC provider simultaneously. When a user logs out from one service, the session is invalidated everywhere. Flipt supports both back-channel and front-channel logout as defined by the [OIDC Front-Channel Logout](https://openid.net/specs/openid-connect-frontchannel-1_0.html) and [OIDC Back-Channel Logout](https://openid.net/specs/openid-connect-backchannel-1_0.html) specifications. ##### Back-Channel Logout Back-channel logout is the most common approach. The OIDC provider sends a signed `logout_token` to Flipt via a server-to-server POST request at `/auth/v1/method/oidc/{provider}/revoke`. Flipt verifies the token and removes the matching session. No additional configuration is required to enable back-channel logout — it is available whenever an OIDC provider is configured. To use back-channel logout, register the Flipt revoke endpoint as the provider's **Back-Channel Logout URL**: ```text theme={null} https://your.flipt.instance.url.com/auth/v1/method/oidc/{provider}/revoke ``` When the provider initiates a logout, it sends a form-encoded POST request with a `logout_token` parameter. Flipt verifies the token's signature, issuer, and audience, then uses the `sid` (session ID) or `sub` (subject) claim to locate and delete the corresponding authentication record. ##### Front-Channel Logout Front-channel logout uses browser redirects instead of server-to-server calls. When the OIDC provider initiates logout, it embeds an invisible iframe pointing to Flipt's front-channel logout endpoint. The browser makes a GET request to: ```text theme={null} https://your.flipt.instance.url.com/auth/v1/method/oidc/{provider}/revoke?iss={issuer}&sid={session_id} ``` To enable front-channel logout, set `allow_front_channel_logout` to `true` on the provider: ```yaml config.yaml theme={null} authentication: required: true session: domain: "flipt.yourorg.com" secure: true methods: oidc: enabled: true providers: some_provider: issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" allow_front_channel_logout: true ``` Front-channel logout requires `session.secure: true`. The logout flow sets `SameSite=None` on session cookies so the browser can discard them in a cross-origin iframe context. Browsers reject `SameSite=None` cookies unless the `Secure` flag is set, so enabling front-channel logout without a secure session will result in a configuration error. To use front-channel logout, register the Flipt revoke endpoint as the provider's **Front-Channel Logout URL**: ```text theme={null} https://your.flipt.instance.url.com/auth/v1/method/oidc/{provider}/revoke ``` The provider includes `iss` and `sid` query parameters so Flipt can identify the session to terminate. ##### End-Session Endpoint Flipt can also redirect users to the OIDC provider's end-session endpoint when they log out from the UI. This ensures the provider terminates its own session as well. To enable this, set `use_end_session_endpoint` to `true` on the provider: ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true providers: some_provider: issuer_url: "https://some.oidc.issuer.com" client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" use_end_session_endpoint: true ``` When enabled, Flipt constructs a redirect URL using the provider's `end_session_endpoint` (discovered from the OIDC well-known configuration) with the following query parameters: * `id_token_hint` — the user's ID token * `post_logout_redirect_uri` — the provider's configured `redirect_address` The `use_end_session_endpoint` option requires the provider to expose an `end_session_endpoint` in its OIDC discovery document. If the provider does not, Flipt logs an error and skips the redirect. #### Self-Signed Certificates If your OIDC provider uses self-signed or internal CA certificates (common with self-hosted Keycloak, Dex, or corporate identity providers), Flipt will reject the TLS connection with an error like: ```text theme={null} x509: certificate signed by unknown authority ``` The full error may also appear as `tls: failed to verify certificate: x509: certificate signed by unknown authority` depending on the log context. Flipt relies on the system trust store for TLS validation. To trust your internal CA, you need to add your CA certificate(s) to the container's trust store. Unlike the [`kubernetes` auth method](/v2/configuration/authentication#kubernetes), OIDC does not expose a `ca_path` configuration option. You must add your CA certificate(s) to the container's system trust store instead. ##### Dockerfile Example ```dockerfile theme={null} FROM flipt/flipt:latest # Install CA certificates tooling RUN apk add --no-cache ca-certificates # Copy your internal CA certificate(s) COPY certs/Internal_Root_CA.crt /usr/local/share/ca-certificates/ COPY certs/Internal_Intermediate_CA.crt /usr/local/share/ca-certificates/ # Update the system trust store RUN update-ca-certificates ``` ##### Kubernetes Example First, create a Secret containing your CA certificate: ```bash theme={null} kubectl create secret generic internal-ca-certs \ --from-file=ca.crt=/path/to/your/ca.crt ``` Then deploy Flipt with an init container that updates the trust store: ```yaml theme={null} apiVersion: apps/v1 kind: Deployment metadata: name: flipt spec: replicas: 1 selector: matchLabels: app: flipt template: metadata: labels: app: flipt spec: initContainers: - name: update-ca-certs image: alpine:latest command: ["sh", "-c"] args: - | apk add --no-cache ca-certificates && cp /certs/*.crt /usr/local/share/ca-certificates/ && update-ca-certificates && cp -r /etc/ssl/certs/* /shared-certs/ volumeMounts: - name: ca-certs mountPath: /certs - name: shared-certs mountPath: /shared-certs containers: - name: flipt image: flipt/flipt:v2 volumeMounts: - name: shared-certs mountPath: /etc/ssl/certs readOnly: true volumes: - name: ca-certs secret: secretName: internal-ca-certs - name: shared-certs emptyDir: {} ``` You can verify that the certificates are trusted by running: ```bash theme={null} echo | openssl s_client -connect your-oidc-provider:443 2>&1 | grep "Verification" ``` You should see `Verification: OK` if the CA is properly trusted. #### PKCE A good amount of OIDC providers support the PKCE (Proof Key for Code Exchange) flow and the implicit OAuth flow. Flipt allows for a configuration to enable PKCE for all the legs of the OIDC authentication flow. To enable this, you must set the [`use_pkce`](/v2/configuration/overview#authentication-methods-oidc) property to `true` for each provider you would like to leverage PKCE with. #### Example: OIDC With Google Given we're running our instance of Flipt on the public internet at `https://flipt.myorg.com`. Using Google as an example and the documentation linked above, we obtained the following credentials for a Google OAuth client: ```yaml theme={null} client_id: "CyJcdvQMadOjSEx7ArArom0ytrbIHWd2Fb3N59oh8NQ=" client_secret: "WGgJmfQqN7cf17dFyZKXDL5S445/qhp+hfDAC0Mnl7oBrxgdAgiMyuwCkPiwfgQy" ``` We could create a provider definition in our configuration like so: ```yaml config.yaml theme={null} authentication: required: true methods: oidc: enabled: true providers: google: issuer_url: "https://accounts.google.com" client_id: "CyJcdvQMadOjSEx7ArArom0ytrbIHWd2Fb3N59oh8NQ=" client_secret: "WGgJmfQqN7cf17dFyZKXDL5S445/qhp+hfDAC0Mnl7oBrxgdAgiMyuwCkPiwfgQy" redirect_address: "https://flipt.myorg.com" scopes: - email - profile ``` The redirect URL for this provider would be `https://flipt.myorg.com/auth/v1/method/oidc/google/callback`. Additional `scopes` such as `profile` aren't 100% necessary, however, adding them will result in Flipt being able to identify more details about your users such as personalized greeting messages and user profile pictures in the UI. Once this configuration has been enabled a `Login with Google` option will be presented in the UI. Clicking this button will navigate the user to a Google consent screen. Once the user has authenticated with Google, they will be redirected to the address defined in the `redirect_address` section of the provider configuration. Google's consent screen can be configured to only accept accounts that are within your Google Workspace organization. Other providers have similar mechanisms for attenuating who can leverage this authentication flow. ### GitHub The `GitHub` method is a `session compatible` authentication method. The `github` method provides the ability to establish client tokens via OAuth 2.0 with GitHub as the identity provider. Once enabled and configured, the UI will automatically leverage it and present a "Login with GitHub" button. ```yaml config.yaml theme={null} authentication: required: true methods: github: enabled: true client_id: "some_client_identifier" client_secret: "some_client_secret_credential" redirect_address: "https://your.flipt.instance.url.com" scopes: - user:email ``` GitHub Login #### Allowed Organizations The GitHub authentication method supports the ability to restrict access to a set of GitHub organizations. This is important if you want to limit access to Flipt to only members of a specific organization as opposed to all GitHub users. To enable this feature, set the `github.allowed_organizations` configuration value to a list of GitHub organizations. For example: ```yaml config.yaml theme={null} authentication: required: true methods: github: enabled: true scopes: - read:org allowed_organizations: - my-org - my-other-org ``` The `read:org` scope is required to retrieve the list of organizations that the user is a member of. Your OAuth application **must have permission** to access the specified organization(s). Without this permission, the GitHub API won't return organization membership information when Flipt verifies access. For a complete setup guide, see [Login with GitHub](/v2/guides/operations/authentication/login-with-github). GitHub Organization OAuth Permissions #### Allowed Teams The GitHub authentication method also supports the ability to restrict access to a set of GitHub teams. This is important if you want to limit access to Flipt to only members of a specific team within an organization as opposed to all members of the organization. To enable this feature, set the `github.allowed_teams` configuration value to a list of GitHub teams within existing allowed organizations. For example: ```yaml config.yaml theme={null} authentication: required: true methods: github: enabled: true scopes: - read:org allowed_organizations: - my-org - my-other-org allowed_teams: my-org: - my-team my-other-org: - my-other-team ``` The organizations to check for team membership must be included in the `allowed_organizations` list. ### Kubernetes The `kubernetes` method provides the ability to exchange Kubernetes service account tokens for client tokens. ```yaml config.yaml theme={null} authentication: required: true methods: kubernetes: enabled: true discovery_url: https://kubernetes.default.svc.cluster.local ca_path: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt service_account_token_path: /var/run/secrets/kubernetes.io/serviceaccount/token ``` Once enabled, client tokens can be retrieved by sending a Kubernetes pod's service account token to the `VerifyServiceAccount` operation in the API. Further explanation for using this method can be found in the [Authentication: Kubernetes](/v1/authentication/methods#kubernetes) documentation. #### Troubleshooting **verifying service account: failed to verify signature: fetching keys oidc** In some managed Kubernetes cluster environments, the default cluster OIDC provider is replaced with the platform's managed alternative. For example, EKS clusters leverage this so that they can issue service account tokens which can assume the capabilities of AWS IAM roles. In this situation, the default OIDC discovery URL isn't appropriate for fetching key material from. Instead, you should locate your clusters OIDC URL and use that instead. Your cluster's OIDC URL will vary between Kubernetes providers. For example, here is some documentation which should help for EKS: [EKS troubleshoot OIDC and IRSA](https://repost.aws/knowledge-center/eks-troubleshoot-oidc-and-irsa). It's also important to note that custom OIDC providers likely will use HTTPS which has been signed with certificates not authorized by the cluster TLS certificate authority. In this situation, you can override the `kubernetes` auth providers `ca_path` field with relevant key material. The `flipt` distributed Docker image has valid and trusted certificates in `/etc/ssl/certs/ca-certificates.crt`, which can be appropriate if your OIDC provider has certificates granted by a valid public certificate authority. ```yaml example-config-for-eks.yaml theme={null} authentication: required: true methods: kubernetes: enabled: true discovery_url: https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E # note: yours will be different ca_path: /etc/ssl/certs/ca-certificates.crt # this can be enough if your OIDC provider TLS certificates have been signed by a public certificate authority ``` See [this issue](https://github.com/flipt-io/flipt/issues/2942) for more context. ### JSON Web Token The `jwt` method provides the ability to authenticate with Flipt using an externally issued JSON Web Token. This method is useful for integrating with other authentication systems that can issue JWTs (e.g. [Auth0](https://auth0.com/docs/tokens/json-web-tokens)) or by generating your own signed JWTs on the fly. Flipt supports asymmetrically signed JWTs using the following algorithms: * RS256 * RS512 * ES256 * ES512 * EdDSA This means that the JWT must be signed using a private key leveraging one of these algorithms and Flipt must be configured with the corresponding public key. Flipt supports key verification using the following methods: * [JWKS](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) URL (JSON Web Key Set URL) * PEM (Privacy Enhanced Mail) encoded public key These methods are mutually exclusive, meaning that only one of them can be configured at a time. #### JWKS URL The `jwks_url` configuration value is a URL that points to a JWKS (JSON Web Key Set) endpoint. This endpoint must return a JSON object that contains a list of public keys that can be used to verify the JWT signature. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true jwks_url: https://auth0.com/.well-known/jwks.json ``` #### PEM Encoded Public Key The `public_key_file` configuration value is the path to a PEM encoded public key that can be used to verify the JWT signature. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true public_key_file: /path/to/public_key.pem ``` #### Claim Validation Flipt supports validating the following claims: * `iss` (issuer) * `aud` (audience) * `sub` (subject) * `exp` (expiration time) * `nbf` (not before) * `iat` (issued at) The `exp`, `nbf`, and `iat` claims are validated by default. To enable claim validation, configure the values in the `validate_claims` configuration option to the expected values. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true validate_claims: issuer: https://auth0.com/ subject: user@domain.com audiences: https://flipt.io/, https://flipt.com/ # at least one audience must match ``` #### Claims Mapping By default, Flipt extracts user attributes from JWT claims using predefined paths within the JWT payload. The default mappings are: * `email` from `/user/email` * `name` from `/user/name` * `sub` from `/user/sub` * `picture` from `/user/image` * `role` from `/user/role` You can customize these mappings using the `claims_mapping` configuration option. This allows you to specify [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) expressions to extract user attributes from different locations in the JWT payload. The custom mappings are merged with the default mappings, so you can override specific attributes while keeping the defaults for others. Only the predefined attribute names (`email`, `name`, `sub`, `picture`, `role`) are supported in claims mapping. Custom attribute names are not allowed to ensure compatibility with consuming code. ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true claims_mapping: email: "/user/email" # Override default (same path) name: "/profile/displayName" # Override default (custom path) sub: "/user_id" # Override default (custom path) ``` With this configuration: * `email` is extracted from `/user/email` (default behavior) * `name` is extracted from `/profile/displayName` (custom override) * `sub` is extracted from `/user_id` (custom override) * `picture` is still extracted from `/user/image` (default, not overridden) * `role` is still extracted from `/user/role` (default, not overridden) **Example JWT payload:** ```json theme={null} { "iss": "https://auth0.com/", "sub": "auth0|123456", "user_id": "12345", "user": { "email": "user@example.com" }, "profile": { "displayName": "John Doe" } } ``` The resulting metadata available in Flipt would be: * `io.flipt.auth.jwt.email`: `user@example.com` * `io.flipt.auth.jwt.name`: `John Doe` * `io.flipt.auth.jwt.sub`: `12345` Invalid JSON Pointer expressions or paths that don't exist in the JWT payload are silently ignored. # Authorization Source: https://docs.flipt.io/v2/configuration/authorization This document describes how to configure the authorization mechanisms for Flipt v2. Flipt v2 introduces an enhanced authorization system that provides environment-aware, hierarchical access control. This system builds upon v1's foundation while adding support for multi-environment deployments. Flipt supports the ability to secure its core API routes by setting the `required` field to `true` on the `authorization` configuration object. ```yaml config.yaml theme={null} authorization: required: true ``` When authorization is set to `required`, the API will ensure valid credentials are present on all management API requests. Once authorization has been set to `required: true` all management API routes will require a valid authentication session as well. The UI will require a session-compatible authentication method (e.g. OIDC) to be enabled. ## Backends Flipt uses [Open Policy Agent (OPA)](https://www.openpolicyagent.org/) to enforce authorization policies. OPA is a general-purpose policy engine that can be used to enforce policies across the stack. Flipt supports sourcing policies and external data from various backends. Currently, Flipt supports the following backends: * [Local](#local) ## Local Flipt supports loading policy and external data from the local filesystem. ### Policies For configuring policies, the files must be valid [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) files. You can specify the path to the policy file in the `policy` object in the `authorization` configuration object. ```yaml theme={null} authorization: required: true local: policy: path: "policy.rego" ``` The policy **must** have the following package declaration: ```rego policy.rego theme={null} package flipt.authz.v2 ``` Flipt v2 uses `package flipt.authz.v2` instead of v1's `package flipt.authz.v1`. This is a breaking change that reflects the enhanced authorization model. #### Polling Interval Flipt will poll the policy file for changes at a regular interval. By default, Flipt will poll the policy file every 5 minutes. You can adjust this interval by setting the `poll_interval` field in the `policy` object. ```yaml theme={null} authorization: required: true local: policy: path: "policy.rego" poll_interval: "1m" ``` ### External Data In addition to policies that can be used to enforce authorization rules, Flipt also provides a way to pass external data to the policy evaluation from the local filesystem. These data objects **must be valid JSON objects**. This can be done by setting the `data` object in the `authorization` configuration object. ```yaml theme={null} authorization: required: true local: policy: path: "policy.rego" data: path: "data.json" ``` #### Polling Interval Like policies, Flipt will poll data files for changes at a regular interval. By default, Flipt will poll the data file every 30 seconds. You can adjust this interval by setting the `poll_interval` field in the `data` object. ```yaml theme={null} authorization: required: true local: data: path: "data.json" poll_interval: "1m" ``` ## Key Differences from v1 Flipt v2 authorization introduces several important changes: ### 1. Environment-Aware Authorization Unlike v1, which operates at the namespace level, v2 introduces a hierarchical model with environments: * **Global scope**: Full access to all environments and namespaces * **Environment scope**: Manage namespaces within specific environments * **Namespace scope**: Manage resources (flags, segments, etc.) within specific namespaces ### 2. Optional Policy Queries for UI Filtering v2 policies can optionally implement two special queries to enable UI filtering. When implemented, these queries allow the Flipt UI to show only the environments and namespaces that users have access to: ```rego theme={null} # Returns list of environments the user can access viewable_environments := ["production", "staging"] # or ["*"] for all # Returns list of namespaces in an environment the user can access viewable_namespaces(env) := ["frontend", "backend"] # or ["*"] for all ``` These queries are **optional**. If not implemented, the UI will show all environments and namespaces, but authorization will still be enforced when users attempt to access them. Implementing these queries improves the user experience by filtering out inaccessible resources in the UI. ### 3. Simplified Request Structure v2 uses a simplified request structure with `scope` field: ```json theme={null} { "request": { "scope": "namespace", // or "environment" "environment": "production", "namespace": "frontend", "action": "update" } } ``` ## Example Policies ### Basic RBAC Policy Here's a complete example of a v2 RBAC policy: ```rego policy.rego theme={null} package flipt.authz.v2 import rego.v1 # Default deny default allow := false default viewable_environments := [] # Helper to get user/group identifiers subject_ids contains id if { user := input.authentication.metadata["io.flipt.auth.user"] id := sprintf("user:%s", [user]) } subject_ids contains id if { groups := input.authentication.metadata["io.flipt.auth.groups"] id := sprintf("group:%s", [groups[_]]) } # Check for global admin access has_global_access if { some binding in data.role_bindings binding.scope.type == "global" some subject in binding.subjects some id in subject_ids subject == id } # Environment visibility viewable_environments := ["*"] if { has_global_access } else := envs if { envs := {env | some binding in data.role_bindings some subject in binding.subjects some id in subject_ids subject == id some b in binding.scope.bindings env := b.environment } } # Namespace visibility within an environment viewable_namespaces(env) := ["*"] if { has_global_access } else := ["*"] if { # Check for wildcard namespace access some binding in data.role_bindings some subject in binding.subjects some id in subject_ids subject == id some b in binding.scope.bindings b.environment == env "*" in b.namespaces } else := namespaces if { # Return specific namespaces namespaces := {ns | some binding in data.role_bindings some subject in binding.subjects some id in subject_ids subject == id some b in binding.scope.bindings b.environment == env some ns in b.namespaces ns != "*" } } # Main authorization logic allow if { has_global_access } allow if { scope := input.request.scope env := input.request.environment ns := input.request.namespace action := input.request.action # Check permissions based on scope some binding in data.role_bindings some subject in binding.subjects some id in subject_ids subject == id some b in binding.scope.bindings b.environment == env # Check namespace access ns in b.namespaces # Check action permission action in b.permissions } ``` ### Example Data Structure The accompanying `data.json` file defines role bindings: ```json data.json theme={null} { "role_bindings": [ { "role": "admin", "subjects": ["user:admin@company.com"], "scope": { "type": "global" } }, { "role": "platform_team", "subjects": ["group:platform"], "scope": { "type": "environment", "bindings": [ { "environment": "production", "namespaces": ["*"], "permissions": ["*"] }, { "environment": "staging", "namespaces": ["*"], "permissions": ["read", "update"] } ] } }, { "role": "developer", "subjects": ["user:dev@company.com", "group:developers"], "scope": { "type": "namespace", "bindings": [ { "environment": "development", "namespaces": ["frontend", "backend"], "permissions": ["*"] }, { "environment": "staging", "namespaces": ["frontend"], "permissions": ["read"] } ] } } ] } ``` This structure allows: * **Global admins**: Full access to everything * **Platform team**: Manage all namespaces in production, read/update in staging * **Developers**: Full access to specific namespaces in development, read-only in staging ## Migration from v1 When migrating from v1 to v2: 1. **Update package declaration** from `flipt.authz.v1` to `flipt.authz.v2` 2. **Add environment context** to your role bindings 3. **Optionally implement the UI filtering queries**: `viewable_environments` and `viewable_namespaces(env)` for better UX 4. **Update request handling** to use the new `scope` field instead of `resource`/`subject` 5. **Remove bundle configurations** as they're not supported in v2 (yet) Existing v1 policies will not work without modification. Plan your migration carefully and test thoroughly before deploying to production. # Commit Signing Source: https://docs.flipt.io/v2/configuration/commit-signing GPG commit signing for enhanced security and change verification Flipt v2 supports GPG commit signing to provide cryptographic verification of configuration changes. This feature ensures the authenticity and integrity of your feature flag modifications, creating a verifiable audit trail for compliance and security purposes. This functionality is only available in Flipt v2 Pro. [Learn more](/v2/licensing) about our commercial license or purchase a [monthly](https://getflipt.co/pro/monthly) or [annual](https://getflipt.co/pro/annual) license. ## Why Use Commit Signing? GPG commit signing provides several important benefits: * **Authenticity Verification**: Prove who made configuration changes with cryptographic signatures * **Integrity Assurance**: Detect if commits have been tampered with after creation * **Compliance Support**: Meet regulatory requirements for change management and audit trails * **Trust Enhancement**: Team members can verify the source of feature flag changes * **Non-repudiation**: Prevent disputes about who made specific changes ## How It Works When commit signing is enabled, Flipt automatically signs all commits to your flag configuration repository with a GPG key. These signatures can be verified by Git hosting services like GitHub, GitLab, and others, displaying a "Verified" badge next to signed commits. ## Prerequisites Before enabling commit signing, ensure you have: 1. **Secrets Management Configured**: GPG keys are stored securely using [secrets management](/v2/configuration/secrets) 2. **GPG Key Pair**: A valid GPG private/public key pair for signing 3. **Flipt Pro License**: Commit signing is a Pro feature For step-by-step instructions on setting up commit signing with GitHub and other Git providers, see the [Commit Signing Setup Guide](/v2/guides/operations/environments/commit-signing-setup). ## Configuration Configure commit signing in your Flipt configuration: ```yaml theme={null} storage: default: signature: enabled: true type: "gpg" key_ref: provider: "vault" # Your secrets provider path: "flipt/signing-key" # Path to private key in secrets key: "private_key" # Key name within the secret name: "Flipt Bot" # Signer name email: "flipt@yourcompany.com" # Signer email key_id: "flipt@yourcompany.com" # GPG key identifier ``` # Environments Source: https://docs.flipt.io/v2/configuration/environments This document describes how environments are configured for Flipt v2. Flipt v2 supports the ability to configure multiple environments, allowing the user to switch between them in the UI as well as at evaluation time. Environments are unique to other Flipt resources in that they are not created or managed via the Flipt API or UI. Instead, they are defined in the Flipt server configuration file as they are tightly coupled to the [storage configuration](/v2/configuration/storage). ## Identifiers Each environment has an identifier that is used to reference the environment in the configuration and in the UI/API and is used to determine the environment that will be used when evaluating flags. Identifiers can be any string value but must be unique. Flipt creates a `default` identifier and environment for you automatically if you don't specify one. ```yaml theme={null} environments: local: # id name: "local" default: true staging: # id name: "staging" storage: "staging" ``` ## Storage Each environment has a storage configuration field that is used to determine the storage backend that will be used for the environment. The storage configuration is a reference to the [storage backend](/v2/configuration/storage) that will be used for the environment. ```yaml theme={null} environments: local: storage: "local" ``` In the above configuration, the `local` environment will use the `local` storage backend as defined in the [storage configuration](/v2/configuration/storage). This mapping between environments and storage backends means that multiple environments can share the same storage backend. For example you could have all environments share the same storage which syncs to a single git repository. ### Directories Each environment has an optional `directory` configuration field that is used to determine the directory that will be used to store the environment's resources. This is only required if multiple environments share the same storage backend, as Flipt needs to know where to ultimately store the state without conflicting with other environments. ```yaml theme={null} environments: foo: directory: "foo" storage: "local" bar: directory: "bar" storage: "local" ``` In the above configuration, the `foo` and `bar` environments will use the same `local` storage backend but will store their resources in different directories. ## Default Each environment has a default configuration field that is used to determine if the environment is the default environment. The default environment is the environment that will be used when no other environment is specified. ```yaml theme={null} environments: local: default: true ``` This means that if no environment is specified when performing actions such as flag evaluation, creation, or updates, the `local` environment will be used. This will also be the environment that is selected in the UI by default. ## Branching You can create branches from an existing environment. Branches are a complete copy of the base environment and are completely independent of each other after creation. Branches are created in the UI or API and do not require any additional configuration. Branches Branches can optionally be configured to sync to a remote Git repository. This allows you to create and track merge proposals for your branches if you have an [SCM provider configured](#source-control-management). See the [Branching](/v2/guides/user/environments/branches) guide for more information on how to create and use branches. ## Source Control Management Source Control Management is a paid feature and requires a commercial license. Each environment can be configured to use a source control management provider. This allows you to go beyond just storing your environment's data in a remote Git repository, but also create and track merge proposals for your branches. SCM ```yaml theme={null} environments: local: scm: type: "github" credentials: "github" api_url: "https://{your-github-enterprise-domain}/api/v3" ``` If you are using a self-hosted SCM provider such as GitHub Enterprise, GitLab, Bitbucket Server/Data Center, Azure DevOps Server, or Gitea, you will need to configure the API URL. Environments can be configured to use a single Source Control Management (SCM) provider. Supported providers include: * **GitHub** (including GitHub Enterprise) * **GitLab** (including GitLab Self-Managed) * **Bitbucket** (including Bitbucket Server/Data Center) * **Azure DevOps** (including Azure DevOps Server) * **Gitea** See the [Git SCM Integration](/v2/guides/operations/environments/git-scm) guide for more information on how to configure Flipt v2 to use a SCM provider. ### Credentials Configuring an SCM provider requires a set of credentials to be provided. These credentials are configured via the same mechanism as the [remote storage credential configuration](/v2/configuration/storage#credentials). The identifier for the credentials is a string value that is used to reference the credentials in the configuration. ```yaml theme={null} credentials: github: type: "access-token" access_token: "{your-github-access-token}" ``` ### API URL The API URL is the URL of the SCM provider's API. This is only required if you are using a self-hosted SCM provider such as GitHub Enterprise. ```yaml theme={null} environments: local: scm: type: "github" credentials: "github" api_url: "https://{your-github-enterprise-domain}/api/v3" ``` # Licensing Source: https://docs.flipt.io/v2/configuration/licensing This document describes how to configure licensing for Flipt v2 and how it works. Flipt v2 is licensed under the [Fair Core License](https://fcl.dev/) (FCL). Most of the features in Flipt v2 are available in the free edition, however some features are only available after purchasing a commercial license. See our [licensing](/v2/licensing) documentation for more information on the license and frequently asked questions. ## License Configuration You can configure the license key in the Flipt v2 configuration file or via environment variables. ```yaml theme={null} license: key: "your-license-key" # Optional: Path to offline license file for annual licenses file: "/path/to/license.lic" # Optional: Stable machine fingerprint for container environments machine_id: "your-stable-machine-id" ``` ```bash theme={null} FLIPT_LICENSE_KEY="your-license-key" # Optional: Path to offline license file for annual licenses FLIPT_LICENSE_FILE="/path/to/license.lic" # Optional: Stable machine fingerprint for container environments FLIPT_LICENSE_MACHINE_ID="your-stable-machine-id" ``` You'll need to restart your Flipt v2 instance for the license configuration to take effect. ## Machine ID in Container Environments Flipt identifies the host machine during license validation. In containerd-based Kubernetes clusters and serverless container runtimes, automatic machine ID detection can fail because files such as `/etc/machine-id` or Docker-specific cgroup paths might not be available. If this happens, Flipt starts with Pro features disabled and logs an error similar to: ```text theme={null} license is invalid; additional features are disabled. {"error": "machineid: machineid: no machine-id found"} ``` Set `license.machine_id` or `FLIPT_LICENSE_MACHINE_ID` to a stable value for the deployment. Use the same value across restarts for the same licensed deployment, and use a different value for separate deployments that should count as different machines. ```yaml config.yaml theme={null} license: key: "your-license-key" machine_id: "flipt-production-us-east-1" ``` For Kubernetes, store the value in a Secret and expose it as an environment variable: ```yaml theme={null} apiVersion: v1 kind: Secret metadata: name: flipt-license type: Opaque stringData: machine-id: "flipt-production-us-east-1" --- apiVersion: apps/v1 kind: Deployment metadata: name: flipt spec: # ... template: spec: containers: - name: flipt env: - name: FLIPT_LICENSE_MACHINE_ID valueFrom: secretKeyRef: name: flipt-license key: machine-id ``` `license.machine_id` overrides automatic machine ID detection. It does not change the license key or bypass license validation. ## Acquiring a License You can get a 14 day trial license for the Pro edition by purchasing a [monthly](https://getflipt.co/pro/monthly) license. Note that trials are only available for monthly licenses, not [annual](https://getflipt.co/pro/annual) licenses. The license will be emailed to you after checkout. After the trial period, you will need to provide a payment method to continue using the Pro edition. ### License Types Flipt v2 supports both **monthly** and **annual** commercial licenses: * **Monthly licenses**: Require continuous internet connectivity for validation * **Annual licenses**: Support offline validation using license files for air-gapped environments Choose [monthly](https://getflipt.co/pro/monthly) for standard subscription or [annual](https://getflipt.co/pro/annual) for offline validation support. You can also purchase a license by contacting us at [support@flipt.io](mailto:support@flipt.io). ### Trial Expiration If you do not provide a payment method after the trial period, the license will expire and your Flipt v2 instance(s) will revert to the free edition. This means that you will lose functionality such as [Merge Proposals](/v2/introduction#merge-proposals), [Commit Signing](/v2/configuration/commit-signing), and other paid features. ### License Renewal Paid licenses will be renewed automatically based on your subscription type (monthly or annual). You can cancel the subscription at any time. Cancellations take effect immediately and you will lose access to paid features. You will be prorated for the remaining time in your current billing cycle. See our [licensing](/v2/licensing) documentation for more information on how to cancel your subscription. ## License Validation Flipt v2 will validate the license key on startup. If the license key is invalid, Flipt v2 will start with paid features disabled. You'll see a message in the logs indicating that the license key is invalid. ### Continuous Validation Flipt v2 will continuously validate the license key every 12 hours. For monthly licensing this means that you will **need to have an active network connection from the Flipt v2 instance to the internet** to validate the license key. ### Offline License Validation For **annual license purchases**, Flipt v2 supports offline license validation using cryptographically signed license files. This allows you to run Flipt v2 in air-gapped environments without internet connectivity. To use offline validation: 1. Purchase an annual license 2. Download the provided license file (.lic) 3. Configure the `file` path in your license configuration 4. Restart your Flipt v2 instance Offline license validation is only available for annual license purchases. Monthly licenses require continuous internet connectivity for validation. ### License Expiration If the license key expires, the Flipt v2 instance will continue to run but will be unable to access paid features. # Observability Source: https://docs.flipt.io/v2/configuration/observability This document describes how to configure observability mechanisms including metrics, logging, and tracing for Flipt v2. ## Metrics ### Prometheus Flipt exposes [Prometheus](https://prometheus.io/) metrics by default at the `/metrics` HTTP endpoint. To see which metrics are currently supported, point your browser to `FLIPT_HOST/metrics` (ex: `localhost:8080/metrics`). You should see a bunch of metrics being recorded such as: ```yaml theme={null} flipt_cache_hit_total{cache="memory",type="flag"} 1 flipt_cache_miss_total{cache="memory",type="flag"} 1 --- go_gc_duration_seconds{quantile="0"} 8.641e-06 go_gc_duration_seconds{quantile="0.25"} 2.499e-05 go_gc_duration_seconds{quantile="0.5"} 3.5359e-05 go_gc_duration_seconds{quantile="0.75"} 6.6594e-05 go_gc_duration_seconds{quantile="1"} 0.00026651 go_gc_duration_seconds_sum 0.000402094 go_gc_duration_seconds_count 5 ``` You can disable the Prometheus metrics collection by setting the `metrics.enabled` configuration option to `false`. ### OTLP Flipt supports sending metrics to an [OTLP](https://opentelemetry.io/docs/concepts/data-collection/) collector. OTLP supports additional configuration such as specifying the protocol to use (gRPC or HTTP) as well as providing custom headers to send with the request. Custom headers can be used to provide authentication information to the collector which may be required if you are using a hosted collector such as [NewRelic](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/), [DataDog](https://docs.datadoghq.com/opentelemetry/otlp_ingest_in_the_agent/?tab=host), or [Honeycomb](https://docs.honeycomb.io/getting-data-in/opentelemetry-overview/#instrumenting-with-opentelemetry). OpenTelemetry OTLP metrics are configured via the default OpenTelemetry Environment Variables. See the [OpenTelemetry Environment Variables](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) documentation for more details. For example, to configure the OTLP metrics endpoint, you can set the `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4317 ``` To configure the OTLP headers, you can set the `OTEL_EXPORTER_OTLP_METRICS_HEADERS` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_METRICS_HEADERS="Authorization=Bearer " ``` ## Logging Flipt writes logs to STDOUT in two formats: * [JSON](#json) * [Console](#console) The format can be configured via the `log.encoding` configuration option. ```yaml theme={null} log: encoding: json ``` For production deployments, we recommend using the JSON format as it's easier to parse and ingest into log aggregation systems such as Elasticsearch, Splunk, Loki, or Datadog. ### JSON ```json theme={null} { "L": "INFO", "T": "2024-01-20T21:59:49-05:00", "M": "finished unary call with code OK", "server": "grpc", "grpc.start_time": "2024-01-20T21:59:49-05:00", "system": "grpc", "span.kind": "server", "grpc.service": "flipt.evaluation.EvaluationService", "grpc.method": "Boolean", "peer.address": "127.0.0.1:52635", "grpc.code": "OK", "grpc.time_ms": 0.146 } ``` #### Log Key Descriptions * `L`: Level (log level). Possible values include: debug, info, warn, error, fatal, and panic. * `T`: Timestamp. The timestamp is in ISO 8601 format, widely used for representing date and time. It includes the date, time, and time zone information. For example, "2024-01-20T21:59:49-05:00" represents the date and time in the Eastern Time Zone (UTC-5). * `M`: Message. The message describes the log event. It can include information about the operation, errors encountered, or other relevant details. ### Console ```text theme={null} 2024-01-20T22:04:18-05:00 INFO finished unary call with code OK {"server": "grpc", "grpc.start_time": "2024-01-20T22:04:18-05:00", "system": "grpc", "span.kind": "server", "grpc.service": "flipt.evaluation.EvaluationService", "grpc.method": "Boolean", "peer.address": "127.0.0.1:53714", "grpc.code": "OK", "grpc.time_ms": 0.373} ``` More information about the available configuration options can be found in the [Logging configuration](/v2/configuration/overview#logging) section. ### OTLP Flipt v2 supports the new [OpenTelemetry OTLP logging specification](https://opentelemetry.io/docs/specs/otel/logs/). To enable OTLP logging, set the `OTLP_LOGS_EXPORTER` environment variable ```console theme={null} export OTLP_LOGS_EXPORTER=otlp ``` OpenTelemetry logging is in addition to the existing logging configuration. It does not replace the ability to log to a file or stdout/stderr. OpenTelemetry OTLP logging is configured via the default OpenTelemetry Environment Variables. See the [OpenTelemetry Environment Variables](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) documentation for more details. For example, to configure the OTLP logging endpoint, you can set the `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4317 ``` ## Tracing Flipt supports distributed tracing via the [OpenTelemetry](https://opentelemetry.io/) project using the [OTLP](https://opentelemetry.io/docs/reference/specification/protocol/) protocol. ### OTLP Datadog OTLP OTLP supports additional configuration such as specifying the protocol to use (gRPC or HTTP) as well as providing custom headers to send with the request. Custom headers can be used to provide authentication information to the collector which may be required if you are using a hosted collector such as [NewRelic](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/), [Datadog](https://docs.datadoghq.com/opentelemetry/otlp_ingest_in_the_agent/?tab=host), or [Honeycomb](https://docs.honeycomb.io/getting-data-in/opentelemetry-overview/#instrumenting-with-opentelemetry). OpenTelemetry OTLP tracing is configured via the default OpenTelemetry Environment Variables. See the [OpenTelemetry Environment Variables](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) documentation for more details. For example, to configure the OTLP tracing endpoint, you can set the `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317 ``` To configure the OTLP headers, you can set the `OTEL_EXPORTER_OTLP_TRACES_HEADERS` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_TRACES_HEADERS="Authorization=Bearer " ``` #### Environment Variables Flipt supports all OTLP environment variables that are part of the [OTLP spec](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/). Here are a few of the most commonly used environment variables supported by Flipt: * `OTEL_SERVICE_NAME` - Sets the value of the `service.name` resource attribute (default: `flipt`) * `OTEL_RESOURCE_ATTRIBUTES` - Key-value pairs to be used as [resource attributes](https://opentelemetry.io/docs/specs/semconv/resource/#semantic-attributes-with-dedicated-environment-variable). * `OTEL_EXPORTER_OTLP_ENDPOINT` - The OTLP endpoint to any signal data (metrics, traces, logs) to * `OTEL_EXPORTER_OTLP_HEADERS` - Key-value pairs to be used as [OTLP headers](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#otel_exporter_otlp_headers) for any signal data (metrics, traces, logs). * `OTEL_EXPORTER_OTLP_PROTOCOL` - The protocol to use for the OTLP endpoint (grpc, http/protobuf, http/json) # Overview Source: https://docs.flipt.io/v2/configuration/overview This document describes how to configure the Flipt v2 server. Configuration precedence is as follows: 1. [Environment Variables](#environment-variables) 2. [Configuration File](#configuration-file) ## Configuration File The default way that Flipt is configured is with the use of a configuration file [default.yml](https://github.com/flipt-io/flipt/blob/v2/config/default.yml). This file is read when Flipt starts up and configures several important properties for the server. You can generate a default configuration file by running `flipt config init`. The server will check in a few different locations for server configuration (in order): 1. `--config` flag as an override 2. `{{ USER_CONFIG_DIR }}/flipt/config.yml` (the `USER_CONFIG_DIR` value is based on your architecture and specified in the [Go documentation](https://pkg.go.dev/os#UserConfigDir)) 3. `/etc/flipt/config/default.yml` We provide both a [JSON schema](https://raw.githubusercontent.com/flipt-io/flipt/v2/config/flipt.schema.json) and a [Cue schema](https://raw.githubusercontent.com/flipt-io/flipt/v2/config/flipt.schema.cue) that you can use to validate your configuration file and its properties. You can edit any of these properties to your liking, and on restart, Flipt will pick up the new changes. ### Environment Substitution and Secret References The configuration file supports both environment variable substitution and secret references. #### Environment Variables You can use environment variables in your configuration file with the `${env:VARIABLE_NAME}` syntax. For example: ```yaml theme={null} authentication: required: ${env:FLIPT_CUSTOM_AUTH_REQUIRED} ``` This will replace `${env:FLIPT_CUSTOM_AUTH_REQUIRED}` with the value of the `FLIPT_CUSTOM_AUTH_REQUIRED` environment variable. The v1 syntax `${VARIABLE_NAME}` is not supported in v2. You must use the explicit `${env:VARIABLE_NAME}` format. #### Secret References You can also reference secrets from configured secret providers using the `${secret:provider:path:key}` syntax: ```yaml theme={null} server: cert_file: ${secret:file:tls-cert} # Reference to file provider secret cert_key: ${secret:vault:tls/certs:private-key} # Reference to Vault secret ``` #### Combined Usage You can combine environment variables and secret references in the same configuration: ```yaml theme={null} authentication: methods: oidc: providers: google: client_id: ${env:GOOGLE_CLIENT_ID} # Environment variable client_secret: ${secret:vault:auth/oidc:client_secret} # Secret reference ``` This can be used to provide sensitive information to Flipt without storing it in the configuration file. For example, you can use environment variables to store the database URL, API keys, or other sensitive information without having to conform to the pre-defined Flipt [environment variable format](#environment-variables). ### Remote Configuration Flipt supports fetching configuration from a remote source. This is useful for managing configuration across multiple instances of Flipt. The remote configuration source can be a URL to a configuration file stored in one of the following object storage services: * S3 (e.g.: `s3://bucket-name/path/to/config.yml`) * Azure Blob Storage (e.g.: `azblob://container-name/path/to/config.yml`) * Google Cloud Storage (e.g.: `googlecloud://bucket-name/path/to/config.yml`) To load Flipt configuration from a remote source, replace the `config.yml` file with the URL to the remote configuration file in the `--config` flag when starting the server. ```console theme={null} flipt server --config s3://bucket-name/path/to/config.yml ``` For authenticating with the object storage service, you can use the following environment variables depending on the service: * `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` * `AZURE_STORAGE_ACCOUNT` and `AZURE_STORAGE_KEY` or `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_CLIENT_SECRET` * `GOOGLE_APPLICATION_CREDENTIALS` ## Environment Variables All options in the configuration file can be overridden using environment variables using the syntax: ```yaml theme={null} FLIPT__ ``` Environment variables **MUST** have `FLIPT_` prefix and be in `UPPER_SNAKE_CASE` format. Using environment variables to override defaults is especially helpful when running with Docker. Keys should be uppercase and `.` should be replaced by `_`. For example, given these configuration settings: ```yaml theme={null} server: grpc_port: 9000 ``` You can override them using: ```console theme={null} export FLIPT_SERVER_GRPC_PORT=9001 ``` ### Multiple Values Some configuration options can have a list of values. For example, the `cors.allowed_origins` option can have multiple origins. In this case, you can use a space separated list of values for the environment variable override: ```console theme={null} export FLIPT_CORS_ALLOWED_ORIGINS="http://localhost:3000 http://localhost:3001" ``` ## Configuration Parameters The following sections group related configuration options for easier navigation: 1. **Core Server Setup** - Essential configuration to get Flipt running 2. **Security & Access Control** - Authentication, authorization, and security settings 3. **Observability & Operations** - Monitoring, logging, and analytics 4. **Additional Settings** - Optional features and enhancements ## Core Server Setup ### Server Server configuration controls how Flipt listens for and serves HTTP, HTTPS, and gRPC connections. | Property | Description | Default | Since | | ---------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------- | ------ | | server.protocol | http or https | http | v2.0.0 | | server.host | The host address on which to serve the Flipt application | 0.0.0.0 | v2.0.0 | | server.http\_port | The HTTP port on which to serve the Flipt REST API and UI | 8080 | v2.0.0 | | server.https\_port | The HTTPS port on which to serve the Flipt REST API and UI | 443 | v2.0.0 | | server.grpc\_port | The port on which to serve the Flipt GRPC server | 9000 | v2.0.0 | | server.grpc\_conn\_max\_idle\_time | Maximum amount of time a GRPC connection can be idle | unlimited | v2.0.0 | | server.grpc\_conn\_max\_age | Maximum amount of time a GRPC connection can live | unlimited | v2.0.0 | | server.grpc\_conn\_max\_age\_grace | Maximum amount of time a GRPC connection can live for outstanding RPCs after exceeding `grpc_conn_max_age` | unlimited | v2.0.0 | | server.cert\_file | Path to the certificate file (if protocol is set to https) | | v2.0.0 | | server.cert\_key | Path to the certificate key file (if protocol is set to https) | | v2.0.0 | ### Storage Storage configuration defines where and how Flipt persists feature flag data, including local and remote Git repositories. | Property | Description | Default | Since | | --------------------------------- | ------------------------------------------------------------------------------------- | ------------------- | ------ | | storage.\[id].name | The canonical name of the storage instance | default | v2.0.0 | | storage.\[id].backend.type | The type of backend to use (options: memory, local) | memory | v2.0.0 | | storage.\[id].backend.path | The path to the local storage directory for git backend | temporary directory | v2.0.0 | | storage.\[id].remote | The remote URL to sync storage to/from | | v2.0.0 | | storage.\[id].branch | The branch to use for git backend | main | v2.0.0 | | storage.\[id].poll\_interval | The interval to poll the git repository and ref for changes | 30s | v2.0.0 | | storage.\[id].ca\_cert\_bytes | The CA certificate bytes for the remote URL | | v2.0.0 | | storage.\[id].ca\_cert\_path | The CA certificate path for the remote URL | | v2.0.0 | | storage.\[id].insecure\_skip\_tls | Skip verifying the server's certificate chain (avoid in production) | false | v2.0.0 | | storage.\[id].fetch\_policy | Policy for handling connection issues when fetching from remote Git (strict, lenient) | strict | v2.3.0 | | storage.\[id].credentials | The id of the credentials to use for the remote URL | | v2.0.0 | #### Commit Signing | Property | Description | Default | Since | | ----------------------------------------- | ----------------------------------------------- | ------- | ------ | | storage.\[id].signature.enabled | Enable or disable commit signing | false | v2.0.0 | | storage.\[id].signature.type | Signature type (currently only "gpg" supported) | "gpg" | v2.0.0 | | storage.\[id].signature.name | Name to use in Git commits | | v2.0.0 | | storage.\[id].signature.email | Email to use in Git commits | | v2.0.0 | | storage.\[id].signature.key\_id | GPG key ID for identification | | v2.0.0 | | storage.\[id].signature.key\_ref.provider | Secrets provider name for GPG private key | | v2.0.0 | | storage.\[id].signature.key\_ref.path | Path to secret in provider | | v2.0.0 | | storage.\[id].signature.key\_ref.key | Key name within the secret | | v2.0.0 | ### Environments Environments configuration allows you to create isolated feature flag namespaces with separate storage backends. | Property | Description | Default | Since | | ---------------------------- | --------------------------------------------------------------- | ------- | ------ | | environments.\[id].name | The canonical name of the environment | default | v2.0.0 | | environments.\[id].default | Whether the environment is the default environment | false | v2.0.0 | | environments.\[id].storage | The id of the storage to use for the environment | | v2.0.0 | | environments.\[id].directory | The directory to use for the environment with the given storage | | v2.0.0 | #### Source Control Management | Property | Description | Default | Since | | ---------------------------------- | ---------------------------------------------------------------------------------- | ------- | ------ | | environments.\[id].scm.type | The type of SCM provider to use (options: github, gitlab, bitbucket, azure, gitea) | | v2.0.0 | | environments.\[id].scm.api\_url | The API URL of the SCM provider to use (optional) | | v2.0.0 | | environments.\[id].scm.credentials | The id of the credentials to use for the SCM provider | | v2.0.0 | ### User Interface User interface configuration customizes the appearance and behavior of the Flipt web UI. | Property | Description | Default | Since | | ----------------- | ----------------------------------- | ------- | ------ | | ui.default\_theme | Sets the default UI theme for users | system | v2.0.0 | | ui.topbar.color | Sets the color of the topbar | | v2.0.0 | ### CORS Cross-Origin Resource Sharing (CORS) configuration allows web applications from different domains to access Flipt's API. | Property | Description | Default | Since | | --------------------- | -------------------------------------------------- | ------------------ | ------ | | cors.enabled | Enable CORS support | false | v2.0.0 | | cors.allowed\_origins | Sets Access-Control-Allow-Origin header on server | "\*" (all domains) | v2.0.0 | | cors.allowed\_headers | Sets Access-Control-Allow-Headers header on server | "\*" (all headers) | v2.0.0 | #### CORS Troubleshooting If you're experiencing CORS issues with browser-based applications (such as Vue, React, or Angular), simply setting `cors.enabled: true` may not be sufficient. Browsers can be strict about CORS policies, and you may need to explicitly configure the allowed origins and other options. **Common Issue:** Browser applications receive CORS errors even when `cors.enabled: true` is set. **Solution:** Configure explicit CORS settings instead of relying on the wildcard defaults: ```yaml theme={null} cors: enabled: true allowed_origins: - http://localhost:3000 # React development server - http://localhost:5173 # Vite development server - https://yourapp.com # Production domain allowed_headers: - Content-Type - Authorization - X-Requested-With - x-flipt-environment ``` When using client-side SDKs like the [Flipt JavaScript SDK](https://github.com/flipt-io/flipt-client-js), make sure to include your application's origin in the `allowed_origins` list and include any custom headers your application sends. ## Security & Access Control ### Authentication Authentication configuration controls how users and systems authenticate with Flipt, supporting multiple methods including OIDC, GitHub, JWT, and static tokens. Authentication is configured slightly differently in v2 compared to v1. See the [Authentication](/v2/configuration/authentication) documentation for more details. | Property | Description | Default | Since | | --------------------------------- | ------------------------------------------------------- | ------- | ------ | | authentication.required | Enable or disable authentication validation on requests | false | v2.0.0 | | authentication.exclude.evaluation | Exclude authentication for /evaluation/v1 API prefix | false | v2.0.0 | | authentication.exclude.ofrep | Exclude authentication for /ofrep API prefix | false | v2.0.0 | #### Authentication Session | Property | Description | Default | Since | | -------------------------------------- | ------------------------------------------------------------- | ------- | ------ | | authentication.session.domain | Public domain on which Flipt instance is hosted | | v2.0.0 | | authentication.session.secure | Configures the `Secure` property on created session cookies | false | v2.0.0 | | authentication.session.token\_lifetime | Configures the lifetime of the session token (login duration) | 24h | v2.0.0 | | authentication.session.state\_lifetime | Configures the lifetime of state parameters during OAuth flow | 10m | v2.0.0 | | authentication.session.csrf.key | Secret credential used to sign CSRF prevention tokens | | v2.0.0 | | authentication.session.csrf.secure | Enable secure CSRF token enforcement | false | v2.0.0 | #### Authentication Session Storage | Property | Description | Default | Since | | ---------------------------------------------------- | -------------------------------------------------------------- | ------- | ------ | | authentication.session.storage.type | The type of storage to use for session storage (memory, redis) | memory | v2.0.0 | | authentication.session.storage.cleanup.grace\_period | The grace period for the cleanup of expired sessions | 30m | v2.0.0 | #### Authentication Session Storage: Redis | Property | Description | Default | Since | | ---------------------------------------------------------- | ------------------------------------------------------------------- | --------- | ------ | | authentication.session.storage.redis.mode | **Required** Redis mode: `single` or `cluster` | single | v2.0.0 | | authentication.session.storage.redis.host | Host to access the Redis database | localhost | v2.0.0 | | authentication.session.storage.redis.port | Port to access the Redis database | 6379 | v2.0.0 | | authentication.session.storage.redis.db | Redis database to use | 0 | v2.0.0 | | authentication.session.storage.redis.username | Username to access the Redis database | | v2.0.0 | | authentication.session.storage.redis.password | Password to access the Redis database | | v2.0.0 | | authentication.session.storage.redis.prefix | Prefix added to all session keys | | v2.0.0 | | authentication.session.storage.redis.require\_tls | Require TLS to access the Redis database | false | v2.0.0 | | authentication.session.storage.redis.pool\_size | Max number of socket connections per CPU | 10 | v2.0.0 | | authentication.session.storage.redis.min\_idle\_conn | Minimum number of idle connections in the pool | 0 | v2.0.0 | | authentication.session.storage.redis.conn\_max\_idle\_time | Maximum amount of time a connection can be idle | 30m | v2.0.0 | | authentication.session.storage.redis.net\_timeout | Network timeout for Redis connections | 0 | v2.0.0 | | authentication.session.storage.redis.ca\_cert\_path | Path to custom certificate authority (CA) certificate | | v2.0.0 | | authentication.session.storage.redis.ca\_cert\_bytes | (Alternative) Raw certificate authority (CA) certificate bytes | | v2.0.0 | | authentication.session.storage.redis.insecure\_skip\_tls | Skip verifying the server's certificate chain (avoid in production) | false | v2.0.0 | #### Authentication Methods: Static Token | Property | Description | Default | Since | | ------------------------------------------------------- | ----------------------------------------------- | ------- | ------ | | authentication.methods.token.enabled | Enable static token authentication | false | v2.0.0 | | authentication.methods.token.tokens | List of static tokens to use for authentication | | v2.0.0 | | authentication.methods.token.tokens.\[token].credential | The credential to use for the token | | v2.0.0 | | authentication.methods.token.tokens.\[token].metadata | The metadata to use for the token | | v2.0.0 | #### Authentication Methods: OIDC | Property | Description | Default | Since | | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ---------- | ------- | | authentication.methods.oidc.enabled | Enable OIDC authentication | false | v2.0.0 | | authentication.methods.oidc.providers.\[provider].issuer\_url | Provider specific OIDC issuer URL (see your providers docs) | | v2.0.0 | | authentication.methods.oidc.providers.\[provider].client\_id | Provider specific OIDC client ID (see your providers docs) | | v2.0.0 | | authentication.methods.oidc.providers.\[provider].client\_secret | Provider specific OIDC client secret (see your providers docs) | | v2.0.0 | | authentication.methods.oidc.providers.\[provider].redirect\_address | Public URL on which this Flipt instance is reachable | | v2.0.0 | | authentication.methods.oidc.providers.\[provider].scopes | Scopes to request from the provider | | v2.0.0 | | authentication.methods.oidc.providers.\[provider].use\_pkce | Enable PKCE with a cryptographic nonce for OIDC authentication | false | v2.0.0 | | authentication.methods.oidc.providers.\[provider].algorithms | List of accepted ID token signing algorithms | \["RS256"] | v2.6.0 | | authentication.methods.oidc.providers.\[provider].fetch\_extra\_user\_info | Fetch additional claims from the provider's UserInfo endpoint | false | v2.6.0 | | authentication.methods.oidc.providers.\[provider].authorize\_parameters | Extra query parameters to append to the provider authorize URL | v2.11.0 | | | authentication.methods.oidc.providers.\[provider].use\_end\_session\_endpoint | Redirect to the provider's end-session endpoint on logout | false | v2.11.0 | | authentication.methods.oidc.providers.\[provider].allow\_front\_channel\_logout | Enable OIDC front-channel logout support | false | v2.12.0 | | authentication.methods.oidc.email\_matches | List of email addresses (regex) of users allowed to authenticate | | v2.0.0 | #### Authentication Methods: GitHub | Property | Description | Default | Since | | ---------------------------------------------------- | ------------------------------------------------------------------ | ------------------------ | ------ | | authentication.methods.github.enabled | Enable GitHub authentication | false | v2.0.0 | | authentication.methods.github.client\_id | GitHub client ID | | v2.0.0 | | authentication.methods.github.client\_secret | GitHub client secret | | v2.0.0 | | authentication.methods.github.redirect\_address | Public URL on which this Flipt instance is reachable | | v2.0.0 | | authentication.methods.github.scopes | Scopes to request from GitHub | | v2.0.0 | | authentication.methods.github.allowed\_organizations | List of GitHub organizations allowed to authenticate | | v2.0.0 | | authentication.methods.github.allowed\_teams | Map of GitHub organizations to teams that users must be members of | | v2.0.0 | | authentication.methods.github.server\_url | GitHub Server URL (to support GHES) | `https://github.com` | v2.0.0 | | authentication.methods.github.api\_url | GitHub API URL (to support GHES) | `https://api.github.com` | v2.0.0 | | authentication.methods.github.use\_pkce | Enable PKCE for GitHub OAuth flow | false | v2.9.0 | #### Authentication Methods: Kubernetes | Property | Description | Default | Since | | --------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------- | ------ | | authentication.methods.kubernetes.enabled | Enable Kubernetes service account token authentication | false | v2.0.0 | | authentication.methods.kubernetes.discovery\_url | Kubernetes API server URL for OIDC configuration discovery | `https://kubernetes.default.svc.cluster.local` | v2.0.0 | | authentication.methods.kubernetes.ca\_path | Kubernetes API CA certification path | /var/run/secrets/kubernetes.io/serviceaccount/ca.crt | v2.0.0 | | authentication.methods.kubernetes.service\_account\_token\_path | Path to Flipt service account token | /var/run/secrets/kubernetes.io/serviceaccount/token | v2.0.0 | #### Authentication Methods: JWT | Property | Description | Default | Since | | ----------------------------------------------------- | --------------------------------------------------- | ------- | ------ | | authentication.methods.jwt.enabled | Enable JWT authentication | false | v2.0.0 | | authentication.methods.jwt.jwks\_url | URL to retrieve JWKS for JWT validation | | v2.0.0 | | authentication.methods.jwt.public\_key\_file | Path to public key file for JWT validation | | v2.0.0 | | authentication.methods.jwt.validate\_claims.issuer | The issuer claim to validate on JWT tokens | | v2.0.0 | | authentication.methods.jwt.validate\_claims.audiences | The audience claim (list) to validate on JWT tokens | | v2.0.0 | | authentication.methods.jwt.validate\_claims.subject | The subject claim to validate on JWT tokens | | v2.0.0 | ### Authorization Authorization configuration enforces fine-grained access control policies to restrict operations based on user roles and permissions. | Property | Description | Default | Since | | ---------------------- | ------------------------------------------------------ | ------- | ------ | | authorization.required | Enable or disable authorization validation on requests | false | v2.0.0 | #### Authorization Backend: Local | Property | Description | Default | Since | | ----------------------------------------- | -------------------------------------------- | ------- | ------ | | authorization.local.policy.path | Path to the local policy file | | v2.0.0 | | authorization.local.policy.poll\_interval | Interval to poll the policy file for changes | 5m | v2.0.0 | | authorization.local.data.path | Path to the local data file | | v2.0.0 | | authorization.local.data.poll\_interval | Interval to poll the data file for changes | 30s | v2.0.0 | ### Credentials Credentials configuration manages authentication details for accessing remote Git repositories and SCM providers. | Property | Description | Default | Since | | ---------------------- | -------------------------------------------------------------------------------- | ------- | ------ | | credentials.\[id].type | The type of credentials to use (options: basic, ssh, access\_token, github\_app) | basic | v2.0.0 | #### Credentials: Basic | Property | Description | Default | Since | | -------------------------------- | -------------------------------------------- | ------- | ------ | | credentials.\[id].basic.username | The username to use for basic authentication | | v2.0.0 | | credentials.\[id].basic.password | The password to use for basic authentication | | v2.0.0 | #### Credentials: SSH | Property | Description | Default | Since | | ------------------------------------------------- | -------------------------------------------------------- | ------- | ------ | | credentials.\[id].ssh.user | The username to use for SSH authentication | git | v2.0.0 | | credentials.\[id].ssh.password | Password used to generate the SSH key pair | | v2.0.0 | | credentials.\[id].ssh.private\_key\_path | Path to private key on the filesystem | | v2.0.0 | | credentials.\[id].ssh.private\_key\_bytes | (Alternative) Raw private key bytes | | v2.0.0 | | credentials.\[id].ssh.insecure\_ignore\_host\_key | Skip verifying the known hosts key (avoid in production) | false | v2.0.0 | #### Credentials: Access Token | Property | Description | Default | Since | | ------------------------------- | ----------------------------------- | ------- | ------ | | credentials.\[id].access\_token | The token to use for authentication | | v2.0.0 | #### Credentials: GitHub App | Property | Description | Default | Since | | ------------------------------------------------- | ---------------------------------------------------- | ------- | ------ | | credentials.\[id].github\_app.client\_id | The GitHub App client ID | | v2.6.0 | | credentials.\[id].github\_app.installation\_id | The GitHub App installation ID | | v2.6.0 | | credentials.\[id].github\_app.private\_key\_path | Path to the GitHub App private key on the filesystem | | v2.6.0 | | credentials.\[id].github\_app.private\_key\_bytes | (Alternative) Raw GitHub App private key bytes | | v2.6.0 | | credentials.\[id].github\_app.api\_url | Custom GitHub API URL (for GitHub Enterprise Server) | | v2.6.0 | ### Secrets Secrets configuration enables integration with external secret management systems for secure credential storage. See the [Secrets](/v2/configuration/secrets) documentation for detailed provider setup and usage. | Property | Description | Default | Since | | ------------------------------- | -------------------------------------- | ------- | ------ | | secrets.providers.\[id].enabled | Enable or disable the secrets provider | false | v2.0.0 | #### Secrets Provider: File | Property | Description | Default | Since | | --------------------------------- | -------------------------------------------- | ------------------ | ------ | | secrets.providers.file.base\_path | Base directory path for storing secret files | /etc/flipt/secrets | v2.0.0 | #### Secrets Provider: Vault | Property | Description | Default | Since | | ------------------------------------ | ------------------------------------------------ | ------- | ------ | | secrets.providers.vault.address | URL address of the Vault server | | v2.0.0 | | secrets.providers.vault.auth\_method | Authentication method | token | v2.0.0 | | secrets.providers.vault.token | Vault token for authentication | | v2.0.0 | | secrets.providers.vault.role | Role name for authentication | | v2.0.0 | | secrets.providers.vault.mount | Vault mount path for secrets | secret | v2.0.0 | | secrets.providers.vault.namespace | Vault namespace for enterprise Vault deployments | | v2.0.0 | #### Secrets Provider: AWS Secrets Manager | Property | Description | Default | Since | | ----------------------------------- | --------------------------------------------------------------- | ------- | ------ | | secrets.providers.aws.endpoint\_url | Custom endpoint URL (for LocalStack or AWS-compatible services) | | v2.8.0 | #### Secrets Provider: GCP Secret Manager | Property | Description | Default | Since | | --------------------------------- | --------------------------------------------- | ------- | ------ | | secrets.providers.gcp.project | GCP project ID | | v2.8.0 | | secrets.providers.gcp.location | GCP region for regional secrets | | v2.8.0 | | secrets.providers.gcp.credentials | Path to service account credentials JSON file | | v2.8.0 | #### Secrets Provider: Azure Key Vault | Property | Description | Default | Since | | ---------------------------------- | --------------------------------------------------------------- | ------- | ------ | | secrets.providers.azure.vault\_url | Azure Key Vault URL (e.g., `https://my-vault.vault.azure.net/`) | | v2.8.0 | ## Observability & Operations ### Logging Logging configuration controls the format, destination, and verbosity of Flipt's application logs. | Property | Description | Default | Since | | ---------------- | -------------------------------------------------------------------------------- | ------- | ------ | | log.level | Level at which messages are logged (debug, info, warn, error, fatal, panic) | info | v2.0.0 | | log.grpc\_level | Level at which gRPC messages are logged (debug, info, warn, error, fatal, panic) | error | v2.0.0 | | log.file | File to log to instead of STDOUT | | v2.0.0 | | log.encoding | Encoding to use for logging (json, console) | console | v2.0.0 | | log.keys.time | Structured logging key used when outputting log timestamp | T | v2.0.0 | | log.keys.level | Structured logging key used when outputting log level | L | v2.0.0 | | log.keys.message | Structured logging key used when outputting log message | M | v2.0.0 | #### Logging: OTLP Flipt v2 supports the new [OpenTelemetry OTLP logging specification](https://opentelemetry.io/docs/specs/otel/logs/). To enable OTLP logging, set the `OTLP_LOGS_EXPORTER` environment variable ```console theme={null} export OTLP_LOGS_EXPORTER=otlp ``` OpenTelemetry logging is in addition to the existing logging configuration. It does not replace the ability to log to a file or stdout/stderr. OpenTelemetry OTLP logging is configured via the default OpenTelemetry Environment Variables. See the [OpenTelemetry Environment Variables](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) documentation for more details. For example, to configure the OTLP logging endpoint, you can set the `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4317 ``` ### Metrics Metrics configuration enables operational monitoring through Prometheus or OpenTelemetry exporters. | Property | Description | Default | Since | | ---------------- | -------------------------------------- | ---------- | ------ | | metrics.enabled | Enable metrics support | true | v2.0.0 | | metrics.exporter | The exporter to use (prometheus, otlp) | prometheus | v2.0.0 | #### Metrics: OTLP OpenTelemetry OTLP metrics are configured via the default OpenTelemetry Environment Variables. See the [OpenTelemetry Environment Variables](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) documentation for more details. For example, to configure the OTLP metrics endpoint, you can set the `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4317 ``` To configure the OTLP headers, you can set the `OTEL_EXPORTER_OTLP_METRICS_HEADERS` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_METRICS_HEADERS="Authorization=Bearer " ``` ### Tracing Tracing configuration enables distributed tracing for observability and performance analysis using OpenTelemetry. | Property | Description | Default | Since | | --------------- | ---------------------- | ------- | ------ | | tracing.enabled | Enable tracing support | false | v2.0.0 | The only supported tracing backend is OTLP. #### Tracing: OTLP OpenTelemetry OTLP tracing is configured via the default OpenTelemetry Environment Variables. See the [OpenTelemetry Environment Variables](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/) documentation for more details. For example, to configure the OTLP tracing endpoint, you can set the `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317 ``` To configure the OTLP headers, you can set the `OTEL_EXPORTER_OTLP_TRACES_HEADERS` environment variable. ```console theme={null} export OTEL_EXPORTER_OTLP_TRACES_HEADERS="Authorization=Bearer " ``` ### Evaluation Evaluation configuration controls feature flag evaluation behavior and related API response data. | Property | Description | Default | Since | | ---------------------------------- | ------------------------------------------------------- | ------- | ------ | | evaluation.include\_flag\_metadata | Include flag metadata in ListFlags API response objects | false | v2.3.0 | Flag metadata can contain operator-defined data. Keep `evaluation.include_flag_metadata` disabled unless clients that call ListFlags should receive that metadata. ### Analytics Analytics configuration enables collection and export of feature flag evaluation metrics to external analytics systems. | Property | Description | Default | Since | | ------------------------------ | ----------------------------------------------- | ------- | ------ | | analytics.buffer.flush\_period | Duration to wait before sending events to sinks | 10s | v2.0.0 | #### Analytics: Clickhouse | Property | Description | Default | Since | | ------------------------------------ | ----------------------------------- | ------- | ------ | | analytics.storage.clickhouse.enabled | Enable Clickhouse support | false | v2.0.0 | | analytics.storage.clickhouse.url | URL to connect to clickhouse server | | v2.0.0 | #### Analytics: Prometheus | Property | Description | Default | Since | | ---------------------------------------------- | ------------------------------------------------------------------------ | ------- | ------ | | analytics.storage.prometheus.enabled | Enable Prometheus support | false | v2.0.0 | | analytics.storage.prometheus.url | URL to connect to prometheus server | | v2.0.0 | | analytics.storage.prometheus.headers | Additional headers to send with Prometheus requests (map\[string]string) | | v2.0.0 | | analytics.storage.prometheus.sigv4.enabled | Enable Prometheus SigV4 suppport | false | v2.7.0 | | analytics.storage.prometheus.sigv4.region | AWS region for SigV4 signing (for Amazon Managed Service for Prometheus) | | v2.7.0 | | analytics.storage.prometheus.sigv4.access\_key | AWS access key ID | | v2.7.0 | | analytics.storage.prometheus.sigv4.secret\_key | AWS secret access key | | v2.7.0 | | analytics.storage.prometheus.sigv4.profile | AWS credentials profile name | | v2.7.0 | | analytics.storage.prometheus.sigv4.role\_arn | ARN of an IAM role to assume for authentication | | v2.7.0 | ## Additional Settings ### Templates Templates configuration customizes the generated commit messages and merge proposal content that Flipt creates for Git-backed workflows. Template values use Go [`text/template`](https://pkg.go.dev/text/template) syntax. | Property | Description | Default | Since | | ------------------------- | ---------------------------------------------- | ------- | ------ | | templates.commit\_message | Commit message template for UI-created changes | | v2.5.0 | | templates.proposal\_title | Merge proposal title template | | v2.5.0 | | templates.proposal\_body | Merge proposal body template | | v2.5.0 | ```yaml config.yaml theme={null} templates: commit_message: "{{ (index .Changes 0) }} [skip ci]" proposal_title: "Flipt: Update {{.Base.Ref}} from {{.Branch.Ref}}" proposal_body: | This proposal updates Flipt resources. Source branch: {{.Branch.Ref}} Target branch: {{.Base.Ref}} ``` Server-wide templates override Flipt's built-in defaults. Repository-level templates in `flipt.yaml` or `flipt.yml` override server-wide templates for that repository. Flipt validates configured templates when it loads the configuration. Invalid server-wide templates prevent the configuration from loading. ### License License configuration enables Pro features by providing a valid license key. | Property | Description | Default | Since | | ------------------- | ------------------------------------------------------------------ | ------- | ------ | | license.key | The license key to use for the license (required for Pro features) | | v2.0.0 | | license.machine\_id | Stable machine fingerprint override for container environments | | v2.8.0 | A license is only required for Pro features. See the [Licensing](/v2/licensing) documentation for more information. ### Meta & Diagnostics Meta configuration controls Flipt's internal behavior including update checks, telemetry, and diagnostic endpoints. | Property | Description | Default | Since | | ----------------------------- | ------------------------------------------------------------------------------ | -------------------- | ------ | | meta.check\_for\_updates | Enable check for newer versions of Flipt on startup | true | v2.0.0 | | meta.telemetry\_enabled | Enable anonymous telemetry data (see [Telemetry](/v2/configuration/telemetry)) | true | v2.0.0 | | meta.state\_directory | Directory on the host to store local state | \$HOME/.config/flipt | v2.0.0 | | diagnostics.profiling.enabled | Enable profiling endpoints for pprof | false | v2.0.0 | Changed in **v2.10.0**: diagnostics.profiling.enabled now defaults to false. If you rely on pprof endpoints, explicitly set it to true in your configuration. ## Deprecations From time to time configuration options will need to be deprecated and eventually removed. Deprecated configuration options will be removed after \~6 months from the time they were deprecated. All deprecated configuration options will be removed from the documentation, however, they will still work as expected until they're removed. A warning will be logged in the Flipt logs when a deprecated configuration option is used. All deprecated options are listed in the [DEPRECATIONS](https://github.com/flipt-io/flipt/blob/v2/DEPRECATIONS.md) file in the Flipt repository as well as the [CHANGELOG](https://github.com/flipt-io/flipt/blob/v2/CHANGELOG.md). # Secrets Source: https://docs.flipt.io/v2/configuration/secrets Secrets integration with file-based and external secret providers Flipt v2 supports external secrets management, allowing you to store sensitive configuration data like API keys, tokens, and certificates outside of your main configuration files. This enhances security by centralizing secret management and reducing the risk of accidentally exposing sensitive data. ## Why Use External Secrets? Instead of storing sensitive values directly in Flipt configuration files, external secrets provide: * **Enhanced Security**: Sensitive data is stored in dedicated secret management systems with proper access controls * **Centralized Management**: All secrets managed in one place with audit trails and access policies * **Environment Separation**: Different secrets for development, staging, and production environments * **Rotation Support**: Easy secret rotation without updating configuration files (coming soon) * **Access Control**: Fine-grained permissions for who can access which secrets ## Supported Providers Flipt supports multiple secret providers to fit different deployment scenarios: Store secrets in local files - ideal for development and simple deployments Enterprise-grade secret management with advanced authentication and access controls Retrieve secrets from AWS Secrets Manager using standard AWS credentials Retrieve secrets from Google Cloud Secret Manager with Application Default Credentials or service account keys Retrieve secrets from Azure Key Vault using Azure identity credentials ## Configuration Overview Enable secrets management by configuring providers in your Flipt configuration: ```yaml theme={null} secrets: providers: # Multiple providers can be configured file: enabled: true base_path: "/etc/flipt/secrets" vault: enabled: true address: "https://vault.company.com" auth_method: "token" aws: enabled: true gcp: enabled: true project: "my-gcp-project" azure: enabled: true vault_url: "https://my-vault.vault.azure.net/" ``` ## File Provider The file provider is the simplest option, storing each secret as an individual file in the configured directory. ### Configuration ```yaml theme={null} secrets: providers: file: enabled: true base_path: "/etc/flipt/secrets" # Default: /etc/flipt/secrets ``` ### Usage Create individual secret files in the configured directory. Each file becomes a secret where the filename is the key and the file contents are the value: ```bash theme={null} # Create individual secret files echo "sk-1234567890abcdef" > /etc/flipt/secrets/api-key echo "your-csrf-secret-key" > /etc/flipt/secrets/csrf-key echo "-----BEGIN CERTIFICATE-----..." > /etc/flipt/secrets/tls-cert echo "-----BEGIN PRIVATE KEY-----..." > /etc/flipt/secrets/tls-key ``` Each secret is stored as a separate file. The filename becomes the secret key, and the file contents become the secret value. ## HashiCorp Vault Provider Vault provides enterprise-grade secret management with advanced features like dynamic secrets, encryption as a service, and detailed audit logs. ### Basic Configuration ```yaml theme={null} secrets: providers: vault: enabled: true address: "https://vault.company.com" auth_method: "token" token: "hvs.your_vault_token" mount: "secret" # Default: secret ``` ### Authentication Methods #### Token Authentication Best for development and testing: ```yaml theme={null} vault: enabled: true address: "https://vault.company.com" auth_method: "token" token: "hvs.your_vault_token" ``` #### Kubernetes Authentication Ideal for Kubernetes deployments: ```yaml theme={null} vault: enabled: true address: "https://vault.company.com" auth_method: "kubernetes" role: "flipt-role" mount: "secret" ``` #### AppRole Authentication Good for automated systems and CI/CD: ```yaml theme={null} vault: enabled: true address: "https://vault.company.com" auth_method: "approle" role: "flipt-role" mount: "secret" ``` ### Environment Variables Avoid storing sensitive values in configuration files by using environment variables: ```bash theme={null} export FLIPT_SECRETS_PROVIDERS_VAULT_TOKEN="hvs.your_vault_token" export FLIPT_SECRETS_PROVIDERS_VAULT_ROLE_ID="your_role_id" export FLIPT_SECRETS_PROVIDERS_VAULT_SECRET_ID="your_secret_id" ``` ## AWS Secrets Manager Provider The AWS Secrets Manager provider retrieves secrets stored in [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/). It uses the AWS SDK for Go v2, which automatically resolves credentials from the standard AWS credential chain. ### Configuration ```yaml theme={null} secrets: providers: aws: enabled: true ``` | Field | Type | Required | Default | Description | | -------------- | ------ | -------- | --------- | -------------------------------------------------------------------------------- | | `enabled` | bool | No | `false` | Enables the AWS Secrets Manager provider | | `endpoint_url` | string | No | *(empty)* | Custom endpoint URL (useful for [LocalStack](https://localstack.cloud/) testing) | ### Authentication The AWS provider relies on the [default AWS credential chain](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html). You can authenticate using any of the following methods: * Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_SESSION_TOKEN` for temporary credentials) * Shared credentials file (`~/.aws/credentials`) * IAM roles for Amazon EC2 or ECS * IAM Roles Anywhere * SSO credentials Set the AWS region using the `AWS_DEFAULT_REGION` or `AWS_REGION` environment variable. ### Environment Variables ```bash theme={null} export AWS_DEFAULT_REGION="us-east-1" export AWS_ACCESS_KEY_ID="your_access_key" export AWS_SECRET_ACCESS_KEY="your_secret_key" export AWS_SESSION_TOKEN="your_session_token" # Only needed for temporary credentials (STS, assumed roles) ``` You can also configure the provider itself through environment variables: ```bash theme={null} export FLIPT_SECRETS_PROVIDERS_AWS_ENABLED=true export FLIPT_SECRETS_PROVIDERS_AWS_ENDPOINT_URL="http://localhost:4566" ``` ### Custom Endpoint For local development with LocalStack or other AWS-compatible services, specify a custom endpoint: ```yaml theme={null} secrets: providers: aws: enabled: true endpoint_url: "http://localhost:4566" ``` ## GCP Secret Manager Provider The GCP Secret Manager provider retrieves secrets stored in [Google Cloud Secret Manager](https://cloud.google.com/secret-manager). It supports both global and regional secrets. ### Configuration ```yaml theme={null} secrets: providers: gcp: enabled: true project: "my-gcp-project" ``` | Field | Type | Required | Default | Description | | ------------- | ------ | ------------------ | --------- | ------------------------------------------------------------------------------------------------------ | | `enabled` | bool | No | `false` | Enables the GCP Secret Manager provider | | `project` | string | Yes (when enabled) | *(none)* | GCP project ID | | `location` | string | No | *(empty)* | GCP region for [regional secrets](https://cloud.google.com/secret-manager/docs/create-secret-regional) | | `credentials` | string | No | *(empty)* | Path to a service account credentials JSON file | ### Authentication The GCP provider supports two authentication methods: * **Application Default Credentials (ADC)**: Automatically used when no `credentials` path is specified. This works with GCE metadata, GKE workload identity, and `gcloud auth application-default login`. * **Service account key file**: Specify an explicit path to a service account JSON credentials file. ```yaml theme={null} secrets: providers: gcp: enabled: true project: "my-gcp-project" credentials: "/path/to/service-account.json" ``` ### Regional Secrets By default, the provider accesses global secrets. To use [regional secrets](https://cloud.google.com/secret-manager/docs/create-secret-regional), specify the `location` field: ```yaml theme={null} secrets: providers: gcp: enabled: true project: "my-gcp-project" location: "us-central1" ``` ### Environment Variables ```bash theme={null} export FLIPT_SECRETS_PROVIDERS_GCP_ENABLED=true export FLIPT_SECRETS_PROVIDERS_GCP_PROJECT="my-gcp-project" export FLIPT_SECRETS_PROVIDERS_GCP_LOCATION="us-central1" export FLIPT_SECRETS_PROVIDERS_GCP_CREDENTIALS="/path/to/credentials.json" ``` ## Azure Key Vault Provider The Azure Key Vault provider retrieves secrets stored in [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault). It uses the Azure SDK for Go with `DefaultAzureCredential`, which supports multiple authentication methods. ### Configuration ```yaml theme={null} secrets: providers: azure: enabled: true vault_url: "https://my-vault.vault.azure.net/" ``` | Field | Type | Required | Default | Description | | ----------- | ------ | ------------------ | -------- | ---------------------------------------------------------------------- | | `enabled` | bool | No | `false` | Enables the Azure Key Vault provider | | `vault_url` | string | Yes (when enabled) | *(none)* | Azure Key Vault URL (for example, `https://my-vault.vault.azure.net/`) | ### Authentication The Azure provider uses [`DefaultAzureCredential`](https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication), which tries multiple authentication methods in order: * Environment variables (`AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET`) * Workload identity (for Kubernetes) * Managed identity (for Azure VMs, App Service, and other Azure services) * Azure CLI credentials ### Environment Variables ```bash theme={null} export AZURE_CLIENT_ID="your_client_id" export AZURE_TENANT_ID="your_tenant_id" export AZURE_CLIENT_SECRET="your_client_secret" ``` You can also configure the provider itself through environment variables: ```bash theme={null} export FLIPT_SECRETS_PROVIDERS_AZURE_ENABLED=true export FLIPT_SECRETS_PROVIDERS_AZURE_VAULT_URL="https://my-vault.vault.azure.net/" ``` ## Using Secrets in Configuration Secrets can be referenced throughout your Flipt v2 configuration using the secret reference syntax. Secret references must always include the provider specification. ### Secret Reference Syntax Secret references use the format `${secret:provider:key}` where: * `provider` is the name of the configured secrets provider (e.g., `file`, `vault`, `aws`, `gcp`, `azure`) * `key` is the name of the secret to retrieve ### File Provider Examples ```yaml theme={null} server: cert_file: "${secret:file:tls-cert}" # References /etc/flipt/secrets/tls-cert cert_key: "${secret:file:tls-key}" # References /etc/flipt/secrets/tls-key authentication: required: true session: csrf: key: "${secret:file:csrf-key}" # References /etc/flipt/secrets/csrf-key methods: token: enabled: true storage: tokens: "ci_token": credential: "${secret:file:ci-token}" # References /etc/flipt/secrets/ci-token ``` ### Vault Provider Examples ```yaml theme={null} authentication: required: true methods: oidc: providers: google: client_id: "${secret:vault:auth/oidc:client_id}" client_secret: "${secret:vault:auth/oidc:client_secret}" github: client_id: "${secret:vault:auth/github:client_id}" client_secret: "${secret:vault:auth/github:client_secret}" token: enabled: true storage: tokens: "ci_token": credential: "${secret:vault:flipt/tokens:ci-token}" ``` ### Cloud Provider Examples For cloud providers (AWS, GCP, Azure), the `key` in the secret reference corresponds to the exact secret name as stored in the provider. Path separators and version specifiers are not supported in the key — use the secret's name directly. ```yaml theme={null} storage: default: git: authentication: token: "${secret:gcp:git-token}" # GCP Secret Manager password: "${secret:aws:git-password}" # AWS Secrets Manager authentication: methods: oidc: providers: azure_ad: client_id: "${secret:azure:oidc-client-id}" # Azure Key Vault client_secret: "${secret:azure:oidc-client-secret}" # Azure Key Vault ``` ### Combined with Environment Variables You can combine secret references with environment variables in the same configuration: ```yaml theme={null} authentication: methods: oidc: providers: google: issuer_url: ${env:OIDC_ISSUER_URL} # Environment variable client_id: ${secret:vault:auth/oidc:client_id} # Secret reference client_secret: ${secret:vault:auth/oidc:client_secret} # Secret reference redirect_address: ${env:FLIPT_BASE_URL} # Environment variable ``` ### Structured Secret References For more complex scenarios, you can also use the structured `key_ref` format in configuration sections that support it: ```yaml theme={null} storage: default: signature: enabled: true key_ref: provider: "vault" # Secrets provider name path: "flipt/signing-key" # Path to secret in provider key: "private_key" # Key name within the secret ``` # Storage Source: https://docs.flipt.io/v2/configuration/storage This document describes how to configure the storage backend mechanisms for Flipt v2. Flipt v2 stores all of its resources in git repositories. This section describes how those git repositories are persisted and managed. ## Identifiers Each storage backend has an identifier that is used to reference the storage backend in the configuration, such as when specifying the storage backend for an environment. Identifiers can be any string value but must be unique. Flipt creates a `default` identifier and storage backend for you automatically if you don't specify one. In the following example, we've defined two storage backends: * `staging` is a local storage backend that will serve Flipt flag state from a local directory. * `development` is a memory storage backend that will serve Flipt flag state from an in-memory store. ```yaml theme={null} storage: staging: # id name: "staging" backend: type: local path: "/path/to/staging/repository" development: # id name: "development" backend: type: memory ``` ## Backends Flipt v2 supports the following storage backends: * [Local](#local) * [Memory](#memory) ### Local The purpose of this backend type is to support serving Flipt flag state directly from your local filesystem in a git repository. This allows the the data to be persisted between server restarts. Flipt will periodically rebuild its state from the local disk every 10 seconds. ```yaml theme={null} storage: backend: type: local path: "." ``` The above configuration will create a local storage backend with the identifier `default` and serve Flipt flag state from the current working directory. For guidance on setting up Git repositories with existing feature files, see our [Git Repository Initialization guide](/v2/guides/operations/environments/git-repository-initialization). ### Memory The purpose of this backend type is to support serving Flipt flag state from an in-memory store. This is useful for development and testing purposes where you don't want to persist flag state to disk. ```yaml theme={null} storage: backend: type: memory ``` The above configuration will create a memory storage backend with the identifier `default` and serve Flipt flag state from an in-memory store. ## Git Remotes Flipt v2 supports syncing flag state to and from a remote git repository. ```yaml theme={null} storage: staging: remote: "https://github.com/flipt-io/example.git" branch: "main" poll_interval: "30s" fetch_policy: "strict" credentials: "github" backend: type: memory ``` This configuration will create a git storage backend with the identifier `staging` in memory and will sync flag state to and from the remote repository. ### Fetch Policy The `fetch_policy` configuration option controls how Flipt handles connection-related issues when attempting to fetch from a remote Git repository. #### Available Policies * **`strict`** (default): Flipt will fail and return an error if it encounters connection issues when trying to fetch from the remote repository. This ensures that any connectivity problems are immediately visible and must be resolved. * **`lenient`**: Flipt will continue operating even if connection issues prevent fetching from the remote repository. This allows Flipt to remain functional during temporary network issues or remote repository unavailability. #### Usage Example ```yaml theme={null} storage: production: remote: "https://github.com/company/flags.git" fetch_policy: "strict" # Fail fast on connection issues backend: type: local path: "/var/lib/flipt" development: remote: "https://github.com/company/flags.git" fetch_policy: "lenient" # Continue operation during connection issues backend: type: memory ``` In production environments, consider using `strict` to ensure that connectivity issues are detected and resolved promptly, preventing potential configuration drift between your remote repository and running Flipt instances. ### Conflict Resolution Conflicts can occur when syncing flag state to and from a remote repository. The conflict resolution strategy in Flipt v2 is currently rudimentary and we aim to improve this in future releases. When syncing flag state to and from a remote repository, Flipt will behave as follows: * Remote state is synced to the local storage backend using the configured `poll_interval` * On writes to the Flipt server, the local storage backend will create a new commit and push it to the remote repository * Flipt keeps track of the last commit hash for each storage backend * If a write is made to a flag state file that has been modified since the last commit, Flipt will refuse to push the changes to the remote repository and will instead return an error * If a write is made to a flag state file that has not been modified since the last commit, Flipt will push the changes to the remote repository ### Credentials Credentials enable the ability to authenticate with remote repositories. Supported authentication schemes are: * `basic` * `ssh` * `access_token` * `github_app` Credentials are configured using the `credentials` configuration section and use identifiers to reference the credentials in the configuration. This means that you can use the same credentials for multiple storage backends if needed. #### Basic Basic authentication is a username and password pair. ```yaml theme={null} credentials: github: type: basic basic: username: < username > password: < github-personal-access-token > ``` #### SSH In order to configure a git remote with SSH, you will need to generate an SSH key-pair and configure your repository provider with the public key. GitHub has some excellent documentation regarding how to generate and install your credentials [here](https://docs.github.com/en/authentication/connecting-to-github-with-ssh). Once you have your private key credentials you will need to configure Flipt to use them. This can be done via the `storage.git.authentication.ssh` configuration section: ```yaml theme={null} credentials: github: type: ssh ssh: user: git private_key_path: ~/.ssh/id_rsa private_key_bytes: # alternatively pass the raw bytes inline ``` `insecure_ignore_host_key` is not encouraged for production use, and is `false` by default. Instead, you are advised to put the key fingerprint in the known hosts file where you are running Flipt. For example, for GitHub you can do `ssh-keyscan github.com >> ~/.ssh/known_hosts` on the Flipt host. *Container Deployment*: When running Flipt in containers, mount the known\_hosts file to the system-wide SSH path instead of a user directory. For example, with Docker ```yaml theme={null} volumes: - /path/to/your/known_hosts:/etc/ssh/ssh_known_hosts:ro ``` #### Access Token Access tokens are a type of credential that are used to authenticate with a remote repository. These can be used for any remote repository provider that supports access tokens such as GitHub, GitLab, Gitea, and Azure DevOps. ```yaml theme={null} credentials: github: type: access_token access_token: < github-access-token > ``` #### GitHub App GitHub App authentication provides a more secure alternative to personal access tokens (PATs) for authenticating with GitHub repositories. GitHub App tokens are short-lived, offer higher rate limits, and provide more granular permissions. To use this credential type, you need to [create a GitHub App](https://docs.github.com/en/apps/creating-github-apps) and install it on your repository or organization. You can provide the private key either as a file path or as raw bytes inline: ```yaml theme={null} credentials: github: type: github_app github_app: client_id: < github-app-client-id > installation_id: < github-app-installation-id > private_key_path: /path/to/private-key.pem ``` Alternatively, you can pass the private key bytes inline: ```yaml theme={null} credentials: github: type: github_app github_app: client_id: < github-app-client-id > installation_id: < github-app-installation-id > private_key_bytes: < raw-private-key-bytes > ``` You must provide either `private_key_path` or `private_key_bytes`, but not both. For GitHub Enterprise Server, you can optionally specify a custom API URL: ```yaml theme={null} credentials: github: type: github_app github_app: client_id: < github-app-client-id > installation_id: < github-app-installation-id > private_key_path: /path/to/private-key.pem api_url: "https://github.example.com/api/v3" ``` # Telemetry Source: https://docs.flipt.io/v2/configuration/telemetry This document describes how to configure telemetry outputs as well as what data is captured for Flipt v2. Flipt developers rely on anonymous usage data to help prioritize new features and improve the product. The information collected is completely anonymous, never shared with external entities, and you can opt-out at any time. The telemetry data is collected by default, but you can disable it by following the instructions below. Telemetry is only collected when Flipt is running, **once at startup** and then every **4 hours**. ### What Kind of Data is Collected? * Flipt version (i.e.: v2.0.0) * Operating system (i.e.: Linux) * Architecture (i.e.: amd64) We use [Jitsu](https://jitsu.com/) to collect the data. Only the Flipt team has access to the raw data. Here is an example of the telemetry data sent to Jitsu: ```json theme={null} { "version": "2.0", "uuid": "1545d8a8-7a66-4d8d-a158-0a1c576c68a6", "lastTimestamp": "2023-04-25T01:01:51Z", "flipt": { "version": "v2.0.0", "os": "linux", "arch": "amd64" } } ``` You can always view the current schema of the telemetry data and see how it's collected on [GitHub](https://github.com/flipt-io/flipt/blob/main/internal/telemetry/telemetry.go). ### How To Disable Telemetry Telemetry collection can be disabled in several ways: #### Configuration File ```yaml theme={null} meta: telemetry_enabled: false ``` #### Environment Variables ```shell theme={null} export FLIPT_META_TELEMETRY_ENABLED=false ``` Telemetry can also be disabled by setting the [DO\_NOT\_TRACK](https://consoledonottrack.com/) environment variable to `true` or `1`: ```shell theme={null} export DO_NOT_TRACK=true ``` # Flipt Cloud to Flipt v2 Source: https://docs.flipt.io/v2/guides/migration/cloud/flipt-cloud-to-v2 Learn how to migrate from Flipt Cloud to a self-hosted Flipt v2 instance This guide will walk you through migrating from Flipt Cloud to a self-hosted Flipt v2 instance while preserving your existing feature flag data. ## Prerequisites * An active [Flipt Cloud](https://flipt.cloud) account with configured environments * A GitHub repository containing your feature flag data (managed by Flipt Cloud) * [Flipt v2 installed](/v2/installation) on your target environment * Access to the GitHub repository containing your feature flag data ## Migration Overview Since Flipt Cloud already stores your feature flag data in Git repositories, migrating to Flipt v2 is straightforward. You'll configure Flipt v2 to sync with the same GitHub repository that Flipt Cloud has been using. ### 1. Identify Your Flipt Cloud Repository First, identify the GitHub repository and configuration that Flipt Cloud is using for your environment: 1. Log into your [Flipt Cloud](https://flipt.cloud) dashboard 2. Navigate to your environment settings 3. Click on the **Integrations** tab 4. Click on the 'View GitHub Repository' button 5. Note the following information: * **Repository URL**: The GitHub repository where your flags are stored * **Branch**: The branch being used (typically `main`) * **Directory**: The directory path within the repository (if any) Flipt Cloud Repository ### 2. Export Authorization Configuration 1. While logged into Flipt Cloud, click on the **Settings** tab 2. Click on the **Roles** tab 3. Click on the **Export RBAC** button 4. Download the authorization configuration archive and save it for later Export Authorization ### 3. Set Up GitHub Authentication Create a GitHub Personal Access Token (PAT) that Flipt v2 can use to access your repository: 1. Go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens) 2. Click **"Generate new token"** 3. Give your token a descriptive name (e.g., "Flipt v2 Migration") 4. Select the appropriate resource owner and repositories 5. Set an expiration date 6. Select the following repository scopes: * `repo` read and write access (for private repositories) * `contents` read and write access 7. Click **"Generate token"** and copy the token Save your token securely. You will not be able to see it again after leaving this page. ### 4. Configure Flipt v2 Create or update your Flipt v2 configuration file to connect to your existing GitHub repository: #### Add GitHub Credentials ```yaml theme={null} credentials: github: type: access_token access_token: ${env:GITHUB_TOKEN} ``` #### Configure Storage Backend ```yaml theme={null} storage: github: remote: "https://github.com//.git" branch: "main" poll_interval: "30s" credentials: "github" backend: type: local path: "/tmp/flipt-repo" ``` Replace: * `` and `` with your actual GitHub repository details * `branch` with the branch used by Flipt Cloud (if different from `main`) * `path` with your preferred local storage location #### Configure Environments If you have multiple environments in Flipt Cloud, configure them in Flipt v2: ```yaml theme={null} environments: production: name: "Production" storage: "github" default: true directory: "production" # Use the same directory as Flipt Cloud staging: name: "Staging" storage: "github" directory: "staging" # Use the same directory as Flipt Cloud ``` Make sure the directory paths match exactly what Flipt Cloud was using to avoid data conflicts. #### Configure Authorization If you have any custom RBAC roles or permissions in Flipt Cloud, you'll need to configure them in Flipt v2. If you don't have any custom RBAC roles or permissions in Flipt Cloud, you can skip this step. Unarchive the authorization configuration from earlier and put the files somewhere accessible to Flipt v2. Update the `policy.rego` file to have the package name `flipt.authz.v2` instead of `flipt.authz.v1`. ```rego policy.rego theme={null} package flipt.authz.v2 import rego.v1 default allow := false allow if { some rule in has_rules permit_string(rule.resource, input.request.resource) permit_slice(rule.actions, input.request.action) permit_string(rule.namespace, input.request.namespace) } ``` Update the `config.yaml` file to point to the new policy files: ```yaml theme={null} authorization: required: true local: policy: path: "policy.rego" data: path: "data.json" ``` See [Authorization](/v2/configuration/authorization) for more information. ### 5. Start Flipt v2 1. Set your GitHub token as an environment variable: ```bash theme={null} export GITHUB_TOKEN=your_github_token_here ``` 2. Start Flipt v2 with your configuration: ```bash theme={null} ./flipt server --config config.yaml ``` 3. Flipt v2 will: * Clone your existing repository * Load your feature flag data * Begin syncing with GitHub ### 6. Verify Migration 1. Access the Flipt v2 UI (typically at `http://localhost:8080`) 2. Verify that all your feature flags, segments, and rules are present 3. Check that all environments are configured correctly 4. Test flag evaluation to ensure everything works as expected ### 7. Update Your Applications Update your applications to point to your new Flipt v2 instance instead of Flipt Cloud: 1. **Update SDK Configuration**: Change the Flipt server URL in your application code 2. **Update API Keys**: Generate new [Static Tokens](/v2/configuration/authentication#static-token) in Flipt v2 if needed 3. **Test Evaluation**: Verify that flag evaluation works with your new instance ### 8. Decommission Flipt Cloud Once you've verified that your migration is successful: 1. Update any remaining applications to use Flipt v2 2. When ready, you can delete your Flipt Cloud environment ### Data Continuity Your feature flag data will remain intact throughout this migration because: * Flipt Cloud stores data in your GitHub repository * Flipt v2 reads from the same repository structure * No data transformation or conversion is required * All flag history is preserved in Git ### Troubleshooting #### Repository Access Issues If Flipt v2 cannot access your repository: * Verify your GitHub token has the correct permissions * Check that the repository URL is correct * Ensure the branch name matches what Flipt Cloud was using * Ensure the directory path matches what Flipt Cloud was using #### Sync Issues If changes aren't syncing properly: * Check the `poll_interval` setting * Verify write permissions on the local storage path * Verify your GitHub token as the correct scopes (write access to the repository) * Review Flipt v2 logs for sync errors ## Next Steps After successful migration: * [Configure authentication](/v2/guides/operations/authentication) for your team * [Set up environments](/v2/configuration/environments) for your deployment pipeline * [Review configuration settings](/v2/configuration/overview) for your deployment * [Setup Merge Proposals](/v2/guides/user/environments/merge-proposals) for your environments ## Support If you encounter issues during migration: * Check the [Flipt v2 documentation](/v2/introduction) * Join our [Discord community](https://discord.gg/flipt) * Visit [GitHub Discussions](https://github.com/flipt-io/flipt/discussions) *** **References:** * [Flipt v2 Storage Configuration](/v2/configuration/storage) * [Git Sync with GitHub](/v2/guides/operations/environments/git-sync) # Connecting Applications to Flipt Source: https://docs.flipt.io/v2/guides/operations/authentication/connecting-applications Learn how to authenticate your applications with Flipt using client tokens, JWT, or Kubernetes service account tokens This guide explains how to connect your applications to Flipt for production use. You'll learn how to create authentication credentials and use them with Flipt's SDKs, REST API, and gRPC. ## Overview Flipt supports these application authentication patterns: 1. **Static Client Tokens** — generate a secure token and configure it in Flipt 2. **JWT Authentication** — use JWTs from your existing identity provider 3. **Kubernetes Service Account Exchange** — exchange a pod service account token for a Flipt client token Static client tokens and JWTs work with Flipt's SDKs and HTTP APIs. Kubernetes service account authentication is a token exchange flow that returns a Flipt client token (or is handled automatically by supported SDKs). ## Method 1: Static Client Tokens Static tokens are the simplest way to authenticate. You generate a secure random token, add it to your Flipt configuration, and then use that token in your applications. ### Step 1: Generate a Secure Token Generate a cryptographically secure random token: ```bash theme={null} # Using openssl (recommended) openssl rand -hex 32 # Using python python3 -c "import secrets; print(secrets.token_hex(32))" ``` This produces a 64-character hex string (e.g., `7f3a8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a`). ### Step 2: Configure Flipt with Your Token Add the token to your Flipt configuration: ```yaml config.yaml theme={null} authentication: required: true methods: token: enabled: true storage: tokens: "my-app-token": credential: "7f3a8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a" metadata: app: "production-api" environment: "production" ``` Use environment variable substitution to avoid committing secrets to config files: ```yaml theme={null} authentication: methods: token: storage: tokens: "my-app-token": credential: "${env:FLIPT_CLIENT_TOKEN}" ``` Then set `FLIPT_CLIENT_TOKEN` in your environment or Kubernetes Secret. ### Step 3: Restart Flipt Restart your Flipt instance to pick up the new configuration. ### Step 4: Use the Token in Your Application Once configured, pass the client token to your SDK or send it in the HTTP `Authorization` header. SDK authentication class names and initialization options vary by language and SDK version. Use the auth strategy/client token option documented in the SDK README for your language from the [Server SDKs](/v2/integration/server/rest) and [Client SDKs](/v2/integration/client) pages. Example HTTP request using a client token: ```bash theme={null} curl --request POST http://localhost:8080/evaluate/v1/variant \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer ' \ --data '{ "flagKey": "dark-mode", "entityId": "user-123", "namespaceKey": "default", "context": { "theme": "dark" } }' ``` ### Using Tokens with Kubernetes Secrets For Kubernetes deployments, store the token in a Secret and reference it via environment variables: ```yaml theme={null} # Create secret apiVersion: v1 kind: Secret metadata: name: flipt-client-token type: Opaque stringData: token: "7f3a8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a" --- # In your application deployment env: - name: FLIPT_CLIENT_TOKEN valueFrom: secretKeyRef: name: flipt-client-token key: token ``` *** ## Method 2: JWT Authentication If you already have an identity provider (Auth0, Okta, Keycloak, etc.) that issues JWTs, you can use those with Flipt without creating static tokens. ### Step 1: Configure Flipt for JWT Add JWT authentication to your Flipt configuration: ```yaml config.yaml theme={null} authentication: required: true methods: jwt: enabled: true jwks_url: "https://your-idp.com/.well-known/jwks.json" ``` ### Step 2: Use JWTs in Your Application Your application obtains a JWT from your identity provider, then passes it to Flipt using the JWT authorization header format: ```bash theme={null} curl --request POST http://localhost:8080/evaluate/v1/variant \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: JWT ' \ --data '{ "flagKey": "dark-mode", "entityId": "user-123", "namespaceKey": "default", "context": {} }' ``` For SDK usage, configure the SDK's JWT authentication strategy/option for your language and pass the token returned by your identity provider. JWT authentication is useful when: * You already have SSO set up * You want to avoid managing static tokens * You need per-user authentication and audit trails *** ## Method 3: Kubernetes Service Account Tokens If you're running Flipt in Kubernetes, you can use the Kubernetes authentication method to exchange a pod service account token for a Flipt client token. ### Step 1: Enable Kubernetes Authentication ```yaml config.yaml theme={null} authentication: required: true methods: kubernetes: enabled: true # Path where Kubernetes mounts the service account token service_account_token_path: /var/run/secrets/kubernetes.io/serviceaccount/token ``` ### Step 2: Exchange the Service Account Token for a Flipt Client Token Kubernetes service account tokens are not used directly as Flipt client tokens. Instead, send the pod token to Flipt's Kubernetes auth endpoint to obtain a Flipt client token: ```bash theme={null} # assumes curl (and optionally jq) is installed in the pod curl --request POST http://flipt:8080/auth/v1/method/kubernetes/serviceaccount \ --header 'Content-Type: application/json' \ --data "{\"service_account_token\":\"$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\"}" ``` Use the returned `clientToken` value as a normal Flipt client token (`Authorization: Bearer `). Some SDKs can perform this Kubernetes token exchange and refresh flow automatically. See the SDK documentation for your language. This approach: * Avoids provisioning static tokens per workload * Aligns Flipt credentials to Kubernetes service account token expiration * Works well for in-cluster service-to-service authentication *** ## Choosing an Authentication Method | Method | Best For | Complexity | | ----------------- | ----------------------------------------------- | ---------- | | **Static Token** | Simple deployments, CI/CD, single application | Low | | **JWT** | Teams with existing IdP (Auth0, Okta, Keycloak) | Medium | | **Kubernetes SA** | Running in Kubernetes with multiple services | Low | *** ## Related * [Authentication Configuration](/v2/configuration/authentication) — Full reference for all auth options * [REST API Reference](/v2/integration/server/rest) — REST API authentication details * [Server SDKs](/v2/integration/server/rest) — SDK documentation * [Client SDKs](/v2/integration/client) — Client-side evaluation SDKs # Login with GitHub Source: https://docs.flipt.io/v2/guides/operations/authentication/login-with-github Configuring Flipt v2 to enable login with GitHub via OAuth 2.0 This guide will serve as a walk-through on how to set up Flipt v2 to enable login with GitHub via OAuth 2.0. ## Prerequisites * [Docker](https://www.docker.com/) * [A GitHub Account](https://github.com/) ## Brief Explanation of OAuth 2.0 OAuth 2.0 is an authentication standard whose goal is to allow 3rd party applications to access authorized resources from a provider. It relies on the user explicitly granting access to the 3rd party application to issue a token on behalf of the OAuth 2.0 provider for authorized use. Unlike OIDC, OAuth 2.0 does not have a standardized identity layer, which means the process of retrieving identity information varies between providers. Users should consult their OAuth 2.0 provider's documentation to understand the specific methods for retrieving identity information. ## Creating a GitHub OAuth 2.0 Application 1. Navigate to your GitHub account, and click on `Settings` under the menu of your Profile icon 2. At the bottom of the menu on the left, click on the menu option titled `Developer Settings` 3. This should bring you to a page that has `OAuth Apps` as a menu option on the left, click on that and click `New OAuth App` to start creating the application 4. You should be brought to a page that looks like the image below, and can start filling out the information: OAuth 2.0 App Creation * `Application Name`: Give your application a meaningful name like "Flipt" * `Homepage URL`: Usually Flipt will be used internally by organizations, so this value depends on how you plan to expose Flipt. When in doubt you can just use the URL to your organization's home page * `Authorization callback URL`: For this value, you'll need your Flipt URL followed by `/auth/v1/method/github/callback`. We're using `localhost:8080` here for illustration purposes. In a production setting, you would use whichever accessible domain name you have configured for your Flipt deployment. These values can always be changed later after the creation of the application. 5. Retrieve the `Client ID` and `Client Secret` from the created OAuth 2.0 app The Client ID should already be provided to you. You will have to generate a client secret. Click on the `Generate a new client secret` button (it may ask you to authenticate again with GitHub). ## Running Flipt ### 1. Define a Flipt `config.yml` Flipt relies on configuration that the user provides for many bits of functionality. To enable the Login With GitHub feature, you must define a configuration file `config.yml` with certain fields and values. The [configuration documentation](/v2/configuration/authentication) goes into more detail on the configuration values available for authentication. Configure your `config.yml` file to enable the GitHub authentication method. ```yaml theme={null} authentication: required: true session: domain: "localhost:8080" secure: false methods: github: enabled: true client_id: ${env:FLIPT_GITHUB_CLIENT_ID} client_secret: ${env:FLIPT_GITHUB_CLIENT_SECRET} redirect_address: "http://localhost:8080" scopes: - user:email ``` The `client_id` and `client_secret` are going to be the values from your GitHub OAuth application. The `redirect_address` will be `http://localhost:8080`. The `scopes` are entirely dependent on what level of access you would like the returned GitHub access token to have. The [GitHub documentation](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps) describes a list of valid scopes. The last bit of configuration is the session details. In order for the browser to establish a session to communicate with Flipt in an authenticated way, you must provide access details in an HTTP cookie whose value is a static token created by Flipt. This static token is created during the GitHub OAuth 2.0 flow, and associated with the GitHub metadata retrieved from the GitHub API with the access token. The `domain` value will specify which host can receive the cookie. ### 2. Run Flipt as a Docker container ```bash theme={null} docker run -it --rm \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ -v "$(pwd)/config.yml:/etc/flipt/config/default.yml" \ docker.flipt.io/flipt/flipt:v2 ``` This will mount both the data directory for persistent storage and the `config.yml` configuration file into the container at the standard location. ### 3. Navigate to the Flipt UI Access the Flipt UI by typing in the `http://localhost:8080` URL in the address bar of a browser. You should see the following screen: Login With GitHub Click the button to Login With GitHub, and it should take you to the GitHub domain to complete the authentication flow. GitHub Authorization After authenticating with GitHub, you should be redirected back to the Flipt UI and see the Flipt dashboard with your profile picture and name. Flipt Dashboard ## Conclusion This guide showed the basics of getting Flipt running with GitHub OAuth 2.0 authentication in a development environment. You can now use GitHub to authenticate with Flipt and start using Flipt to manage your flags. If you have any questions or feedback, please reach out to the Flipt team on [Discord](https://discord.gg/flipt) or [GitHub Discussions](https://github.com/flipt-io/flipt/discussions). *** **References:** * [Flipt v2 Authentication Configuration](/v2/configuration/authentication) * [GitHub OAuth 2.0 Documentation](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps) # Deploy to Kubernetes Source: https://docs.flipt.io/v2/guides/operations/deployment/deploy-to-kubernetes Deploy Flipt v2 to Kubernetes using our official Helm chart ## What You'll Learn In this guide, you will learn how to deploy Flipt v2 to a local Kubernetes cluster (via [Kind](https://kind.sigs.k8s.io/)) using our official Helm chart. You'll also learn how to override the default Flipt v2 configuration by providing a `values.yaml` file. By the end of this guide, we will have: * 🚢 Created a Kind cluster locally using Docker * 📦 Installed Flipt v2 into your cluster via Helm * ⚙️ Configured Flipt v2 settings via a `values.yaml` file * 🔄 Explored v2's Git-native storage capabilities ## Prerequisites * Docker installed ([Download](https://www.docker.com/products/docker-desktop)) * Helm v3.x installed ([Installation guide](https://helm.sh/docs/intro/install/)) * Kind installed ([Installation guide](https://kind.sigs.k8s.io/docs/user/quick-start/)) ## Deploying Flipt v2 ### 1. Create a Local Kubernetes Cluster Using Kind First, we need to create a local Kubernetes cluster. We'll use [Kind](https://kind.sigs.k8s.io/) to accomplish this. Open a terminal and run the following command: ```bash theme={null} kind create cluster --name flipt-v2 ``` This command will create a new Kubernetes cluster named `flipt-v2`. Wait for the command to complete and ensure the cluster is correctly set up. ### 2. Add the Flipt Helm Repository Next, we'll add the [Flipt Helm repository](https://helm.flipt.io/) which hosts the Flipt Helm charts. Run the following command: ```bash theme={null} helm repo add flipt https://helm.flipt.io/ ``` After running this command, Helm will fetch shared information about the new repository. ### 3. Update Helm Repositories To ensure that Helm has the latest information about the charts from the Flipt Helm repository, update the repositories: ```bash theme={null} helm repo update ``` ### 4. Install Flipt v2 with Custom Configuration Before installing Flipt v2, you can create a `values.yaml` file to customize the deployment according to your preferences. Flipt v2 works out-of-the-box without any configuration using Git-native storage. However, you can customize various aspects of the deployment. Here's an example `values.yaml` file with some common v2 configurations: ```yaml theme={null} flipt: config: log: level: INFO encoding: json server: grpc_port: 9000 http_port: 8080 cors: enabled: true allowed_origins: - "http://localhost:3000" - "https://your-frontend-domain.com" ui: default_theme: dark topbar: color: "#7C3AED" meta: check_for_updates: false telemetry_enabled: false metrics: enabled: true exporter: prometheus storage: default: backend: type: memory ``` This example configures: * Structured JSON logging at INFO level * CORS support for frontend integration * Custom UI theme and branding * Disabled telemetry and update checks * Prometheus metrics enabled * Memory storage backend (default) This example uses memory storage which works out-of-the-box without requiring a Git repository. For production use with Git-backed storage, see the [Git Storage guide](/v2/guides/operations/environments/git-sync) for setup details. You can adjust this file to include any configuration values you need based on the [v2 configuration documentation](/v2/configuration/overview). Once you have your `values.yaml` file (or to use default settings), install Flipt v2 with Helm: ```bash theme={null} # Install with custom values helm install flipt-v2 flipt/flipt-v2 -f values.yaml # Or install with default settings helm install flipt-v2 flipt/flipt-v2 ``` Note the chart name is `flipt-v2`, not `flipt`. This is the dedicated chart for Flipt v2 which includes v2-specific configurations and defaults. This command installs the Flipt v2 Helm chart into your Kubernetes cluster using the configuration options specified in your `values.yaml` file merged with the default values from the chart. ### 5. Forward the Port to Access Flipt v2 After successfully installing Flipt v2 via the Helm chart, you should see instructions on how to access Flipt in your terminal. The instructions will look something like this: ```bash theme={null} export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=flipt-v2,app.kubernetes.io/instance=flipt-v2" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT ``` Execute the commands in your terminal to forward the port and access Flipt v2. You should now be able to access Flipt v2 at `http://localhost:8080`. ### 6. Verify the Installation and Configuration To ensure that Flipt v2 has been correctly deployed to your Kubernetes cluster, you can check the running pods: ```bash theme={null} kubectl get pods ``` You should see the Flipt v2 pod in the list with a status of `Running`. ```console theme={null} NAME READY STATUS RESTARTS AGE flipt-v2-6d64f856d7-4l5qn 1/1 Running 0 32m ``` To verify that your configuration changes were applied, open the application in your browser at [http://localhost:8080](http://localhost:8080) and you should see the Flipt UI with the dark theme and custom topbar color: Deployed via Helm ## Flipt v2 Features in Kubernetes ### Git-Native Storage Flipt v2's Git-native storage works seamlessly in Kubernetes environments. The deployed instance can: * **Clone repositories**: Automatically clone and sync with your Git repository containing feature flag definitions * **Work offline**: Continue serving flags even when the source Git repository is temporarily unavailable * **Support multiple Git providers**: Works with GitHub, GitLab, Bitbucket, Azure DevOps, Gitea, and other Git platforms ### Environment Support Flipt v2 introduces environments that map to Git branches, allowing you to: * Deploy multiple environments (dev/staging/prod) from different branches * Use branch-based workflows for flag management * Create merge proposals through the UI that generate Git pull requests ### Configuration Flexibility The v2 Helm chart supports all v2 configuration options, including: * **Storage backends**: Git, local filesystem, or hybrid approaches * **Analytics**: Optional ClickHouse integration for advanced analytics * **Authentication**: GitHub, OIDC, and other authentication methods * **Authorization**: RBAC and policy-based access control ## Next Steps Congratulations! You've successfully deployed Flipt v2 to a local Kubernetes cluster using our Helm chart. You've also learned about v2's Git-native capabilities and configuration options. You should be able to take the knowledge you've gained in this guide and deploy Flipt v2 to a real Kubernetes cluster. ### Additional Resources * [Flipt v2 Helm Chart Repository](https://github.com/flipt-io/helm-charts/tree/main/charts/flipt-v2) - Chart source and configuration options * [v2 Configuration Documentation](/v2/configuration/overview) - Complete configuration reference * [Git Storage Guide](/v2/guides/operations/environments/git-sync) - Detailed Git storage setup * [Authentication Methods](/v2/configuration/authentication) - Setting up authentication in v2 * [Kubernetes Troubleshooting](/v2/guides/operations/deployment/kubernetes-troubleshooting) - Common issues and solutions for Kubernetes deployments ### Production Considerations For production deployments, consider: * **Resource limits**: Set appropriate CPU and memory limits in your `values.yaml` * **Persistent storage**: Configure persistent volumes if using local storage * **High availability**: Deploy multiple replicas with appropriate anti-affinity rules * **Security**: Enable authentication and configure RBAC policies * **Monitoring**: Set up observability with metrics and distributed tracing * **Backup**: Implement backup strategies for your Git repositories and any local data # Kubernetes Troubleshooting Source: https://docs.flipt.io/v2/guides/operations/deployment/kubernetes-troubleshooting Common issues and solutions when deploying Flipt v2 to Kubernetes This guide covers common issues encountered when deploying Flipt v2 to Kubernetes using the official Helm chart, along with their solutions. ## Helm Schema Validation Errors When installing or upgrading the Flipt Helm chart, you may encounter schema validation errors like: ```text theme={null} helm install flipt flipt/flipt-v2 -f values.yaml Error: INSTALLATION FAILED: values don't meet the specifications of the schema(s) in the following chart(s): flipt-v2: - autoscaling: Additional property targetMemoryUtilizationPercentage is not allowed - resources: Additional property limits is not allowed - resources: Additional property requests is not allowed ``` This happens when the chart's JSON schema doesn't cover all valid configuration options. To work around this, skip schema validation (requires Helm 3.13+): ```bash theme={null} helm install flipt flipt/flipt-v2 -f values.yaml --skip-schema-validation ``` Or for upgrades: ```bash theme={null} helm upgrade flipt flipt/flipt-v2 -f values.yaml --skip-schema-validation ``` `--skip-schema-validation` bypasses chart schema checks entirely. Use it as a temporary workaround while tracking upstream schema fixes in [flipt-io/helm-charts](https://github.com/flipt-io/helm-charts) — typos in your `values.yaml` will no longer be caught automatically when this flag is set. ## Machine ID Not Found (License Validation) When running Flipt Pro on containerd-based Kubernetes clusters (such as GKE or modern EKS), you may see: ```text theme={null} license is invalid; additional features are disabled. {"error": "machineid: machineid: no machine-id found"} ``` ### Why This Happens Flipt uses a machine fingerprint for license validation. The fingerprinting library reads from: 1. `/var/lib/dbus/machine-id` 2. `/etc/machine-id` 3. Docker-specific paths in `/proc/self/cgroup` and `/proc/self/mountinfo` In containerd-based environments (GKE, EKS with containerd, etc.), none of these files exist inside the container because: * The Flipt container image is Alpine-based and doesn't include dbus * `/etc/machine-id` is not present in minimal container images * The Docker-specific fallback paths don't match containerd's format ### Solution: Configure a Stable Machine ID Set `license.machine_id` or the `FLIPT_LICENSE_MACHINE_ID` environment variable to a stable value for the deployment. Use the same value across restarts for the same licensed deployment. For Helm deployments, set the environment variable from a Kubernetes Secret: ```yaml theme={null} extraEnvVars: - name: FLIPT_LICENSE_MACHINE_ID valueFrom: secretKeyRef: name: flipt-license key: machine-id ``` See [Licensing](/v2/configuration/licensing#machine-id-in-container-environments) for more details. ### Legacy Workaround: Mount the Host Machine ID If you cannot configure `FLIPT_LICENSE_MACHINE_ID`, you can mount the Kubernetes node's `/etc/machine-id` into the Flipt container by adding these values to your `values.yaml`: ```yaml theme={null} extraVolumeMounts: - name: machine-id mountPath: /etc/machine-id readOnly: true extraVolumes: - name: machine-id hostPath: path: /etc/machine-id ``` This mounts the host node's machine ID into the container, allowing the license system to identify the machine. This workaround depends on `hostPath` volumes and a node filesystem. It won't work in environments that don't allow `hostPath` (for example, many managed serverless node offerings such as EKS Fargate). Prefer `FLIPT_LICENSE_MACHINE_ID` when possible. ### Affected Environments * Google Kubernetes Engine (GKE) * Amazon EKS with containerd runtime * Any Kubernetes cluster using containerd instead of Docker * Rootless container environments ## Persistent Volume Configuration Flipt needs a writable directory for local state. If you see read-only filesystem errors or Flipt fails to start with write permission errors, you likely need to configure persistence. ### Enable Persistence Add the following to your `values.yaml`: ```yaml theme={null} persistence: enabled: true storageClass: "standard" # Use your cluster's storage class size: 10Gi ``` Run `kubectl get storageclass` to see available storage classes in your cluster. The default varies by provider and cluster configuration. ### Match the Storage Backend Path The `path` in your Flipt storage backend configuration refers to the path **inside the container**, not on the host. It must match where the PersistentVolumeClaim is mounted. The Helm chart mounts the PVC at `/var/opt/flipt` by default. Your storage backend configuration should use this path: ```yaml theme={null} flipt: config: storage: my-storage: backend: type: local path: /var/opt/flipt ``` Do not use a relative path like `"."` for the backend path. This writes to the container's working directory, which may be read-only. Always use the absolute path where the PVC is mounted. ## Secrets Management with GitOps When deploying Flipt via ArgoCD, FluxCD, or other GitOps tools, you should not commit sensitive values (license keys, Git access tokens) to your Git repository inside `values.yaml`. ### Using Kubernetes Secrets with Environment Variable Substitution Flipt supports [environment variable substitution](/v2/configuration/overview#environment-substitution-and-secret-references) in configuration values using the `${env:VAR_NAME}` syntax. Combined with the Helm chart's `envFrom` support, this lets you keep secrets out of your values file. **Step 1:** Create a Kubernetes Secret containing your sensitive values: ```bash theme={null} kubectl create secret generic flipt-secrets \ --from-literal=FLIPT_LICENSE_KEY=your-license-key \ --from-literal=FLIPT_GIT_ACCESS_TOKEN=your-access-token ``` Or use [External Secrets Operator](https://external-secrets.io/) to sync from your cloud provider's secret manager (GCP Secret Manager, AWS Secrets Manager, Azure Key Vault, HashiCorp Vault). **Step 2:** Reference the Secret in your `values.yaml`: ```yaml theme={null} envFrom: - secretRef: name: flipt-secrets ``` **Step 3:** Use environment variable references in your Flipt configuration: ```yaml theme={null} flipt: config: license: key: ${env:FLIPT_LICENSE_KEY} credentials: my-git: type: access_token access_token: ${env:FLIPT_GIT_ACCESS_TOKEN} storage: my-storage: remote: "https://github.com/your-org/flipt-config.git" branch: main credentials: "my-git" ``` This approach keeps your `values.yaml` free of secrets and safe to commit to Git. ### Compatible Secret Management Tools This pattern works with any tool that creates Kubernetes Secrets: * **[External Secrets Operator](https://external-secrets.io/)** — syncs secrets from GCP Secret Manager, AWS Secrets Manager, Azure Key Vault, HashiCorp Vault * **[Sealed Secrets](https://sealed-secrets.netlify.app/)** — encrypt secrets client-side, commit encrypted `SealedSecret` resources to Git * **[ArgoCD Vault Plugin](https://argocd-vault-plugin.readthedocs.io/)** — inject secrets from Vault at deploy time * **`kubectl create secret`** — create secrets manually for simpler setups ### Using Individual Environment Variables If you prefer to inject secrets as individual environment variables rather than from a Secret reference, use `extraEnvVars`: ```yaml theme={null} extraEnvVars: - name: FLIPT_LICENSE_KEY valueFrom: secretKeyRef: name: flipt-license key: license-key - name: FLIPT_GIT_ACCESS_TOKEN valueFrom: secretKeyRef: name: flipt-git-creds key: access-token ``` # Commit Signing Setup Source: https://docs.flipt.io/v2/guides/operations/environments/commit-signing-setup Step-by-step guide to configure GPG commit signing with GitHub and other Git providers This guide will show you how to set up GPG commit signing for Flipt v2 to provide cryptographic verification of your configuration changes. This functionality is only available in Flipt v2 Pro. [Learn more](/v2/licensing) about our commercial license or purchase a [monthly](https://getflipt.co/pro/monthly) or [annual](https://getflipt.co/pro/annual) license. ## Prerequisites * [Flipt v2](/v2/quickstart) * A Flipt v2 environment configured with [Git Sync](/v2/guides/operations/environments/git-sync) * [Secrets management](/v2/configuration/secrets) configured * A Flipt v2 Pro license or trial license This guide uses GitHub as an example, but the process is similar for GitLab, Gitea, and other Git providers. ## 1. Generate a GPG Key If you don't have a GPG key, create one specifically for Flipt: ```bash theme={null} # Generate a new GPG key gpg --full-generate-key # Select RSA and RSA (default) # Choose 4096 bits for maximum security # Set expiration (recommended: 2 years) # Enter details: # Real name: Flipt Bot # Email: flipt@yourcompany.com # Comment: Flipt configuration signing ``` ## 2. Export the Private Key Export your private key for storage in your secrets provider: ```bash theme={null} # Export private key (replace with your key ID) gpg --export-secret-keys --armor flipt@yourcompany.com > flipt-signing-key.asc # The key ID can be found with: gpg --list-secret-keys flipt@yourcompany.com ``` ## 3. Store Key in Secrets Provider Store the private key securely using your configured secrets provider: **Vault Example:** ```bash theme={null} vault kv put secret/flipt/signing-key private_key=@flipt-signing-key.asc ``` ## 4. Upload Public Key to GitHub 1. Export your public key: ```bash theme={null} # Export public key gpg --export --armor flipt@yourcompany.com > flipt-public-key.asc ``` 2. Go to [GitHub Settings > SSH and GPG keys](https://github.com/settings/keys) 3. Click **"New GPG key"** 4. Copy and paste the contents of `flipt-public-key.asc` 5. Click **"Add GPG key"** GitHub GPG Key Setup ## 5. Configure Flipt Add commit signing configuration to your Flipt configuration file: ```yaml theme={null} storage: default: signature: enabled: true type: "gpg" key_ref: provider: "vault" # Your secrets provider path: "flipt/signing-key" # Path to private key in secrets key: "private_key" # Key name within the secret name: "Flipt Bot" # Signer name email: "flipt@yourcompany.com" # Signer email key_id: "flipt@yourcompany.com" # GPG key identifier ``` ## 6. Deploy and Start Flipt Deploy your updated configuration and start or restart your Flipt server. Flipt will now automatically sign all commits to your flag configuration repository. ## 7. Verify Commit Signing After enabling signing, verify that new commits are being signed: ```bash theme={null} # Clone your flag repository git clone https://github.com/company/flags.git cd flags # Check recent commits for signatures git log --show-signature -5 # Look for GPG signature verification git verify-commit HEAD ``` ### GitHub Verification On GitHub, signed commits will display: * ✅ **Verified** badge next to the commit * GPG key information when clicking the badge * Signature details in the commit view ## Troubleshooting ### Commits Not Showing as Verified If commits aren't showing as verified: 1. **Check public key upload**: Ensure the public key is added to your Git hosting service 2. **Verify email match**: The email in the GPG key must match the configured email 3. **Confirm key validity**: Ensure the GPG key hasn't expired 4. **Check key ID**: Verify the key\_id matches your actual GPG key ### Common Issues **Signing Failures** ``` Error: failed to sign commit: gpg key not found ``` * Verify the key exists in your secrets provider * Check the key reference path and key name * Ensure the secrets provider is accessible **Key Loading Errors** ``` Error: failed to load GPG private key ``` * Verify secrets provider connectivity * Check authentication credentials for your secrets provider * Ensure the private key is in valid ASCII armored format **Permission Errors** ``` Error: insufficient permissions to access secret ``` * Verify Flipt has the necessary permissions in your secrets provider * Check authentication method configuration * Review access policies for the signing key secret ### Debug Configuration Enable debug logging to troubleshoot signing issues: ```yaml theme={null} log: level: "debug" ``` ### Validation Commands Test your GPG key setup: ```bash theme={null} # Check if GPG key can be loaded gpg --import /path/to/private-key.asc # Verify key information gpg --list-secret-keys your-email@company.com # Test signing echo "test" | gpg --armor --sign --default-key your-email@company.com ``` ## Conclusion This guide showed how to configure GPG commit signing for Flipt v2 with GitHub. Your flag configuration changes will now be cryptographically signed, providing enhanced security and audit capabilities. You can now use Flipt to manage your flags with verified commit signatures that prove the authenticity and integrity of your configuration changes. If you have any questions or feedback, please reach out to the Flipt team on [Discord](https://discord.gg/flipt) or [GitHub Discussions](https://github.com/flipt-io/flipt/discussions). *** **References:** * [Flipt v2 Commit Signing Configuration](/v2/configuration/commit-signing) * [Flipt v2 Secrets Configuration](/v2/configuration/secrets) * [Flipt v2 Git Sync](/v2/guides/operations/environments/git-sync) * [GitHub: Adding a GPG key to your GitHub account](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account) # Git Repository Initialization Source: https://docs.flipt.io/v2/guides/operations/environments/git-repository-initialization Learn how to initialize Git repositories for existing feature flag configurations in Flipt v2. This guide explains how to set up Git repository initialization for existing feature flag configurations in Flipt v2. This is particularly useful when you already have `features.yaml` or `features.yml` files but need to initialize version control for them. ## Overview Flipt v2 supports automatic Git repository detection and initialization for existing feature files when using the local storage backend. This addresses the common workflow where you have existing feature flag configurations but no Git repository initialized yet. This is only necessary if you want to pre-populate Flipt with existing feature data from your local machine. If you are starting fresh or have data synced to a remote repository then following this guide is not necessary. ## Supported File Formats Flipt v2 supports both YAML file extensions for feature configurations: * `features.yaml` (recommended) * `features.yml` Both formats work identically and you can use whichever extension you prefer. ## Basic Setup Workflow The typical workflow for initializing a Git repository with existing feature files is: ### 1. Organize Your Feature Files Create a directory structure with your existing features: ```bash theme={null} mkdir -p my-project/flags/production cp existing-features.yaml my-project/flags/production/features.yaml ``` ### 2. Initialize Git Repository Navigate to your flags directory and initialize Git: ```bash theme={null} cd my-project/flags git init -b main git add . git commit -m "Initial features" ``` ### 3. Configure Flipt Create a Flipt configuration that points to your flags directory: ```yaml theme={null} storage: local: name: "local" backend: type: local path: "flags" # Path to your flags directory branch: "main" environments: default: name: "Default" storage: "local" default: true ``` ### 4. Start Flipt Server Run Flipt pointing to your configuration: ```bash theme={null} cd .. # Back to my-project directory flipt server --config config.yml ``` ## Repository Detection Flipt v2 includes enhanced repository detection logic that can handle: 1. **Normal Git Repositories**: Standard repositories created with `git init` (with `.git` subdirectory) 2. **Bare Repositories**: Repositories managed internally by Flipt (Git files in root directory) 3. **Automatic Fallback**: Graceful handling when repository types are ambiguous The system automatically: * Detects the repository type * Creates necessary remote tracking references (`refs/remotes/origin/main`) * Sets up proper branch management for Flipt's operations ## Working Directory Synchronization When you make changes through the Flipt UI, the system automatically: * Updates the actual `.yaml` files on disk for normal repositories * Maintains backward compatibility with existing bare repository workflows * Synchronizes changes back to the filesystem This means changes made in the Flipt web interface will be reflected in your actual feature files, allowing you to see modifications through standard Git tools. ## Configuration Examples ### Basic Local Storage ```yaml theme={null} storage: backend: type: local path: "." # Current directory ``` ### Multiple Environments ```yaml theme={null} storage: staging: name: "Staging" backend: type: local path: "flags/staging" branch: "staging" production: name: "Production" backend: type: local path: "flags/production" branch: "main" environments: staging: name: "Staging" storage: "staging" production: name: "Production" storage: "production" default: true ``` ### With Remote Git Repository You can also combine local storage with remote Git synchronization: ```yaml theme={null} storage: local: remote: "https://github.com/your-org/feature-flags.git" branch: "main" poll_interval: "30s" credentials: "github" backend: type: local path: "flags" environments: default: name: "Default" storage: "local" default: true credentials: github: type: access_token access_token: "your-github-token" ``` ## Docker Usage When using Docker, you can initialize the repository in your container build process: ```dockerfile theme={null} FROM docker-registry.example.com/base:latest as builder COPY main/features /tmp/data RUN cd /tmp/data && \ git config --global init.defaultBranch main && \ git init && \ git config user.name "Flipt Container" && \ git config user.email "flipt@container.local" && \ git add . && \ git commit -m "Initial commit with feature flags" FROM docker.flipt.io/flipt/flipt:v2 COPY --from=builder --chown=flipt:flipt /tmp/data /data COPY --chown=flipt:flipt main/config.yml /config.yml USER flipt EXPOSE 8080 9000 CMD ["/flipt", "server", "--config", "/config.yml"] ``` ## Troubleshooting ### Repository Does Not Exist Error If you see this error, ensure that: 1. Your `path` configuration points to a valid directory 2. The directory contains your feature files 3. Git is properly initialized in the directory ### Features Not Loading Check that: 1. Your feature files use the correct naming: `features.yaml` or `features.yml` 2. The files are in the correct directory structure 3. The YAML syntax is valid 4. You added and committed the files at `path` ## Backward Compatibility This enhancement is fully backward compatible: * Existing bare repository workflows continue to work unchanged * All existing functionality is preserved * Safe fallbacks handle edge cases gracefully You can migrate existing setups without any breaking changes. # Git SCM Integration Source: https://docs.flipt.io/v2/guides/operations/environments/git-scm Configure Flipt v2 to allow deeper integration with your Git Provider Flipt v2 supports Source Control Management (SCM) for Git repositories. This functionality is only available in Flipt v2 Pro. [Learn more](/v2/licensing) about our commercial license or purchase a [monthly](https://getflipt.co/pro/monthly) or [annual](https://getflipt.co/pro/annual) license. ## Prerequisites * [Flipt v2](/v2/quickstart) * A Flipt v2 environment configured with [Git Sync](/v2/guides/operations/environments/git-sync) * A Flipt v2 Pro license or trial license Flipt v2 SCM integration supports most of the major Git providers including GitHub, GitLab, Bitbucket, Gitea, and Azure DevOps. ## 1. Configure SCM Integration This section will walk you through configuring Flipt v2 to more deeply integrate with your Git provider to enable features like [Merge Proposals](/v2/introduction#merge-proposals). ## GitHub Integration ### 1. Create a Personal Access Token (PAT) 1. Go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens). 2. Click **"Generate new token"** 3. Give your token a name 4. Select a resource owner (e.g. your organization) 5. Select the repositories you want to give access to (or Select all). These should be the same repositories that you have configured to [sync with Flipt](/v2/guides/operations/environments/git-sync). 6. Set an expiration date 7. Select the following repository scopes (**required**): * `contents` read and write access * `pull-requests` read and write access GitHub PAT Scopes 8. Click **"Generate token"** and copy the token. **You will not be able to see it again!** ### 2. Configure GitHub Credentials Edit your Flipt configuration file to use the GitHub credentials you created in the previous step: ```yaml theme={null} credentials: github: type: access_token access_token: ``` ### 3. Configure Flipt Storage with GitHub Remote Edit your Flipt configuration file to add or update the storage backend that syncs with your GitHub repository: ```yaml theme={null} storage: github: remote: "https://github.com//.git" branch: "main" poll_interval: "30s" credentials: "github" backend: type: local path: "/path/to/local/clone" ``` ### 4. Configure an Environment to use GitHub SCM Edit your Flipt configuration file to add or update the environment that uses the GitHub SCM storage backend and add the `scm` section: ```yaml highlight={6-8} theme={null} environments: production: name: "Production" storage: "github" default: true scm: type: github credentials: "github" ``` ## Bitbucket Integration ### 1. Create API Token or App Password **App passwords are being deprecated and will stop working in 2026.** We strongly recommend using API tokens instead. **Option A: API Token (Recommended for Bitbucket Cloud)** 1. Go to [Bitbucket Account Settings > API tokens](https://bitbucket.org/account/settings/api-tokens/) 2. Click **"Create API token"** 3. Give your token a name 4. Select the following scopes (**required**): * Repositories: Read, Write * Pull requests: Read, Write 5. Click **"Create"** and copy the generated token. **You will not be able to see it again!** **Option B: App Password (Legacy - Not recommended)** Only use app passwords if API tokens are not available. **App passwords will be deprecated on September 9, 2025 and will stop working on June 9, 2026.** 1. Go to [Bitbucket Account Settings > App passwords](https://bitbucket.org/account/settings/app-passwords/) 2. Click **"Create app password"** 3. Give your app password a name 4. Select the following permissions (**required**): * Repositories: Read, Write * Pull requests: Read, Write 5. Click **"Create"** and copy the generated password. **You will not be able to see it again!** **Option C: Access Token (For Bitbucket Server/Data Center)** 1. Go to your Bitbucket Server settings 2. Navigate to Personal access tokens 3. Create a new token with repository and pull request permissions ### 2. Configure Bitbucket Credentials Edit your Flipt configuration file to use the Bitbucket credentials: **Using API Token (Recommended):** ```yaml theme={null} credentials: bitbucket: type: access_token access_token: ``` **Using App Password (Legacy):** ```yaml theme={null} credentials: bitbucket: type: basic basic: username: password: ``` **Using Access Token (Bitbucket Server/Data Center):** ```yaml theme={null} credentials: bitbucket: type: access_token access_token: ``` ### 3. Configure Flipt Storage with Bitbucket Remote Edit your Flipt configuration file to add or update the storage backend that syncs with your Bitbucket repository: ```yaml theme={null} storage: bitbucket: remote: "https://bitbucket.org//.git" branch: "main" poll_interval: "30s" credentials: "bitbucket" backend: type: local path: "/path/to/local/clone" ``` ### 4. Configure an Environment to use Bitbucket SCM Edit your Flipt configuration file to add or update the environment that uses the Bitbucket SCM storage backend and add the `scm` section: ```yaml highlight={6-8} theme={null} environments: production: name: "Production" storage: "bitbucket" default: true scm: type: bitbucket credentials: "bitbucket" ``` **For Bitbucket Server (Custom Instance):** ```yaml highlight={6-9} theme={null} environments: production: name: "Production" storage: "bitbucket" default: true scm: type: bitbucket api_url: "https://bitbucket.company.com/api/v2.0" credentials: "bitbucket" ``` ## Azure DevOps Integration ### 1. Create a Personal Access Token (PAT) 1. Go to your Azure DevOps organization (e.g., `https://dev.azure.com/{your-organization}`) 2. Click on your profile picture in the top right corner 3. Select **"Personal access tokens"** 4. Click **"New Token"** 5. Give your token a name and set an expiration date 6. Select the organization and scope: * **Code (read & write)** - Required for repository access * **Pull Request (read & write)** - Required for merge proposals 7. Click **"Create"** and copy the token. **You will not be able to see it again!** ### 2. Configure Azure DevOps Credentials Edit your Flipt configuration file to use the Azure DevOps credentials: ```yaml theme={null} credentials: azure: type: basic basic: username: password: ``` ### 3. Configure Flipt Storage with Azure DevOps Remote Edit your Flipt configuration file to add or update the storage backend that syncs with your Azure DevOps repository: ```yaml theme={null} storage: azure: remote: "https://dev.azure.com///_git/" branch: "main" poll_interval: "30s" credentials: "azure" backend: type: local path: "/path/to/local/clone" ``` ### 4. Configure an Environment to use Azure DevOps SCM Edit your Flipt configuration file to add or update the environment that uses the Azure DevOps SCM storage backend: ```yaml highlight={6-8} theme={null} environments: production: name: "Production" storage: "azure" default: true scm: type: azure credentials: "azure" ``` **For Azure DevOps Server (On-premises):** ```yaml highlight={6-9} theme={null} environments: production: name: "Production" storage: "azure" default: true scm: type: azure api_url: "https://your-server/tfs/{collection}/_apis" credentials: "azure" ``` ## GitLab Integration ### 1. Create a Personal Access Token (PAT) 1. Go to [GitLab Settings > Access Tokens](https://gitlab.com/-/user_settings/personal_access_tokens) (or your GitLab instance) 2. Click **"Add new token"** 3. Give your token a name 4. Set an expiration date (optional but recommended) 5. Select the following scopes (**required**): * `api` - Full access to the API * `read_repository` - Read access to repositories * `write_repository` - Write access to repositories 6. Click **"Create personal access token"** and copy the token. **You will not be able to see it again!** ### 2. Configure GitLab Credentials Edit your Flipt configuration file to use the GitLab credentials: ```yaml theme={null} credentials: gitlab: type: access_token access_token: ``` ### 3. Configure Flipt Storage with GitLab Remote Edit your Flipt configuration file to add or update the storage backend that syncs with your GitLab repository: ```yaml theme={null} storage: gitlab: remote: "https://gitlab.com//.git" branch: "main" poll_interval: "30s" credentials: "gitlab" backend: type: local path: "/path/to/local/clone" ``` ### 4. Configure an Environment to use GitLab SCM Edit your Flipt configuration file to add or update the environment that uses the GitLab SCM storage backend: ```yaml highlight={6-8} theme={null} environments: production: name: "Production" storage: "gitlab" default: true scm: type: gitlab credentials: "gitlab" ``` **For GitLab Self-Managed (Self-hosted):** ```yaml highlight={6-9} theme={null} environments: production: name: "Production" storage: "gitlab" default: true scm: type: gitlab api_url: "https://gitlab.company.com/api/v4" credentials: "gitlab" ``` ## 2. Start Flipt Start or restart your Flipt server with the updated configuration. Flipt will now: * Clone your Git repository to the specified local path * Periodically sync flag state to and from your Git provider * Commit and push changes when you update flags via the Flipt API or UI * Enable merge proposals in the Flipt UI Merge Proposals ## 3. Troubleshooting ### Common Issues * **Authentication**: Ensure your credentials (PAT, API token, or app password) have the correct permissions and haven't expired * **Permissions**: Make sure the local path is writable by the Flipt process * **Logs**: Check Flipt logs for any sync or authentication errors * **Network**: For self-hosted instances, verify the API URL is correct and accessible ### Provider-Specific Troubleshooting **GitHub:** * Ensure your PAT has the correct repository scopes (`contents` and `pull-requests`) * Verify the repository URL format: `https://github.com/{owner}/{repo}.git` **Bitbucket:** * For API tokens: Ensure you have `Repositories: Read, Write` and `Pull requests: Read, Write` scopes * For app passwords: Note that they will be deprecated in September 2025 * For Bitbucket Server/Data Center: Verify the API URL format (typically `/api/v2.0`) **Azure DevOps:** * Ensure your PAT has `Code (read & write)` and `Pull Request (read & write)` scopes * Verify the repository URL format: `https://dev.azure.com/{org}/{project}/_git/{repo}` * For Azure DevOps Server: Verify the API URL format: `https://your-server/tfs/{collection}/_apis` **GitLab:** * Ensure your PAT has the correct scopes: `api`, `read_repository`, `write_repository` * For GitLab Self-Managed: Verify the API URL is correct (typically `/api/v4`) * Verify the repository URL format: `https://gitlab.com/{owner}/{repo}.git` ## Authentication Formats by Provider Different Git providers require different authentication formats for optimal compatibility: | Provider | Recommended Auth Method | Basic Auth Format | Notes | | ---------------- | ----------------------- | --------------------------------------- | ---------------------------------- | | **GitHub** | Personal Access Token | Username: token, Password: (empty) | | | **GitLab** | Personal Access Token | Username: oauth2, Password: token | | | **Bitbucket** | API Token | Username: (not used), Token: api\_token | App passwords deprecated Sept 2025 | | **Azure DevOps** | Personal Access Token | Username: username, Password: PAT | | | **Gitea** | Personal Access Token | Username: token, Password: (empty) | | ## Conclusion This guide showed how to configure Flipt to enable merge proposals in the Flipt UI. You can now use Flipt to manage your flags and use merge proposals to review and approve changes to your flags. If you have any questions or feedback, please reach out to the Flipt team on [Discord](https://discord.gg/flipt) or [GitHub Discussions](https://github.com/flipt-io/flipt/discussions). *** **References:** * [Flipt v2 Environments Configuration](/v2/configuration/environments) * [Flipt v2 Git Sync](/v2/guides/operations/environments/git-sync) * [Flipt v2 Merge Proposals](/v2/introduction#merge-proposals) * [GitHub: Creating a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) # Git Sync with GitHub Source: https://docs.flipt.io/v2/guides/operations/environments/git-sync Configure Flipt to sync your data to a GitHub repository This guide will show you how to configure Flipt to sync your data to a Git repository. ## Prerequisites * [Flipt v2](/v2/quickstart) * A GitHub Account and a repository to sync to Flipt v2 supports any Git provider including Gitea, GitLab, Bitbucket, Azure DevOps, and is not limited to GitHub. ## Using GitHub for Git Sync This section will walk you through configuring Flipt to sync your flag state to a GitHub repository using a Personal Access Token (PAT) for authentication. ### 1. Create a GitHub Personal Access Token (PAT) 1. Go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens). 2. Click **"Generate new token"** 3. Give your token a name 4. Select a resource owner (e.g. your organization) 5. Select the repositories you want to give access to (or Select all) 6. Set an expiration date 7. Select the following repository scopes (**required**): * `repo` read and write access (for private repositories) * `contents` read and write access 8. Click **"Generate token"** and copy the token. **You will not be able to see it again!** GitHub PAT ### 2. Add GitHub Credentials Add your GitHub PAT as a credential in the Flipt configuration file: ```yaml theme={null} credentials: github: type: access_token access_token: ``` * Replace `` with the token you generated above. Flipt can use [environment substitution](/v2/configuration/overview#environment-substitution) for credentials. ```yaml theme={null} credentials: github: type: access_token access_token: ${env:GITHUB_TOKEN} ``` ### 3. Configure Flipt Storage with GitHub Remote Edit your Flipt configuration file to add a storage backend that syncs with your GitHub repository: ```yaml theme={null} storage: github: remote: "https://github.com//.git" branch: "main" poll_interval: "30s" credentials: "github" backend: type: local path: "/path/to/local/clone" ``` * Replace `` and `` with your GitHub username and repository name. * Adjust `path` to where you want Flipt to store the local clone of your repo. Setting the `backend` to `local` is optional as you can store the state in memory which is the default behavior. ### 4. Configure Environments If you want to use multiple environments (e.g., staging, production), reference your storage backend in the environments section and specify a directory for each environment: ```yaml theme={null} environments: production: name: "Production" storage: "github" default: true directory: "production" staging: name: "Staging" storage: "github" directory: "staging" ``` This mapping between environments and storage backends means that multiple environments can share the same storage backend (e.g. a single GitHub repository). Each environment that shares the same storage backend must have a unique directory to avoid conflicts. ### 5. Start Flipt Start or restart your Flipt server with the updated configuration. Flipt will now: * Clone your GitHub repository to the specified local path * Periodically sync flag state to and from GitHub * Commit and push changes when you update flags via the Flipt API or UI ### 6. Troubleshooting * Ensure your PAT has the correct permissions. * Make sure the local path is writable by the Flipt process. * Check Flipt logs for any sync or authentication errors. ## Conclusion This guide showed how to configure Flipt to sync your flag state to a GitHub repository using a Personal Access Token (PAT) for authentication. You can now use GitHub to sync your flag state to a GitHub repository and start using Flipt to manage your flags. If you have any questions or feedback, please reach out to the Flipt team on [Discord](https://discord.gg/flipt) or [GitHub Discussions](https://github.com/flipt-io/flipt/discussions). *** **References:** * [Flipt v2 Storage Configuration](/v2/configuration/storage) * [Flipt v2 Environments Configuration](/v2/configuration/environments) * [GitHub: Creating a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) # Production Readiness Source: https://docs.flipt.io/v2/guides/operations/production Key configuration options for operating Flipt v2 in production Flipt v2's default configuration is designed for local development and quick start. To run Flipt v2 reliably in production, you should review and adjust the following configuration options. ## Logging Debug logging is useful during development or troubleshooting, but under load it consumes CPU and produces excessive noise that can bury important signals. Set the log level to `info` in production: ```bash theme={null} FLIPT_LOG_LEVEL=info ``` ```yaml theme={null} log: level: info ``` For structured log output suitable for log aggregation systems, you can also set the encoding to `json`: ```bash theme={null} FLIPT_LOG_ENCODING=json ``` ```yaml theme={null} log: encoding: json ``` See the [Observability documentation](/v2/configuration/observability) for more logging configuration options. ## Profiling Endpoints Flipt exposes [pprof](https://pkg.go.dev/net/http/pprof) profiling endpoints at `/debug/pprof`. These are invaluable for debugging performance issues but can expose sensitive runtime information if publicly accessible. Disable profiling in production unless you actively need it: ```bash theme={null} FLIPT_DIAGNOSTICS_PROFILING_ENABLED=false ``` ```yaml theme={null} diagnostics: profiling: enabled: false ``` If you need profiling in production, restrict access to internal networks only. ## Update Checks By default, Flipt v2 checks for newer versions on startup. This can be disabled in air-gapped or security-sensitive environments: ```bash theme={null} FLIPT_META_CHECK_FOR_UPDATES=false ``` ```yaml theme={null} meta: check_for_updates: false ``` ## Prometheus Metrics Flipt v2 exposes Prometheus metrics at the `/metrics` HTTP endpoint by default. Ensure this endpoint is not publicly accessible - restrict it via network policies, reverse proxy rules, or your ingress configuration. If you do not require metrics, you can disable them: ```bash theme={null} FLIPT_METRICS_ENABLED=false ``` ```yaml theme={null} metrics: enabled: false ``` For production, Flipt also supports exporting metrics to an [OTLP](https://opentelemetry.io/docs/concepts/data-collection/) collector for integration with observability platforms such as Datadog, Honeycomb, or New Relic. See the [Observability documentation](/v2/configuration/observability) for more details. ## CORS Configuration If you are integrating Flipt v2 with a client-side application (for example, a browser-based frontend built with React, Vue, Angular, or similar frameworks), you must enable and properly configure CORS to allow requests from your frontend domain. For security reasons, restrict `allowed_origins` to your known frontend URLs instead of using the wildcard `*`. ```bash theme={null} FLIPT_CORS_ENABLED=true FLIPT_CORS_ALLOWED_ORIGINS=https://app.example.com ``` ```yaml theme={null} cors: enabled: true allowed_origins: - "https://app.example.com" ``` ## Storage Configuration Flipt v2 supports two storage backend types: * **`memory`** (default): In-memory store. Data is lost on restart. * **`local`**: Persists data to the local filesystem. Data survives restarts. Both backends can be paired with a git remote to sync flag state to and from a remote Git repository for persistence, history, and collaboration across deployments. For production, use the `local` backend with a git remote: ```yaml theme={null} storage: default: backend: type: local path: /var/lib/flipt remote: https://github.com/your-org/flags.git branch: main ``` For private repositories, you'll also need to configure credentials. See the [Storage documentation](/v2/configuration/storage) and [Git Sync guide](/v2/guides/operations/environments/git-sync) for more details. ## Authentication and Authorization In production, you should enable authentication to control access to Flipt v2: ```bash theme={null} FLIPT_AUTHENTICATION_REQUIRED=true ``` ```yaml theme={null} authentication: required: true ``` Flipt v2 supports multiple authentication methods including GitHub OAuth and OIDC. See the [Authentication documentation](/v2/configuration/authentication) for configuration details. For fine-grained access control, [configure RBAC policies using OPA-based authorization](/v2/configuration/authorization) to restrict what authenticated users can do. ## Backup Strategy Flipt v2's Git-native storage means your feature flag data is already version-controlled in a Git repository. Ensure your backup strategy covers: * **Git repository**: The source Git repository should be backed up by your Git provider (e.g. GitHub, GitLab). Consider mirroring to a secondary repository for additional redundancy. * **Analytics data**: If using ClickHouse, ensure that data is backed up according to your organizational policies. ## Next Steps * [Deploy to Kubernetes](/v2/guides/operations/deployment/deploy-to-kubernetes) — Deploy with our official Helm chart * [Git Sync](/v2/guides/operations/environments/git-sync) — Configure Git-backed storage * [Observability](/v2/configuration/observability) — Metrics, logging, and tracing * [Authentication](/v2/configuration/authentication) — Secure your Flipt instance * [Authorization](/v2/configuration/authorization) — Configure RBAC policies for fine-grained access control # Branching Source: https://docs.flipt.io/v2/guides/user/environments/branches How to use branches for environments in Flipt v2 This guide will show you how to configure Flipt v2 to use branches for environments. ## Prerequisites * [Flipt v2](/v2/quickstart) * A GitHub Account and a repository to sync to (Optional). ## Using Branches for Environments Flipt v2 allows you to branch existing environments. This is useful if you want to test changes to your feature flags and configurations in a separate branch without affecting your users in production. ### Branch Storage By default, environments and their branches are stored in memory. This means that if you restart Flipt, the data will be lost. You can configure Flipt to store your environments and branches in a Git repository on your local machine. See the [Storage](/v2/configuration/storage) documentation for more information. You can also configure Flipt to sync your environments and branches to a remote Git repository. This is useful if you want to share your environments and branches with your team or if you want to backup your data. See the [Git Sync](/v2/guides/operations/environments/git-sync) guide for more information. ### Creating a Branch To create a branch simply click the branch button in the top right of the Flipt UI. You cannot branch from a branched environment. You can only branch from 'source' environments that are configured in your Flipt configuration file. Branch Button This will bring up a modal to allow you to enter the branch name. Branch Modal Branch names must be unique within the source environment. They also cannot be the same as the source environment. Once you have entered the branch name, click the `Create` button. This will create a new branch with the same data as the source environment and update the UI to show the new branch. Branch Created As you can see, the new branch has the same data as the source environment however it is completely isolated from the source environment. Any changes you make to the branch will not affect the source environment and vice versa. ### Navigating With Branches You can navigate between environments and branched environments by clicking the environment selector in the top left of the Flipt UI. Environment Selector Branched environments are displayed as children of the source environment with a branch icon. Clicking on a branched environment will switch to that environment. You can also select the namespace after selecting the environment. See the concepts behind [Environments](/v2/concepts#environments) and [Namespaces](/v2/concepts#namespaces) for more information. ### Deleting a Branch In a branched environment, you can see the source environment that the branch is based on in the top right of the Flipt UI. Branch Info Clicking the branch info will bring up a menu to allow you to delete the branch. Delete Branch Modal Type the branch name to confirm the deletion and click the `Delete Branch` button to delete the branch. This will delete the branch and update the UI to show the source environment. Deleting a branch will not delete the data from the source environment. ## Evaluation With Branches Since branches are just environments themselves, you can evaluate within them just like you would evaluate any other environment using our UI, API or SDKs. Review the [Evaluation](/v2/concepts#evaluation) documentation for more information on how evaluation works. ### In the UI You can evaluate a flag in a branch by selecting the branch in the environment selector and then selecting the flag you want to evaluate. Next click the `View in Playground` button to open the playground for that flag in the branched environment. Playground You can then evaluate the flag by entering an entity ID and context values. Playground Evaluation ### Using the API/SDKs All of our SDKs support evaluating within environments and branches. See the [SDKs](/v2/integration/overview) documentation for more information. In this example we'll use the Go [Client Side SDK](/v2/integration/client) to evaluate a flag in a branch. Imagine that you have a branch called `test` and you want to evaluate a flag called `test-flag` in that branch. You can do the following: ```go theme={null} client, err := flipt.NewClient( ctx, flipt.WithURL("http://localhost:8080"), flipt.WithEnvironment("test"), ) if err != nil { log.Fatal(err) } defer client.Close(ctx) variantResult, _ := client.EvaluateVariant(ctx, &flipt.EvaluationRequest{ FlagKey: "test-flag", EntityID: "someentity", Context: map[string]string{"fizz": "buzz"}, }) fmt.Println(variantResult) ``` ## Using GitHub for Git Sync If you've configured Flipt to use a GitHub repository for Git Sync, your branches will also be synced to your GitHub repository. See the [Git Sync](/v2/guides/operations/environments/git-sync) guide for more information on how to configure Flipt to use a GitHub repository for Git Sync. Flipt v2 supports any Git provider including Gitea, GitLab, Bitbucket, Azure DevOps, and is not limited to GitHub. Any changes you make to a branch will be synced to your GitHub repository. If you have Git Sync enabled, you'll see a `View Remote` option in the branch info menu. View Remote Clicking this will open the branch in your GitHub repository that is configured in your Flipt configuration file. GitHub Branch # Using Merge Proposals Source: https://docs.flipt.io/v2/guides/user/environments/merge-proposals How to use merge proposals in Flipt v2 This guide will show you how to use merge proposals in Flipt v2. This functionality is only available in Flipt v2 Pro. [Learn more](/v2/licensing) about our commercial license or purchase a [monthly](https://getflipt.co/pro/monthly) or [annual](https://getflipt.co/pro/annual) license. ## Prerequisites * [Flipt v2](/v2/quickstart) * An understanding of [Flipt v2 Branching](/v2/guides/user/environments/branches) * A Flipt v2 environment configured with [Git Sync](/v2/guides/operations/environments/git-sync) and [Git SCM](/v2/guides/operations/environments/git-scm) * A Flipt v2 Pro license or trial license Flipt v2 merge proposals are supported by most of the major Git providers including GitHub, GitLab, Bitbucket, Gitea, and Azure DevOps. ## Using Merge Proposals Flipt v2 allows you to create merge proposals for your environments. This is useful if you want to review and approve changes to your environments before they are merged into the source environment. ### Creating a Merge Proposal To create a merge proposal you must first create a branch. See the [Branching](/v2/guides/user/environments/branches) guide for more information on how to create a branch. Once you have created a branch and made changes to your environment, you can create a merge proposal by clicking the branch info label in the top right of the Flipt UI. Branch Info This will bring up a menu allowing you to view the remote branch, propose changes, or delete the branch. Click the `Propose changes` button to create a merge proposal. Propose Changes This will bring up a modal allowing you to review the changes you are proposing, add an optional description and optionally open the merge proposal in 'draft' mode for those SCM providers that support it. If you don't provide a description one will be generated for you based on the changes you are proposing. Click the `Submit proposal` button to create a merge proposal. You should see a success message and the merge proposal will be created. Refresh the page and click the branch info label again to see the merge proposal in the menu. Merge Proposal Click the `View open merge proposal` button to view the merge proposal in the SCM provider. ### Customizing Generated Titles and Descriptions Flipt generates merge proposal titles and descriptions from Go [`text/template`](https://pkg.go.dev/text/template) templates. You can configure server-wide defaults in your Flipt configuration: ```yaml config.yaml theme={null} templates: proposal_title: "Flipt: Update {{.Base.Ref}} from {{.Branch.Ref}}" proposal_body: | This proposal updates Flipt resources. Source branch: {{.Branch.Ref}} Target branch: {{.Base.Ref}} ``` The template context includes: | Field | Description | | ------------------- | -------------------------------------------- | | `.Base` | The target environment configuration | | `.Branch` | The source branch environment configuration | | `.Base.Ref` | The target Git reference, such as `main` | | `.Branch.Ref` | The source Git reference for the branch | | `.Base.Directory` | The target directory, when one is configured | | `.Branch.Directory` | The branch directory, when one is configured | Repository-level templates in `flipt.yaml` or `flipt.yml` override the server-wide templates for that repository: ```yaml flipt.yaml theme={null} version: "2.0" templates: proposal_title: "Flags: {{.Branch.Ref}} into {{.Base.Ref}}" proposal_body: | Review changes from {{.Branch.Ref}} before merging into {{.Base.Ref}}. ``` These templates configure the generated defaults. If a merge proposal request provides a title or description, Flipt uses the provided value instead of the template. The Flipt UI can provide a one-off description, but it does not yet let you edit the configured template text or override the generated title directly. ### Review and Merge a Merge Proposal Reviewing and merging a merge proposal is the same as reviewing and merging a code pull request in your SCM provider. Once the merge proposal is approved, you can merge it into the source environment by clicking the `Merge` button or similar button in your SCM provider. Merge Proposal After the merge proposal is merged on the SCM provider, the changes will be synced to the source environment. Refresh the Flipt v2 UI and you should see the changes in the source environment. You will need to wait until the merge proposal is synced by the Flipt v2 server you can see the changes. This is entirely dependent on the `poll_interval` configured in your Flipt configuration file for your Git environment storage. Source Environment ### Close a Merge Proposal Closing a merge proposal before merging follows the same process as closing a code pull request in your SCM provider. To close a merge proposal, click the `Close` button or similar button in your SCM provider. After the merge proposal is closed on the SCM provider, the changes will be reflected in the Flipt v2 UI. If you also delete the branch on the SCM provider the branch will **not** be deleted from the Flipt v2 server. This is because the branch still exists in your configured git environment storage. # Installation Source: https://docs.flipt.io/v2/installation Multiple ways to install and run Flipt v2 on your own infrastructure Flipt v2 is a single binary that can be run on any Linux or macOS host. You can install and try out Flipt v2 in a few different ways: ```console Docker theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:v2 ``` ```console Binary theme={null} curl -fsSL https://get.flipt.io/v2 | sh ``` ```console Kubernetes/Helm theme={null} helm repo add flipt https://helm.flipt.io helm install my-flipt-v2 flipt/flipt-v2 ``` ```console Homebrew theme={null} brew install flipt-io/brew/flipt@2 ``` For more details on each installation method, see the sections below. * [Docker](#docker) * [Binary](#binary) * [Kubernetes/Helm](#kubernetes%2Fhelm) * [Homebrew](#homebrew) ## Supported Architectures Flipt v2 is built for the following architectures/os: * **x86-64** / **Linux** * **ARM64** / **Linux** * **x86-64** / **Darwin/MacOS** * **ARM64** / **Darwin/MacOS** You can find the binaries for each architecture in the [Latest Release](https://github.com/flipt-io/flipt/releases/latest) assets section on GitHub. The [Docker image](https://hub.docker.com/r/flipt/flipt/tags) for Flipt v2 is multi-arch and supports both **x86-64** and **ARM64** architectures on **Linux**. If you need a different architecture, please open an issue on the [GitHub repository](https://github.com/flipt-io/flipt/issues) and we will try to accommodate your request. ## Docker Docker installation is required on the host, see the [official installation docs](https://docs.docker.com/install/). Flipt requires Docker Engine version [20.10](https://docs.docker.com/engine/release-notes/20.10/) or higher. ### Running ```console theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:v2 ``` This will download the image and start a Flipt container and publish ports needed to access the UI and backend server. All persistent Flipt data will be stored in `$HOME/flipt`. `$HOME/flipt` is just used as an example, you can use any directory you would like on the host. The Flipt container uses host-mounted volumes to persist data: | Host location | Container location | Purpose | | ------------- | ------------------ | ---------------------------- | | \$HOME/flipt | /var/opt/flipt | For storing application data | This allows data to persist between Docker container restarts. If you don't use mounted volumes to persist your data, your data will be lost when the container exits! After starting the container you can visit [http://127.0.0.1:8080](http://127.0.0.1:8080) to view the application. Flipt runs without the root user in the Docker container. ### Configuration A default configuration file is included within the image. To supply a custom configuration, update the `docker run` command to mount your local configuration into the container. The example below shows how to configure Flipt v2 with both persistent storage and a custom configuration file: ```console theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ -v $HOME/flipt/config.yaml:/etc/flipt/config/default.yml \ docker.flipt.io/flipt/flipt:v2 ``` In this configuration: * `$HOME/flipt:/var/opt/flipt` mounts the host directory for persistent data storage * `$HOME/flipt/config.yaml:/etc/flipt/config/default.yml` mounts your custom configuration file Your `config.yaml` should specify the full path for storage: ```yaml theme={null} storage: default: backend: type: local path: /var/opt/flipt ``` ## Homebrew You can install Flipt v2 using [Homebrew](https://brew.sh/) on macOS and Linux. If you have Flipt v1 installed via Homebrew, you'll need to unlink it first: `brew unlink flipt` ### Installing ```console theme={null} brew install flipt-io/brew/flipt@2 ``` ### Running Once installed, you can run Flipt v2 with: ```console theme={null} flipt server [--config OPTIONAL_PATH_TO_YOUR_CONFIG] ``` ## Binary You can always download the latest release archive of Flipt v2 from the [Releases](https://github.com/flipt-io/flipt/releases) section on GitHub. ### Installing You can use the following script to download and install the latest Flipt binary: ```console theme={null} curl -fsSL https://get.flipt.io/v2 | sh ``` This will install Flipt to `/usr/local/bin/flipt` on Mac and Linux systems. View the [install.sh](https://github.com/flipt-io/flipt/blob/v2/install.sh) source for more details. ### Running Run the Flipt server with: ```console theme={null} flipt server [--config OPTIONAL_PATH_TO_YOUR_CONFIG] ``` Flipt will check in a few different locations for server configuration (in order): 1. `--config` flag as an override 2. `{{ USER_CONFIG_DIR }}/flipt/config.yml` (the `USER_CONFIG_DIR` value is based on your architecture and specified in the [Go documentation](https://pkg.go.dev/os#UserConfigDir)) 3. `/etc/flipt/config/default.yml` See the [Configuration](/v2/configuration/overview) section for more details. ## Kubernetes/Helm Deploy Flipt v2 to Kubernetes using the official Helm chart. This method is ideal for production deployments and provides easy configuration management. ### Prerequisites * Kubernetes cluster (local or remote) * Helm v3.x installed * `kubectl` configured to access your cluster ### Installing Add the Flipt Helm repository and install Flipt v2: ```console theme={null} # Add the Flipt Helm repository helm repo add flipt https://helm.flipt.io helm repo update # Install Flipt v2 helm install my-flipt-v2 flipt/flipt-v2 # Or with custom configuration helm install my-flipt-v2 flipt/flipt-v2 -f values.yaml ``` The chart name is `flipt-v2`, which is separate from the v1 `flipt` chart. This ensures v2-specific configurations and compatibility. ### Key Features Flipt v2's Helm chart includes: * **Git-native storage**: Works out-of-the-box without external databases * **Environment support**: Deploy multiple environments from different Git branches * **Flexible configuration**: Support for all v2 configuration options * **Production ready**: Includes security, observability, and scaling options ### Configuration Create a `values.yaml` file to customize your deployment: ```yaml theme={null} flipt: config: log: level: INFO encoding: json server: grpc_port: 9000 http_port: 8080 cors: enabled: true allowed_origins: - "http://localhost:3000" - "https://your-frontend-domain.com" ui: default_theme: dark topbar: color: "#7C3AED" meta: check_for_updates: false telemetry_enabled: false metrics: enabled: true exporter: prometheus storage: default: backend: type: memory ``` This example showcases common v2 configuration options including CORS, UI customization, and observability settings. For production use with Git-backed storage, see the [Git Storage guide](/v2/guides/operations/environments/git-sync). For comprehensive deployment instructions and configuration examples, see the [Deploy Flipt v2 to Kubernetes](/v2/guides/operations/deployment/deploy-to-kubernetes) guide. If you run into issues, check the [Kubernetes Troubleshooting](/v2/guides/operations/deployment/kubernetes-troubleshooting) guide. # Client-Side SDKs Source: https://docs.flipt.io/v2/integration/client An overview of the client-side SDKs available for integrating with Flipt. Not sure which SDK to use? Check out our [Integration Overview](/v2/integration/overview) documentation. ## Overview Flipt provides a number of client-side SDKs to help you integrate with Flipt in your application. The SDKs are available in a number of languages: These SDKs are the same ones that are available for the [Flipt v1 Client API](/v2/integration/client) and are backward and forward compatible which means there is no need to rewrite your existing code to integrate with Flipt v2. ## Authentication Client-side SDKs connect to your Flipt server, which handles authentication. Your application needs a valid client token to communicate with Flipt. For detailed instructions on setting up authentication, see the [Connecting Applications to Flipt](/v2/guides/operations/authentication/connecting-applications) guide. In brief: create a static token in your Flipt configuration, then pass it to your SDK initialization. Evaluate flags client-side in your Node.js or browser-based applications Evaluate flags client-side in your React applications Evaluate flags client-side in your Python applications Evaluate flags client-side in your Go applications Evaluate flags client-side in your Java applications Evaluate flags client-side in your Ruby applications Evaluate flags client-side in your Dart/Flutter applications Evaluate flags client-side in your C# applications Evaluate flags client-side in your Swift applications Evaluate flags client-side in your Android applications > Need a client in another language? Let us know! ## Polling vs Streaming By default, the SDKs will use a polling mechanism to sync the state of the flags with the Flipt server. You can set the polling interval using the `updateInterval` option in the SDK's configuration. Unlike v1, **Flipt v2 supports streaming mode**, which allows our SDKs to subscribe to changes on the Flipt server and update the state of the flags accordingly in real-time. To change to streaming mode, you can set the `mode` option in the SDK's configuration to `streaming`. # OpenFeature Source: https://docs.flipt.io/v2/integration/openfeature An overview of OpenFeature and Flipt OpenFeature integrations. [OpenFeature](https://openfeature.dev/) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool. OpenFeature allows you to use the same feature flagging API across multiple feature flag management tools. This means that you can switch between feature flag management tools without having to change your code. OpenFeature is a CNCF Sandbox project. You can learn more about OpenFeature on the [OpenFeature website](https://openfeature.dev/). ## Providers As a feature flag management tool, Flipt provides our own OpenFeature integrations (providers). This means that you can use the OpenFeature API with Flipt v2. From the [OpenFeature Specification](https://docs.openfeature.dev/docs/specification/sections/providers): > Providers are the "translator" between the flag evaluation calls made in application code, and the flag management system that stores flags and in some cases evaluates flags. We currently provide the following OpenFeature providers: While Flipt v2 is backward compatible with Flipt v1, the OpenFeature providers have not yet been updated to support the new `environments` concept in Flipt v2. We are currently working on updating the OpenFeature providers to support environments. The official Flipt OpenFeature Provider using the OpenFeature Node SDK. The official Flipt OpenFeature Provider using the OpenFeature Web SDK. The official Flipt OpenFeature Provider using the OpenFeature Go SDK. The official Flipt OpenFeature Provider using the OpenFeature Java SDK. The official Flipt OpenFeature Provider using the OpenFeature C# SDK. The official Flipt OpenFeature Provider using the OpenFeature Python SDK. The official Flipt OpenFeature Provider using the OpenFeature Ruby SDK. > Need a client in another language? Let us know! ## Remote Evaluation Protocol The OpenFeature Remote Evaluation Protocol (OFREP) is an API specification for feature flagging that allows the use of generic providers to connect to any feature flag management systems that support the protocol. Flipt is one of the early adopters of the OFREP protocol and has implemented the protocol in its API. The OFREP protocol is still in the early stages of development, so the specification is subject to change. The API documentation for the OFREP protocol implementation in Flipt is available in the [OpenFeature Remote Evaluation](/v1/reference/openfeature/overview) API documentation. For more information on the OFREP protocol, see the [OpenFeature Remote Evaluation Protocol](https://github.com/open-feature/protocol) repository on GitHub. # Overview Source: https://docs.flipt.io/v2/integration/overview This document describes how to integrate Flipt v2 with your existing applications. To learn how to install and run Flipt, see the [Getting Started](/v2/quickstart) documentation. Once you have the Flipt v2 server up and running within your infrastructure or local development environment, the next step is to integrate the Flipt client(s) with your applications for evaluating your feature flags. There are two main ways to evaluate feature flags with Flipt: 1. [Server-Side Evaluation](#server-side-evaluation) 2. [Client-Side Evaluation](#client-side-evaluation) These SDKs are the same ones that are available for the Flipt v1 and are backward and forward compatible which means there is no need to rewrite your existing code to integrate with Flipt v2. ## Server-Side Evaluation Server-side evaluation is the most common way to evaluate feature flags. This is where your application makes a request to Flipt to evaluate a feature flag and Flipt responds with the result of the evaluation. Flipt exposes two different APIs for performing server-side evaluation: 1. [REST API](#rest-api) 2. [GRPC API](#grpc-api) The choice of which API to use is up to you. Both APIs are fully supported and are functionally equivalent. The REST API is easier to get started with, but the GRPC API is more performant. ### REST API Flipt v2 comes equipped with a fully functional REST API. The Flipt UI is completely backed by this same API. This means that anything that can be done in the Flipt UI can also be done via the REST API. The Flipt REST API can also be used with any language that can make HTTP requests. This means you don't need to use one of our official clients to integrate your application with Flipt. See all official REST SDKs in the [REST SDK](/v2/integration/server/rest) section. ### GRPC API Since Flipt v2 is a [GRPC](https://grpc.io/) enabled application, you can connect to it using the GRPC protocol. This means that you can use any language that has a GRPC client implementation to integrate with Flipt. We are working on instructions for how to generate GRPC clients for Flipt v2. ## Client-Side Evaluation Client-side evaluation is another way Flipt supports evaluating feature flags. This is where your application has a local copy of the feature flag rules and evaluates them locally. Client-side evaluation is much more performant than server-side evaluation, but it comes with some tradeoffs. The main tradeoff is that you need to keep your feature flag rules in sync with Flipt. This means that you will need to periodically fetch the feature flag rules from Flipt and update your local copy. Our client-side SDKs provide a way to do this automatically. Flipt v2 supports streaming mode, which will make the SDK subscribe to changes on the Flipt server and update the state of the flags accordingly in real-time. Reasons for using client-side evaluation include: * You want to reduce the number of requests your application makes to Flipt for feature flag evaluations * You want to reduce the latency of feature flag evaluations See all official client-side SDKs in the [Client-Side SDKs](/v2/integration/client) section. # REST SDKs Source: https://docs.flipt.io/v2/integration/server/rest An overview of the REST server-side SDKs available for integrating with Flipt. Not sure which SDK to use? Check out our [Integration Overview](/v2/integration/overview) documentation. ## Overview For server-side applications, Flipt v2 provides a REST API for evaluating flags. The REST API SDKs are available in the following languages: These SDKs are the same ones that are available for the [Flipt v1 REST API](/v2/integration/server/rest) and are backward and forward compatible which means there is no need to rewrite your existing code to integrate with Flipt v2. ## Authentication Server-side SDKs authenticate with Flipt using client tokens or JWTs. For detailed setup instructions, see the [Connecting Applications to Flipt](/v2/guides/operations/authentication/connecting-applications) guide. Evaluate flags in your Node applications Evaluate flags in your Python applications Evaluate flags in your Go applications Evaluate flags in your Rust applications Evaluate flags in your Java applications Evaluate flags in your PHP applications Evaluate flags in your C# applications > Need a client in another language? Let us know! # Introduction Source: https://docs.flipt.io/v2/introduction This document describes the features and benefits of Flipt v2. Flipt v2 is a major new version of Flipt that is built to be Git-native and support a more flexible and powerful feature management platform. We've also given the UI a makeover to make it more user-friendly and intuitive. Flipt v2 UI ## Differences from v1 Flipt v2 introduces a number of new features and capabilities that are not available in v1 while maintaining backwards compatibility with v1. ### Git-Native Flipt v2 is built to be Git-native, meaning that your feature flags and configurations are stored in your own Git repositories. This allows you to use your existing Git workflow and tools to manage your feature flags and configurations. By default, Flipt v2 uses a local git-backed storage backend that is stored in memory or on disk. You can also configure Flipt v2 to sync your local git-backed storage to a remote Git repository such as **GitHub, GitLab, Bitbucket, Azure DevOps, and Gitea**. Flipt v2 is designed to be self-hosted and gives you complete control over your feature flag infrastructure. While Flipt v1 has the ability to read flag data from a Git repository, Flipt v2 takes this one step further by allowing you to write flag data to a Git repository using the Flipt v2 API and UI. We believe that Git is the best way to manage configuration data. We also believe that feature flags are a type of configuration data, and as such, they should be stored in the same way. By combining the power of Git with a user-friendly interface, Flipt v2 offers the best of both worlds: the robustness and version control of Git-backed storage, and the ease of use of a modern feature flag management system. ### Multi-Environment Flipt v2 introduces the concept of environments, which are an additional layer above Flipt v1's concept of [Namespaces](/v2/concepts#namespace). Environments allow you to manage your feature flags and configurations in different several ways including: * Different Git repositories * Different directories within the same Git repository * Different branches within the same directory Each environment has its own set of namespaces, feature flags and configurations, and is completely isolated from the others. ### Branching Flipt v2 allows you to create branches of any environment. This allows you to test changes to your feature flags and configurations in a separate branch without affecting your users in production. Flipt v2 Branching Branches use Git under the hood and create a complete copy of the base environment. You can also optionally sync the branch to a remote Git repository. See our [Branching](/v2/guides/user/environments/branches) guide for more information on how to use branches. ### Merge Proposals Flipt v2 allows you to create merge proposals for any environment branch. This enables you to review changes from your branched environments before merging them into the base environment. This models the same workflow as GitHub Pull Requests, GitLab Merge Requests, and Bitbucket Pull Requests. Flipt v2 Merge Proposals Merge proposals are a Pro feature. See [licensing](/v2/licensing) for details. ### Real-Time Client Updates Flipt v2 introduces a new streaming API that allows you to subscribe to changes on the Flipt server and update the state of the flags accordingly in real-time. This means you'll be able to see changes to flags and configurations as they are made, without having to poll the Flipt server for updates. ### No External Dependencies Flipt v2 is a standalone binary that does not depend on any external services. This means that you can run Flipt v2 on any machine that has a compatible operating system. V2 does not require any database or cache by default. Even the git-backed storage is local by default either in memory or on disk. You can configure Flipt v2 to sync your local git-backed storage to a remote Git repository such as GitHub, GitLab, Bitbucket, Azure DevOps, or Gitea. ### Secrets Management Flipt v2 introduces secure external secrets management, allowing you to store sensitive configuration data like API keys, tokens, and certificates outside of your main configuration files. This enhances security by centralizing secret management and reducing the risk of accidentally exposing sensitive data. Flipt v2 supports multiple secrets providers including: * **File Provider** - Store secrets in local files for development and simple deployments * **HashiCorp Vault** - Enterprise-grade secret management with advanced authentication and access controls * **AWS Secrets Manager** - Retrieve secrets using standard AWS credentials * **GCP Secret Manager** - Retrieve secrets with Application Default Credentials or service account keys * **Azure Key Vault** - Retrieve secrets using Azure identity credentials ### Commit Signing Flipt v2 supports GPG commit signing to provide cryptographic verification of configuration changes. This feature ensures the authenticity and integrity of your feature flag modifications, creating a verifiable audit trail for compliance and security purposes. When commit signing is enabled, Flipt automatically signs all commits to your flag configuration repository with a GPG key. These signatures can be verified by Git hosting services like GitHub, GitLab, and others, displaying a "Verified" badge next to signed commits. Key benefits include: * **Authenticity Verification** - Prove who made configuration changes with cryptographic signatures * **Integrity Assurance** - Detect if commits have been tampered with after creation * **Compliance Support** - Meet regulatory requirements for change management and audit trails Commit signing is a Pro feature. See [licensing](/v2/licensing) for details. ### Declarative APIs Flipt v2 introduces a declarative API for managing feature flags and configurations. This allows you to manage your feature flags and configurations in a declarative way, using a simple JSON schema. Flipt v2 works on the principle of managing resources. A resource is a collection of related configurations that are managed together. Feature flags are just one type of resource and are managed through the Flipt v2 API. # Licensing Source: https://docs.flipt.io/v2/licensing This document describes the licensing options for Flipt v2. ## Free and Open Source Components The **majority of Flipt v2 remains free and open source**, including: * Core feature flag evaluation engine * Dashboard and UI * Multi-environment support * Branch environments * Git-backed storage and sync * Authentication mechanisms * Real-time client updates ## Feature Comparison: Free vs Pro | Feature Category | Free | Pro | Notes | | ----------------------------------- | ---- | --- | ----------------------------------------------------------------------------------------------------- | | **Core Functionality** | | | | | Feature flag evaluation engine | ✅ | ✅ | Full functionality in both | | Dashboard and UI | ✅ | ✅ | Complete interface | | Multi-environment support | ✅ | ✅ | Unlimited environments | | Branch environments | ✅ | ✅ | Git-based branching | | Git-backed storage and sync | ✅ | ✅ | Full Git integration | | Authentication mechanisms | ✅ | ✅ | OIDC, token-based | | Real-time client updates | ✅ | ✅ | Server Sent Events (SSE) support | | **Advanced Workflows** | | | | | Enterprise DevOps Integration | ❌ | ✅ | GitHub, GitLab, Bitbucket, Azure DevOps, Gitea | | Merge proposals with SCM | ❌ | ✅ | Automated PR/MR creation | | GPG commit signing | ❌ | ✅ | Cryptographic verification | | **Security & Operations** | | | | | Integrated secrets management | ❌ | ✅ | HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, and Azure Key Vault with secrets references | | Air-gapped environment support | ❌ | ✅ | Offline license validation | | Enterprise authentication providers | ❌ | 🔄 | Coming soon | | Advanced analytics and reporting | ❌ | 🔄 | Coming soon | | **Support** | | | | | Community support | ✅ | ✅ | Discord, GitHub issues | | Dedicated support channel | ❌ | ✅ | Direct Slack access | | Priority bug fixes | ❌ | ✅ | Faster resolution | | Priority feature requests | ❌ | ✅ | Influence roadmap | ## Pro Licensing Pro features are protected by license key validation and cannot be accessed without a valid license. For detailed information about Pro features and purchasing options, see our [Flipt Pro](/v2/pro) page. ### Managing Your License Flipt provides CLI commands to help you manage your Pro license: * [`flipt license check`](/v2/cli/commands/license/check): Validate your current license and view available Pro features * [`flipt license activate`](/v2/cli/commands/license/activate): Interactive wizard to activate a new license These commands provide a streamlined way to check license status, verify expiration dates, and activate new licenses directly from the command line. ## SDK and Integration Licensing **All Flipt SDKs and client libraries remain MIT licensed**, ensuring that: * Your application code using Flipt SDKs has no licensing restrictions * You can integrate Flipt into commercial applications freely * There are no licensing concerns for end-user applications This includes: * All language-specific SDKs (Go, Python, Node.js, etc.) * OpenFeature providers * Integration libraries and tools ## Fair Core License Flipt v2 is licensed under the [Fair Core License](https://fcl.dev/) (FCL). The Fair Core License is a [Fair Source](https://fair.io/) license specifically designed for self-hosted software that balances developer sustainability with user freedom. It's a mostly-permissive non-compete license that eventually transitions to Open Source after 2 years. ### What the FCL Allows Under the Fair Core License, you can: * **Read, use, modify, and redistribute** the Flipt source code * **Use Flipt for any purpose** that doesn't compete with Flipt's business interests * **Self-host and deploy** Flipt in your infrastructure * **Modify the code** to suit your needs ### What the FCL Restricts The FCL restricts **competing uses**, which means you cannot: * Create a competing cloud or SaaS offering using Flipt * Offer Flipt as a managed service to third parties * Remove or circumvent license checks for commercial features ### Transition to Open Source After 2 years from each software version's release, that version automatically becomes available under an Open Source license (MIT), ensuring long-term access and community benefit. ## Why We Chose the Fair Core License The Fair Core License allows us to: * Share our entire codebase in a single repository under a single license * Maintain sustainable development while keeping core functionality free * Ensure all features eventually become Open Source * Protect our ability to offer commercial services while respecting user freedom ## Important Restrictions ### License Compliance When using Flipt v2, you **must not**: * Remove or modify license checks in the source code * Attempt to circumvent license protection mechanisms * Distribute modified versions that bypass commercial feature restrictions * Use Flipt to create competing feature flag services ### Commercial Use Guidelines For most users and organizations, Flipt v2 can be used freely in commercial environments. The restrictions primarily apply to companies wanting to compete directly with Flipt's business model. ## Questions? If you have questions about licensing or whether your use case requires a commercial license, please: * Review the [Fair Core License FAQ](https://fcl.dev/) * Contact us at [support@flipt.io](mailto:support@flipt.io) * Open a discussion on our [GitHub repository](https://github.com/flipt-io/flipt) # Flipt Pro Source: https://docs.flipt.io/v2/pro Enterprise-grade security, workflows, and support for teams. Native GitHub, GitLab, Bitbucket, Azure DevOps, and Gitea workflows with merge proposals and GPG signed commits for maximum security and auditability. Deploy on your infrastructure with complete data sovereignty. No vendor lock-in, unlimited users, and your data never leaves your environment. Secure storage for sensitive configuration data including GPG keys, API keys, tokens, and certificates with HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, and Azure Key Vault. Annual Pro license works seamlessly in air-gapped environments with no external connectivity required. Direct access to our engineering team via dedicated Slack channel for faster issue resolution and feature requests. Full 14-day trial with all Pro features included. No credit card required, cancel anytime. ## Pro Features ### Enterprise GitOps Integration Flipt Pro provides native integration with popular source control management (SCM) platforms: * **Multi-Provider SCM Support**: Create merge proposals directly from the Flipt UI that generate pull requests across GitHub, GitLab, Bitbucket, Azure DevOps, and Gitea * **GPG Commit Signing**: All commits are cryptographically signed for maximum security and auditability ### Integrated Secrets Management Securely manage sensitive data with built-in secrets management: * **Comprehensive Secrets Support**: Store GPG keys, API keys, tokens, and certificates securely * **Multiple Providers**: HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, and Azure Key Vault, with secrets references throughout configuration * **Cloud Provider Support**: AWS Secrets Manager, GCP Secret Manager, and Azure Key Vault ### Air-Gapped Environment Support Deploy Flipt Pro in completely isolated environments: * **Offline License Validation**: Annual licenses work without internet connectivity * **Self-Contained Deployment**: No external dependencies or data transmission * **Compliance Ready**: Meet strict security and compliance requirements * **Enterprise Security**: Deploy in the most secure environments without compromise ### Dedicated Support Get the help you need when you need it: * **Dedicated Slack Channel**: Direct access to our engineering team * **Same-Day Response**: Priority support with rapid response times * **Priority Bug Fixes**: Pro customers get first priority for bug fixes * **Feature Request Priority**: Influence our roadmap with priority feature requests ## Getting Started No credit card required • Cancel anytime • Full Pro features included Includes offline validation support for air-gapped environments ## Licensing Options ### Monthly Subscription * **Price**: \$200/month * **Trial**: 14-day free trial included * **Validation**: Requires internet connectivity * **Billing**: Monthly via Stripe * **Support**: Dedicated Slack channel ### Annual License * **Price**: \$2,000/year (**save \$400**) * **Offline Support**: Works in air-gapped environments * **Validation**: Local license validation * **Billing**: Annual via Stripe * **Support**: Dedicated Slack channel + priority support ## Configuration Once you have your license key, configure it in your Flipt v2 instance: ```yaml theme={null} license: key: "your-license-key-here" ``` For detailed configuration instructions, see our [licensing configuration documentation](/v2/configuration/licensing). ## Frequently Asked Questions The Pro edition includes all Free edition features plus enterprise GitOps integration, integrated secrets management, air-gapped environment support, and dedicated support. A license key is required to access Pro features. Trial licenses support up to 5 instances. Paid subscriptions have **no limit** on the number of instances you can run with the same license key. Monthly licenses require internet connectivity for validation. Annual licenses include offline validation support, perfect for air-gapped environments. Pro subscribers get access to a dedicated Slack channel for same-day support, priority bug fixes, and priority consideration for feature requests. Yes! If you have a valid payment method, your trial automatically converts to a paid subscription. No configuration changes needed. You can cancel anytime through our [Stripe customer portal](https://getflipt.co/billing). Your license deactivates immediately with prorated refund for remaining time. ## Enterprise Sales For enterprise deployments with custom requirements: * **Custom Contracts**: Tailored licensing agreements * **Enterprise Support**: Dedicated account management * **Professional Services**: Implementation and training services Contact us at [support@flipt.io](mailto:support@flipt.io) to discuss your requirements. # Quickstart Source: https://docs.flipt.io/v2/quickstart This document describes how to get started with Flipt v2. ## Setup Before getting started, make sure the Flipt server is up and running on your host on your chosen ports. ```console Binary theme={null} curl -fsSL https://get.flipt.io/v2 | sh ``` ```console Docker theme={null} docker run -d \ -p 8080:8080 \ -p 9000:9000 \ -v $HOME/flipt:/var/opt/flipt \ docker.flipt.io/flipt/flipt:v2 ``` In this example, we'll use the default location of [http://localhost:8080](http://localhost:8080). **Quick Configuration**: If you want to quickly set up Flipt with Git storage and SCM integration, you can use the interactive [`flipt quickstart`](/v2/cli/commands/quickstart) command. The wizard will guide you through configuring your Git repository and authentication. ## Environments and Namespaces Flipt v2 introduces the concept of environments in addition to namespaces. By default, Flipt v2 will create a single environment called `default` along with the `default` namespace. Environments Environments are managed via configuration files. See the [Environments](/v2/concepts#environments) documentation for more. ## Flags and Variants First, we'll create a flag and variants that we will use to evaluate against in the default environment and namespace. ### Create a Flag A flag is the basic entity in Flipt. Flags can represent features in your applications that you want to enable/disable for your users. To create a flag: 1. Open the UI at [http://localhost:8080](http://localhost:8080). 2. Click `New Flag`. 3. Select the `Variant` type. 4. Populate the details of the flag as you wish. 5. Click `Enabled` so the flag will be enabled once created. 6. Click `Create`. Create Flag ### Create Variants Variants allow you to return different values for your flags based on rules that you define. To create a variant: 1. On the page for the flag you just created, click `Create Variant`. 2. Populate the details of the variant as you wish. 3. Click `Add`. 4. Click `Update` to save the flag and variants. Create Variant Click `Flags` in the navigation menu and you should now see your newly created flag in the list. ## Segments and Constraints Next, we'll create a segment with a constraint that will be used to determine the reach of your flag. ### Create a Segment Segments are used to split your user base into subsets. To create a segment: 1. From the navigation click `Segments`. 2. Click `New Segment`. 3. Populate the details of the segment as you wish. 4. Click `Create`. Create Segment ### Create a Constraint Constraints are used to target a specific segment. Constraints aren't required to match a segment. A segment with no constraints will match every request by default. To create a constraint: 1. On the page for the segment you just created, click `Create Constraint`. 2. Populate the details of the constraint as you wish. 3. Click `Add`. 4. Click `Update` to save the segment and constraint. Create Constraint Click `Segments` in the navigation menu and you should now see your newly created segment in the list. ## Rules and Distributions Finally, we'll create a rule defining a distribution for your flag and variants. Rules allow you to define which variant gets returned when you evaluate a specific flag that falls into a given segment. ### Create a Rule To create a rule: 1. Go back to the flag you created at the beginning. 2. Scroll down and click the `Rules` tab. 3. Click `New Rule`. 4. Next to `Segment` choose or search for the segment you created earlier. 5. Next to `Type` choose `Multi-Variate`. 6. You should see the variants you created earlier, with a percentage assigned to each. 7. Click `Add`. 8. Click `Update` to save the rule. Create Rule A distribution is a way of assigning a percentage for which entities evaluated get a specific variant. The higher the percentage assigned, the more likely it is that any entity will get that specific variant. You could just as easily have picked `Single Variant` instead of `Multi-Variate` when setting up your rule. This would effectively mean you have a single distribution, a variant with `100%` chance of being returned. ## Evaluation Playground After creating the above flag, segment and targeting rule, you're now ready to test how this would work in your application. The Flipt UI contains an Evaluation Playground to allow you to experiment with different requests to see how they would be evaluated. The main ideas behind how evaluation works are described in more detail in the [Concepts](/v2/concepts#evaluation) documentation. To test evaluation: 1. Navigate to the `Playground` page from the main navigation. 2. Select or search for the flag you created earlier. 3. Notice that the `Entity ID` field is pre-populated with a random UUID. This represents the ID that you would use to uniquely identify entities (ex: users) that you want to test against your flags. 4. Click `Evaluate`. 5. Note the pane to the right has been populated with the evaluation response from the server, informing you that this request would match the segment that you created earlier, and return one of the variants defined. 6. Experiment with different values for the `Request Context` and `Entity ID` fields. Evaluation Playground That's it! You're now ready to integrate Flipt into your applications and start defining your flags and segments that will enable you to seamlessly rollout new features to your users while reducing risk. # API Overview Source: https://docs.flipt.io/v2/reference/overview Learn how to interact with the Flipt REST API to manage flags, segments, rules, and evaluate feature flags programmatically. Flipt's API is the primary way to interact with Flipt Open Source outside of the UI. It's used to create, update, and delete entities such as namespaces, flags, segments, rules, and also to evaluate flags. The Flipt UI is completely backed by this same API. This means that anything that can be done in the Flipt UI can also be done via the REST API. The latest version of the [management REST API](https://raw.githubusercontent.com/flipt-io/flipt/refs/heads/v2/rpc/v2/environments/openapi.yaml) and [evaluation REST API](https://raw.githubusercontent.com/flipt-io/flipt/refs/heads/v2/rpc/v2/evaluation/openapi.yaml) are documented using the OpenAPI v3 specification. # GitHub Actions Source: https://docs.flipt.io/v2/tooling/github-actions How to use our GitHub Actions to automate your workflows. ## Setup Flipt Flipt Setup Action The [flipt-setup-action](https://github.com/marketplace/actions/flipt-setup-action) can be used to setup Flipt v2 in your GitHub workflow. Once setup, you can then use any of the [CLI commands](/v2/cli/overview) that Flipt provides in your workflow. ### Usage The following example demonstrates how to use the action in a GitHub workflow which runs the [flipt validate](/v2/cli/commands/validate) command. ```yaml theme={null} validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: flipt-io/setup-action@v0.5.0 with: version: v2 # Installs the latest v2 release # Optional, additional arguments to pass to the `flipt` command # args: # Optional, the directory to run Flipt against, defaults to the repository root # working-directory: - run: flipt validate ``` # Model Context Protocol (MCP) Source: https://docs.flipt.io/v2/tooling/model-context-protocol Use Flipt's MCP server to enable AI assistants to interact with your feature flags ## Overview The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open protocol that standardizes how applications provide context to Large Language Models (LLMs). Think of MCP like a USB-C port for AI applications - it provides a standardized way to connect AI models to different data sources and tools. [Flipt's v2 MCP server](https://github.com/flipt-io/mcp-server-flipt/tree/main/packages/mcp-server-flipt-v2) allows AI assistants and LLMs to directly interact with your environments, feature flags, segments, and evaluations through a standardized interface. This enables powerful AI-driven workflows and integrations with tools that support the MCP protocol. Using Flipt v1? See the [v1 MCP server documentation](/v1/tooling/model-context-protocol) instead. ## Use Cases ### AI-Enabled IDEs When using AI-enabled IDEs like Cursor that support MCP, your AI assistant can: * Check feature flag states while reviewing code * Help toggle features on/off during development * Assist in creating and managing feature flags * Evaluate flags for specific users/entities * Create [branch environments](/v2/concepts#branches) to test flag changes safely and propose them back via your SCM * Help debug feature flag logic and rules For example, you could ask your AI assistant: * "What's the current state of the 'dark-mode' flag?" * "Enable the 'beta-features' flag for all users in the 'internal' segment" * "Create a branch of the production environment and add a flag for our upcoming notification system" ### AI Agents and Workflows The Flipt MCP server can be integrated into broader AI agent workflows to: * Automate feature flag management based on system metrics * Coordinate feature rollouts across multiple services * Propose flag changes as pull requests through branch environments * Manage complex feature flag rules and segments ## Getting Started Check out the [Flipt MCP server repository](https://github.com/flipt-io/mcp-server-flipt/tree/main/packages/mcp-server-flipt-v2) for the most up to date information on how to use the MCP server. ### Cursor To use the Flipt MCP server with Cursor, you need to configure Cursor to use the MCP server. The Cursor docs have a [guide on how to configure Cursor](https://docs.cursor.com/context/model-context-protocol#configuring-mcp-servers) to use a MCP server. For Flipt v2, you can use the following configuration: ```json theme={null} { "mcpServers": { "flipt": { "command": "npx", "args": ["-y", "@flipt-io/mcp-server-flipt-v2"] } } } ``` ### Docker You can also run the server in a Docker container: ```bash theme={null} docker run -d --name mcp-server-flipt-v2 ghcr.io/flipt-io/mcp-server-flipt-v2:latest ``` ### Configuration The server can be configured using environment variables: ```bash theme={null} # The URL of your Flipt instance FLIPT_URL=http://localhost:8080 # Optional API key for authentication FLIPT_API_KEY= # The environment used when a tool call doesn't specify one FLIPT_ENVIRONMENT=default ``` You can also set these in a `.env` file in the directory where you run the server. ## Available Tools Every tool that operates inside an environment accepts an optional `environmentKey`, falling back to the `FLIPT_ENVIRONMENT` environment variable. | Group | Tools | | ------------- | --------------------------------------------------------------------------------------------------------------- | | Environments | `list_environments`, `list_branches`, `create_branch`, `delete_branch`, `propose_branch`, `list_branch_changes` | | Namespaces | `list_namespaces`, `get_namespace`, `create_namespace`, `update_namespace`, `delete_namespace` | | Flags | `list_flags`, `get_flag`, `create_flag`, `update_flag`, `delete_flag`, `toggle_flag` | | Variants | `create_variant`, `update_variant`, `delete_variant` | | Rules | `create_rule`, `delete_rule` | | Distributions | `create_distribution`, `delete_distribution` | | Rollouts | `create_rollout`, `delete_rollout` | | Segments | `list_segments`, `get_segment`, `create_segment`, `update_segment`, `delete_segment` | | Constraints | `create_constraint`, `delete_constraint` | | Evaluation | `evaluate_boolean_flag`, `evaluate_variant_flag`, `evaluate_batch` | ### Notes on the v2 Data Model In Flipt v2, variants, rules, rollouts, distributions, and constraints live inside their parent flag or segment document rather than behind their own API endpoints. The corresponding tools read the parent document, apply the change, and write it back with the revision from the read, so a concurrent modification results in a conflict error instead of a lost update - fetch the resource again and retry. Rules, rollouts, and constraints have no IDs in v2; delete them by their index as shown by `get_flag` / `get_segment`. Variants and distributions are addressed by key.