"""Operator-only provisioning. Never package keys, pass them in argv, or print them.""" import argparse import json import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) from decision_server.credentials import deepseek_llm, openrouter_jev # noqa: E402 REMOTE = r""" import json, os, pathlib, re, sys values = json.loads(sys.stdin.read(16384)) assert set(values) == {'Deepseek_API_KEY', 'OPENROUTER_API_KEY'} assert all(re.fullmatch(r'[A-Za-z0-9_-]{16,4096}', v) for v in values.values()) root = pathlib.Path('/opt/cadworld-sim') secrets = root / 'secrets' secrets.mkdir(mode=0o700, exist_ok=True) os.chmod(str(secrets), 0o700) path = secrets / 'model-keys.env' payload = ''.join(k+'='+v+'\n' for k,v in sorted(values.items())).encode() if path.exists(): if path.is_symlink() or path.read_bytes() != payload: raise SystemExit('Existing credentials differ; explicit rotation required') else: fd = os.open(str(path), os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o400) with os.fdopen(fd, 'wb') as stream: stream.write(payload) os.chown(str(path), 10001, 10001) os.chmod(str(path), 0o400) budget = root / 'budget' budget.mkdir(mode=0o700, exist_ok=True) os.chown(str(budget), 10001, 10001) os.chmod(str(budget), 0o700) print('Server-only credentials provisioned; values not displayed.') """ def main(): parser = argparse.ArgumentParser() parser.add_argument("--confirm-server-keys", action="store_true") args = parser.parse_args() if not args.confirm_server_keys: parser.error("Explicit authorization required before reading the two .env variables") keys = { "Deepseek_API_KEY": deepseek_llm(ROOT / ".env").key, "OPENROUTER_API_KEY": openrouter_jev(ROOT / ".env").key, } if not (ROOT / "website-dist/index.html").is_file(): raise SystemExit("Build website before provisioning") for path in (ROOT / "website-dist").rglob("*"): if path.is_file(): content = path.read_bytes() if any(value.encode() in content for value in keys.values()): raise SystemExit("Credential found in static build; provisioning refused") # The remote source contains no values. Only SSH's encrypted stdin carries keys. import shlex result = subprocess.run( [ "ssh", "-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", "-o", "UpdateHostKeys=no", "root@47.93.31.109", "python3 -c " + shlex.quote(REMOTE), ], input=json.dumps(keys).encode(), capture_output=True, ) if result.returncode: raise SystemExit("Credential provisioning failed; values/logs withheld, no automatic retry") print("Static secret scan passed; server-only credentials provisioned (0400, read-only mount).") if __name__ == "__main__": main()