From 342a6f25af5cdc602841948f42759ea52ef1c8f5 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 17 Oct 2026 20:28:50 +0200 Subject: [PATCH] test: restore independent mint admission coverage and refine remaining fixes Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1468b-63fa-7710-85dc-8f2e16b3ebfa --- sso-mfa/k8s/keycape/test_admit_1_3_type.py | 32 ++++++-- workplans/NK-WP-0048-security-case-types.md | 90 +++++++++++++++++++++ 2 files changed, 115 insertions(+), 7 deletions(-) diff --git a/sso-mfa/k8s/keycape/test_admit_1_3_type.py b/sso-mfa/k8s/keycape/test_admit_1_3_type.py index 084df94..1b3e537 100644 --- a/sso-mfa/k8s/keycape/test_admit_1_3_type.py +++ b/sso-mfa/k8s/keycape/test_admit_1_3_type.py @@ -1,9 +1,9 @@ """Kernel admission against the real 1.3 successor type (NK-WP-0048-T16 candidate). -Unlike test_admit_1_2_adapter_descriptors.py, nothing is patched into the type's -execution_descriptors: the map tested here is the one committed in -security-case-type-revisions/1.3. The type is `proposed`, so the kernel must refuse -it as it stands. Warden's BrowserInputs also pins each type version's parameter +The committed-map tests use security-case-type-revisions/1.3 unchanged. One +separate fixture-map test acknowledges only an agent-actor mint descriptor digest +to reach the independent kernel mint prohibition after map validation. The type +is `proposed`, so the kernel must refuse it as it stands. Warden's BrowserInputs also pins each type version's parameter fingerprint and knows only 1.1 and 1.2 (ops-warden case_inputs.PARAMETER_PINS), so an acknowledged 1.3 is still refused until ops-warden adds a 1.3 pin. That is an ops-warden owner change, and it is not made here. The tests show that 1.3's @@ -74,7 +74,7 @@ class Admit13TypeTests(unittest.TestCase): ARTIFACT['params']['consumer_owner_repo'], version='1.3')) - def admit(self, desc, type_source, *, actor=None, lane=None): + def admit(self, desc, type_source, *, actor=None, lane=None, agent_id=None): desc_bytes = c.encode(desc) adapter = Adapter(desc.adapter, desc.adapter_source, unused, unused) executor = Executor(Journal(Path(self.temp.name) / desc.step), @@ -82,7 +82,10 @@ class Admit13TypeTests(unittest.TestCase): lambda purpose, source, evidence: evidence in EVIDENCE, browser_inputs=inputs.BrowserInputs(REPO)) with mock.patch.dict(os.environ): - os.environ.pop('WARDEN_AGENT_ID', None) + if agent_id is None: + os.environ.pop('WARDEN_AGENT_ID', None) + else: + os.environ['WARDEN_AGENT_ID'] = agent_id return executor.admit(self.case_source, type_source, desc_bytes, b'fixture-only-catalog', principal='founder', actor=actor or desc.actor, lane=lane or desc.lane, @@ -125,7 +128,8 @@ class Admit13TypeTests(unittest.TestCase): def test_descriptor_outside_the_map_is_refused(self): acknowledged = with_status('acknowledged') mint = self.descriptors['mint-secret'] - for changed in (replace(mint, lane='other-lane'), replace(mint, retry_safe=True)): + for changed in (replace(mint, lane='other-lane'), replace(mint, retry_safe=True), + replace(mint, actor='agent')): with self.subTest(changed=changed), pinned_13(), self.assertRaisesRegex( Refused, 'no exact acknowledged machine descriptor'): self.admit(changed, acknowledged) @@ -138,6 +142,20 @@ class Admit13TypeTests(unittest.TestCase): with pinned_13(), self.assertRaisesRegex(Refused, 'principal actor or lane mismatch'): self.admit(mint, acknowledged, actor='agent') + def test_agent_mint_is_refused_after_fixture_map_acknowledges_descriptor(self): + # A committed-map mismatch cannot exercise the independent mint guard. + mint = replace(self.descriptors['mint-secret'], actor='agent') + typ = yaml.safe_load(with_status('acknowledged')) + typ['spec']['execution_descriptors']['mint-secret'] = digest(c.encode(mint)) + with pinned_13(), self.assertRaisesRegex(Refused, 'agent mint is forbidden'): + self.admit(mint, yaml.safe_dump(typ).encode()) + + def test_human_mint_is_refused_with_agent_runtime_identity(self): + mint = self.descriptors['mint-secret'] + self.assertEqual(mint.actor, 'human') + with pinned_13(), self.assertRaisesRegex(Refused, 'agent mint is forbidden'): + self.admit(mint, with_status('acknowledged'), agent_id='fixture-agent') + def test_wrong_lane_is_refused(self): # Moved from test_admit_1_2_adapter_descriptors.py in r5. acknowledged = with_status('acknowledged') diff --git a/workplans/NK-WP-0048-security-case-types.md b/workplans/NK-WP-0048-security-case-types.md index 8c3529a..16914fc 100644 --- a/workplans/NK-WP-0048-security-case-types.md +++ b/workplans/NK-WP-0048-security-case-types.md @@ -915,6 +915,16 @@ Platform-owned evidence seams; (d) bind-env and (e) deliver-consumer-secret; over the reviewed set. Each candidate needs its owner's source review before pinning; none is authored here as owner-accepted. Status stays todo. +2026-10-17 task refinement after coordinator r5: completed independent mint- +guard regression coverage is extracted as T32. T33 tracks the exact Platform +issuer-store source/reference correction; T34 tracks the Apps configuration +inverse reachable without secret or hand-over resource creation. T16 retains +final exact seven-descriptor composition, independent owner reviews and admission; +its status and existing dependencies are preserved. The kernel branch also needs +its own KR1-F1/F2 admission/dispatch corrections and independent review under +WARDEN-WP-0044-T03 before any 1.3 pin. Historical r4 acceptance does not supersede +r5's findings or establish native readiness. + ## T17 — Build and exercise the exact offline config-checker artifact ```task @@ -1517,3 +1527,83 @@ attempt/case/source/principal and unavailable-holder cases refuse; and a missing or ambiguous record stays uncertain, with no add replay or undo. The interface is Warden's own dispatch record, not owner-authenticated created-only provenance. Selecting the actual authenticated holder stays a T15 owner gate. + + +## T32 — Restore independent agent-mint admission regression coverage + +```task +id: NK-WP-0048-T32 +status: done +priority: high +state_hub_task_id: "c6d0a27e-f6a7-5df0-95f6-3e7473d38bb5" +``` + +Completed 2026-10-17, source tests only. Extracted from T16's coordinator r5 +finding NK48-R5-F1; no earlier adapter outcome is counted again. The real 1.3 +admission test now separately checks the committed descriptor map, an in-memory +fixture map acknowledging the changed agent descriptor to reach the independent +mint prohibition, and the human descriptor under an explicit fixture agent +runtime marker. Only `sso-mfa/k8s/keycape/test_admit_1_3_type.py` changes. + +Against frozen Warden `117fec9241e7b985dfb187b992e173d0a5dc3700`, the new +suite passes 10 tests / 32 subtests. Independent mutation evidence removes only +the mint admission guard in scratch: both new guard tests fail while eight +controls pass; the old suite passed that mutant. Custodian independently reran +the canonical successor: 10 tests / 32 subtests pass. Evidence: +`the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-r5-f1-implementation-r1/` +(patch, frozen/mutant results and canonical-validation.json). No descriptor, +parameter pin, catalog, acknowledgment, kernel or native execution changed. +T16 still owns actual composition and admission; F2/F3 follow below. + +## T33 — Close the issuer-store reference finding with Platform source + +```task +id: NK-WP-0048-T33 +status: todo +priority: high +state_hub_task_id: "5ace28ff-a4cb-5647-a8f6-3cd54bb9d0a5" +``` + +Owner: Platform for the fixed store/template source and its delivery boundary; +NetKingdom for the 1.3 type reference. Split from T16's current coordinator r5 +finding NK48-R5-F2. Next action: independently review the prepared Platform +candidate and publish a concrete owner-controlled issuer store kind/name/scope +and template reference, then integrate only that exact proposed source into the +1.3 deliver-secret entry point and regenerate its composition artifact. Candidate +and current review evidence are under Custodian +`docs/changes/netkingdom-target-2026-10-17/nk48-r5-f2-implementation-r1/` +and `nk48-r5-f2-review-r1/`. + +Completion requires exact committed source, a passing independent source review +and unchanged type parameter bytes. No consumer store may be inferred as issuer +store, and no source declaration supplies owner assent, installed ESO support, +CCR/grant changes or a real delivery capability. Those remain existing +RPF-1.3-T4 and T16 admission/native requirements. + +## T34 — Close the consumer configuration inverse finding + +```task +id: NK-WP-0048-T34 +status: todo +priority: high +state_hub_task_id: "37f43c40-d014-544e-aa0b-5219dd4a6b93" +``` + +Owner: Apps for consumer configuration and inverse; NetKingdom for exact type +placement. Split from T16's coordinator r5 finding NK48-R5-F3. Next action: +independently review and implement the owner transaction/inverse through the +existing RAPPS-WP-0016-T05 path, with authenticated durable before/after release +provenance, exclusive serialization of all release writers and a fresh authorized +attended session for every inverse attempt after the hand-over session is revoked. +The inverse must remain reachable for public clients, confidential NO_CHANGE +secret delivery and verification failure before a hand-over receipt exists. + +Completion requires real owner configuration/inverse source bindings and +independent regressions, then exact reviewed 1.3 entry/rollback text and composed +artifact. A synthetic wrapper with an injected backend alone is insufficient. +Keep hand-over receipt rollback receipt-only and secret deletion created-only; +preexisting or drifted resources must refuse unsafe inverse. Candidate evidence: +Custodian `docs/changes/netkingdom-target-2026-10-17/nk48-r5-f3-implementation-r1/` +and `nk48-r5-f3-review-r1/`. Source review, owner acknowledgment and native proof +remain distinct. T16's final composition/admission and T06's native first case +are not completed by this refinement.