Supported SCM Providers#
Flipt v2 integrates with the following SCM providers:
- GitHub (including GitHub Enterprise)
- GitLab (including GitLab Self-Managed)
- Bitbucket (Cloud and Server/Data Center)
- Azure DevOps (including Azure DevOps Server)
- Gitea
Each provider supports both cloud-hosted and self-hosted instances. For self-hosted deployments, specify the provider’s API URL in your environment configuration.
Authentication Methods#
Authentication is configured per provider using credentials in your Flipt configuration. Supported methods include Personal Access Tokens (PAT), API tokens, SSH keys, and (for GitHub) GitHub App authentication. The recommended authentication format varies by provider:
| Provider | Recommended Auth Method | Basic Auth Format | Notes |
|---|---|---|---|
| GitHub | Personal Access Token or GitHub App | Username: token, Password: (empty) | GitHub App authentication supported |
| 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) |
GitHub App Authentication:
Flipt supports authenticating to GitHub and GitHub Enterprise using a GitHub App. This is recommended for organizations that require granular permissions and improved security over personal access tokens. To use GitHub App authentication, create a GitHub App with the necessary permissions (typically contents and pull-requests), install it on your repository, and generate a private key.
Configure your credentials in Flipt as follows:
credentials:
github_app:
type: github_app
github_app:
client_id: <your-github-app-client-id>
installation_id: <your-github-app-installation-id>
private_key_path: "/path/to/private-key.pem" # or use private_key_bytes instead
# api_url: "https://github.company.com/api/v3" # for GitHub Enterprise (optional)
client_id: The App's Client ID (from GitHub App settings)installation_id: The installation ID for your repository/organizationprivate_key_path: Path to the PEM-encoded private key file for the Appprivate_key_bytes: (alternative to private_key_path) The PEM-encoded private key as a stringapi_url: (optional) The GitHub API URL for GitHub Enterprise
You must provide exactly one of private_key_path or private_key_bytes. If both are provided, Flipt will return an error.
SSH Remote URL Normalization and Port Handling:
When using SSH credentials, Flipt automatically normalizes the configured remote URL to the correct format for SSH operations. For the default SSH port (22), Flipt converts URLs to SCP-style format (git@host:path). For non-default SSH ports, Flipt preserves the ssh:// protocol format (ssh://git@host:port/path) to ensure Git correctly uses the specified port during sync operations.
You may specify the remote as HTTPS, HTTP, ssh://, SCP-style, or host/path format. Flipt will convert it as needed for Git operations. If the SSH user in your credentials differs from the user in the remote URL, Flipt will raise an error to prevent misconfiguration.
Provider Requirements:
- GitHub: PAT with
contentsandpull-requestsscopes, or GitHub App with equivalent permissions. - GitLab: PAT with
api,read_repository, andwrite_repositoryscopes. - Bitbucket Cloud: API tokens (recommended) with repository and pull request scopes. App passwords deprecated June 2026.
- Bitbucket Server/Data Center: Access tokens with repository and pull request permissions.
- Azure DevOps: PAT with
Code (read & write)andPull Request (read & write)scopes, configured as basic auth. - Gitea: PAT with repository access.
Credentials are referenced in configuration as follows:
credentials:
github:
type: access_token
access_token: <your-personal-access-token>
github_app:
type: github_app
github_app:
client_id: <your-github-app-client-id>
installation_id: <your-github-app-installation-id>
private_key_path: "/path/to/private-key.pem"
You can reference either credential in your storage backend configuration depending on your organization's requirements.
Pull Request Creation and Management#
Flipt v2 models pull request workflows through its "merge proposals" feature. When you create a branch of an environment, Flipt uses Git to create a complete copy of the base environment. Merge proposals allow you to review and approve changes before merging, mirroring workflows found in GitHub Pull Requests, GitLab Merge Requests, and Bitbucket Pull Requests. Merge proposals require a Pro license.
Branch Filtering#
Branch filtering is managed by specifying the branch in your storage backend configuration. This determines which branch Flipt syncs with in your remote repository:
storage:
github:
remote: "https://github.com/<your-username>/<your-repo>.git"
branch: "main"
poll_interval: "30s"
credentials: "github"
backend:
type: local
path: "/path/to/local/clone"
You can configure multiple environments to share the same storage backend by specifying unique directories for each environment.
Fetch Policy and Git Fetch Behavior#
Flipt supports a configurable fetch_policy for Git-backed storage:
strict(default): Flipt requires a successful fetch from the remote repository during startup. If the remote is unavailable, Flipt will fail to start the environment.lenient: Flipt will continue operating with local (potentially stale) data if the remote is temporarily unavailable. Changes will not sync until connectivity is restored.
Git Fetch Details:
- Flipt performs a shallow fetch (
depth: 1) from the remote repository, fetching only the latest commit(s). - Flipt does not fetch Git tags. Only branch references are synchronized.
Example configuration:
storage:
github:
remote: "https://github.com/<your-username>/<your-repo>.git"
branch: "main"
fetch_policy: lenient
poll_interval: "30s"
credentials: "github"
backend:
type: local
path: "/path/to/local/clone"
If fetch_policy is omitted, the default is strict.
Performance Considerations#
Performance is managed through the poll_interval setting, which controls how frequently Flipt syncs with the remote Git repository. The default is 30 seconds, but you can adjust this to balance data freshness against API rate limits and system load.
Flipt always performs shallow fetches (depth=1) and does not fetch tags. Only the latest commit(s) on the configured branch are available locally. If you require access to tags or deeper history, consider these limitations.
Flipt supports both memory and local storage backends for caching the repository.
Server-wide Commit and PR Templates#
Flipt supports configuring server-wide templates for commit messages and pull request (merge proposal) content. These templates are used when creating commits and pull requests via the Flipt UI, allowing operators to enforce organization-wide standards.
Configuration#
Add a templates section at the top level of your Flipt configuration file:
# Server-wide custom templates for commit messages and pull requests.
templates:
# Template for commit messages when updating flags via the UI.
# Available variables: .Changes (array), .Environment (config)
commit_message: |
{{- if eq (len .Changes) 1 }}
{{- (index .Changes 0) }} [skip ci]
{{- else -}}
updated multiple resources [skip ci]
{{ range $change := .Changes }}
{{ $change }}
{{- end }}
{{- end }}
# Template for pull request titles.
# Available variables: .Base (target env config), .Branch (source env config)
proposal_title: "Flipt: Update features on {{.Base.Ref}}"
# Template for pull request body.
proposal_body: |
This PR updates Flipt resources on branch {{.Base.Ref}}.
Source: {{.Branch.Ref}}
All templates use Go's text/template syntax. You can use variables such as .Changes, .Base, .Branch, and .Environment depending on the template type.
Precedence and Overrides#
- Server-level templates override Flipt's built-in defaults.
- Repository-level templates (in a repository's
flipt.yaml) take precedence over server-level templates for that repository. - If neither is set, Flipt uses its built-in defaults.
Validation#
Templates are validated at startup. If a template is invalid, Flipt will fail to start and log an error.
Example#
templates:
commit_message: "[Flipt] {{ (index .Changes 0) }}"
proposal_title: "Update flags on {{.Base.Ref}}"
proposal_body: |
Automated update from Flipt UI.
Source: {{.Branch.Ref}}
Target: {{.Base.Ref}}
This feature allows you to standardize commit and PR formatting across all environments and storage backends managed by your Flipt server.
Setup Instructions#
1. Create Credentials#
Follow your SCM provider’s documentation to create a Personal Access Token or API token with the required scopes. Add the token to your Flipt configuration under credentials.
2. Configure Storage Backend#
Specify the remote repository URL, branch, fetch policy (optional), poll interval, credentials reference, and backend path in your Flipt configuration.
When using SSH credentials, you may specify the remote URL in HTTPS, HTTP, ssh://, SCP-style (git@host:path), or host/path format. Flipt will automatically convert the URL to the correct format for SSH operations, including preserving non-standard ports. If the SSH user in your credentials does not match the user in the remote URL, Flipt will raise an error at startup.
Example for GitHub:
storage:
github:
remote: "https://github.com/<your-username>/<your-repo>.git"
branch: "main"
fetch_policy: strict
poll_interval: "30s"
credentials: "github"
backend:
type: local
path: "/path/to/local/clone"
SSH Remote URL Normalization and Port Support#
When configuring a storage backend with SSH credentials, Flipt supports specifying the remote URL in any of the following formats:
- HTTPS:
https://github.com/org/repo.git - HTTP:
http://github.com/org/repo.git - SSH protocol:
ssh://git@github.com/org/repo.git - SSH protocol with port:
ssh://git@github.com:2222/org/repo.git - SCP-style:
git@github.com:org/repo.git - SCP-style with port:
git@github.com:2222:org/repo.git - Host/path:
github.com/org/repo.git
Flipt will automatically normalize the URL to the correct format for SSH operations. For the default SSH port (22), URLs are converted to SCP-style format (git@host:path). For non-default ports, the ssh:// protocol format is preserved (ssh://git@host:port/path) to ensure Git correctly uses the specified port. The SSH user is taken from your credentials configuration (defaults to git if not specified). If the remote URL already contains a user (e.g., deploy@github.com:org/repo.git), it must match the user in your credentials, otherwise Flipt will fail to start with an error indicating the conflict.
Examples:
| Configured Remote URL | SSH User in Credentials | Normalized URL |
|---|---|---|
https://github.com/org/repo.git | git | git@github.com:org/repo.git |
ssh://deploy@gitlab.com/group/repo.git | deploy | deploy@gitlab.com:group/repo.git |
ssh://git@localhost:6022/root/demo.git | git | ssh://git@localhost:6022/root/demo.git |
git@github.com:org/repo.git | git | git@github.com:org/repo.git |
git@localhost:2222:owner/repo.git | git | ssh://git@localhost:2222/owner/repo.git |
github.com/org/repo.git | (empty) | git@github.com:org/repo.git |
If you see an error about conflicting SSH users, ensure that the user in your credentials matches the user in the remote URL, or remove the user from the URL and let Flipt insert it automatically.
This normalization is handled automatically by Flipt; you do not need to manually convert URLs for SSH usage. For non-default ports, Flipt preserves the ssh:// protocol format to ensure Git uses the specified port correctly.
3. Configure Environments#
Reference your storage backend in the environments section and specify a directory for each environment.
environments:
production:
name: "Production"
storage: "github"
default: true
directory: "production"
staging:
name: "Staging"
storage: "github"
directory: "staging"
For self-hosted SCM providers, specify the API URL:
environments:
production:
name: "Production"
storage: "gitlab"
default: true
scm:
type: gitlab
api_url: "https://gitlab.company.com/api/v4"
credentials: "gitlab"
4. Start Flipt#
Start or restart the Flipt server. Flipt will clone the repository, periodically sync flag state, and commit/push changes when flags are updated via the API or UI. The fetch policy will determine startup behavior if the remote is unavailable. Flipt will only fetch the latest commit(s) (shallow fetch) and will not fetch tags.
Logging Standards#
Flipt logs sync operations, authentication errors, and permission issues. Ensure your credentials have the correct permissions and that the local path is writable by the Flipt process. Check Flipt logs for troubleshooting.
Integration with Quickstart Wizard#
The quickstart wizard supports SCM integration by requiring a Flipt v2 environment configured with Git Sync and a Pro license or trial license. The wizard guides you through setting up Git-backed storage and connecting your SCM provider.
For more details and provider-specific guides, see the Flipt v2 SCM Integration documentation.
Note: Flipt's Git integration always performs shallow fetches (depth=1) and does not fetch tags. If your workflow depends on tags or full history, consider these limitations when configuring your environments.