Authentication
For a runnable authenticated snapshot-to-disk example, see Clone an Azure DevOps repository. It supports Entra access tokens and PATs through the existing credential types.
Existing support
Authentication is already part of the library. GitClient accepts an optional IGitCredentials instance; omitting it uses anonymous requests. GitHttpTransport calls ApplyAsync on each request before sending it, including requests recreated for transient retries.
| Type | Behavior |
|---|---|
| BasicGitCredentials | Sends Authorization: Basic with UTF-8 username:token encoded as Base64; rejects null values and a colon in the username |
| BearerGitCredentials | Sends Authorization: Bearer using the supplied token |
| IGitCredentials | Async extension point for application-managed credentials |
Basic encoding is not encryption; transport security comes from HTTPS. Choose the authentication scheme, token type, username, and permissions accepted by your repository endpoint. The client does not discover a provider-specific login mechanism.
Basic credentials
Acquire a token from your application's secret store. This standalone example uses an environment variable supplied outside source control:
using CODE.Git.Client;
var token = Environment.GetEnvironmentVariable("CODE_GIT_TOKEN")
?? throw new InvalidOperationException("Configure CODE_GIT_TOKEN before running.");
var username = Environment.GetEnvironmentVariable("CODE_GIT_USER") ?? "git";
var credentials = new BasicGitCredentials(username, token);
using var client = new GitClient(
new Uri("https://git.example.com/team/project.git"),
credentials: credentials);
var tree = await client.GetFileTreeAsync();
The git username is only an example default; use the value required by your endpoint. CODE_GIT_TOKEN and CODE_GIT_USER are example application settings, not variables automatically read by the library or sample.
Bearer credentials
using CODE.Git.Client;
var token = Environment.GetEnvironmentVariable("CODE_GIT_TOKEN")
?? throw new InvalidOperationException("Configure CODE_GIT_TOKEN before running.");
using var client = new GitClient(
new Uri("https://git.example.com/team/project.git"),
credentials: new BearerGitCredentials(token));
var tree = await client.GetFileTreeAsync();
Custom credentials and missing login features
Implement IGitCredentials.ApplyAsync(HttpRequestMessage, CancellationToken) to integrate an application-owned token provider. Apply headers to the supplied request, honor cancellation, and avoid logging or persisting secrets. The implementation is trusted application code: it should not change the target URI or leak credentials. Shared credential instances must handle any concurrent use by separate clients.
The built-in credential classes hold fixed values. There is no interactive sign-in, OAuth/device-code acquisition, automatic refresh, Git Credential Manager integration, OS credential-store lookup, SSH key handling, or challenge-driven login. If a richer authentication workflow is needed next, it should build on IGitCredentials; the host application currently supplies and manages tokens.
Credential boundaries and failures
Repository URLs must be absolute HTTPS URLs without userinfo, query, or fragment. Never put secrets in URLs. Built-in requests target the configured repository origin, and the default transport refuses all redirects, including same-origin redirects. Use the final trusted repository URL.
An injected HttpClient is a trusted boundary. Its handler must disable automatic redirects and use trusted headers, cookies, proxies, and connection-time network policy. The library cannot prevent an injected handler from forwarding a request before it observes the response. See Security and limits.
Access failures raise HttpRequestException with sanitized messages and a status code for unsuccessful HTTP responses:
| Status | Interpretation |
|---|---|
| 401 | Credentials required or rejected |
| 403 | Access forbidden |
| 404 | Repository missing, or existence concealed by the server |
These failures do not trigger credential refresh or HTTP status retries. Verify the URL, scheme, token expiry, and repository permissions in application code. Remote response bodies and progress/errors are not logged by the library.
Verification coverage
SafetyTests exercises anonymous, Basic, and Bearer schemes through fake-server requests, plus sanitized access failures and redirect refusal. Those tests check schemes rather than complete token values. ProviderTests can use Basic credentials via GITCLIENT_TEST_USER and GITCLIENT_TEST_TOKEN; it runs only when GITCLIENT_TEST_URLS is set. These tests do not establish universal provider compatibility or live Bearer coverage. See Development for commands.