Files
orca/.ciagent/PHASE2_VERIFICATION_v0.6.md
T
Jon Chery 82dd01f620 docs(P02): verification report — all 4 layers PASS
---ci---
project: orca
phase: 2
milestone: v0.6
status: verify
---/ci---
2026-08-03 19:56:05 +00:00

4.5 KiB

Phase 2 Verification — Orca v0.6 P02

Phase: P02 — Proxmox SSH Join REQ Coverage: REQ-050, REQ-051 Verification date: 2026-08-03 Result: PASS (all 4 layers; integration test against real PVE deferred — unit tests cover all logic)

Structural Verification

  • go build ./... — PASS
  • go vet ./... — PASS
  • gofmt -l . — PASS (all Go files formatted)
  • make lint — PASS
  • golang.org/x/crypto v0.54.0 added as direct dep (D-030); transitive: x/sys v0.47.0, x/term v0.45.0
  • internal/proxmox new package follows existing package layout conventions
  • internal/security/sshkey.go follows the CAInit pattern (idempotent fast-path, writeAtomic, mode enforcement)

Behavioral Verification

REQ-050: Proxmox SSH bootstrap via golang.org/x/crypto/ssh

  • TestGenerateOrLoadSSHKey_Generates: Ed25519 keygen, 0600/0644 modes, ssh-ed25519 pub format, ssh.ParsePrivateKey round-trip
  • TestGenerateOrLoadSSHKey_IdempotentLoad: second call loads existing (D-036)
  • TestGenerateOrLoadSSHKey_CreatesDir: nested dir creation
  • TestBootstrapProxmox_Validation: missing host → error, missing password → error
  • TestDefaultOptions: DefaultProxmoxUser=orca, DefaultProxmoxRole=OrcaOperator, DefaultSSHPort=22
  • CLI --type proxmox --host ... --password ... flag wiring verified via orca node join --help
  • Password from --password flag OR $ORCA_PROXMOX_PASSWORD env var (D-031)
  • TOFU host-key via knownhosts.New (D-035, avoids deprecated InsecureIgnoreHostKey)
  • File upload via session heredoc (no SFTP dep — D-030)

REQ-051: OrcaOperator role + orca@pam user + sudoers

  • TestSudoersContent: NOEXEC on pct/qm, NOPASSWD on apt-get/dpkg (no NOEXEC), pvesh excluded from command lines (AD-020)
  • TestSudoersContent_CustomUser: custom user name works
  • TestOrcaOperatorPrivileges: exactly 3 privileges (VM.Audit, Datastore.AllocateSpace, SDN.Use) space-separated (D-033)
  • orca@pam realm (AD-019 — not @pve)
  • pveum commands use --privs (space-separated), probe-then-add idempotency pattern
  • visudo -cf validation step aborts bootstrap on syntax error
  • Node registered with kind=proxmox, os=pve

Security Verification

  • SSH private key mode 0600 enforced (TestGenerateOrLoadSSHKey_Generates)
  • SSH public key mode 0644 enforced
  • Password never persisted (D-031) — used only for SSH auth, zeroed after use
  • Password from env var preferred over flag (reduces ps/proc exposure)
  • pvesh excluded from sudoers (AD-020 — API execute bypasses NOEXEC)
  • NOEXEC on pct/qm (blocks shell escapes via dynamically-linked perl)
  • TOFU host-key pinning (D-035) — capture on first connect, verify on subsequent, fail closed on mismatch
  • No secrets in logs (audit log entries contain host, user, role — never password)
  • sudoers file mode 0440 enforced (sudo requirement)

Quality Verification

  • go test -race -count=1 ./internal/proxmox/... ./internal/security/... ./internal/cli/... — all PASS
  • Test coverage: sshkey (4 tests), proxmox (5 tests), sudoers content (2 tests), privileges (1 test), validation (1 test), defaults (1 test)
  • Error wrapping with fmt.Errorf("...: %w", err) (REQ-018)
  • context.Context propagation (REQ-017)
  • Idempotency: all bootstrap steps probe-before-add (D-036)
  • New direct dep: 1 (golang.org/x/crypto) — matches D-030 minimal-deps rationale

Integration Test Note

A live integration test against a real Proxmox VE 8/9 host is out of scope for automated CI (requires a PVE host + credentials). The SSH bootstrap logic is tested via:

  • Unit tests for command builders (sudoers content, privilege set)
  • Unit tests for validation (missing host/password)
  • Unit tests for SSH key generation (Ed25519, modes, idempotency)
  • Manual verification via orca node join --help (flag surface)

A // +build integration test against a real PVE host can be added in a future phase if a PVE test environment becomes available.

Must-Have Checklist

  • go.mod / go.sum — golang.org/x/crypto v0.54.0
  • internal/certpaths/certpaths.go — SSHKeyPath, SSHPubPath, KnownHostsPath
  • internal/security/sshkey.go — GenerateOrLoadSSHKey (Ed25519)
  • internal/proxmox/bootstrap.go — BootstrapProxmox full SSH dance
  • internal/cli/node.go — --type/--host/--password flag wiring + joinProxmox
  • internal/security/sshkey_test.go — 4 tests
  • internal/proxmox/bootstrap_test.go — 5 tests

Escalations

None.