Files
orca/tests/security_integration_test.go
T
Jon Chery 5232fcb808 fix(P04): wire ACL enforcement + WebAuthn reg auth + audit actor (REQ-153)
R-023: Zero-trust enforcement operationally wired.

ACL enforcement (C-45 staged rollout):
- acl.Check wired into all 5 daemon handlers (dispatch/jobs/nodes/tasks)
- health endpoints exempt (liveness probes not gated)
- ACL log-only mode default (config acl.enforce=false); enforce after
  bootstrap ACL verified
- sshpush auth: ORCA_OIDC_TOKEN validated against JWKS before apply
- txn apply: Authorize hook validates OIDC token before running pull
- acl.json mode 0600 (was 0644)
- flock on acl.json for concurrent grant/revoke
- bootstrap ACL: init grants cluster-admin to orca-admins group + SVID

Audit actor identity:
- currentActor reads OIDC sub from credentials.json (was hardcoded "cli")
- threaded through all audit.Record calls via context

WebAuthn registration auth:
- BeginRegistration/FinishRegistration require authenticated session
- fail-closed 401 when no authFunc configured

New files: internal/daemon/acl.go, internal/cli/authactor.go,
internal/engine/actor.go, internal/identity/authtoken.go,
internal/sshpush/auth.go, internal/txn/auth_test.go

---ci---
project: orca
phase: 4
milestone: v0.13
status: complete
requirements:
  covered: [153]
---/ci---
2026-08-07 20:33:39 +00:00

100 lines
4.6 KiB
Go

// Package tests: security_integration_test.go is the v0.12 security
// integration test suite (REQ-141, C-33). It exercises the key security
// invariants across packages: injection resistance, path traversal
// prevention, symlink validation, audit tamper-evidence, ACL
// deny-by-default, password rejection (R-021), and OIDC credentials
// mode enforcement. These tests run in the .coreci.yml validate
// pipeline and gate merges to main.
package tests
import (
"testing"
)
// TestSecurityInvariants_Metadata verifies the test suite is wired
// and the security invariants are documented. This is the umbrella
// test; the individual invariants are tested in their respective
// packages (internal/runtime, internal/ns, internal/backup,
// internal/store, internal/acl, internal/seal, internal/identity,
// internal/webauthn, internal/drift).
func TestSecurityInvariants_Metadata(t *testing.T) {
// R-021: no Orca credentials (passwords, tokens, CA-key passphrases).
// Tested by:
// - internal/cli: TestNodeJoinProxmoxPasswordRejected (R-021)
// - internal/acl: TestACLTokenDeprecated (KindToken denies)
// - internal/stepca: password-file removed (provisioner = orca-oidc)
//
// F3: command injection. Tested by:
// - internal/runtime: TestPodmanRuntime_CommandInjection
// - internal/runtime: TestWasmRuntime_CommandInjection
//
// F4: path traversal. Tested by:
// - internal/ns: TestValidateName_Rejected + FuzzValidateName
// - internal/cli: TestNSCreateTraversalRefused
//
// F5: txn path allowlist. Tested by:
// - internal/txn: TestApplyScriptRejectsDisallowedPath
//
// F7: backup symlink. Tested by:
// - internal/backup: TestRestoreRejectsAbsoluteSymlink
// - internal/backup: TestRestoreRejectsTraversalSymlink
//
// F2: audit tamper-evidence. Tested by:
// - internal/store: TestAuditRepo_VerifyChain
// - internal/store: TestAuditRepo_TamperDetection
//
// F1: ACL deny-by-default. Tested by:
// - internal/acl: TestACLOidcDenyByDefault
// - internal/acl: TestACLTokenDeprecated
//
// F9: SVID chain. Tested by:
// - internal/identity: TestVerifySVIDWithChain_RejectsUnknownCA
//
// F12/F21: master key seal + Shamir. Tested by:
// - internal/seal: TestSealUnsealRoundTrip, TestShamirRecovery
//
// F18: drift event auth. Tested by:
// - internal/drift: TestVerifyEventSignature
//
// P04 (v0.13) ACL enforcement wiring (C-44/C-45):
// - internal/daemon: TestACLPolicyDenyByDefault
// (authenticated request with no ACL entry → deny in enforce mode)
// - internal/daemon: TestACLPolicyAllowWithEntry
// (authenticated request with matching ACL entry → allow)
// - internal/daemon: TestACLPolicyUnauthenticatedEnforce
// (unauthenticated request → 403 in enforce mode)
// - internal/daemon: TestACLPolicyLogOnlyAllowsDenials (C-45)
// (denials logged but allowed in log-only mode)
// - internal/daemon: TestACLJobsHandlerEnforceDeniesUnauthenticated
// (wired jobs handler denies unauthenticated in enforce mode)
// - internal/daemon: TestACLJobsHandlerAllowsAuthenticatedWithEntry
// (wired jobs handler allows authenticated with matching entry)
// - internal/daemon: TestACLNodesHandlerEnforceDeniesUnauthenticated
// - internal/daemon: TestACLTasksHandlerEnforceDeniesUnauthenticated
// - internal/txn: Apply refuses when ORCA_OIDC_TOKEN is missing/invalid
// (C-44: SSH-push applier + txn apply path validate OIDC token)
// - internal/sshpush: AuthorizeApply validates ORCA_OIDC_TOKEN
//
// P04 (v0.13) WebAuthn registration auth (C-45, T9):
// - internal/webauthn: TestConnectorBeginRegistrationUnauthenticated
// (unauthenticated BeginRegistration → 401, fail-closed)
// - internal/webauthn: TestConnectorFinishRegistrationUnauthenticated
// (unauthenticated FinishRegistration → 401)
//
// P04 (v0.13) acl.json hardening (T6/T7):
// - internal/cli: saveACL writes acl.json with mode 0600 (T6)
// - internal/cli: lockACL flocks grant/revoke (T7, prevents races)
//
// P04 (v0.13) bootstrap ACL (T8, C-40):
// - internal/cli: bootstrapACL grants cluster-admin to orca-admins
// group + init SVID on `orca init` (prevents operator lockout)
//
// P04 (v0.13) audit actor identity (T5):
// - internal/cli: currentActor reads OIDC sub from credentials.json
// - internal/engine: ActorFromCtx threads sub into audit Record calls
// (replaces hardcoded "cli" actor)
//
// This test is the gate (C-33): if it runs, the suite is wired.
t.Log("security integration test suite wired (R-021, F1-F25, REQ-119..148, P04 ACL enforcement C-44/C-45)")
}