Skip to content

omry/llm-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

llm-auth

llm-auth is a local credential manager for LLM developer tools. It keeps API-key and subscription-OAuth credentials in an ignored project .env file, with metadata that makes each auth surface discoverable, testable, and refreshable.

It is built for local workflows where scripts, benchmarks, and agent tools need model access without committing secrets or scattering credentials across many ad hoc files.

What It Supports

  • API-key surfaces for providers such as OpenAI and OpenRouter.
  • ChatGPT subscription OAuth through LiteLLM's ChatGPT provider.
  • Redacted credential status checks.
  • Lightweight auth validation.
  • OAuth token refresh for renewable surfaces.
  • Repo-local .env auth storage with explicit metadata envelopes.

Install

pip install llm-auth

After installation, use the llm-auth command:

llm-auth status

Mental Model

A surface is a named auth target, such as chatgpt, research, or evals. Each surface has an auth mode:

  • api-key: a provider key stored in a named env var.
  • subscription-oauth: a renewable OAuth record managed through LiteLLM.

llm-auth stores those surfaces in .env as metadata envelopes. The env file must be ignored by version control.

Before using an existing .env, llm-auth checks that the file is not readable by group or other users. In Git, Sapling, and Mercurial repositories, it also checks that the file is ignored, not currently tracked, and not present in commit history.

Common Workflows

ChatGPT Subscription OAuth

# Create or refresh the ChatGPT subscription OAuth surface.
llm-auth login chatgpt

# Show redacted status for the ChatGPT surface.
llm-auth status chatgpt

# Validate the ChatGPT auth state without printing secrets.
llm-auth test chatgpt

login chatgpt uses LiteLLM's ChatGPT authenticator. LiteLLM owns the device-code flow and token exchange; llm-auth stores the resulting auth record in .env as CHATGPT_AUTH_JSON.

If the stored access token is still valid, llm-auth login chatgpt exits with ok. If a refresh token exists, it attempts refresh before opening a new device-code login.

When you already have refreshable OAuth state, renew without opening a browser:

# Refresh only the ChatGPT subscription OAuth surface.
llm-auth renew chatgpt

Device codes are sensitive while active. Never share them.

API-Key Surface

Create an API-key surface:

# Create a research surface for OpenAI. The default env var template is
# <PROVIDER>_<SURFACE>_API_KEY, so this uses OPENAI_RESEARCH_API_KEY.
llm-auth add-api-key research openai --model gpt-4.1-mini

This appends an empty env assignment to .env:

# BEGIN LLM AUTH SURFACE research api-key
# surface=research
# provider=openai
# auth=api-key
# env=OPENAI_RESEARCH_API_KEY
# model=gpt-4.1-mini
OPENAI_RESEARCH_API_KEY=
# END LLM AUTH SURFACE research api-key

Fill in the key manually, then check it:

# Show redacted status for every configured surface.
llm-auth status

# Test every configured surface.
llm-auth test

# Test only the research surface.
llm-auth test research

Use a specific env var when a provider already has a conventional name:

# Create an OpenRouter surface backed by OPENROUTER_API_KEY.
llm-auth add-api-key evals openrouter \
  --env OPENROUTER_API_KEY \
  --api-base https://openrouter.ai/api/v1 \
  --model openrouter/openai/gpt-5.4-mini

Use --key only when you intentionally want the command to write the secret:

llm-auth add-api-key research openai \
  --model gpt-4.1-mini \
  --key "$OPENAI_RESEARCH_API_KEY"

API-key surfaces do not use login or renew. Rotate them by changing the configured env var value.

LiteLLM App Integration

Apps that use LiteLLM can treat .env as the local auth bootstrap file.

For API-key surfaces, load .env before creating LiteLLM requests and read the configured env var, such as OPENAI_RESEARCH_API_KEY or OPENROUTER_API_KEY. The metadata envelope tells your app which provider, model, API base, and env var belong to a surface.

For ChatGPT subscription OAuth, load .env so CHATGPT_AUTH_JSON is present, then install the llm-auth ChatGPT/LiteLLM integration before making chatgpt/... calls. That integration makes LiteLLM read and refresh the auth record from .env instead of its default token file.

