guildhouse-spire-plugins/pkg/keylime/keylime_test.go
Tyler J King 5f62da6ca9 feat(spire): Keylime node attestor plugin — single TPM authority
Custom SPIRE NodeAttestor that queries Keylime attestation status
instead of performing independent TPM attestation. Keylime remains
the single TPM authority in the stack.

Two data source strategies:
- ConfigMap (default): reads posture-current ConfigMap (recommended,
  consistent with single-consumer principle)
- Verifier: queries Keylime verifier REST API directly (for
  out-of-cluster SPIRE servers)

Fail-closed: unknown nodes, unreachable sources, degraded posture
all result in non-attested verdict — no SVID issued.

Maps posture level to attestation verdict:
  Normal(5)/Elevated(4) → Attested
  Restricted(3) → Pending
  Critical(2)/Lockdown(1) → Failed

8 unit tests covering ConfigMap source, verifier mapping, edge cases.

Signed-off-by: Tyler King <tking@guildhouse.dev>
Signed-off-by: Tyler J King <tking727@gmail.com>
2026-04-15 20:35:45 -04:00

116 lines
2.7 KiB
Go

// SPDX-License-Identifier: Apache-2.0
package keylime
import (
"os"
"path/filepath"
"testing"
)
func TestAttestedStatus(t *testing.T) {
s := &AttestationStatus{Verdict: "Attested", PostureLevel: 5}
if !s.IsAttested() {
t.Error("expected IsAttested() = true")
}
}
func TestFailedStatus(t *testing.T) {
s := &AttestationStatus{Verdict: "Failed", PostureLevel: 2}
if s.IsAttested() {
t.Error("expected IsAttested() = false for Failed")
}
}
func TestUnknownStatus(t *testing.T) {
s := &AttestationStatus{Verdict: "Unknown"}
if s.IsAttested() {
t.Error("expected IsAttested() = false for Unknown")
}
}
func TestConfigMapSourceNormal(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "level"), []byte("5"), 0644); err != nil {
t.Fatal(err)
}
c := NewClient(&Config{
Source: "configmap",
PostureConfigMapPath: dir,
})
status, err := c.GetStatus("node-1")
if err != nil {
t.Fatal(err)
}
if status.Verdict != "Attested" {
t.Errorf("expected Attested, got %s", status.Verdict)
}
if status.PostureLevel != 5 {
t.Errorf("expected level 5, got %d", status.PostureLevel)
}
}
func TestConfigMapSourceLockdown(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "level"), []byte("1"), 0644); err != nil {
t.Fatal(err)
}
c := NewClient(&Config{
Source: "configmap",
PostureConfigMapPath: dir,
})
status, err := c.GetStatus("node-1")
if err != nil {
t.Fatal(err)
}
if status.Verdict != "Failed" {
t.Errorf("expected Failed for lockdown, got %s", status.Verdict)
}
}
func TestConfigMapSourceMissing(t *testing.T) {
c := NewClient(&Config{
Source: "configmap",
PostureConfigMapPath: "/nonexistent/path",
})
status, err := c.GetStatus("node-1")
if err != nil {
t.Fatal(err)
}
if status.Verdict != "Unknown" {
t.Errorf("expected Unknown for missing configmap, got %s", status.Verdict)
}
}
func TestMapOpState(t *testing.T) {
approved := 7
if v := mapOpState(&approved); v != "Attested" {
t.Errorf("state 7 should be Attested, got %s", v)
}
failed := 9
if v := mapOpState(&failed); v != "Failed" {
t.Errorf("state 9 should be Failed, got %s", v)
}
pending := 3
if v := mapOpState(&pending); v != "Pending" {
t.Errorf("state 3 should be Pending, got %s", v)
}
if v := mapOpState(nil); v != "Pending" {
t.Errorf("nil state (push model) should be Pending, got %s", v)
}
}
func TestDefaultConfig(t *testing.T) {
cfg := DefaultConfig()
if cfg.Source != "configmap" {
t.Errorf("default source should be configmap, got %s", cfg.Source)
}
if cfg.APIVersion != "2.1" {
t.Errorf("default api version should be 2.1, got %s", cfg.APIVersion)
}
}