generated from coulomb/repo-seed
Initial Commit
This commit is contained in:
0
src/warden/scripts/__init__.py
Normal file
0
src/warden/scripts/__init__.py
Normal file
82
src/warden/scripts/ops_ssh_wrapper.py
Normal file
82
src/warden/scripts/ops_ssh_wrapper.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""ops-ssh-wrapper — acquire a warden cert and exec the given SSH command.
|
||||
|
||||
Usage:
|
||||
WARDEN_ACTOR=agt-my-agent SSH_PUBKEY=~/.ssh/agt-my-agent_ed25519.pub \\
|
||||
ops-ssh-wrapper ssh -R 8001:127.0.0.1:8000 agt-my-agent@host
|
||||
|
||||
Environment:
|
||||
WARDEN_ACTOR Actor name in the warden inventory (e.g. agt-state-hub-bridge)
|
||||
SSH_PUBKEY Path to the actor's SSH public key file
|
||||
|
||||
The wrapper requests a fresh cert from warden on every invocation, loads it into
|
||||
ssh-agent, then execs the given command. Equivalent to the pattern in
|
||||
AccessManagementDirective §4.1, hardened for production use.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main() -> None:
|
||||
actor = os.environ.get("WARDEN_ACTOR")
|
||||
pubkey = os.environ.get("SSH_PUBKEY")
|
||||
|
||||
if not actor:
|
||||
print("ops-ssh-wrapper: WARDEN_ACTOR not set", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if not pubkey:
|
||||
print("ops-ssh-wrapper: SSH_PUBKEY not set", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
pubkey_path = Path(os.path.expanduser(pubkey))
|
||||
if not pubkey_path.exists():
|
||||
print(f"ops-ssh-wrapper: SSH_PUBKEY not found: {pubkey_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
cert_text = subprocess.check_output(
|
||||
["warden", "sign", actor, "--pubkey", str(pubkey_path)],
|
||||
text=True,
|
||||
).strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(
|
||||
f"ops-ssh-wrapper: warden sign failed (exit {e.returncode})", file=sys.stderr
|
||||
)
|
||||
sys.exit(1)
|
||||
except FileNotFoundError:
|
||||
print(
|
||||
"ops-ssh-wrapper: 'warden' not found in PATH. "
|
||||
"Install ops-warden: uv tool install ops-warden",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
with tempfile.NamedTemporaryFile(
|
||||
suffix="-cert.pub", mode="w", delete=False, prefix=f"{actor}-"
|
||||
) as f:
|
||||
f.write(cert_text + "\n")
|
||||
cert_path = f.name
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["ssh-add", cert_path], capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print(
|
||||
f"ops-ssh-wrapper: ssh-add warning: {result.stderr.strip()} "
|
||||
f"(ssh-agent may not be running — continuing anyway)",
|
||||
file=sys.stderr,
|
||||
)
|
||||
finally:
|
||||
os.unlink(cert_path)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
os.execvp(sys.argv[1], sys.argv[1:])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user