Originally created by: kumaakh
`provision_vcs_auth` deploys git credentials to fleet members so they can perform HTTPS git operations autonomously. The architecture differs significantly by provider — and GitHub's path is the right model.
When `github_mode: github-app` is used, `provision_vcs_auth` mints a short-lived installation token from the configured GitHub App rather than storing a personal credential:
This is the right model. The plaintext credential file on the member machine is a real trade-off, but with a 1-hour TTL the blast radius of any exposure is narrow.
The current implementation always writes to a single hardcoded file:
And registers it at host scope in `.gitconfig`:
[credential "https://github.com"]
helper = ~/.fleet-git-credential.bat
This fails in any multi-identity scenario:
| Scenario | Problem |
|---|---|
| Work GitHub + Personal GitHub | Second provision_vcs_auth overwrites the file — first identity gone |
| GitHub + Bitbucket | Same file serves both hosts — file contains one provider's token |
| Two Bitbucket workspaces with different logins | No way to differentiate at all |
| Any credential rotation | Overwrites any other active credential for that host |
Git credential helpers support URL-prefix scoping, not just host scoping:
[credential "https://github.com/work-org"]
helper = ~/.fleet-git-credential-work.bat
[credential "https://github.com/personal"]
helper = ~/.fleet-git-credential-personal.bat
The most specific URL prefix wins. This means per-identity, per-org, or per-repo-set credentials are all representable — if the implementation uses it.
label parameter to provision_vcs_authA short slug that uniquely identifies this credential registration on the member (e.g. work-github, bitbucket-main, personal-gh). Defaults to the provider name for backwards compatibility.
scope_url parameter (optional)The URL prefix to register in `.gitconfig`. Defaults to https://<host> (current behaviour). For org-scoped access: https://github.com/my-org.
~/.fleet-git-credential-<label>.bat (Windows)
~/.fleet-git-credential-<label> (Linux)
Each provision_vcs_auth call writes its own file and registers its own gitconfig entry. Multiple identities coexist without collision.
revoke_vcs_auth removes the file and the gitconfig entry for the given label.
Do not replace the credential file with a shim that calls back to apra-fleet (`apra-fleet git-credential --host github.com`). Any process running as the same OS user could call that shim and extract any stored credential without authentication — making apra-fleet a local unauthenticated secrets API.
| Provider | Minting | TTL | Notes |
|---|---|---|---|
| GitHub | ✅ GitHub App installation tokens | ~1 hour | Current implementation — the right model |
| Azure DevOps | ✅ Entra ID service principal tokens | ~1 hour, auto-rotating | Uses bearer token in HTTP header or git URL; non-personal, supports managed identities |
| Bitbucket | ⚠️ Workspace access tokens | Days–365 days (admin-configurable) | Scoped to repos/permissions but not short-lived; no sub-hour minting. App passwords deprecated June 2026 |
Azure DevOps has a viable minting path (service principal → Entra ID token) that should be wired up. Bitbucket workspace tokens are an improvement over personal API tokens but lack auto-rotation — plaintext file is the only current option.
Windows backslashes written to `.gitconfig` are stripped by bash. The helper call fails silently and git falls back to `credential.helper=store`.
Fix: Use forward slashes in the gitconfig value when writing from bash contexts.
provision_vcs_auth accepts label (slug, default: provider name) and optional scope_url (default: https://<host>)~/.fleet-git-credential-<label>.bat / ~/.fleet-git-credential-<label>scope_url as the credential URL keyrevoke_vcs_auth removes by label (file + gitconfig entry).gitconfig uses forward slashes (bash/WSL compatible)provision_vcs_auth, remove legacy ~/.fleet-git-credential.bat / ~/.fleet-git-credential if present
Originally posted by: kumaakh
Technical direction: This is a well-scoped design issue. Recommended implementation order:
evoke_vcs_auth to accept label and remove only the matching file + gitconfig entry.
Azure DevOps Entra ID minting and Bitbucket workspace token support can be a follow-up sprint — the label/scope_url isolation fix is the blocking part and can ship independently.
Related
Tickets:
#157Originally posted by: kumaakh
Addressed in PR [#183] (sprint/session-lifecycle-oob-fix → main).
Changes shipped: provision_vcs_auth now writes per-label isolated credential files instead of a single shared file.
PR is open for testing — will be merged once testing is complete.
Related
Tickets:
#183Ticket changed by: kumaakh