# How the Codex Plugin Handles Authentication Status: A Technical Deep Dive

> Understand how the Codex plugin manages authentication status by querying app-server for account details and normalizing responses into a unified auth status object.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: deep-dive
- Published: 2026-08-05

---

**The Codex plugin determines authentication status by querying the app-server for account details and provider configuration, normalizing the responses into a unified auth status object that indicates login state, method, and verification details.**

The authentication flow in the `openai/codex-plugin-cc` repository centers on reliable detection of user credentials across multiple auth methods. Whether the user signs in via ChatGPT, configures an API key, or uses a provider that requires no OpenAI authentication at all, the plugin provides consistent status reporting through a single entry point.

## How Authentication Status Is Retrieved

The core function **`getCodexAuthStatusFromClient`** in `plugins/codex/scripts/lib/codex.mjs` orchestrates all authentication checks. This async function makes dual requests to the app-server and transforms the results into a predictable format.

### The Dual-Request Pattern

The function issues two RPC calls in sequence:

1. **`account/read`** – retrieves user account information
2. **`config/read`** – fetches provider configuration for the current workspace

```ts
// plugins/codex/scripts/lib/codex.mjs
async function getCodexAuthStatusFromClient(client, cwd) {
  try {
    const accountResponse = await client.request("account/read", { refreshToken: false });
    const configResponse  = await client.request("config/read", { includeLayers: false, cwd });
    return buildAppServerAuthStatus(accountResponse, configResponse);
  } catch (error) {
    return buildAuthStatus({
      loggedIn: false,
      detail:   error instanceof Error ? error.message : String(error),
      source:   "app-server"
    });
  }
}

```

Any failure in these requests immediately results in a logged-out status with error details preserved for debugging.

## Building the Auth Status Object

Raw server responses pass through **`buildAppServerAuthStatus`**, which applies conditional logic to determine the final authentication state.

### Auth Method Detection Logic

The plugin recognizes three distinct authentication patterns:

| Condition | Result |
|-----------|--------|
| `account.type === "chatgpt"` | **ChatGPT login** – `loggedIn: true`, `authMethod: "chatgpt"`, email included in detail |
| `account.type === "apiKey"` | **API key auth** – `loggedIn: true`, `authMethod: "apiKey"`, unverified status noted |
| `requiresOpenaiAuth === false` | **Provider bypass** – `loggedIn: true`, `authMethod: null`, provider name displayed |

When none of these conditions match, the status reports `loggedIn: false` with a message indicating OpenAI authentication is required.

### Standardized Output Format

The helper **`buildAuthStatus`** enforces consistent field presence across all codepaths:

```ts
{
  available: true,           // Service connectivity confirmed
  loggedIn: boolean,         // Core authentication state
  detail: string,            // Human-readable status message
  source: "app-server",      // Origin of this status
  authMethod: "chatgpt" | "apiKey" | null,
  verified: boolean | null,  // Email verification status (ChatGPT only)
  requiresOpenaiAuth: boolean | null,
  provider: string | null    // Derived from config via formatProviderLabel
}

```

## Programmatic Auth Checks

### Inside Plugin Scripts

```ts
// Programmatically checking auth status inside a Codex plugin script
import { createClient } from "./lib/app-server.mjs";

async function checkAuth(cwd) {
  const client = await createClient({ cwd });
  const auth = await getCodexAuthStatusFromClient(client, cwd);
  console.log(`Codex auth: ${auth.loggedIn ? "✅ logged in" : "❌ not logged in"}`);
  console.log(`Method: ${auth.authMethod ?? "none"}`);
  console.log(`Detail: ${auth.detail}`);
}

```

### Direct Helper Usage

```js
// Direct use of the exported helper (as done by the status command)
import { getCodexAuthStatusFromClient } from "./plugins/codex/scripts/lib/codex.mjs";

const client = await createClient({ cwd: process.cwd() });
const authInfo = await getCodexAuthStatusFromClient(client, process.cwd());
console.log(authInfo);

```

## User-Facing Status Command

The built-in **`!codex status`** command surfaces this information for end users:

```bash
!codex status

# Output:

# Codex auth: ✅ logged in (ChatGPT login active for user@example.com)

# Method: chatgpt

```

This command wires directly into the same `getCodexAuthStatusFromClient` function, ensuring CLI output matches internal plugin state.

## Key Source Files

| File | Role |
|------|------|
| `plugins/codex/scripts/lib/codex.mjs` | Core implementation: `getCodexAuthStatusFromClient`, `buildAppServerAuthStatus` |
| [`plugins/codex/commands/status.md`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/commands/status.md) | User-facing command definition |
| `plugins/codex/scripts/lib/app-server.mjs` | Client factory for app-server RPC |
| `plugins/codex/scripts/lib/render.mjs` | UI formatting for auth status display |

## Summary

- **`getCodexAuthStatusFromClient`** is the single source of truth for authentication status in the Codex plugin
- The plugin queries both **account** and **config** endpoints to determine complete auth state
- Three auth methods are supported: **ChatGPT login**, **API key**, and **provider-level bypass**
- All failures are caught and normalized into consistent `loggedIn: false` responses with error details
- The standardized status object includes `authMethod`, `verified`, and `requiresOpenaiAuth` for downstream decision-making

## Frequently Asked Questions

### How does the Codex plugin check if I'm logged in?

The plugin sends two requests to the app-server: `account/read` for user credentials and `config/read` for provider settings. These run through `getCodexAuthStatusFromClient` in `plugins/codex/scripts/lib/codex.mjs`, which returns a normalized object with `loggedIn: true` or `loggedIn: false`.

### What authentication methods does the Codex plugin support?

The plugin recognizes **ChatGPT account login** (`authMethod: "chatgpt"`), **API key configuration** (`authMethod: "apiKey"`), and **provider-level authentication bypass** (`authMethod: null` when `requiresOpenaiAuth` is false).

### What happens if the app-server is unreachable?

Any network or RPC error triggers the catch block in `getCodexAuthStatusFromClient`, returning `loggedIn: false` with the error message preserved in the `detail` field and `source: "app-server"` for troubleshooting.

### Can I check authentication status programmatically?

Yes. Import `getCodexAuthStatusFromClient` from `plugins/codex/scripts/lib/codex.mjs`, create a client via `createClient` from `app-server.mjs`, and await the auth status. The function is fully async and designed for both internal use and plugin extension authors.