FLEX-WP-0035 T01-T03: application access readback pin
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 58s

Contract accepted by user-engine; FLEX-DEC-2026-019 accepted.
- serve-readback: dedicated pin, no enforcement routes, own caller binding
- CheckRequest.purpose hashed into every digest when set; /v1/check refuses it
- POST /v1/readback/application_access and GET /v1/readback/systems
- optional client_binding on protected systems; readback schemas
- schemaguard implements maxItems
- T05 added: informed-decision needs an application.access rule over
  realm-level claims (its lifecycle rules read authentication_audience)

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:02:31 +02:00
parent b6d6bff85e
commit 8f2ba75e4a
23 changed files with 1314 additions and 44 deletions

View file

@ -0,0 +1,24 @@
- id: fixture:demo-app-access-allow
request:
subject:
id: user:alice
attributes:
groups: [app-users]
assurance: {level: aal2, mfa: true}
action: application.access
resource: {id: demo-app, type: application, system: demo-app}
expect:
effect: allow
reason: app_user
- id: fixture:demo-app-access-deny-no-mfa
request:
subject:
id: user:bob
attributes:
groups: [app-users]
assurance: {level: aal1, mfa: false}
action: application.access
resource: {id: demo-app, type: application, system: demo-app}
expect:
effect: deny
reason: no_matching_rule

View file

@ -0,0 +1,53 @@
---
id: testdata.demo-app
name: readback test package demo-app
namespace: testdata:demo-app
version: v1
status: fixture
package: flexauth.testdata.demo_app
actions:
- application.access
- read
owner: team:platform-security
fixtures:
- policy_fixtures.yaml
caring:
profile: caring-0.4.0-rc2
enforce: false
canonical_roles: [Operator]
organization_relations: [ServiceProvider]
scopes:
- {level: Platform, id: platform:testdata, tenant: tenant:platform}
planes: [Identity]
capabilities: [Use]
exposure_modes: [Metadata]
conditions: [Logged]
restrictions: [PrivilegeEscalationBlocked]
---
# Readback test package (FLEX-WP-0035)
Test-only. Do not copy.
```rego
import future.keywords.if
import future.keywords.in
default decision := {"effect": "deny", "reason": "no_matching_rule"}
decision := {"effect": "allow", "reason": "app_user"} if {
input.action == "application.access"
"app-users" in input.subject.attributes.groups
input.subject.attributes.assurance.mfa == true
}
```
```rego test
package flexauth.testdata.demo_app_test
import future.keywords.if
import data.flexauth.testdata.demo_app
test_default_deny if {
demo_app.decision.effect == "deny" with input as {"action": "read", "subject": {"attributes": {}}}
}
```

View file

@ -0,0 +1,28 @@
{
"systems": [
{
"id": "demo-app",
"name": "Demo App",
"client_binding": {
"issuer": "https://keycape.example/realms/netkingdom",
"client_id": "demo-app"
}
}
],
"subjects": [
{
"id": "demo-app-profile",
"type": "Human",
"display_name": "Readback contract profile (declares caller-supplied keys)",
"groups": [
"app-users"
],
"claims": {
"assurance": {
"level": "aal2",
"mfa": true
}
}
}
]
}

View file

@ -0,0 +1,14 @@
# The rule would allow application.access, but this package does not declare
# the action. The readback must answer not_applicable regardless (T01 §2).
- id: fixture:other-app-undeclared-rule-would-allow
request:
subject:
id: user:alice
attributes:
groups: [app-users]
assurance: {level: aal2, mfa: true}
action: application.access
resource: {id: other-app, type: application, system: other-app}
expect:
effect: allow
reason: app_user

View file

@ -0,0 +1,52 @@
---
id: testdata.other-app
name: readback test package other-app
namespace: testdata:other-app
version: v1
status: fixture
package: flexauth.testdata.other_app
actions:
- read
owner: team:platform-security
fixtures:
- policy_fixtures.yaml
caring:
profile: caring-0.4.0-rc2
enforce: false
canonical_roles: [Operator]
organization_relations: [ServiceProvider]
scopes:
- {level: Platform, id: platform:testdata, tenant: tenant:platform}
planes: [Identity]
capabilities: [Use]
exposure_modes: [Metadata]
conditions: [Logged]
restrictions: [PrivilegeEscalationBlocked]
---
# Readback test package (FLEX-WP-0035)
Test-only. Do not copy.
```rego
import future.keywords.if
import future.keywords.in
default decision := {"effect": "deny", "reason": "no_matching_rule"}
decision := {"effect": "allow", "reason": "app_user"} if {
input.action == "application.access"
"app-users" in input.subject.attributes.groups
input.subject.attributes.assurance.mfa == true
}
```
```rego test
package flexauth.testdata.other_app_test
import future.keywords.if
import data.flexauth.testdata.other_app
test_default_deny if {
other_app.decision.effect == "deny" with input as {"action": "read", "subject": {"attributes": {}}}
}
```

View file

@ -0,0 +1,24 @@
{
"systems": [
{
"id": "other-app",
"name": "Other App"
}
],
"subjects": [
{
"id": "other-app-profile",
"type": "Human",
"display_name": "Readback contract profile (declares caller-supplied keys)",
"groups": [
"app-users"
],
"claims": {
"assurance": {
"level": "aal2",
"mfa": true
}
}
}
]
}