How the Codex Plugin Handles Authentication Status Checking

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.

// 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:

{
  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:

// 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:


# 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, which delegates to the same getCodexAuthStatusFromClient function for consistency.

Direct helper usage in external tooling:

// 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 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 surfacing auth status
plugins/codex/scripts/lib/app-server.mjs RPC client creation for "account/read" and "config/read" requests
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) invokes the auth checking logic and presents formatted results. Additional formatting for companion UI interfaces is handled by plugins/codex/scripts/lib/render.mjs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →