fix: remove Codex API key auth path, add secret redaction and d7 auto-rotation

- Remove OPENAI_API_KEY from .env and Codex child process env to prevent
  API billing when subscription quota is exhausted
- Remove writeCodexApiKeyAuth entirely — Codex now uses OAuth only
- Add 9-pattern secret redaction in formatOutbound() to prevent key leaks
- Fix Codex usage bucket aggregation: use 'codex' bucket only instead of
  max across all buckets (bengalfox = Codex Spark, not needed)
- Add d7≥100% auto-rotation in updateCodexAccountUsage to skip exhausted
  accounts and prevent API billing fallback
- Add findNextCodexAvailable that checks both rate-limits and d7 usage
- Clean stale apikey auth.json files from all session directories
- Update tests: OAuth-only auth, d7 auto-skip (3 new tests), dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eyejoker
2026-03-25 10:39:42 +09:00
parent 094278b08e
commit 00ffde7623
11 changed files with 818 additions and 192 deletions

View File

@@ -112,12 +112,13 @@ describe('prepareGroupEnvironment codex auth handling', () => {
fs.rmSync(tempRoot, { recursive: true, force: true });
});
it('writes API-key auth when OPENAI_API_KEY is available', () => {
it('ignores OPENAI_API_KEY and always uses OAuth auth', () => {
const rotatedAuthPath = path.join(tempRoot, 'rotated-auth.json');
fs.writeFileSync(
rotatedAuthPath,
JSON.stringify({ auth_mode: 'chatgpt', tokens: { access_token: 'x' } }),
);
const rotatedAuth = {
auth_mode: 'chatgpt',
tokens: { access_token: 'x' },
};
fs.writeFileSync(rotatedAuthPath, JSON.stringify(rotatedAuth));
mockGetActiveCodexAuthPath.mockReturnValue(rotatedAuthPath);
mockReadEnvFile.mockReturnValue({
OPENAI_API_KEY: 'sk-test-api-key',
@@ -139,9 +140,10 @@ describe('prepareGroupEnvironment codex auth handling', () => {
tokens?: unknown;
};
expect(auth.auth_mode).toBe('apikey');
expect(auth.OPENAI_API_KEY).toBe('sk-test-api-key');
expect(auth.tokens).toBeUndefined();
// API key auth is never used — always OAuth
expect(auth.auth_mode).toBe('chatgpt');
expect(auth.OPENAI_API_KEY).toBeUndefined();
expect(auth.tokens).toEqual({ access_token: 'x' });
});
it('falls back to rotated OAuth auth when no API key is configured', () => {