# How Pi‑Web Handles Dual‑Auth Providers Like Anthropic and GitHub Copilot

> Discover how Pi-Web's capability-based architecture handles dual-auth providers like Anthropic and GitHub Copilot, dynamically detecting API-key and OAuth support for seamless integration.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: internals
- Published: 2026-08-15

---

**Pi‑Web authenticates dual‑auth providers through a capability‑based architecture that dynamically detects API‑key and OAuth support, then exposes separate provider lists with cross‑reference flags to prevent UI duplication and credential type mismatches.**

The **pi‑web** repository implements a flexible authentication system that adapts to providers offering multiple login methods. Unlike single‑method providers, **dual‑auth providers** such as **Anthropic** and **GitHub Copilot** require the system to simultaneously track both API‑key and OAuth capabilities while ensuring users cannot accidentally mix credential types.

## Detecting Provider Capabilities at Runtime

The system begins by interrogating the Pi SDK to determine which authentication methods each provider supports. In [`lib/provider‑listing‑runtime.ts`](https://github.com/agegr/pi-web/blob/main/lib/provider-listing-runtime.ts#L25-L30), the `collectProviderListingInputs()` function inspects the provider’s `auth` object to extract boolean flags for `hasApiKeyLogin` and `hasOAuth`.

This runtime detection ensures that dual‑auth providers are identified dynamically rather than hard‑coded. When the function processes Anthropic or GitHub Copilot, both flags return `true`, signaling to downstream components that the provider appears in both authentication lists.

## Building Separate Provider Lists with Cross‑Reference Flags

Once capabilities are detected, the system constructs distinct lists for each authentication method while preserving the dual‑auth relationship through metadata flags.

### API‑Key Provider List Construction

The `buildApiKeyProviderList()` function in [`lib/provider‑listing.ts`](https://github.com/agegr/pi-web/blob/main/lib/provider-listing.ts#L81-L99) generates the list of providers accepting API keys. For each provider that also supports OAuth, it appends a `supportsOAuth: true` flag. This allows the UI to indicate that API‑key login is not the exclusive method available.

### OAuth Provider List Construction

Conversely, `buildOAuthProviderList()` in [`lib/provider‑listing.ts`](https://github.com/agegr/pi-web/blob/main/lib/provider-listing.ts#L102-L116) creates the OAuth‑capable list and adds a `supportsApiKey: true` flag for dual‑auth providers. This symmetry ensures that regardless of which authentication method a user initially selects, the interface can inform them of the alternative.

```typescript
// Runtime detection of dual‑auth capabilities
const modelRuntime = await ModelRuntime.create();
const inputs = await collectProviderListingInputs(modelRuntime);

// Build API‑key list with OAuth flags for dual‑auth providers
const apiKeyList = buildApiKeyProviderList(inputs);
// Returns: [{ id: 'anthropic', name: 'Anthropic', supportsOAuth: true }, ...]

// Build OAuth list with API‑key flags
const oauthList = buildOAuthProviderList(inputs);
// Returns: [{ id: 'anthropic', name: 'Anthropic', supportsApiKey: true }, ...]

```

## API Routes for Dual‑Auth Provider Discovery

The separation of concerns continues at the API layer, where dedicated endpoints serve each authentication type while maintaining consistency for dual‑auth entries.

### Listing API‑Key Capable Providers

The `GET /api/auth/all‑providers` endpoint in [`app/api/auth/all‑providers/route.ts`](https://github.com/agegr/pi-web/blob/main/app/api/auth/all-providers/route.ts#L7-L12) returns providers that accept API keys, explicitly including dual‑auth providers like Anthropic and GitHub Copilot. The route implementation leverages the `supportsOAuth` flag to annotate these entries, informing the frontend that OAuth is also available.

### OAuth Provider Endpoints

A corresponding OAuth endpoint (mirroring the structure shown in the API‑key implementation) serves the OAuth provider list, utilizing the `supportsApiKey` flag to mark dual‑auth providers. This prevents the UI from rendering duplicate provider tiles while still offering users the choice of authentication method.

## Managing Credentials Safely

Dual‑auth support introduces complexity when deleting or updating credentials, as the system must verify that the operation matches the stored authentication type.

### Type‑Safe Deletion and Conflict Prevention

In [`app/api/auth/api‑key/[provider]/route.ts`](https://github.com/agegr/pi-web/blob/main/app/api/auth/api-key/%5Bprovider%5D/route.ts#L64-L70), the DELETE handler checks the existing credential type before proceeding. If a user attempts to delete an API key for a provider that is currently authenticated via OAuth, the endpoint returns a **409 Conflict** status with a descriptive error message.

```typescript
// Example: Safely deleting credentials with type checking
const response = await fetch(`/api/auth/api-key/${provider}`, { 
  method: 'DELETE' 
});

if (response.status === 409) {
  const data = await response.json();
  console.error(data.error); 
  // Output: "Provider is authenticated with OAuth, not an API key"
}

```

This validation prevents accidental deletion of the wrong credential type and ensures that dual‑auth providers maintain clean, unambiguous authentication state.

## Summary

- **Capability Detection**: The system inspects `hasApiKeyLogin` and `hasOAuth` flags at runtime via `collectProviderListingInputs()` to identify dual‑auth providers dynamically.
- **Flag‑Based Lists**: `buildApiKeyProviderList()` and `buildOAuthProviderList()` add reciprocal `supportsOAuth` and `supportsApiKey` flags to prevent UI duplication.
- **Dedicated Endpoints**: Separate API routes serve API‑key and OAuth provider lists, with explicit handling for dual‑auth cases in the `/api/auth/all‑providers` route.
- **Type Safety**: Credential deletion operations validate the stored authentication method, returning 409 errors when attempting to delete mismatched types.

## Frequently Asked Questions

### How does the system prevent duplicate provider entries in the UI?

The system utilizes the `supportsOAuth` and `supportsApiKey` boolean flags generated during list construction. When rendering provider tiles, the UI checks these flags to display a provider only once while indicating the availability of alternative authentication methods.

### What happens if I try to delete an API key for a provider authenticated via OAuth?

The DELETE handler in `app/api/auth/api-key/[provider]/route.ts` validates the stored credential type. If the provider is currently authenticated via OAuth, the endpoint returns a **409 Conflict** error with a message explaining the mismatch, preventing accidental deletion of OAuth credentials.

### Are dual‑auth providers hard‑coded in the pi‑web repository?

No. The repository uses runtime capability detection through `collectProviderListingInputs()` to inspect each provider's `auth` configuration. This allows the system to automatically recognize new dual‑auth providers as they are added to the Pi SDK without code changes.

### Can a provider support both authentication methods simultaneously for the same user?

While the system tracks both capabilities via flags, it enforces type safety during credential operations. A user can configure both methods, but the deletion and validation logic ensures operations target the correct credential type, preventing conflicts between API‑key and OAuth sessions.