From 61c231c2b4620b9dffa768f031d2185ea0687a16 Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:24:35 -0400 Subject: [PATCH 1/4] docs: document incoming webhooks for instant v2 sync --- docs/docs.json | 8 + docs/v2/configuration/environments.mdx | 6 + .../operations/environments/git-scm.mdx | 4 + .../operations/environments/git-sync.mdx | 4 + .../operations/environments/webhooks.mdx | 161 ++++++++++++++++++ docs/v2/pro.mdx | 1 + docs/v2/webhooks/overview.mdx | 106 ++++++++++++ 7 files changed, 290 insertions(+) create mode 100644 docs/v2/guides/operations/environments/webhooks.mdx create mode 100644 docs/v2/webhooks/overview.mdx diff --git a/docs/docs.json b/docs/docs.json index 77b60571..9c4b287d 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -66,6 +66,13 @@ "v2/configuration/licensing" ] }, + { + "group": "Webhooks", + "icon": "webhook", + "pages": [ + "v2/webhooks/overview" + ] + }, { "group": "Integration", "icon": "plug", @@ -154,6 +161,7 @@ "v2/guides/operations/environments/git-repository-initialization", "v2/guides/operations/environments/git-sync", "v2/guides/operations/environments/git-scm", + "v2/guides/operations/environments/webhooks", "v2/guides/operations/environments/commit-signing-setup" ] } diff --git a/docs/v2/configuration/environments.mdx b/docs/v2/configuration/environments.mdx index e6916a27..7d3b4182 100644 --- a/docs/v2/configuration/environments.mdx +++ b/docs/v2/configuration/environments.mdx @@ -133,6 +133,12 @@ Environments can be configured to use a single Source Control Management (SCM) p 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. +### Webhooks + +With Flipt Pro, you can configure incoming webhooks to fetch changes from Git after a push or merge to a tracked branch. Polling continues as a fallback. + +Add `webhook.secret` under the environment's `scm` block. See the [webhook reference](/v2/webhooks/overview) for configuration and the [setup guide](/v2/guides/operations/environments/webhooks) for provider instructions. + ### 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). diff --git a/docs/v2/guides/operations/environments/git-scm.mdx b/docs/v2/guides/operations/environments/git-scm.mdx index 47503f52..126208cc 100644 --- a/docs/v2/guides/operations/environments/git-scm.mdx +++ b/docs/v2/guides/operations/environments/git-scm.mdx @@ -370,6 +370,10 @@ Start or restart your Flipt server with the updated configuration. Flipt will no ![Merge Proposals](/v2/images/guides/operations/environments/merge_proposals.png) +## Receive Changes with Webhooks + +To fetch changes after a push or merge without waiting for the next poll, configure [incoming webhooks](/v2/webhooks/overview). The [webhook setup guide](/v2/guides/operations/environments/webhooks) covers each supported provider. + ## 3. Troubleshooting ### Common Issues diff --git a/docs/v2/guides/operations/environments/git-sync.mdx b/docs/v2/guides/operations/environments/git-sync.mdx index 2061ba38..64b01b46 100644 --- a/docs/v2/guides/operations/environments/git-sync.mdx +++ b/docs/v2/guides/operations/environments/git-sync.mdx @@ -122,6 +122,10 @@ Start or restart your Flipt server with the updated configuration. Flipt will no - Make sure the local path is writable by the Flipt process. - Check Flipt logs for any sync or authentication errors. +## Sync Changes with Webhooks + +With Flipt Pro, you can use [incoming webhooks](/v2/webhooks/overview) to fetch changes after a push or merge without waiting for the next poll. Follow the [webhook setup guide](/v2/guides/operations/environments/webhooks) to connect your Git provider. Polling remains the fallback for missed deliveries. + ## 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. diff --git a/docs/v2/guides/operations/environments/webhooks.mdx b/docs/v2/guides/operations/environments/webhooks.mdx new file mode 100644 index 00000000..4a8740ea --- /dev/null +++ b/docs/v2/guides/operations/environments/webhooks.mdx @@ -0,0 +1,161 @@ +--- +title: Set Up Webhooks +description: Configure your Git provider to trigger Flipt synchronization after a push or merge. +--- + +import V2Pro from "/snippets/v2-pro.mdx"; + + + +This guide connects your Git provider to Flipt's incoming webhook endpoint. After setup, a push or merge to a tracked branch triggers a Git fetch without waiting for the next poll. + +## Prerequisites + +- A running Flipt v2 server with an active [Pro or trial license](/v2/licensing) and webhook support. +- An environment configured with [Git sync](/v2/guides/operations/environments/git-sync) and [SCM integration](/v2/guides/operations/environments/git-scm). +- Permission to manage webhooks or service hooks for your Git repository. +- An HTTPS URL for Flipt that your Git provider can reach. + +## 1. Create a webhook secret + +Generate a random secret with OpenSSL: + +```bash +openssl rand -hex 32 +``` + +Store the result securely. Set `FLIPT_WEBHOOK_SECRET` to this value in the environment of the Flipt server process. You also need this value when you configure your Git provider. + +Use a separate value from the access token that Flipt uses to read and write your repository. + +## 2. Configure Flipt + +Add the `webhook` block to your existing environment's `scm` configuration. This example uses the `production` environment and GitHub: + +```yaml highlight={8-9} +environments: + production: + storage: github + default: true + scm: + type: github + credentials: github + webhook: + secret: ${env:FLIPT_WEBHOOK_SECRET} +``` + +Keep your existing storage identifier and SCM credentials. For another provider, use its [SCM type](/v2/webhooks/overview#supported-providers). You can also use a [secret reference](/v2/webhooks/overview#configuration) instead of an environment variable. + +Restart your Flipt server with the updated configuration. Make sure that `FLIPT_WEBHOOK_SECRET` is available to the server process. Flipt refuses to start if the webhook secret resolves to an empty value. + +The webhook endpoint for this example is `https://flipt.example.com/api/v2/webhooks/production`. Replace `flipt.example.com` with your Flipt host. The final path segment must match the environment's configured `name`, which defaults to its YAML key. If your existing environment sets `name: Production`, use `/api/v2/webhooks/Production`, with the same capitalization. + +## 3. Configure your Git provider + +Use the endpoint URL from the previous step and the same secret that you configured in Flipt. Keep TLS certificate verification enabled. + + + + +1. Open your repository's **Settings > Webhooks** and select **Add webhook**. +2. Set **Payload URL** to your Flipt webhook endpoint. +3. Set **Content type** to `application/json`. +4. Set **Secret** to your webhook secret. +5. Select **Just the push event** and keep **Active** selected. +6. Select **Add webhook**. + +GitHub sends a `ping` event after creation. Flipt returns `200 OK` for an authenticated ping without fetching the repository. + +See [GitHub's webhook documentation](https://docs.github.com/en/webhooks/using-webhooks/creating-webhooks) for details. + + + + +1. Open your project's **Settings > Webhooks** and add a webhook. +2. Set **URL** to your Flipt webhook endpoint. +3. Set **Secret token** to your webhook secret. +4. Select **Push events**. If you filter branches, include the branches that Flipt tracks. +5. Save the webhook. + + + Flipt authenticates GitLab deliveries through `X-Gitlab-Token`. Configure the + **Secret token** field even if your GitLab version also offers a signing + token. A signing token alone does not authenticate deliveries to Flipt. + + +See [GitLab's webhook documentation](https://docs.gitlab.com/user/project/integrations/webhooks/) for details. + + + + +1. Open your repository's **Settings > Webhooks** and add a **Gitea** webhook. +2. Set **Target URL** to your Flipt webhook endpoint. +3. Select `POST` and the `application/json` content type. +4. Set **Secret** to your webhook secret. +5. Select push events, keep the webhook active, and save it. + +Use the native Gitea webhook type so that Gitea sends the signature and event headers that Flipt expects. + +See [Gitea's webhook documentation](https://docs.gitea.com/usage/webhooks) for details. + + + + +For Bitbucket Cloud: + +1. Open your repository's settings and select **Webhooks > Add webhook**. +2. Enter a title and set **URL** to your Flipt webhook endpoint. +3. Set **Secret** to your webhook secret. +4. Select **Repository push**, keep the webhook active, and save it. + +For Bitbucket Server/Data Center, add a repository webhook with the same endpoint and secret. Select the repository push event that sends `repo:refs_changed` deliveries. + +Both variants use `scm.type: bitbucket` in Flipt. Make sure that your Bitbucket version supports webhook secrets and sends an HMAC-SHA256 signature in `X-Hub-Signature`. + +See [Bitbucket Cloud's webhook documentation](https://support.atlassian.com/bitbucket-cloud/docs/manage-webhooks/) for details. + + + + +1. Open **Project settings > Service hooks** and create a subscription. +2. Select **Web Hooks** as the service. +3. Select **Code pushed** as the trigger and choose your repository. +4. If you filter branches, include the branches that Flipt tracks. +5. Set **URL** to your Flipt webhook endpoint. +6. Configure Basic authentication with a username, such as `flipt`, and your webhook secret as the password. +7. Finish creating the subscription. + +Flipt checks the Basic authentication password against `webhook.secret`. Flipt does not require a particular username. Use `scm.type: azure` in your Flipt configuration. + +See [Azure DevOps' webhook documentation](https://learn.microsoft.com/en-us/azure/devops/service-hooks/services/webhooks?view=azure-devops) for details. + + + + +## 4. Test synchronization + +Make a flag change in your Git repository and push it to the branch that Flipt tracks. You can also merge a pull request or merge request that changes a flag on that branch. + +Open your provider's webhook delivery history and inspect the push delivery. A matching push returns `202 Accepted`. Make sure that the changed flag state appears in Flipt. + +A `200 OK` response means that Flipt authenticated the delivery but did not schedule a fetch. Provider test buttons can send pings, unrelated events, or a branch that Flipt does not track. Use a real push to test synchronization. + + + Keep `poll_interval` configured as a fallback. In a deployment with multiple + replicas, a webhook updates the instance that receives it. Deliver to each + replica for prompt updates across the deployment. A load balancer that sends + each request to one replica does not broadcast the update to the others. + + +## Troubleshooting + +| Symptom | Action | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| No delivery reaches Flipt | Make sure that your provider can reach the HTTPS endpoint and that your proxy forwards the path and authentication headers. | +| `404 Not Found` | Make sure that the URL is correct, your Flipt build includes webhook support, and a Pro license and webhook configuration are active. | +| `401 Unauthorized` | Make sure that the configured environment name and secrets match. For GitLab, use **Secret token**. For Azure DevOps, use the secret as the Basic authentication password. | +| `200 OK` but no update | Make sure that the delivery is a push event for a tracked branch, rather than a ping or tag event. | +| `202 Accepted` but no update | Inspect Flipt's logs and [webhook metrics](/v2/webhooks/overview#monitoring) for Git fetch failures. Make sure that repository credentials still work. | +| Flipt fails to start | Make sure that the webhook secret is nonempty after environment or secret resolution. | + +For payload limits, authentication headers, and all response codes, see the [webhook reference](/v2/webhooks/overview). diff --git a/docs/v2/pro.mdx b/docs/v2/pro.mdx index 378fd6c3..48d9d8b7 100644 --- a/docs/v2/pro.mdx +++ b/docs/v2/pro.mdx @@ -43,6 +43,7 @@ mode: "wide" 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 +- **Incoming Webhooks**: [Sync changes from Git](/v2/webhooks/overview) after a push or merge without waiting for the next poll - **GPG Commit Signing**: All commits are cryptographically signed for maximum security and auditability ### Integrated Secrets Management diff --git a/docs/v2/webhooks/overview.mdx b/docs/v2/webhooks/overview.mdx new file mode 100644 index 00000000..3ad43553 --- /dev/null +++ b/docs/v2/webhooks/overview.mdx @@ -0,0 +1,106 @@ +--- +title: Webhooks +description: Sync flag changes from your Git provider without waiting for the next poll. +--- + +import V2Pro from "/snippets/v2-pro.mdx"; + + + +A webhook is an HTTP notification from your Git provider. When you push or merge changes to a tracked branch, Flipt fetches the repository without waiting for the next poll. + +Use webhooks when you need changes from Git to reach Flipt quickly, such as when you disable a flag during an incident. + +To configure your provider, follow the [webhook setup guide](/v2/guides/operations/environments/webhooks). + +## How synchronization works + +Your Git provider sends a push event to `POST /api/v2/webhooks/{environment}`. Flipt authenticates the request and makes sure that the event affects a branch tracked by the environment's storage. + +For a matching event, Flipt schedules a Git fetch and returns `202 Accepted`. The fetch updates all environments that share that repository within the Flipt instance. Flipt combines overlapping requests for the same repository to avoid concurrent webhook fetches. + +Flipt reads flag state from Git. The webhook payload only triggers the fetch. A merge triggers synchronization through the resulting push event on the target branch. You do not need to subscribe to pull request or merge request events. + + + A `202` response means that Flipt scheduled a fetch. It does not mean that + synchronization completed. Polling continues at the configured `poll_interval` + and remains the fallback for missed deliveries or failed fetches. + + +Webhooks update the Flipt server's flag state. Your application's update timing also depends on its SDK polling or streaming configuration. + +## Configuration + +Configure `webhook.secret` under an environment's `scm` block. The environment must already use storage with a Git remote. This example assumes that the `github` storage and credentials are configured through [Git sync](/v2/guides/operations/environments/git-sync). + +```yaml +environments: + production: + storage: github + scm: + type: github + credentials: github + webhook: + secret: ${env:FLIPT_WEBHOOK_SECRET} +``` + +The endpoint for this example is `/api/v2/webhooks/production`. The path uses the configured environment `name`, which defaults to the `production` key. If you explicitly set `name: live`, use `/api/v2/webhooks/live` instead. + +The secret is required and must match the value in your Git provider's webhook configuration. Use a separate random secret for webhook authentication, rather than your Git access token. + +You can supply a literal value, an [environment substitution](/v2/configuration/overview#environment-substitution-and-secret-references), or a [secret reference](/v2/configuration/secrets#secret-reference-syntax): + +```yaml +webhook: + secret: ${secret:file:github-webhook} +``` + +Flipt resolves the secret at startup. If the resolved value is empty, Flipt refuses to start. Restart Flipt after you change the secret. + +Without a Pro license, Flipt does not register the webhook endpoint and logs a warning. + +## Supported providers + +The environment's `scm.type` selects how Flipt authenticates and parses deliveries. + +| Provider | `scm.type` | Event | Authentication | +| ------------------------------------- | ----------- | ------------------- | --------------------------------------------------------- | +| GitHub, including GitHub Enterprise | `github` | `push` | HMAC-SHA256 in `X-Hub-Signature-256` | +| GitLab, including GitLab Self-Managed | `gitlab` | `Push Hook` | Secret token in `X-Gitlab-Token` | +| Gitea | `gitea` | `push` | HMAC-SHA256 in `X-Gitea-Signature` | +| Bitbucket Cloud | `bitbucket` | `repo:push` | HMAC-SHA256 in `X-Hub-Signature` | +| Bitbucket Server/Data Center | `bitbucket` | `repo:refs_changed` | HMAC-SHA256 in `X-Hub-Signature` | +| Azure DevOps | `azure` | `git.push` | HTTP Basic authentication with the secret as the password | + +HMAC-SHA256 signatures let Flipt authenticate the request body with the shared secret. Your provider generates the signature automatically. + +The endpoint uses provider authentication instead of a Flipt API token. Use HTTPS and allow your Git provider to reach the endpoint through your firewall or reverse proxy. Preserve the request body and authentication headers when forwarding deliveries. + +## Responses + +Flipt accepts request bodies up to 5 MiB. + +| Status | Meaning | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | +| `202 Accepted` | Flipt scheduled a fetch for a tracked branch. | +| `200 OK` | Flipt authenticated the delivery but ignored it, such as a ping, an unrelated event, a tag, or an untracked branch. | +| `401 Unauthorized` | Authentication failed, or the environment does not exist or has no webhook configured. | +| `400 Bad Request` | The event payload is malformed. | +| `413 Request Entity Too Large` | The request body exceeds 5 MiB. | +| `503 Service Unavailable` | Flipt is shutting down and cannot accept the fetch. | + +Only a `202` response schedules a fetch. Unknown environments and environments without webhook configuration return the same `401` response as invalid authentication. + +## Monitoring + +Flipt exposes these Prometheus metrics through its [metrics endpoint](/v2/configuration/observability#metrics): + +| Metric | Description | +| ---------------------------------------------- | ---------------------------------------------------- | +| `flipt_incoming_webhook_requests_total` | Requests by `environment`, `scm`, and `result`. | +| `flipt_incoming_webhook_fetch_errors_total` | Failed fetches by `environment` and `scm`. | +| `flipt_incoming_webhook_sync_duration_seconds` | Fetch duration histogram by `environment` and `scm`. | + +Request results are `accepted`, `ignored`, `unauthorized`, `not_found`, or `invalid`. Unknown environments use `environment="unknown"` and `scm="unknown"` to avoid creating labels for arbitrary request paths. + +If a delivery receives `202` but flag state does not update, inspect Flipt's logs and the fetch error counter. A successful delivery can still be followed by a Git authentication or network failure. From f41a47c4ad179de3c0401873a9513076b947f7fb Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:29:41 -0400 Subject: [PATCH 2/4] docs: move new badge to webhooks sidebar section --- docs/docs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs.json b/docs/docs.json index 9c4b287d..1c60f78f 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -42,7 +42,6 @@ }, { "group": "Pro Features", - "tag": "NEW", "icon": "crown", "pages": [ "v2/pro", @@ -68,6 +67,7 @@ }, { "group": "Webhooks", + "tag": "NEW", "icon": "webhook", "pages": [ "v2/webhooks/overview" From 900e26bf52290fcad1055e39ebaf8fb104f9b906 Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:31:27 -0400 Subject: [PATCH 3/4] docs: move webhooks into configuration navigation --- docs/docs.json | 9 +-------- docs/v2/webhooks/overview.mdx | 1 + 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/docs.json b/docs/docs.json index 1c60f78f..5db25afe 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -54,6 +54,7 @@ "pages": [ "v2/configuration/overview", "v2/configuration/environments", + "v2/webhooks/overview", "v2/configuration/storage", "v2/configuration/secrets", "v2/configuration/commit-signing", @@ -65,14 +66,6 @@ "v2/configuration/licensing" ] }, - { - "group": "Webhooks", - "tag": "NEW", - "icon": "webhook", - "pages": [ - "v2/webhooks/overview" - ] - }, { "group": "Integration", "icon": "plug", diff --git a/docs/v2/webhooks/overview.mdx b/docs/v2/webhooks/overview.mdx index 3ad43553..6091dadc 100644 --- a/docs/v2/webhooks/overview.mdx +++ b/docs/v2/webhooks/overview.mdx @@ -1,5 +1,6 @@ --- title: Webhooks +tag: NEW description: Sync flag changes from your Git provider without waiting for the next poll. --- From ed7e18f54334cedbc74896da146c1a5ca43568fe Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:34:05 -0400 Subject: [PATCH 4/4] docs: add webhook settings to configuration reference --- docs/v2/configuration/overview.mdx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/v2/configuration/overview.mdx b/docs/v2/configuration/overview.mdx index 5f040ebe..6c764a86 100644 --- a/docs/v2/configuration/overview.mdx +++ b/docs/v2/configuration/overview.mdx @@ -227,6 +227,18 @@ Environments configuration allows you to create isolated feature flag namespaces | 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 | +#### Incoming Webhooks + +Incoming webhooks require Flipt Pro and an environment with a Git remote and SCM configuration. Add a `webhook` block under the environment's `scm` block to fetch changes after a push or merge to a tracked branch. Polling continues as a fallback. + +| Property | Description | Default | Since | +| ------------------------------------ | -------------------------------------------------------------------------------------------------- | ------- | ------- | +| environments.[id].scm.webhook.secret | Shared secret for authenticating incoming webhooks. Required when the webhook block is configured. | None | v2.14.0 | + +The secret accepts a literal value, an [environment substitution](#environment-substitution-and-secret-references), or a [secret reference](/v2/configuration/secrets#secret-reference-syntax). Flipt refuses to start if the secret resolves to an empty value. + +See [Webhooks](/v2/webhooks/overview) for configuration examples and endpoint details, or follow the [webhook setup guide](/v2/guides/operations/environments/webhooks) for provider instructions. + ### User Interface User interface configuration customizes the appearance and behavior of the Flipt web UI.