FLEX-WP-0035-T05: informed-decision lifecycle v2 declares application.access
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Container Image / build-and-push (push) Successful in 1m5s

- application.access allows only with purpose=readback and the authoring
  human bar; no workload path, no audience or client-scoped claims
- v1 operations unchanged; pin.json moves to v2; live pin stays v1 until T04
- examples/application-readback: readback catalogue with informed-decision's
  key-cape client binding; integration test over the shipped files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 609675@bnt-lap001
Assistant-Session: 4987a36e-eb38-4b10-803c-15a29cd78212
This commit is contained in:
tegwick 2026-10-09 20:10:50 +02:00
parent a4103272e1
commit b5da745063
10 changed files with 207 additions and 12 deletions

View file

@ -42,11 +42,34 @@ func TestInformedDecisionLifecycle(t *testing.T) {
human(d)["type"] = "service"
human(d)["attributes"] = map[string]any{"principal_type_source": "authentication-derived", "tenant_source": "registration-supplied", "workload_uid": "verified-uid", "authentication_audience": "informed-decision-lifecycle"}
}
// FLEX-WP-0035-T05: the readback asks for the application, not a memo.
app := func(d map[string]any) {
d["action"] = "application.access"
d["purpose"] = "readback"
d["resource"] = map[string]any{"id": "informed-decision", "type": "application", "system": "informed-decision"}
delete(d, "context")
delete(attrs(d), "principal_type_source")
delete(attrs(d), "tenant_source")
}
tests := []struct {
name string
effect string
change func(map[string]any)
}{
{"readback application access", "allow", app},
{"application access without readback purpose", "deny", func(d map[string]any) { app(d); delete(d, "purpose") }},
{"workload application access", "deny", func(d map[string]any) { hub(d); app(d) }},
{"application access outside group", "deny", func(d map[string]any) { app(d); attrs(d)["groups"] = []any{"other"} }},
{"application access stale MFA", "deny", func(d map[string]any) {
app(d)
attrs(d)["assurance"].(map[string]any)["at"] = time.Now().Unix() - 43201
}},
{"application access without otp", "deny", func(d map[string]any) { app(d); attrs(d)["assurance"].(map[string]any)["methods"] = []any{"pwd"} }},
{"application access other application", "deny", func(d map[string]any) {
app(d)
d["resource"].(map[string]any)["id"] = "markitect"
}},
{"application access foreign tenant", "deny", func(d map[string]any) { app(d); d["tenant"] = "tenant:foreign" }},
{"human registration", "allow", func(d map[string]any) {}},
{"workload registration", "allow", hub},
{"foreign workload", "deny", func(d map[string]any) { hub(d); human(d)["id"] = "system:serviceaccount:foreign:foreign" }},