feat(authz): operator signed-op verifier + durable nonce store (slice 2, v0.2.0)
internal/authz: production form of the Phase-4 SSHSIG signing primitive. - Verifier.New/Verify with the LOCKED pipeline (namespace → allow-list by key material → crypto over RAW bytes → target → time → nonce LAST); each post-crypto stage rejects even with a valid sig; an invalid sig never burns a nonce. - SSHSIG framing via x/crypto/ssh (no hand-rolled crypto); key-type-agnostic (ed25519 / sk-ssh-ed25519 / rsa / ecdsa via pub.Verify). Fixed namespace felhom-op-v1. Typed errors. OpBlob (fixed host_id/guest_id tags) + VerifiedOp. - NonceStore: MemoryNonceStore + durable crash-safe FileNonceStore (fsync'd append log, replay-on-open, compaction, expiry-only pruning; survives restart). - config.AuthzConfig (nonce path + pinned operational/recovery signer keys). - Tests (14): real ssh-keygen fixture, per-stage rejection, nonce-not-burned, replay, persistence-across-restart, synthetic sk, byte-exactness. Dep: golang.org/x/crypto v0.52.0 (declares go 1.25 — the Phase-4 doc's "Go 1.24.4 / x/crypto v0.52.0" pairing doesn't build; build server upgraded to go1.26.0, backward-compatible). Version 0.1.0 -> 0.2.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewAllowedSigner(t *testing.T) {
|
||||
line, err := os.ReadFile("testdata/operator.pub")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s, err := NewAllowedSigner("felhom-op-1", RoleOperational, string(line))
|
||||
if err != nil {
|
||||
t.Fatalf("NewAllowedSigner: %v", err)
|
||||
}
|
||||
if s.KeyID != "felhom-op-1" || s.Role != RoleOperational || s.PublicKey == nil {
|
||||
t.Errorf("signer = %+v", s)
|
||||
}
|
||||
if s.PublicKey.Type() != "ssh-ed25519" {
|
||||
t.Errorf("key type = %q", s.PublicKey.Type())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAllowedSigner_BadRole(t *testing.T) {
|
||||
line, _ := os.ReadFile("testdata/operator.pub")
|
||||
if _, err := NewAllowedSigner("k", "bogus", string(line)); err == nil {
|
||||
t.Fatal("invalid role should error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAllowedSigner_BadLine(t *testing.T) {
|
||||
if _, err := NewAllowedSigner("k", RoleOperational, "not a key"); err == nil {
|
||||
t.Fatal("malformed key line should error")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user