tests/test_audit.py
2.7 KB · 75 lines · python Raw
1 """Tests for AttestationLog."""
2
3 from __future__ import annotations
4
5 from pqc_ebpf_attestation import (
6 AttestationLog,
7 BPFProgram,
8 BPFProgramMetadata,
9 BPFProgramType,
10 BPFSigner,
11 PolicyDecision,
12 )
13
14
15 def test_log_entry_captures_fields(signed_program) -> None:
16 log = AttestationLog()
17 entry = log.log(signed_program, PolicyDecision.ALLOW, "ok", actor="ops@example")
18 assert entry.program_name == signed_program.program.metadata.name
19 assert entry.program_type == signed_program.program.metadata.program_type.value
20 assert entry.bytecode_hash == signed_program.program.bytecode_hash
21 assert entry.signer_did == signed_program.signer_did
22 assert entry.decision == "allow"
23 assert entry.reason == "ok"
24 assert entry.actor == "ops@example"
25 assert entry.timestamp
26 assert len(log) == 1
27
28
29 def test_filter_by_decision(signed_program) -> None:
30 log = AttestationLog()
31 log.log(signed_program, PolicyDecision.ALLOW, "allowed")
32 log.log(signed_program, PolicyDecision.DENY, "bad")
33 log.log(signed_program, PolicyDecision.DENY, "worse")
34 allows = log.entries(decision="allow")
35 denies = log.entries(decision="deny")
36 assert len(allows) == 1
37 assert len(denies) == 2
38 assert all(e.decision == "deny" for e in denies)
39
40
41 def test_filter_by_signer_did(signer_identity, untrusted_identity, sample_bpf_metadata) -> None:
42 trusted_signed = BPFSigner(signer_identity).sign(
43 BPFProgram.from_bytes(sample_bpf_metadata, b"trusted-bytes")
44 )
45 untrusted_signed = BPFSigner(untrusted_identity).sign(
46 BPFProgram.from_bytes(sample_bpf_metadata, b"untrusted-bytes")
47 )
48 log = AttestationLog()
49 log.log(trusted_signed, PolicyDecision.ALLOW, "ok")
50 log.log(untrusted_signed, PolicyDecision.DENY, "no")
51 log.log(trusted_signed, PolicyDecision.ALLOW, "ok")
52
53 only_trusted = log.entries(signer_did=signer_identity.did)
54 only_untrusted = log.entries(signer_did=untrusted_identity.did)
55 assert len(only_trusted) == 2
56 assert len(only_untrusted) == 1
57 assert all(e.signer_did == signer_identity.did for e in only_trusted)
58
59
60 def test_max_entries_rotation(signer, sample_bpf_metadata) -> None:
61 # Create several distinct signed programs to fill the log past its cap.
62 log = AttestationLog(max_entries=3)
63 for i in range(10):
64 meta = BPFProgramMetadata(
65 name=f"prog-{i}",
66 program_type=BPFProgramType.KPROBE,
67 )
68 signed = signer.sign(BPFProgram.from_bytes(meta, f"bytes-{i}".encode()))
69 log.log(signed, PolicyDecision.ALLOW, f"entry-{i}")
70 assert len(log) == 3
71 # Most recent first, so the first entry should be prog-9.
72 recent = log.entries()
73 assert recent[0].program_name == "prog-9"
74 assert recent[-1].program_name == "prog-7"
75