databrickslabs / databrickslabs/ontos
[PRD]: Multi-Provider Git Support for Indirect Delivery Mode
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 212
- Forks
- 71
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 43
Description
Problem Statement
The indirect delivery mode exports governance changes as YAML files to a Git repository that admins can review, commit, and push. While the underlying Git operations (clone, pull, push via HTTPS) are protocol-level and technically work with any Git hosting provider, the entire user experience is GitHub-centric. The repository URL placeholder says https://github.com/org/repo.git, the token placeholder says ghp_xxxxxxxxxxxx, the credential logic assumes GitHub's x-access-token convention for PAT-only auth, the USER-GUIDE only documents GitHub PAT creation, and — critically — credentials are not URL-encoded before embedding in the clone URL, which breaks tokens containing special characters (common in Azure DevOps PATs).
Users who want to connect Azure DevOps, GitLab, Bitbucket, or self-hosted Git servers must already know the correct URL format, credential conventions, and required token scopes for their provider. There is no guidance in the app and no validation that the combination will work. The result is a frustrating trial-and-error experience for non-GitHub users.
Solution
Introduce a GitProvider abstraction that maps each supported hosting provider to its URL pattern, default username for token-only auth, example URLs, and required token scopes. The provider is auto-detected from the repository URL the user enters. The Git settings UI dynamically adapts — swapping placeholder text, inline help, and token scope guidance — based on the detected provider. A manual override dropdown is available for edge cases (e.g., GitHub Enterprise on a custom domain). A new "Test Connection" button lets users verify their credentials work before attempting to clone. Credential URL-encoding is fixed to handle special characters in tokens. The USER-GUIDE is expanded with per-provider PAT creation instructions.
Supported providers with first-class UX: GitHub, GitLab, Azure DevOps, Bitbucket, and Generic HTTPS Git (catch-all for self-hosted or unknown providers).
User Stories
- As a data governance admin using Azure DevOps, I want the Git settings page to recognize my
dev.azure.comURL and show me the correct token format, so that I can configure indirect delivery without guessing credential conventions. - As a data governance admin using GitLab, I want the token field placeholder to show the GitLab token format and required scopes (
write_repository), so that I create a token with the right permissions on the first try. - As a data governance admin using Bitbucket, I want the UI to tell me that a username is required (not just a token), so that I don't waste time debugging authentication failures.
- As a data governance admin using any provider, I want a "Test Connection" button that verifies my URL and credentials work before I attempt to clone, so that I can troubleshoot configuration issues quickly.
- As a data governance admin, I want the app to auto-detect my Git provider from the URL I enter, so that I don't have to manually select it from a dropdown.
- As a data governance admin using GitHub Enterprise on a custom domain, I want to manually override the auto-detected provider, so that the correct credential conventions are used even when the URL doesn't match the standard pattern.
- As a data governance admin, I want my credentials to work even when my PAT contains special characters like
@,:, or/, so that Azure DevOps and other providers' tokens don't silently break the clone URL. - As a data governance admin new to the app, I want the USER-GUIDE to include step-by-step PAT creation instructions for my specific provider (GitHub, GitLab, Azure DevOps, or Bitbucket), so that I can set up indirect delivery without external documentation.
- As a data governance admin, I want the Git settings page to show a small badge indicating which provider was detected (e.g., "GitHub detected"), so that I have confidence the app understands my configuration.
- As a data governance admin, I want the repository URL placeholder to match my provider (e.g.,
https://dev.azure.com/{org}/{project}/_git/{repo}for Azure DevOps), so that I know the expected URL format. - As a data governance admin, I want the token field label and help text to match my provider's terminology (e.g., "Personal Access Token" for GitHub/ADO, "Project Access Token" for GitLab, "App Password" for Bitbucket), so that the UI speaks my provider's language.
- As a data governance admin using a self-hosted Gitea or Forgejo instance, I want a "Generic HTTPS" fallback provider that accepts any URL format, so that I'm not blocked by provider detection failing.
- As a data governance admin, I want inline help text below the token field showing the required scopes (e.g., "
reposcope" for GitHub, "Code (Read & Write)scope" for ADO), so that I grant the minimum necessary permissions. - As a developer extending the app, I want provider metadata to be defined in a single backend data structure served via API, so that the frontend doesn't hardcode provider-specific details.
- As a data governance admin, I want the "Test Connection" result to tell me whether the failure was a URL resolution issue or a credentials issue, so that I know what to fix.
- As a data governance admin, I want the settings to persist my detected or manually selected provider, so that it's remembered across sessions and doesn't need to be re-detected every time.
- As a data governance admin, I want the test connection to work even before I've cloned the repository, so that I can validate settings before committing to a clone operation.
- As a data governance admin reading the troubleshooting docs, I want provider-specific entries in the troubleshooting table (e.g., "Azure DevOps clone fails" → "Ensure PAT has Code Read & Write scope"), so that I can self-diagnose common issues.
Implementation Decisions
- GitProvider enum and metadata: A new
GitProviderstring enum (github, gitlab, azure_devops, bitbucket, generic) will be added to the Git service module. A companionPROVIDER_METADATAdictionary maps each provider to: URL hostname patterns for auto-detection, default username for token-only auth, example URL, token placeholder text, and required scope description. - Provider auto-detection: A
detect_provider(url)function checks the repo URL against known hostname patterns (github.com,gitlab.com,dev.azure.com/visualstudio.com,bitbucket.org). Falls back togenericif no match. The detected provider is returned in API responses and can be overridden by storingGIT_PROVIDERin settings. - Credential URL-encoding: The
_get_auth_url()method will URL-encode both username and password usingurllib.parse.quote(value, safe='')before embedding them in the HTTPS URL. This fixes tokens with@,:,/, and other characters. - Provider-aware default usernames: When only a token is provided (no username), the default username is determined by provider:
x-access-token(GitHub),oauth2(GitLab),x-token-auth(Bitbucket), any non-empty string liketoken(Azure DevOps). Generic defaults tox-access-tokenfor backward compatibility. - Test connection: A new
test_connection()method on GitService runsgit ls-remote --heads <auth_url>to verify the URL resolves and credentials are accepted, without cloning. Returns success/failure with a descriptive error message. Exposed via a new API route. - Settings field: A new
GIT_PROVIDERoptional string field is added to the Settings model. It follows the same load/persist/expose pattern as existingGIT_*fields via the settings manager and settings API. - API endpoints: Two new endpoints under
/api/settings/git/:GET /providersreturns the provider metadata list (so the frontend is data-driven), andPOST /test-connectionverifies credentials and returns the detected provider. - Frontend auto-detect UX: The git-settings component watches the repo URL field for changes and runs client-side provider detection (matching URL against the known patterns from the providers API). On match, it swaps placeholder text for URL/username/token fields, shows a provider badge, and displays inline scope help. A collapsed "Change provider" link reveals a manual override dropdown. A "Test Connection" button calls the backend endpoint and shows a success/failure toast.
- URL validation approach: Soft hints only — the expected URL format is shown as placeholder text for the detected provider, but the form never blocks submission. Users may have non-standard URL formats that still work.
- HTTPS only: SSH remotes are out of scope for this iteration. The URL field only accepts HTTPS URLs.
- No database schema changes:
GIT_PROVIDERis stored in the existing key-valueapp_settingstable, same as all other settings. - Provider metadata served from backend: The frontend fetches provider info from the API rather than hardcoding it. This keeps provider details in one place and makes adding new providers a backend-only change.
Testing Decisions
Tests should verify external behavior — given inputs (URL, credentials, provider), assert correct outputs (auth URL, detected provider, connection result) — without testing internal implementation details.
Modules to test (core backend only):
detect_provider(url): Given various URLs (github.com, gitlab.com, dev.azure.com, visualstudio.com, bitbucket.org, custom domains, empty strings), assert correctGitProvideris returned._get_auth_url(): Given combinations of URL, username, password, and provider, assert the constructed auth URL is correct — especially that special characters in credentials are URL-encoded, and that the correct default username is used per provider when no username is supplied.test_connection(): Test with mockedgit ls-remotesubprocess — assert success case returns{ success: True }, failure case returns{ success: False, message: <error> }, and that credentials are not leaked in error messages.
Prior art: The project uses pytest for backend tests. Existing test patterns can be found in the test directories. These are pure-function or lightly-mocked unit tests that don't require database or network access.
Out of Scope
- SSH remote support: Only HTTPS URLs are supported. SSH may be added in a future iteration.
- OAuth browser flows: No OAuth integration with any provider. Users must create PATs/tokens manually.
- Pull Request / Merge Request creation: The app pushes directly to the configured branch. Creating PRs via provider REST APIs is a separate feature.
- Webhooks or branch protection checks: No integration with provider-side policies.
- Frontend component tests: Only backend unit tests are in scope.
- Strict URL validation: No blocking validation — only soft hints via placeholder text.
Further Notes
- The credential URL-encoding fix is the single highest-priority item. Even without the UX polish, this fix alone unblocks Azure DevOps users whose PATs contain special characters.
- The
GET /providersendpoint makes the system extensible — adding a new provider (e.g., Gitea, Forgejo) is a matter of adding an entry toPROVIDER_METADATAin the backend, with no frontend changes needed. - The
test_connectionfeature doubles as a diagnostic tool for support cases — instead of "my clone fails", admins can test credentials in isolation and report the specific error. - Azure DevOps URL format is the trickiest for users:
https://dev.azure.com/{org}/{project}/_git/{repo}. The placeholder text making this visible is likely the single biggest UX win.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Git service module and existing pytest patterns in the test directories, focusing first on detect_provider(), _get_auth_url(), and test_connection(). Then trace the settings API, git-settings component, and USER-GUIDE requirements. Done means provider metadata, encoded credentials, connection testing, persisted provider settings, adaptive UI guidance, and backend unit tests cover the specified behaviors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github, python
- Domain
- backend-api-design, documentation, frontend, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100