NK-WP-0058-T03 step 1: name the causes (window-command identity phase, approval_entry field)
executor-lanes.py: the identity phase distinguishes openbao_unreachable, openbao_sealed and platform_admin_login_required, with a one-line hint; LaneError keeps its fixed code. executor.py: approval_entry:<approver_not_listed|not_human|not_aal2|self_approval>, never the subject. Note: executor.py changed, so the next admission pins a new image. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 943911@bnt-lap001 Assistant-Session: fc322940-1c8e-4bed-ab39-86cec99f23a0
This commit is contained in:
parent
f85a22d245
commit
7350ba8003
7 changed files with 103 additions and 16 deletions
|
|
@ -228,7 +228,7 @@ class RefusalTests(Base):
|
|||
"trust_not_satisfied:runtime_secret_trust": lambda: setattr(self.w, "trust_ok", False),
|
||||
"approval_binding": lambda: self.w.carrier.approval["binding"]["target"].update(admission_digest="sha256:" + "0" * 64),
|
||||
"approval_status": lambda: self.w.carrier.approval.update(status="requested"),
|
||||
"approval_entry": lambda: self.w.carrier.approval["entries"][0].update(assurance=AAL1),
|
||||
"approval_entry:not_aal2": lambda: self.w.carrier.approval["entries"][0].update(assurance=AAL1),
|
||||
"approval_expires_before_window_end": lambda: self.w.carrier.approval["validity"].update(expires_at="2026-11-03T10:00:00Z"),
|
||||
}
|
||||
for reason, mutate in cases.items():
|
||||
|
|
@ -238,12 +238,13 @@ class RefusalTests(Base):
|
|||
self.assert_no_effect(self.run_it(), reason)
|
||||
|
||||
def test_approval_by_someone_not_listed_or_not_human(self):
|
||||
for entry in ({"subject_id": "kc-sub-other", "assurance": AAL2, "principal_type": "human"},
|
||||
{"subject_id": ADMIN_SUB, "assurance": AAL2, "principal_type": "service"}):
|
||||
for entry, field in (({"subject_id": "kc-sub-other", "assurance": AAL2, "principal_type": "human"},
|
||||
"approver_not_listed"),
|
||||
({"subject_id": ADMIN_SUB, "assurance": AAL2, "principal_type": "service"}, "not_human")):
|
||||
with self.subTest(entry=entry):
|
||||
self.setUp()
|
||||
self.w.carrier.approval["entries"] = [entry]
|
||||
self.assert_no_effect(self.run_it(), "approval_entry")
|
||||
self.assert_no_effect(self.run_it(), "approval_entry:" + field)
|
||||
|
||||
def test_assurance_must_be_keycapes_verified_aal2(self):
|
||||
"""T19 finding: approval-engine stores the token's assurance object as JSON, never a bare level."""
|
||||
|
|
@ -252,7 +253,7 @@ class RefusalTests(Base):
|
|||
with self.subTest(assurance=assurance):
|
||||
self.setUp()
|
||||
self.w.carrier.approval["entries"][0]["assurance"] = assurance
|
||||
self.assert_no_effect(self.run_it(), "approval_entry")
|
||||
self.assert_no_effect(self.run_it(), "approval_entry:not_aal2")
|
||||
for assurance in (AAL2, json.loads(AAL2), json.dumps({"level": "aal3", "mfa": True})):
|
||||
self.assertTrue(X.entry_is_aal2(assurance))
|
||||
|
||||
|
|
@ -449,3 +450,16 @@ class FailureTests(Base):
|
|||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
class EntryFailureNames(unittest.TestCase):
|
||||
"""NK-WP-0058-T03: the refusal names the failed field, never a subject."""
|
||||
|
||||
def test_each_field(self):
|
||||
ok = {"subject_id": "sub-a", "principal_type": "human", "assurance": AAL2}
|
||||
allowed = {"sub-a", "service:x"}
|
||||
self.assertIsNone(X.entry_failure(ok, allowed, "service:x"))
|
||||
self.assertEqual(X.entry_failure({**ok, "subject_id": "sub-b"}, allowed, "service:x"), "approver_not_listed")
|
||||
self.assertEqual(X.entry_failure({**ok, "principal_type": "service"}, allowed, "service:x"), "not_human")
|
||||
self.assertEqual(X.entry_failure({**ok, "assurance": AAL1}, allowed, "service:x"), "not_aal2")
|
||||
self.assertEqual(X.entry_failure({**ok, "subject_id": "service:x"}, allowed, "service:x"), "self_approval")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue