gsh/Cargo.toml
Tyler J King eab034f0cc feat: gsh machine mode — first governed shell execution
~200 lines of Rust. Every command: AC → exec → CR → CID.

Usage:
  gsh --exec "echo hello"
  gsh --exec "hcloud server list" --json
  gsh --exec "ansible-playbook site.yml" --dry-run

Flow:
  1. SHA-256 hash the command
  2. POST /governance/authorize/ → AC ID
  3. exec(sh, -c, command) → capture stdout/stderr/exit
  4. POST /governance/complete/ → receipt + Chronicle CID
  5. Print stdout (passthrough) or JSON (structured)
  6. Exit with command's exit code

Environment:
  GSAP_BROKER_URL   http://fastapi-gsap:8000
  GSAP_AGENT_DID    did:web:bxnet.../agent/platform-ops
  GSAP_TOKEN        Bearer token (optional)
  GSAP_CORPUS_CID   sha256:{image_digest} (optional)

Tested against live fastapi-gsap Spoke broker on Hetzner:
  dry-run: AC only ✓
  live exec: stdout passthrough + CID ✓
  JSON mode: ac_id + cr_id + chronicle_cid ✓
  exit code: 42 passed through ✓

The command_hash in the AC request means the broker knows
WHAT will be executed before authorizing. Not just "was
this agent allowed" but "was this exact command authorized."

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:01:22 -04:00

20 lines
467 B
TOML

[package]
name = "gsh"
version = "0.1.0"
edition = "2021"
description = "Governed shell — GCAP-SPEC-SHELLBOUND-SDK-0001"
[[bin]]
name = "gsh"
path = "src/main.rs"
[dependencies]
reqwest = { version = "0.12", features = ["json", "blocking"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
clap = { version = "4", features = ["derive"] }
sha2 = "0.10"
hex = "0.4"
uuid = { version = "1", features = ["v4", "serde"] }
anyhow = "1"
chrono = "0.4"