# Provider Authentication Flow in Forge: OAuth Methods and Configuration Guide

> Master Forge provider authentication with our OAuth guide. Explore Initialize, Complete, and Refresh flows supporting API keys, ADC, device code, auth code, and Codex flows.

- Repository: [Forge Code/forgecode](https://github.com/antinomyhq/forgecode)
- Tags: how-to-guide
- Published: 2026-04-08

---

**The provider authentication flow in Forge is orchestrated by `ForgeProviderAuthService` through three phases—Initialize, Complete, and Refresh—supporting API keys, Google Application Default Credentials (ADC), OAuth device code, OAuth authorization code, and Codex-specific device flows.**

The `antinomyhq/forgecode` repository implements a pluggable, strategy-based authentication system that abstracts provider-specific OAuth complexities into a unified interface. This architecture allows each provider to declare supported **authentication methods** while the service coordinates credential lifecycle management.

## How the Provider Authentication Flow Works

`ForgeProviderAuthService` implements the `ProviderAuthService` trait defined in [`crates/forge_services/src/provider_auth.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_services/src/provider_auth.rs). The service drives three distinct phases:

1. **Initialize** – Prepare an auth request (device code, auth-code URL, or API-key prompt).
2. **Complete** – Consume the user response, resolve the concrete `AuthMethod`, execute the strategy, and persist the credential.
3. **Refresh** – Proactively renew expiring OAuth tokens or Google ADC credentials without user interaction.

Each phase delegates to concrete **strategies** (e.g., `OAuthDeviceStrategy`, `OAuthCodeStrategy`, `GoogleAdcStrategy`, or `ApiKeyStrategy`) created via the infrastructure factory.

## Phase 1: Initialize Authentication (`init_provider_auth`)

The initialization phase begins with `init_provider_auth`, defined at lines 27–74 in [`crates/forge_services/src/provider_auth.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_services/src/provider_auth.rs):

```rust
async fn init_provider_auth(
    &self,
    provider_id: ProviderId,
    auth_method: AuthMethod,
) -> anyhow::Result<AuthContextRequest>

```

### Collecting URL Parameters

For **API key** and **Google ADC** flows, the system first collects `url_params()` from the provider configuration (host, region, etc.):

```rust
let required_params = if matches!(auth_method, AuthMethod::ApiKey | AuthMethod::GoogleAdc) {
    // fetch the provider entry and clone its URL parameters
} else { vec![] };

```

### Strategy Creation and Execution

The service instantiates the appropriate strategy via the infrastructure factory:

```rust
let strategy = self.infra.create_auth_strategy(
    provider_id.clone(),
    auth_method.clone(),
    required_params,
)?;
let request = strategy.init().await?;

```

The `init()` call returns an `AuthContextRequest` containing provider-specific payloads (device codes, authorization URLs, or API-key field definitions).

### Credential Prefilling

If existing credentials are stored for API-key or ADC flows, the service prefills these values (lines 55–71), enabling seamless provider switching without re-entering static keys.

## Phase 2: Complete Authentication (`complete_provider_auth`)

The completion phase resolves user responses into concrete credentials via `complete_provider_auth` (lines 77–133):

```rust
async fn complete_provider_auth(
    &self,
    provider_id: ProviderId,
    auth_context_response: AuthContextResponse,
    _timeout: Duration,
) -> anyhow::Result<()>

```

### AuthMethod Detection

The service inspects `AuthContextResponse` to determine the concrete authentication type:

- **`AuthContextResponse::ApiKey`** – Maps to `ApiKey` or `GoogleAdc` (detected via the special `"google_adc_marker"` string for Vertex AI providers).
- **`AuthContextResponse::Code`** – Maps to `OAuthCode` with the supplied `OAuthConfig`.
- **`AuthContextResponse::DeviceCode`** – Maps to `OAuthDevice` or `CodexDevice` if the provider is `CODEX`.

### Strategy Completion and Persistence

After resolving the method, the service gathers URL parameters if needed, executes `strategy.complete(auth_context_response).await` to perform token exchange or API key validation, then persists the resulting credential via `upsert_credential` (line 132).

## Phase 3: Refresh Credentials (`refresh_provider_credential`)

Long-running sessions remain valid through automatic credential renewal (lines 138–200). The service iterates through each provider's `auth_methods`, identifying refreshable types (`OAuthDevice`, `OAuthCode`, `CodexDevice`, `GoogleAdc`). For each:

1. Retrieves the existing credential from storage.
2. Creates the associated strategy via the factory.
3. Executes `strategy.refresh(&existing_credential)`.
4. Persists the refreshed token if successful.

## Supported OAuth Configurations

All OAuth-capable methods carry an **`OAuthConfig`** structure defined in [`crates/forge_domain/src/auth/oauth_config.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_domain/src/auth/oauth_config.rs) (lines 12–28). The configuration fields include:

| Field | Purpose |
|-------|---------|
| `auth_url` | Authorization endpoint (e.g., `https://auth.openai.com/api/accounts/deviceauth/usercode`). |
| `token_url` | Token exchange endpoint (e.g., `https://auth.openai.com/oauth/token`). |
| `client_id` | Application identifier (`ClientId`). |
| `scopes` | Requested OAuth scopes (e.g., `["openid"]`). |
| `redirect_uri` | Optional callback URL for authorization-code flows. |
| `use_pkce` | Boolean flag enabling PKCE (RFC 7636) for enhanced security. |
| `token_refresh_url` | Optional separate endpoint for refresh token exchange. |
| `custom_headers` | Additional HTTP headers (e.g., `User-Agent`). |
| `extra_auth_params` | Custom query parameters appended to authorization requests. |

### AuthMethod Variants

The **`AuthMethod`** enum in [`crates/forge_domain/src/auth/auth_method.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_domain/src/auth/auth_method.rs) defines supported mechanisms:

- **`OAuthDevice(OAuthConfig)`** – Device-code flow where users manually enter codes at verification URLs.
- **`OAuthCode(OAuthConfig)`** – Standard authorization-code flow with browser redirects.
- **`CodexDevice(OAuthConfig)`** – Codex-specific device-code implementation.
- **`GoogleAdc`** – Google Application Default Credentials (metadata server or local ADC files).
- **`ApiKey`** – Simple header-based authentication without OAuth negotiation.

## Code Examples

### Initializing an Authentication Flow

```rust
use forge_domain::{AuthMethod, ProviderId};
use forge_services::ProviderAuthService;

let provider_id = ProviderId::VERTEX_AI;
let oauth_cfg = OAuthConfig {
    auth_url: "https://auth.example.com/device".to_string(),
    token_url: "https://auth.example.com/token".to_string(),
    client_id: "forge-client".to_string(),
    scopes: vec!["openid".to_string()],
    use_pkce: true,
    ..Default::default()
};
let method = AuthMethod::oauth_device(oauth_cfg);

let request = services
    .provider_auth_service()
    .init_provider_auth(provider_id, method)
    .await?;
// `request` contains device-code payload for UI display

```

### Completing the Flow

```rust
use forge_domain::AuthContextResponse;
use std::time::Duration;

let response = AuthContextResponse::DeviceCode(DeviceCodeResponse {
    device_code: "user-entered-code".to_string(),
    verification_url: "https://verify.example.com".to_string(),
    // ... other fields
});

services
    .provider_auth_service()
    .complete_provider_auth(
        provider_id, 
        response, 
        Duration::from_secs(30)
    )
    .await?;

```

### Refreshing Credentials Programmatically

```rust
let provider = provider_repo.get(provider_id).await?;
let refreshed = services
    .provider_auth_service()
    .refresh_provider_credential(provider)
    .await?;

```

## Key Source Files

- **[`crates/forge_services/src/provider_auth.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_services/src/provider_auth.rs)** – Core `ForgeProviderAuthService` implementation (init, complete, refresh phases).
- **[`crates/forge_domain/src/auth/auth_method.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_domain/src/auth/auth_method.rs)** – `AuthMethod` enum definition (lines 8–18).
- **[`crates/forge_domain/src/auth/oauth_config.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_domain/src/auth/oauth_config.rs)** – `OAuthConfig` struct with OAuth parameters (lines 12–28).
- **[`crates/forge_infra/src/auth/strategy.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_infra/src/auth/strategy.rs)** – Concrete strategy implementations (`OAuthDeviceStrategy`, `OAuthCodeStrategy`, `GoogleAdcStrategy`, `ApiKeyStrategy`).
- **[`crates/forge_app/src/services.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_app/src/services.rs)** – High-level service wiring exposing `provider_auth_service()` to UI layers.

## Summary

- The **provider authentication flow in Forge** follows a three-phase lifecycle: Initialize, Complete, and Refresh.
- **`ForgeProviderAuthService`** in [`provider_auth.rs`](https://github.com/antinomyhq/forgecode/blob/main/provider_auth.rs) coordinates generic authentication through strategy delegation.
- Supported methods include **OAuth device code**, **OAuth authorization code**, **Google ADC**, **Codex device flows**, and **API keys**.
- **`OAuthConfig`** provides granular control over endpoints, scopes, PKCE, and custom headers.
- Automatic credential refresh ensures long-running sessions remain valid without manual re-authentication.

## Frequently Asked Questions

### What authentication methods does Forge support for AI providers?

Forge supports five distinct authentication methods defined in the `AuthMethod` enum: `ApiKey` for header-based authentication, `OAuthDevice` for device-code flows, `OAuthCode` for authorization-code redirects, `GoogleAdc` for Google Application Default Credentials, and `CodexDevice` for Codex-specific device authentication. Each method is implemented as a discrete strategy in the `forge_infra` crate.

### How does Forge handle OAuth token expiration?

The `refresh_provider_credential` method (lines 138–200 in [`provider_auth.rs`](https://github.com/antinomyhq/forgecode/blob/main/provider_auth.rs)) proactively renews tokens by iterating through refreshable auth methods, retrieving stored credentials, and invoking `strategy.refresh(&existing_credential)` for `OAuthDevice`, `OAuthCode`, `CodexDevice`, and `GoogleAdc` flows. Refreshed tokens are automatically persisted to the credential repository.

### What is the difference between `OAuthDevice` and `OAuthCode` in Forge?

`OAuthDevice` implements the device authorization grant (RFC 8628) where users manually enter codes at verification URLs, suitable for CLI environments without browser access. `OAuthCode` implements the standard authorization-code flow with browser redirects, requiring a `redirect_uri` in the `OAuthConfig`. Both use the same configuration structure but employ distinct strategy implementations in [`crates/forge_infra/src/auth/strategy.rs`](https://github.com/antinomyhq/forgecode/blob/main/crates/forge_infra/src/auth/strategy.rs).

### Can providers use custom OAuth parameters like PKCE?

Yes. The `OAuthConfig` struct includes a `use_pkce` boolean field to enable PKCE (RFC 7636) for public clients, along with `custom_headers` and `extra_auth_params` fields for provider-specific requirements. These are passed through the strategy factory when constructing `OAuthDeviceStrategy` or `OAuthCodeStrategy` instances.