---
title: "Providers & credentials — Git for Laravel | Roundly"
description: "Resolve GitHub, GitLab or Bitbucket from the Git facade, authenticate with a token, OAuth or GitHub App credential, or read public repos anonymously."
url: https://roundly-consulting.com/open-source/docs/git-for-laravel/providers
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Git for Laravel](https://roundly-consulting.com/open-source/docs/git-for-laravel.md)

# Providers & credentials

Resolve a provider through the Git facade. With a token in config you don’t pass a credential at all; an explicit credential always overrides config:

```php
use RoundlyConsulting\Git\Dto\Credentials\Token;
use RoundlyConsulting\Git\Enums\ProviderName;
use RoundlyConsulting\Git\Facades\Git;
use RoundlyConsulting\Git\Providers\Gitlab;

$github = Git::github();                       // uses config('git.providers.github.token')
$github = Git::github(Token::from('ghp_...')); // explicit override
$gitlab = Git::gitlab();
$bitbucket = Git::bitbucket();

$gitlab = Git::provider('gitlab');             // by string,
$gitlab = Git::provider(ProviderName::Gitlab); // by ProviderName enum,
$gitlab = Git::provider(Gitlab::class);        // or by class-string
```

## How the default credential is chosen

- When git.providers.github.app.id, installation\_id and private\_key are all set, a self-refreshing GithubAppToken is built from them.
- With any of the three missing, the provider’s token (GITHUB\_TOKEN, GITLAB\_TOKEN, BITBUCKET\_TOKEN) becomes a static Token. An app configured only for Git::githubApp() — id and key, with installation ids arriving per customer — is a normal setup, not an error.
- With neither, the provider is unauthenticated and reads public repositories anonymously — no Authorization header is sent at all, and you get the forge’s anonymous quota (60 requests an hour on GitHub). Writes throw InvalidCredentialsException.

## Credential types

| Credential | Build with | Accepted by |
| --- | --- | --- |
| `Token` | `Token::from($token)` | GitHub, GitLab, Bitbucket — a static personal or API token. |
| `OauthToken` | `OauthToken::forProvider(…) / OauthToken::for(…)` | GitHub, GitLab — self-refreshing OAuth access token. |
| `GithubAppToken` | `GithubAppToken::for($appId, $installationId, $privateKey)` | GitHub — self-refreshing installation token, optionally scoped. |
| `GithubApp` | `GithubApp::for($appId, $privateKey)` | GitHub — the app’s own RS256 JWT, for /app/\*\* endpoints only. |

You can also authenticate a resolved provider yourself and inspect what it accepts:

```php
$provider = Git::provider('github');          // unauthenticated when nothing is configured
$provider->isAuthenticated();                   // false

$provider->authenticate(Token::from($user->github_token));
$provider->isAuthenticated();                   // true

$provider->authenticationMethods();             // [Token::class, GithubAppToken::class, GithubApp::class, OauthToken::class]
$provider->name();                              // "GitHub"
$provider->providerName();                      // ProviderName::Github
```

Passing a credential a provider doesn’t accept throws InvalidCredentialsException listing the supported methods. Every credential redacts its secrets (••••) in toArray() and toJson(), so it never serializes into logs.

## Authentication errors

A 401 — the forge refusing the credential itself — throws InvalidCredentialsException: “requires authentication” when none was configured, “rejected the credential” when the token is invalid, revoked or expired (the forge’s response is getPrevious()). Every other refusal stays Laravel’s RequestException, so you can read its status: a repository you cannot see is a 404 (GitHub hides private repositories from callers without access), and a throttled 403 or 429 stays retryable rather than being mistaken for a broken credential. The same goes for a 401 while minting a GitHub App installation token (a revoked or wrong app key) or refreshing an OAuth token.

```php
use Illuminate\Http\Client\RequestException;
use RoundlyConsulting\Git\Exceptions\InvalidCredentialsException;

try {
    $repository = Git::github()->repo('acme/api')->get();
} catch (InvalidCredentialsException $e) {
    // 401: "requires authentication" (none configured) or "rejected the credential"
    report($e->getPrevious());   // the forge's own response
} catch (RequestException $e) {
    $e->response->status();      // 404 = missing or not visible, 403/429 = throttled
}
```

## Extending the manager

GitHub, GitLab and Bitbucket are the providers this package speaks — provider() resolves only those, by config key, driver class or ProviderName. There are two extension points. GitManager is macroable, so you can register your own shortcuts on top of the drivers and call them through the facade:

```php
use RoundlyConsulting\Git\Dto\Credentials\Token;
use RoundlyConsulting\Git\Facades\Git;
use RoundlyConsulting\Git\Handles\RepositoryHandle;

Git::macro('app', fn (): RepositoryHandle => $this->github()->repo('acme/app'));
Git::macro('forUser', fn (User $user) => $this->github(Token::from($user->github_token)));

Git::app()->pullRequests();          // same as Git::github()->repo('acme/app')->pullRequests()
Git::forUser($user)->repositories();
```

The drivers are resolved from the container and are not final, so you can swap a built-in one for a subclass — to add an endpoint, say. Git::github(), Git::capabilities() and the fake’s feature matrix all pick the subclass up:

```php
use RoundlyConsulting\Git\Providers\Github;

$this->app->bind(Github::class, AcmeGithub::class); // class AcmeGithub extends Github { … }
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/git-for-laravel.md)
