fix(P07): remove all password/token paths (REQ-146, R-021, C-34) -- BREAKING

---ci---
project: orca
phase: 7
milestone: v0.12
status: execute
---/ci---

R-021 invariant: no passwords, no Orca-issued tokens, no CA-key
passphrases anywhere in the system.

Removed:
- proxmox/bootstrap.go: ssh.Password auth -> ssh.PublicKeys (key-based).
  --password/ removed from node join; replaced
  with --ssh-key (default: orca SSH key). Pre-staged key required.
- stepca/stepca.go: --password-file /dev/stdin removed from Init and
  issueCert. Provisioner changed to 'orca-oidc' (OIDC provisioner).
- identity/spiffe.go: --password-file removed from MintSVID. Provisioner
  changed to 'orca-oidc'.

Tests: all proxmox, stepca, identity, cli tests updated + pass. 3 new
password-rejection regression tests. Fake SSH server gains
PublicKeyCallback. go vet clean. Full build green.
This commit is contained in:
Jon Chery
2026-08-07 11:12:18 +00:00
parent 1fb82f09b2
commit 20523ac045
11 changed files with 138 additions and 103 deletions
+58 -56
View File
@@ -13,6 +13,8 @@ import (
"strconv"
"strings"
"testing"
"git.cloudinit.dev/coreci/orca/internal/certpaths"
"time"
"golang.org/x/crypto/ssh"
@@ -89,14 +91,14 @@ func TestOrcaOperatorPrivileges(t *testing.T) {
func TestBootstrapProxmox_Validation(t *testing.T) {
ctx := context.Background()
_, err := BootstrapProxmox(ctx, Options{Password: "pw"})
_, err := BootstrapProxmox(ctx, Options{SSHKeyPath: certpaths.SSHKeyPath()})
if err == nil || !strings.Contains(err.Error(), "host is required") {
t.Errorf("expected host-required error, got %v", err)
}
_, err = BootstrapProxmox(ctx, Options{Host: "10.0.0.1"})
if err == nil || !strings.Contains(err.Error(), "password is required") {
t.Errorf("expected password-required error, got %v", err)
if err == nil || !strings.Contains(err.Error(), "SSH key path is required") {
t.Errorf("expected SSH-key-required error, got %v", err)
}
}
@@ -149,8 +151,8 @@ func TestBootstrapProxmox_SSHAuthFailure(t *testing.T) {
setupORCAHome(t)
_, err := BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.1",
Password: "pw",
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
})
if err == nil {
t.Fatal("expected error, got nil")
@@ -172,9 +174,9 @@ func TestBootstrapProxmox_SSHDialCalledWithCorrectAddr(t *testing.T) {
setupORCAHome(t)
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.42",
Password: "pw",
SSHPort: 2222,
Host: "10.0.0.42",
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: 2222,
})
if dialer.calls != 1 {
t.Errorf("dialer calls = %d, want 1", dialer.calls)
@@ -193,8 +195,8 @@ func TestBootstrapProxmox_DefaultSSHPort(t *testing.T) {
setupORCAHome(t)
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.99",
Password: "pw",
Host: "10.0.0.99",
SSHKeyPath: certpaths.SSHKeyPath(),
})
if dialer.lastAddr != "10.0.0.99:22" {
t.Errorf("dial addr = %q, want 10.0.0.99:22 (default port)", dialer.lastAddr)
@@ -210,9 +212,9 @@ func TestBootstrapProxmox_CustomSSHUser(t *testing.T) {
setupORCAHome(t)
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.1",
Password: "pw",
SSHUser: "custom-admin",
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
SSHUser: "custom-admin",
})
if dialer.calls != 1 {
t.Errorf("dialer calls = %d, want 1", dialer.calls)
@@ -230,8 +232,8 @@ func TestBootstrapProxmox_SSHKeyGenerated(t *testing.T) {
dir := setupORCAHome(t)
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.1",
Password: "pw",
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
})
keyPath := filepath.Join(dir, "orca_ssh_key")
@@ -252,8 +254,8 @@ func TestBootstrapProxmox_KnownHostsFileCreated(t *testing.T) {
dir := setupORCAHome(t)
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.1",
Password: "pw",
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
})
knownHosts := filepath.Join(dir, "known_hosts")
@@ -275,9 +277,9 @@ func TestBootstrapProxmox_NilLogger(t *testing.T) {
}
}()
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.1",
Password: "pw",
Logger: nil,
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
Logger: nil,
})
}
@@ -297,9 +299,9 @@ func TestBootstrapProxmox_CustomLogger(t *testing.T) {
}
}()
_, _ = BootstrapProxmox(context.Background(), Options{
Host: "10.0.0.1",
Password: "pw",
Logger: log,
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
Logger: log,
})
_ = buf.String()
}
@@ -314,8 +316,8 @@ func TestBootstrapProxmox_ContextCancelled(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := BootstrapProxmox(ctx, Options{
Host: "10.0.0.1",
Password: "pw",
Host: "10.0.0.1",
SSHKeyPath: certpaths.SSHKeyPath(),
})
if err == nil {
t.Fatal("expected error with cancelled context")
@@ -362,8 +364,8 @@ func TestBootstrapProxmox_FullFlow_IdempotentReRun(t *testing.T) {
for i := 0; i < 2; i++ {
sessionRunner = nil
if _, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
}); err != nil {
t.Fatalf("bootstrap run %d: %v", i+1, err)
}
@@ -391,9 +393,9 @@ func TestBootstrapProxmox_FullFlow_NoPasswordInLogs(t *testing.T) {
var logBuf bytes.Buffer
_, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "super-secret-pw-12345",
Logger: slog.New(slog.NewTextHandler(&logBuf, nil)),
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
Logger: slog.New(slog.NewTextHandler(&logBuf, nil)),
})
if err != nil {
t.Fatalf("BootstrapProxmox: %v", err)
@@ -425,8 +427,8 @@ func TestBootstrapProxmox_FullFlow_ValidateSudoersFails(t *testing.T) {
host, _, _ := net.SplitHostPort(srv.addr())
_, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
})
if err == nil {
t.Fatal("expected error for invalid sudoers")
@@ -472,7 +474,7 @@ func TestBootstrapProxmox_FullFlow_CreateLinuxUserFails(t *testing.T) {
// ProxmoxUser=root exercises the /root home branch in deployPubKey.
_, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHKeyPath: certpaths.SSHKeyPath(),
ProxmoxUser: "root",
})
if err != nil {
@@ -697,9 +699,9 @@ func TestBootstrapProxmox_PopulatesHostKeyFingerprint(t *testing.T) {
portNum, _ := strconv.Atoi(port)
result, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
})
if err != nil {
t.Fatalf("BootstrapProxmox: %v", err)
@@ -823,7 +825,7 @@ func TestBootstrapE2E_PinnedFingerprintCorrect(t *testing.T) {
result, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
HostKeyFingerprint: pin,
})
@@ -846,7 +848,7 @@ func TestBootstrapE2E_PinnedFingerprintWrong(t *testing.T) {
_, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
HostKeyFingerprint: wrong,
})
@@ -878,9 +880,9 @@ func TestBootstrapE2E_TOFUFirstConnectCapturesKey(t *testing.T) {
}
result, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
})
if err != nil {
t.Fatalf("BootstrapProxmox first connect: %v", err)
@@ -909,9 +911,9 @@ func TestBootstrapE2E_TOFUSecondConnectMatches(t *testing.T) {
for i := 0; i < 2; i++ {
sessionRunner = nil
if _, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
}); err != nil {
t.Fatalf("bootstrap run %d: %v", i+1, err)
}
@@ -947,9 +949,9 @@ func TestBootstrapE2E_TOFUMismatchFails(t *testing.T) {
}
_, err = BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
})
if err == nil {
t.Fatal("expected MITM/mismatch error, got nil")
@@ -980,9 +982,9 @@ func TestBootstrapE2E_PrePopulatedKnownHostsMatches(t *testing.T) {
}
result, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
})
if err != nil {
t.Fatalf("BootstrapProxmox on pre-populated known_hosts: %v", err)
@@ -1009,9 +1011,9 @@ func TestBootstrapE2E_KeyResetThenRePin(t *testing.T) {
// First connect: TOFU captures + writes known_hosts.
sessionRunner = nil
if _, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
}); err != nil {
t.Fatalf("first bootstrap: %v", err)
}
@@ -1034,9 +1036,9 @@ func TestBootstrapE2E_KeyResetThenRePin(t *testing.T) {
// Next connect re-pins via TOFU + succeeds.
sessionRunner = nil
if _, err := BootstrapProxmox(t.Context(), Options{
Host: host,
Password: "pw",
SSHPort: portNum,
Host: host,
SSHKeyPath: certpaths.SSHKeyPath(),
SSHPort: portNum,
}); err != nil {
t.Fatalf("re-pin bootstrap after reset: %v", err)
}