JS Credential Rotation

Update OPENAI_API_KEY or OPENAI_BASE_URL at runtime without restarting the process

praisonai-ts picks up a changed OPENAI_API_KEY or OPENAI_BASE_URL on the next call — no restart, no code change.

Diagram

Env-only client cache

no

yes

📞 next agent.chat

🔑 apiKey + baseURL changed?

♻️ Reuse cached client

🔨 Rebuild client

✅ Fresh client

The env-only OpenAI client caches on client identity (apiKey + baseURL). Rotate either and the next call rebuilds automatically — the exact flow a settings screen needs when a user pastes a new key.

Quick Start

  1. Rotate the key in your settings screen

    Set the env var; the next call uses the new key.

    typescript
    import { Agent } from 'praisonai';
    
    process.env.OPENAI_API_KEY = 'sk-new';
    const agent = new Agent({ instructions: 'You are helpful' });
    await agent.chat('Hello');   // uses sk-new — no restart
  2. Point at a different gateway

    Set OPENAI_BASE_URL; the next call rebuilds against the new endpoint.

    typescript
    process.env.OPENAI_BASE_URL = 'https://gateway.example/v1';
    await agent.chat('Hello via gateway');   // rebuilt against the new endpoint
  3. Force a rebuild explicitly

    Call resetOpenAIClient() to rebuild on the next call — useful in tests and after a bulk settings change.

    typescript
    import { resetOpenAIClient } from 'praisonai';
    
    resetOpenAIClient();
    await agent.chat('Fresh client');

How It Works

The env-only client keys its cache on apiKey + baseURL. A settings-screen edit to either env var changes that identity, so the next getOpenAIClient() rebuilds.

Diagram
getOpenAIClient()Agentprocess.envSettings screenUsergetOpenAIClient()Agentprocess.envSettings screenUserPaste new keyOPENAI_API_KEY = sk-newagent.chat(“Hi”)request clientidentity changed → rebuildfresh client (sk-new)Response
TriggerResult
OPENAI_API_KEY changes between callsRebuild on next call
OPENAI_BASE_URL changes between callsRebuild on next call
Nothing changesReuse cached client
resetOpenAIClient() calledRebuild on next call

When Does This Apply?

Rotation applies only to the shared env-only client. Per-agent credentials never touch that cache.

Diagram

Per-agent apiKey / baseURL on config

Env vars only Agent or convenience function

How are credentials supplied?

Dedicated client — nothing to rotate

Shared env-only client — rotation applies

An Agent built with an explicit apiKey or baseURL gets its own dedicated client, so a later env-var change does not affect it. Rotate by constructing a new Agent with the new value.


Concurrency

A resetOpenAIClient() or credential change that races an in-flight request is safe. Each caller keeps the client it built for its own identity — an overlapping call that swaps the key never hands back another call’s client, and a reset mid-flight never yields null.


Security

The identity that keys the cache contains the secret key. praisonai-ts never logs it — do not add logging that prints it either.


API Reference

Two exports back the rotation contract. The recommended user surface stays new Agent(...) and agent.chat(...).

ExportSignatureWhen to call
resetOpenAIClient() => voidTests; explicit “apply now” from a settings screen; recovery after a suspected stale-cache bug in older versions.
Advanced: getOpenAIClient()

`getOpenAIClient(): Promise

is exported so tests and advanced integrations can reach the shared env-only client. It throws OPENAI_API_KEY not found in environment variables when no key is set. Prefer new Agent(…)` for application code.


Common Patterns

Simple rotation — no code change from the SDK caller

typescript
import { Agent } from 'praisonai';

process.env.OPENAI_API_KEY = 'sk-first';
const agent = new Agent({ instructions: 'You are helpful' });
await agent.chat('Hello');           // uses sk-first

// Settings screen updates the env var:
process.env.OPENAI_API_KEY = 'sk-second';
await agent.chat('Hello again');     // rebuilds automatically; uses sk-second

Change the gateway at runtime

typescript
import { Agent } from 'praisonai';

process.env.OPENAI_API_KEY = 'sk-shared';
process.env.OPENAI_BASE_URL = 'https://gateway-a.example/v1';
const agent = new Agent({ instructions: 'You are helpful' });
await agent.chat('Hello via gateway A');

process.env.OPENAI_BASE_URL = 'https://gateway-b.example/v1';
await agent.chat('Hello via gateway B');   // rebuilt against gateway B

Explicit rebuild — tests and bulk settings updates

typescript
import { Agent, resetOpenAIClient } from 'praisonai';

process.env.OPENAI_API_KEY = 'sk-stable';
const agent = new Agent({ instructions: 'You are helpful' });
await agent.chat('One');

resetOpenAIClient();                   // force next call to rebuild
await agent.chat('Two');               // fresh client, same env

Best Practices

Prefer per-agent credentials in multi-tenant apps

Pass apiKey / baseURL on each Agent to isolate tenants. Each agent gets its own client, so one tenant’s rotation never affects another.

Trust the automatic rebuild in single-tenant apps

The next call rebuilds when the key or base URL changes. There is no need to call resetOpenAIClient() on every key update.

Never log the identity string or API key

The cache identity embeds the secret. Keep it out of logs and error messages.

One reset after a bulk settings change

After changing several settings at once in a UI, a single resetOpenAIClient() is enough — the next call rebuilds once.


Related