> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI OAuth Login

> Sign in to LLM providers using browser-based OAuth or device-code flow — tokens auto-refresh in the background

Sign in to any supported provider with a single command. OAuth tokens refresh automatically, so you never have to re-paste an API key.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(
    name="Researcher",
    instructions="Answer questions using Gemini.",
    model="gemini/gemini-1.5-pro",
)

agent.start("Summarise the RFC 8628 device-code flow in three bullets.")
```

The user runs `praisonai auth login`; OAuth tokens are stored and refreshed so agents call the provider without pasting API keys.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "praisonai auth login --method oauth"
        U[👤 User] --> Cmd[💻 praisonai auth login github<br/>--method oauth --client-id ...]
        Cmd --> Reg{🔎 Provider in<br/>OAUTH_PROVIDERS?}
        Reg -->|Yes| Cid{🔑 client_id set?}
        Reg -->|No| Ovr{📥 Endpoint overrides<br/>via flags?}
        Cid -->|Yes| Flow[🌐 Device / PKCE flow]
        Cid -->|No| Hint[💬 Info: pass --client-id]
        Ovr -->|Yes| Flow
        Ovr -->|No| Fail[❌ Error: not OAuth-capable]
        Flow --> Store[💾 ~/.praisonai/credentials.json]
        Hint --> APIKey[🔑 API-key fallback]
        Store --> Agent[🤖 Agent auto-refreshes token]
    end

    classDef user fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff
    classDef store fill:#6366F1,stroke:#7C90A0,color:#fff

    class U user
    class Cmd,Flow,Hint,APIKey process
    class Reg,Cid,Ovr decision
    class Agent ok
    class Store store
    class Fail decision
```

## Quick Start

<Steps>
  <Step title="Log in with browser (recommended)">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth login github --method oauth --client-id <your-github-oauth-app-client-id>
    ```

    GitHub uses the device-code flow (no local browser callback listener): a short code prints, a browser tab opens to the verification page, and credentials are stored once you approve.
  </Step>

  <Step title="Log in on a headless server (device code)">
    On a machine without a browser, add `--no-browser` to get a device code:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth login github --method oauth --client-id <your-github-oauth-app-client-id> --no-browser
    ```

    ```
    To sign in, visit https://github.com/login/device and enter code: ABCD-1234
    ```

    Enter the code on any device, then come back — the CLI detects approval automatically.
  </Step>

  <Step title="Force API-key login">
    If you prefer to manage keys manually, use `--method apikey`:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth login openai --method apikey
    ```

    You'll be prompted for the key interactively (hidden input), or pipe it:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    echo "sk-..." | praisonai auth login openai --method apikey --key-stdin
    ```
  </Step>

  <Step title="Check auth status and expiry">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth list
    ```

    ```
    Provider    Method    Expiry
    ----------  --------  -------
    github      oauth     2h 14m
    openai      apikey    (n/a)
    ```

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth status github
    ```

    Shows whether the current token is valid and when it expires.
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI as praisonai auth login
    participant OAuth as OAuth Provider
    participant Store as Credential Store
    participant Agent

    User->>CLI: auth login github --method oauth --client-id ...
    CLI->>OAuth: Request device code (RFC 8628)
    OAuth-->>CLI: device_code, user_code, verification_uri
    CLI->>User: "Visit <url>, enter code: XXXX-YYYY"
    User->>OAuth: Approve in browser
    OAuth-->>CLI: access_token + refresh_token
    CLI->>Store: store_oauth_credential(provider, tokens)
    Store-->>CLI: ✅ Saved to ~/.praisonai/credentials.json

    Note over Agent: Later...
    Agent->>Store: load credentials for github
    Store-->>Agent: access_token (auto-refreshed if needed)
    Agent->>OAuth: API call with token
```

***

## Auth Methods

| Method   | Flag              | When to use                                                                              |
| -------- | ----------------- | ---------------------------------------------------------------------------------------- |
| `auto`   | (default)         | Uses OAuth if provider supports it and no `--key` is given; falls back to API-key prompt |
| `oauth`  | `--method oauth`  | Always use OAuth, even if a key is available                                             |
| `apikey` | `--method apikey` | Always use API key, skip OAuth discovery                                                 |

***

## Provider Compatibility

| Provider             | API-key login |           OAuth login          |
| -------------------- | :-----------: | :----------------------------: |
| `github`             |       ✅       |   ✅ (requires `--client-id`)   |
| `google` / `gemini`  |       ✅       |   ✅ (requires `--client-id`)   |
| `azure`              |       ✅       |   ✅ (requires `--client-id`)   |
| `anthropic`          |       ✅       |                ❌               |
| `openai`             |       ✅       |                ❌               |
| Custom / self-hosted |       ✅       | ✅ (supply endpoints via flags) |

Use `praisonai auth login <provider> --method auto` — the CLI auto-detects whether OAuth is supported. Registry providers need a `--client-id`; without one, `auto` prints how to switch to OAuth and falls back to the API-key prompt.

***

## Token Storage

Credentials are stored at `~/.praisonai/credentials.json` (or the path returned by `praisonai paths`). Legacy `~/.praison/credentials.json` is read as a fallback and migrated on the next write — no re-login required. Each provider gets its own entry containing:

* Auth method (`apikey` or `oauth`)
* Token value (API key or access token)
* Refresh token (OAuth only)
* Expiry timestamp (OAuth only)

Tokens are refreshed transparently before each agent run when they are within the refresh window.

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use API keys in CI — not OAuth">
    OAuth device-code flows require human interaction. In automated pipelines (CI/CD, cron jobs), always use API keys via environment variables:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    ANTHROPIC_API_KEY=sk-ant-... praisonai run task.yaml
    ```

    Or store them with `--method apikey` and a `--key-stdin` pipe from your secrets manager.
  </Accordion>

  <Accordion title="Log out when rotating credentials">
    When you rotate an API key or revoke an OAuth token:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth logout github
    praisonai auth login github --method oauth --client-id <your-github-oauth-app-client-id>
    ```

    This removes the old credential and re-runs the login flow.
  </Accordion>

  <Accordion title="Pin the model when using OAuth">
    OAuth credentials are provider-scoped. If a provider has multiple models, pin the default model at login time:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth login gemini --method oauth --client-id <your-google-oauth-client-id> --model gemini-1.5-pro
    ```
  </Accordion>

  <Accordion title="Supply your OAuth app client id">
    Registry providers ship endpoints but no `client_id`. Register your OAuth app with the provider (GitHub App / Google OAuth client for TVs / Azure AD app), then pass its id with `--client-id`. Until a first-party PraisonAI app is provisioned, you use your own.

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth login github --method oauth --client-id <your-github-oauth-app-client-id>
    ```
  </Accordion>

  <Accordion title="Sign in to a self-hosted gateway">
    For a provider outside the registry, supply the OAuth endpoints directly with CLI flags:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai auth login my-gateway --method oauth \
      --client-id cli \
      --device-authorization-url https://gateway.example.com/oauth/device \
      --token-url https://gateway.example.com/oauth/token \
      --scope "read write"
    ```
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Security Environment Variables" icon="shield" href="/docs/features/security-environment-variables">
    How to pass credentials safely via environment variables
  </Card>

  <Card title="Default Model Selection" icon="list-check" href="/docs/features/default-model-selection">
    How the CLI picks the right model when multiple providers are logged in
  </Card>

  <Card title="MCP OAuth" icon="plug" href="/docs/mcp/mcp-oauth">
    MCP tools have their own OAuth flow, separate from CLI provider sign-in
  </Card>
</CardGroup>
