Files
synapbus/tests/e2e/lib/auth.py
T
Algis DumbrisandClaude Opus 4.6 b88d52276a feat: add admin CLI, API keys, threads, and Slack-like UI redesign
Major feature additions across backend and frontend:

Backend:
- Unix domain socket admin server with JSON-RPC protocol
- CLI subcommands: user/agent management, audit, backup, messages, channels
- Managed API keys (sb_ prefix) with permissions, channel limits, expiry
- Thread/reply support in messaging core (reply_to column)
- Context-based trace owner_id propagation for proper audit filtering
- Two-step auth middleware supporting both agent keys and managed API keys

Frontend:
- Complete Slack-like dark theme redesign with custom CSS properties
- Sidebar with Channels, Direct Messages, and Admin sections
- Thread panel (slide-in) for viewing message replies
- API key management page with create form, key display, and
  ready-to-use MCP/Claude Code config snippets with copy-to-clipboard
- All pages restyled: login, dashboard, agents, conversations, settings

E2E Tests:
- Fixed test runner binary path resolution
- Added pyproject.toml for test dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:10:51 +02:00

54 lines
1.8 KiB
Python

"""3-tier Anthropic authentication: API key, OAuth env, macOS Keychain."""
from __future__ import annotations
import json
import os
import subprocess
import sys
import anthropic
def create_anthropic_client() -> anthropic.Anthropic:
"""Create Anthropic client with 3-tier auth fallback.
1. ANTHROPIC_API_KEY env var (standard API key)
2. CLAUDE_CODE_OAUTH_TOKEN env var (OAuth token)
3. macOS Keychain (Claude Code subscription credentials)
"""
# Tier 1: Standard API key
api_key = os.environ.get("ANTHROPIC_API_KEY")
if api_key:
print(" Auth: using ANTHROPIC_API_KEY")
return anthropic.Anthropic(api_key=api_key)
# Tier 2: OAuth token from env
oauth_token = os.environ.get("CLAUDE_CODE_OAUTH_TOKEN")
# Tier 3: macOS Keychain (Claude Code stores credentials as JSON)
if not oauth_token:
try:
raw = subprocess.check_output(
["security", "find-generic-password",
"-s", "Claude Code-credentials", "-w"],
text=True, stderr=subprocess.DEVNULL,
).strip()
if raw:
creds = json.loads(raw)
oauth_token = creds.get("claudeAiOauth", {}).get("accessToken")
if oauth_token:
print(" Auth: using macOS Keychain (Claude Code subscription)")
except (subprocess.CalledProcessError, FileNotFoundError, json.JSONDecodeError):
pass
if oauth_token:
return anthropic.Anthropic(
auth_token=oauth_token,
default_headers={"anthropic-beta": "oauth-2025-04-20"},
)
print("ERROR: No Anthropic credentials found.")
print(" Set ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN,")
print(" or ensure Claude Code is logged in (macOS Keychain).")
sys.exit(1)