diff --git a/config/athena-operator.env.example b/config/athena-operator.env.example index ece31fa..0231249 100644 --- a/config/athena-operator.env.example +++ b/config/athena-operator.env.example @@ -5,5 +5,6 @@ ATHENA_OPERATOR_MODELS=/data/models ATHENA_OPERATOR_SOCKET=/run/mike-ai-operator/operator.sock ATHENA_OPERATOR_GID=10003 ATHENA_OPERATOR_GIT_REMOTE=git@192.168.1.2:michael/AI-Profile-Router.git +ATHENA_OPERATOR_GIT_SSH_KEY=/etc/mike-ai/athena-operator-git ATHENA_OPERATOR_GIT_NAME=Athena Operator ATHENA_OPERATOR_GIT_EMAIL=athena-operator@localhost diff --git a/platform/mcp/README.md b/platform/mcp/README.md index 3d42791..12dbde8 100644 --- a/platform/mcp/README.md +++ b/platform/mcp/README.md @@ -44,6 +44,12 @@ inhaltlich gebundenes, ablaufendes Ticket und eine spätere exakte Bestätigung. Eine freie Shell sowie SSH-, Netzwerk-, Boot-, Kernel-, Treiber-, Partitions-, Reboot- und Shutdown-Aktionen werden nicht angeboten. +Für Git-Publishing besitzt Athena ein eigenes Schlüsselpaar unter +`/etc/mike-ai/athena-operator-git{,.pub}`. Nur der öffentliche Schlüssel wird +in Gitea als schreibberechtigter Deploy-Key für `AI-Profile-Router` hinterlegt. +Der private Schlüssel verlässt Athena nicht und wird weder an den MCP-Container +noch an das Modell ausgegeben. + TinySearch bleibt als Ganzes read-only. Nur das flüchtige tmpfs-Verzeichnis `/home/tinysearch/.crawl4ai` ist beschreibbar, weil Crawl4AI dort seinen temporären Browser- und Sitzungszustand erzeugt. Es wird bei jedem diff --git a/platform/operator/athena_operatord.py b/platform/operator/athena_operatord.py index 2ddcbc5..4232f15 100755 --- a/platform/operator/athena_operatord.py +++ b/platform/operator/athena_operatord.py @@ -14,6 +14,7 @@ import hashlib import json import os import re +import shlex import shutil import socketserver import subprocess @@ -70,8 +71,19 @@ def compact(text: str) -> str: def run(argv: list[str], *, cwd: Path = STACK, timeout: int = 900, check: bool = False) -> dict[str, Any]: + environment = { + "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "LANG": "C.UTF-8", + "HOME": "/root", + } + git_key = Path(os.environ.get("ATHENA_OPERATOR_GIT_SSH_KEY", "/etc/mike-ai/athena-operator-git")) + if git_key.is_file(): + environment["GIT_SSH_COMMAND"] = ( + f"ssh -i {shlex.quote(str(git_key))} -o IdentitiesOnly=yes " + "-o StrictHostKeyChecking=yes" + ) completed = subprocess.run( - argv, cwd=cwd, env={"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LANG": "C.UTF-8", "HOME": "/root"}, + argv, cwd=cwd, env=environment, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, errors="replace", timeout=timeout, check=False, ) diff --git a/platform/operator/install-operator.sh b/platform/operator/install-operator.sh index 54d4b90..34b844c 100755 --- a/platform/operator/install-operator.sh +++ b/platform/operator/install-operator.sh @@ -6,6 +6,12 @@ install -d -m 0700 /etc/mike-ai if [[ ! -e /etc/mike-ai/athena-operator.env ]]; then install -m 0600 "$ROOT/config/athena-operator.env.example" /etc/mike-ai/athena-operator.env fi +if [[ ! -e /etc/mike-ai/athena-operator-git ]]; then + ssh-keygen -q -t ed25519 -N '' -C athena-operator \ + -f /etc/mike-ai/athena-operator-git +fi +chmod 0600 /etc/mike-ai/athena-operator-git +chmod 0644 /etc/mike-ai/athena-operator-git.pub install -d -m 0750 -o root -g 10003 /run/mike-ai-operator install -d -m 0700 /data/mike-ai-operator/state /data/mike-ai-operator/repository install -m 0755 "$ROOT/platform/operator/athena_operatord.py" /usr/local/libexec/mike-ai-athena-operatord