-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathcli_auth.py
More file actions
106 lines (88 loc) · 3.11 KB
/
cli_auth.py
File metadata and controls
106 lines (88 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""Update literal tokens in CLI config files on PAT rotation.
Called by pat_rotator._persist_token() every 10 minutes. Lightweight —
just swaps token values in existing files, no installs or script runs.
"""
import json
import os
import re
import logging
logger = logging.getLogger(__name__)
_HOME = os.environ.get("HOME", "/app/python/source_code")
if not _HOME or _HOME == "/":
_HOME = "/app/python/source_code"
def update_cli_tokens(token):
"""Update the literal token in all CLI config files."""
_update_claude(token)
_update_codex(token)
_update_opencode(token)
_update_gemini(token)
_update_hermes(token)
def _update_claude(token):
"""Update ANTHROPIC_AUTH_TOKEN in ~/.claude/settings.json."""
path = os.path.join(_HOME, ".claude", "settings.json")
try:
with open(path) as f:
settings = json.load(f)
if "env" in settings and "ANTHROPIC_AUTH_TOKEN" in settings["env"]:
settings["env"]["ANTHROPIC_AUTH_TOKEN"] = token
with open(path, "w") as f:
json.dump(settings, f, indent=2)
except (OSError, json.JSONDecodeError):
pass # file doesn't exist yet — initial setup hasn't run
def _update_codex(token):
"""Update OPENAI_API_KEY in ~/.codex/.env."""
path = os.path.join(_HOME, ".codex", ".env")
_replace_dotenv_key(path, "OPENAI_API_KEY", token)
def _update_opencode(token):
"""Update api_key values in ~/.local/share/opencode/auth.json."""
path = os.path.join(_HOME, ".local", "share", "opencode", "auth.json")
try:
with open(path) as f:
auth = json.load(f)
changed = False
for provider in auth.values():
if isinstance(provider, dict) and "api_key" in provider:
provider["api_key"] = token
changed = True
if changed:
with open(path, "w") as f:
json.dump(auth, f, indent=2)
except (OSError, json.JSONDecodeError):
pass
def _update_gemini(token):
"""Update GEMINI_API_KEY in ~/.gemini/.env."""
path = os.path.join(_HOME, ".gemini", ".env")
_replace_dotenv_key(path, "GEMINI_API_KEY", token)
def _update_hermes(token):
"""Update api_key lines in ~/.hermes/config.yaml."""
path = os.path.join(_HOME, ".hermes", "config.yaml")
try:
with open(path) as f:
content = f.read()
new_content = re.sub(
r'^( api_key: ).*$',
rf'\g<1>{token}',
content,
flags=re.MULTILINE
)
if new_content != content:
with open(path, "w") as f:
f.write(new_content)
except OSError:
pass
def _replace_dotenv_key(path, key, value):
"""Replace a KEY=value line in a dotenv file."""
try:
with open(path) as f:
content = f.read()
new_content = re.sub(
rf'^{re.escape(key)}=.*$',
f'{key}={value}',
content,
flags=re.MULTILINE
)
if new_content != content:
with open(path, "w") as f:
f.write(new_content)
except OSError:
pass