# How the Codex Plugin Handles Authentication Status Checking

> Discover how the Codex plugin checks authentication status by querying the app-server and normalizing auth details into a unified object. Learn more about its internal workings.

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

---

**The Codex plugin checks authentication by querying the app-server for account details and provider configuration, normalizing the results into a unified auth status object in `plugins/codex/scripts/lib/codex.mjs`.**

Understanding how the `openai/codex-plugin-cc` repository verifies user authentication is essential for developers building on top of the Codex platform. The authentication status checking system determines whether a user is logged in, identifies the authentication method used, and assesses whether the configured provider requires OpenAI credentials. This guide examines the complete authentication flow, from RPC requests to status object construction.

## Core Authentication Flow in `getCodexAuthStatusFromClient`

The entry point for authentication status checking is **`getCodexAuthStatusFromClient`** in **`plugins/codex/scripts/lib/codex.mjs`**. This async function orchestrates two parallel information-gathering operations against the Codex **app-server**.

```javascript
// 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"
    });
  }
}

```

The function performs these **two RPC requests**:

- **`"account/read"`** – Retrieves account information with `refreshToken: false` to avoid unnecessary token refreshes during status checks
- **`"config/read"`** – Fetches provider configuration with `includeLayers: false` for efficiency, scoped to the current working directory (`cwd`)

Error handling is defensive: any thrown error normalizes to a consistent "not logged in" state with the error message preserved for debugging.

## Building the Auth Status Object with `buildAppServerAuthStatus`

Raw RPC responses undergo transformation in **`buildAppServerAuthStatus`**, which applies provider-specific logic to determine the final authentication state. The function evaluates conditions in priority order:

| Condition | Resulting Auth State |
|-----------|-------------------|
| `account.type === "chatgpt"` | `loggedIn: true`, `authMethod: "chatgpt"`, `detail` includes email when available |
| `account.type === "apiKey"` | `loggedIn: true`, `authMethod: "apiKey"`, `detail: "API key configured (unverified)"` |
| `requiresOpenaiAuth === false` | `loggedIn: true`, `authMethod: null`, `detail: "<provider> is configured and does not require OpenAI authentication"` |
| Default / error case | `loggedIn: false`, `detail: "<provider> requires OpenAI authentication"` |

The **helper `buildAuthStatus`** injects standard fields across all code paths. The provider label is resolved from configuration via `formatProviderLabel`. The complete status object structure:

```typescript
{
  available: true,
  loggedIn: boolean,
  detail: string,
  source: "app-server",
  authMethod: "chatgpt" | "apiKey" | null,
  verified: boolean | null,
  requiresOpenaiAuth: boolean | null,
  provider: string | null
}

```

This normalized shape ensures consistent consumption across the plugin's UI layer and command handlers.

## Programmatic Authentication Checking

For plugin scripts requiring direct auth verification, import and invoke the core function:

```javascript
// Example: 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}`);
}

```

The **`createClient`** utility (from `plugins/codex/scripts/lib/app-server.mjs`) establishes the RPC connection to the app-server, handling transport details transparently.

## Command-Line Authentication Status

End users interact with authentication status through the built-in **`!codex status`** command, which surfaces the evaluated state:

```bash

# Using the built-in command to see auth status

!codex status

# Output (example)

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

# Method: chatgpt

```

Command implementation resides in **[`plugins/codex/commands/status.md`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/commands/status.md)**, which delegates to the same `getCodexAuthStatusFromClient` function for consistency.

Direct helper usage in external tooling:

```javascript
// 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);

```

## Key Files in the Authentication System

| File | Role |
|------|------|
| [`plugins/codex/scripts/lib/codex.mjs`](https://github.com/openai/codex-plugin-cc/blob/main/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)](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/commands/status.md) | User-facing command surfacing auth status |
| [`plugins/codex/scripts/lib/app-server.mjs`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/scripts/lib/app-server.mjs) | RPC client creation for `"account/read"` and `"config/read"` requests |
| [`plugins/codex/scripts/lib/render.mjs`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/scripts/lib/render.mjs) | UI formatting for auth status display |

## Summary

- **Authentication status checking** centers on `getCodexAuthStatusFromClient` in `plugins/codex/scripts/lib/codex.mjs`
- **Dual RPC pattern**: `"account/read"` and `"config/read"` requests to the app-server provide complete authentication context
- **Normalized output**: `buildAppServerAuthStatus` and `buildAuthStatus` produce consistent status objects regardless of provider or error conditions
- **Three auth methods detected**: ChatGPT login, API key configuration, and provider-native auth (no OpenAI credentials required)
- **Consistent consumption**: Same core logic powers programmatic scripts, CLI commands, and UI rendering

## Frequently Asked Questions

### What RPC requests does the Codex plugin use to check authentication?

The plugin issues two requests to the app-server: `"account/read"` with `{ refreshToken: false }` to fetch account information without triggering token refresh, and `"config/read"` with `{ includeLayers: false, cwd }` to obtain provider configuration scoped to the current directory. Both are performed by `getCodexAuthStatusFromClient` in `plugins/codex/scripts/lib/codex.mjs`.

### How does the plugin handle authentication errors?

Errors in `getCodexAuthStatusFromClient` are caught and normalized through `buildAuthStatus` into a consistent failure state: `loggedIn: false` with the error message preserved in `detail` and `source: "app-server"`. This ensures downstream consumers receive predictable data even when the app-server is unreachable or returns malformed responses.

### What authentication methods can the Codex plugin detect?

The plugin recognizes three authentication states: **ChatGPT login** (`authMethod: "chatgpt"` with user email), **API key configuration** (`authMethod: "apiKey"`), and **provider-native authentication** (`authMethod: null` when `requiresOpenaiAuth: false`). Each state produces appropriate `loggedIn: true` with descriptive `detail` text for user presentation.

### Where is the authentication status displayed to users?

The `!codex status` command (defined in [`plugins/codex/commands/status.md`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/commands/status.md)) invokes the auth checking logic and presents formatted results. Additional formatting for companion UI interfaces is handled by `plugins/codex/scripts/lib/render.mjs`.