Command Reference

llm-auth status

Show redacted status for all discovered surfaces:

# Show every API-key and OAuth surface discovered in .env.
llm-auth status

Show one surface:

# Show only ChatGPT subscription OAuth status.
llm-auth status chatgpt

# Show only an API-key surface named research.
llm-auth status research

Example ChatGPT status:

{
  "chatgpt": {
    "access_token": true,
    "account_id": true,
    "auth": "subscription-oauth",
    "auth_json": true,
    "env": "CHATGPT_AUTH_JSON",
    "expired": false,
    "refresh_token": true
  }
}

Example API-key status:

{
  "research": {
    "api_key": true,
    "auth": "api-key",
    "env": "OPENAI_RESEARCH_API_KEY",
    "provider": "openai"
  }
}

Status output reports whether credentials are present, but does not print secret values.

llm-auth test

Run lightweight checks for all discovered surfaces:

# Test every configured auth surface discovered in .env.
llm-auth test

Run detailed checks for one surface:

# Test only ChatGPT subscription OAuth state.
llm-auth test chatgpt

# Test only an API-key surface named research.
llm-auth test research

For ChatGPT subscription OAuth, the default test checks that CHATGPT_AUTH_JSON exists and contains usable OAuth state. The ChatGPT backend completion path is Cloudflare-gated and is not part of the documented OpenAI API, so the live completion check is opt-in. Add live_backend=true to the chatgpt surface envelope only when you explicitly want llm-auth test chatgpt to send a live backend prompt.

For OpenAI API-key surfaces that declare a model, llm-auth test also checks model access and sends a small prompt through the official OpenAI Responses API:

llm-auth test research --model gpt-4.1-mini
llm-auth test --surface-model research=gpt-4.1-mini

llm-auth login

Create or refresh a managed login surface:

# Run the ChatGPT subscription OAuth login flow.
llm-auth login chatgpt

Today, login is for ChatGPT subscription OAuth. API-key surfaces are created with add-api-key.

llm-auth renew

Refresh renewable OAuth surfaces without a new browser/device-code flow:

# Refresh every renewable auth surface discovered in .env.
llm-auth renew

# Refresh only ChatGPT subscription OAuth.
llm-auth renew chatgpt

Use login when you need to create a new auth surface or complete a new browser/device-code flow. Use renew when a surface already has refreshable OAuth state.

llm-auth add-api-key

Create an API-key metadata envelope:

llm-auth add-api-key <surface> <provider>

Useful options:

  • --env: choose the env var name.
  • --model: record default model metadata for tests and consumers.
  • --api-base: record provider API base metadata.
  • --key: write the secret value directly.
  • --allow-unignored: allow writing to an env file that is not ignored.

By default, llm-auth refuses to write credentials unless the target is an ignored repo-root .env. Use --allow-unignored only for deliberate temporary setups; it does not bypass checks for unsafe file permissions, tracked files, or committed history.

Auth Store Format

llm-auth treats .env as a bootstrapping auth store. Each auth surface is wrapped in a metadata envelope:

# BEGIN LLM AUTH SURFACE research api-key
# surface=research
# provider=openai
# auth=api-key
# env=OPENAI_RESEARCH_API_KEY
# model=gpt-5.4-mini
# renew=false
OPENAI_RESEARCH_API_KEY=...
# END LLM AUTH SURFACE research api-key

The .env file should be ignored by version control. llm-auth sets file mode 0600 when it writes the file, where supported by the operating system. If an existing .env has broader permissions, fix it before running commands:

chmod 600 .env

Security Notes

  • Do not commit .env or copied credential values.
  • Keep .env ignored and untracked. llm-auth refuses to use it when Git, Sapling, or Mercurial reports that it is tracked or appears in commit history.
  • Prefer leaving --key out and filling the secret manually when possible.
  • Treat device codes as temporary secrets.
  • llm-auth status redacts credential presence and does not print secret values.
  • llm-auth is local tooling, not a hosted secret manager.

Requirements

  • Python 3.11 or newer.
  • LiteLLM, installed as a package dependency.

License

MIT. See LICENSE.

About

Local auth surface manager for LLM API keys and OAuth tokens.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages