Jon Chery
797bc2f412
feat(P02): Proxmox SSH join + OrcaOperator role + sudoers
...
orca node join --type proxmox bootstraps a remote Proxmox VE 8/9 host
via SSH (REQ-050, REQ-051). The password is used only for initial auth;
subsequent access uses the deployed orca SSH key (D-031).
Changes:
- go.mod: add golang.org/x/crypto v0.54.0 (ssh + ssh/knownhosts + ed25519)
bump x/sys to v0.47.0, add x/term (indirect)
- internal/certpaths: SSHKeyPath, SSHPubPath, KnownHostsPath (D-037)
- internal/security/sshkey.go: GenerateOrLoadSSHKey (Ed25519, PKCS8 PEM,
0600/0644 modes, idempotent load per D-036)
- internal/proxmox/bootstrap.go: BootstrapProxmox SSH dance:
1. Generate/load SSH key
2. SSH dial (password + knownhosts.New TOFU per D-035)
3. Deploy pubkey to ~orca/.ssh/authorized_keys (idempotent)
4. useradd -m orca (idempotent)
5. pveum role add OrcaOperator --privs 'VM.Audit Datastore.AllocateSpace SDN.Use'
6. pveum user add orca@pam (AD-019: PAM realm, not @pve)
7. pveum acl modify / -user orca@pam -role OrcaOperator
8. Write /etc/sudoers.d/orca (AD-020: NOEXEC on pct/qm, no NOEXEC on
apt-get/dpkg, pvesh EXCLUDED — API execute bypasses NOEXEC)
9. visudo -cf validation (abort on failure)
All steps idempotent; audit-logged.
- internal/cli/node.go: --type/--host/--ssh-user/--password/--ssh-port/
--proxmox-user/--proxmox-role flags; joinProxmox() wires to
proxmox.BootstrapProxmox + registers node with kind=proxmox, os=pve.
Password zeroed after use (D-031).
- tests: sshkey generate/load round-trip, idempotency, file modes;
proxmox sudoers content (NOEXEC/NOPASSWD/pvesh-excluded),
privilege set, validation; node join flag wiring
---ci---
project: orca
phase: 2
milestone: v0.6
status: execute
---/ci---
2026-08-03 19:55:14 +00:00
Jon Chery
56fcf8b399
feat(P01): orca init full bootstrap + schema 0006
...
orca init transforms from a bare mkdir into a full single-node cluster
bootstrap. After `orca init`, `orca doctor` passes with zero FAILs
on the bootstrap checks (CA, cert, db, localhost node).
Changes:
- migration 0006: nodes.kind + nodes.os nullable columns (REQ-049)
- model.Node: Kind + OS fields + NodeKind constants (localhost|linux|proxmox)
- NodeRepo: extended Insert/Get/List/Watch/scanNode for kind/os columns
(NULL -> "" mapping); added GetByName + UpdateLastSeenAndOS helpers
- internal/cli/osdetect.go: detectOS() from /etc/os-release ID= field
(D-032); fallback to /usr/lib/os-release then "linux"
- internal/cli/init.go: full bootstrap sequence (REQ-047, REQ-048):
1. MkdirAll namespace dir
2. store.Open (runs migrations 0001..0006)
3. security.CAInit (idempotent fast-path)
4. server cert gen if absent (D-036: skip if present)
5. detectOS from /etc/os-release
6. localhost node upsert (insert if new, refresh last_seen+os if exists)
Idempotent re-run: no duplicate node, no cert regen, id/joined_at preserved
- --json output: full bootstrap summary (namespace, db, ca_fp, cert_fp,
os, node_id, steps array)
- tests: init idempotency, osdetect parsing (ubuntu/debian/alpine/pve),
kind/os round-trip, NULL->"" mapping, GetByName, UpdateLastSeenAndOS
E2E smoke test: orca init -> 5 PASS / 0 WARN / 1 FAIL (network=daemon
not running, expected); orca node list shows localhost node (os=ubuntu).
---ci---
project: orca
phase: 1
milestone: v0.6
status: execute
---/ci---
2026-08-03 19:47:59 +00:00
Jon Chery
4bfc246be4
feat(P01): unified namespace root via ORCA_HOME + --system flag
...
REQ-041: ORCA_HOME is now the single namespace root for all components
(db, certs, init, daemon). store.Open("") and init command both
route through certpaths.Dir()/DBPath() instead of hardcoding ~/.orca.
Backward compatible: empty ORCA_HOME -> ~/.orca.
REQ-042: --system persistent flag on rootCmd sets ORCA_HOME=/root/.orca
via PersistentPreRunE. Errors on conflict with pre-set ORCA_HOME.
Tests: 7 new tests in namespace_test.go (default, ORCA_HOME override,
--system sets root, conflict detection, init --json, flag registered).
Full suite passes (no regressions).
Docs: docs/namespace.md covers default, ORCA_HOME, --system, ORCA_DB,
resolution order, and path layout tables.
---ci---
project: orca
phase: 1
milestone: v0.5
status: verify
---/ci---
2026-08-03 18:05:01 +00:00
Jon Chery
df58bc25a3
docs(milestone): complete scheduling-streaming (v0.3)
...
---ci---
project: orca
phase: 3
milestone: v0.3
status: complete
requirements:
covered: [REQ-022, REQ-030, REQ-032]
partial: []
---/ci---
v0.3 milestone merged to main. Includes all v0.2 work (P08-P10) that
was previously on the milestone branch but not yet merged to main, plus
the v0.3 completion work (iter.Seq streaming + doctor network/db).
v0.2 phases included: P08 (mTLS), P09 (scheduling), P10 (security scan).
v0.3 phases: P0 (pre-execution), P1 (iter.Seq streaming), P2 (doctor),
P3 (final review+ship).
Total: 40 requirements, all complete. No new go.mod dependencies.
Full test suite passes under -race. gofmt + go vet clean.
2026-08-01 20:06:47 +00:00
ciagent
31ccb52114
feat(P08): mTLS daemon + transport + cert CLI + doctor
...
Wave B/C/D of P01 mTLS implementation.
- internal/audit/audit.go — thin wrapper around engine.Audit for
cert/handshake events (Action* and Result* constants; REQ-038).
- internal/certpaths/ — extracted path constants out of cli to break
the cli<->doctor import cycle; cli re-exports the helpers for
backward compat.
- internal/security/ca.go — public WriteCert/WriteKey helpers (0600
for keys, 0644 for certs; REQ-033); used by the cert CLI and
integration test.
- internal/daemon/tls.go — mTLS server with GetCertificate hot-swap
callback. Plaintext HTTP remains the default for v0.1 compat;
StartMTLS() flips the server into mTLS mode.
- internal/daemon/server.go — adds mtls *MTLSState field; MTLSActive()
getter for health endpoints.
- internal/transport/mtls.go — mTLS client with VerifyPeerCertificate
for pinned peer identity; DialContext for raw TLS.
- internal/transport/handshake_log.go — structured slog helpers for
handshake ok/fail (REQ-038 fields: event, result, peer, cert_fp).
- internal/cli/cert.go — orca cert {ca-init,gen,show,renew,fingerprint}
subcommands; file mode enforcement at every entry; redacted cert
show (REQ-035).
- internal/cli/doctor.go — orca doctor {cert,network,db} subcommands
(REQ-032); --json output supported.
- internal/cli/node.go — adds --ca-fingerprint to orca node join
(REQ-026); fails fast on mismatch.
- internal/doctor/doctor.go — 6 checks: cert.ca, cert.server,
cert.expiry, cert.fingerprint, network stub, db stub.
- internal/doctor/doctor_test.go — happy + sad path coverage.
- internal/security/integration_test.go — end-to-end: CA-init, CSR
generation, mTLS handshake, mismatch failure, rotation alarm,
redaction, file mode enforcement.
All tests pass with -race; gofmt -l . clean; go vet ./... clean.
---ci---
project: orca
phase: 8
milestone: v0.2
status: execute
---/ci---
2026-06-03 21:33:41 +00:00
Jon Chery
181cc769e6
feat(P08): CA, CSR, fingerprint, rotation, redact, TLS config + cert repo
...
Internal CA with CSR join, mTLS 1.3 config builders, rotation alarm,
PEM redaction, and cert inventory schema (REQ-033/034/035/036).
- internal/security/ca.go: CAInit/LoadCA/SignCSR, file mode enforcement
(ca.crt 0644, ca.key 0600) per REQ-033
- internal/security/csr.go: GenerateCSR with DNS + IP SANs (REQ-036)
- internal/security/fingerprint.go: SHA-256 hex of cert DER
- internal/security/rotation.go: 30d pre-expiry alarm, history pruning
- internal/security/redact.go: PEM private key block stripping (REQ-035)
- internal/security/tls_config.go: TLS 1.3 with AEAD allowlist
- internal/security/certgen_test.go: round-trip + mode + rotation + redact
- internal/store/migrations/0004_certs.sql: cert inventory table
- internal/store/cert_repo.go: CRUD + PruneOlderThan (REQ-025)
---ci---
project: orca
phase: 8
milestone: v0.2
status: execute
---/ci---
2026-06-03 21:18:50 +00:00
cloudinit-bot
be9afa2d2c
ship: v0.1 Foundation milestone complete ( #1 )
2026-06-03 20:08:57 +00:00