Cover wrong-tenant denials in ops-warden and railiance-platform fixtures.
FLEX-WP-0022-T03: the rules already refused a foreign tenant; the fixture suites never varied the field. No policy or version change. Asked tenant-engine to name the CheckRequest tenant relation for T01/T02. Assistant: grok Assistant-Session: 01a0a6cb-0334-72c0-83b0-2df57474a0f6
This commit is contained in:
parent
6fd3a0cbc4
commit
0e020b2d8c
8 changed files with 117 additions and 8 deletions
|
|
@ -28,6 +28,7 @@ flex-auth validate --kind subject-manifest --file examples/ops-warden/subject_ma
|
||||||
flex-auth load-registry --file examples/ops-warden/registry_snapshot.json
|
flex-auth load-registry --file examples/ops-warden/registry_snapshot.json
|
||||||
flex-auth test-policy --file examples/ops-warden/policy_package.md
|
flex-auth test-policy --file examples/ops-warden/policy_package.md
|
||||||
flex-auth check --registry examples/ops-warden/registry_snapshot.json --policy examples/ops-warden/policy_package.md --request examples/ops-warden/check_request_allow_adm.json
|
flex-auth check --registry examples/ops-warden/registry_snapshot.json --policy examples/ops-warden/policy_package.md --request examples/ops-warden/check_request_allow_adm.json
|
||||||
|
flex-auth check --registry examples/ops-warden/registry_snapshot.json --policy examples/ops-warden/policy_package.md --request examples/ops-warden/check_request_deny_wrong_tenant.json
|
||||||
```
|
```
|
||||||
|
|
||||||
The fixture public-key fingerprints are examples only. Do not put real keys,
|
The fixture public-key fingerprints are examples only. Do not put real keys,
|
||||||
|
|
|
||||||
23
examples/ops-warden/check_request_deny_wrong_tenant.json
Normal file
23
examples/ops-warden/check_request_deny_wrong_tenant.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"id": "check:ops-warden-wrong-tenant",
|
||||||
|
"tenant": "tenant:other",
|
||||||
|
"subject": {
|
||||||
|
"id": "platform-steward",
|
||||||
|
"type": "adm"
|
||||||
|
},
|
||||||
|
"action": "sign",
|
||||||
|
"resource": {
|
||||||
|
"id": "ssh-cert:actor/platform-steward",
|
||||||
|
"type": "ssh-certificate",
|
||||||
|
"system": "ops-warden"
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"principals": [
|
||||||
|
"platform",
|
||||||
|
"root"
|
||||||
|
],
|
||||||
|
"actor_type": "adm",
|
||||||
|
"ttl_hours": 4,
|
||||||
|
"pubkey_fingerprint": "SHA256:example-adm-fingerprint"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -394,5 +394,50 @@
|
||||||
"effect": "audit_only",
|
"effect": "audit_only",
|
||||||
"reason": "advisory_would_signing_policy_matched"
|
"reason": "advisory_would_signing_policy_matched"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fixture:ops-warden-wrong-tenant-deny",
|
||||||
|
"request": {
|
||||||
|
"id": "check:ops-warden-wrong-tenant",
|
||||||
|
"tenant": "tenant:other",
|
||||||
|
"subject": {
|
||||||
|
"id": "platform-steward",
|
||||||
|
"type": "adm"
|
||||||
|
},
|
||||||
|
"action": "sign",
|
||||||
|
"resource": {
|
||||||
|
"id": "ssh-cert:actor/platform-steward",
|
||||||
|
"type": "ssh-certificate",
|
||||||
|
"system": "ops-warden",
|
||||||
|
"attributes": {
|
||||||
|
"actor_id": "platform-steward",
|
||||||
|
"actor_type": "adm",
|
||||||
|
"allowed_subjects": [
|
||||||
|
"platform-steward",
|
||||||
|
"iam:platform-steward"
|
||||||
|
],
|
||||||
|
"allowed_principals": [
|
||||||
|
"platform",
|
||||||
|
"root"
|
||||||
|
],
|
||||||
|
"max_ttl_hours": 8,
|
||||||
|
"security_zone": "z2-protected",
|
||||||
|
"security_zone_admission": "satisfied"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"principals": [
|
||||||
|
"platform",
|
||||||
|
"root"
|
||||||
|
],
|
||||||
|
"actor_type": "adm",
|
||||||
|
"ttl_hours": 4,
|
||||||
|
"pubkey_fingerprint": "SHA256:example-adm-fingerprint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"expect": {
|
||||||
|
"effect": "deny",
|
||||||
|
"reason": "wrong_tenant"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
This package provides the flex-auth side of `FLEX-WP-0012`: registered grant
|
This package provides the flex-auth side of `FLEX-WP-0012`: registered grant
|
||||||
metadata, representative requester subjects, a default-deny `issue` policy,
|
metadata, representative requester subjects, a default-deny `issue` policy,
|
||||||
and fixtures for TTL, actor type, purpose, delivery mode, and unknown grants.
|
and fixtures for TTL, actor type, purpose, delivery mode, unknown grants, and
|
||||||
|
wrong tenant.
|
||||||
|
|
||||||
The wire translation is intentionally outside the policy. Both candidate
|
The wire translation is intentionally outside the policy. Both candidate
|
||||||
integration shapes must emit `requested_ttl_seconds` as a positive number;
|
integration shapes must emit `requested_ttl_seconds` as a positive number;
|
||||||
|
|
@ -13,4 +14,5 @@ go run ./cmd/flex-auth load-registry --file examples/railiance-platform/registry
|
||||||
go run ./cmd/flex-auth test-policy --file examples/railiance-platform/policy_package.md
|
go run ./cmd/flex-auth test-policy --file examples/railiance-platform/policy_package.md
|
||||||
go run ./cmd/flex-auth check --registry examples/railiance-platform/registry_snapshot.json --policy examples/railiance-platform/policy_package.md --request examples/railiance-platform/check_request_allow.json
|
go run ./cmd/flex-auth check --registry examples/railiance-platform/registry_snapshot.json --policy examples/railiance-platform/policy_package.md --request examples/railiance-platform/check_request_allow.json
|
||||||
go run ./cmd/flex-auth check --registry examples/railiance-platform/registry_snapshot.json --policy examples/railiance-platform/policy_package.md --request examples/railiance-platform/check_request_deny_unknown.json
|
go run ./cmd/flex-auth check --registry examples/railiance-platform/registry_snapshot.json --policy examples/railiance-platform/policy_package.md --request examples/railiance-platform/check_request_deny_unknown.json
|
||||||
|
go run ./cmd/flex-auth check --registry examples/railiance-platform/registry_snapshot.json --policy examples/railiance-platform/policy_package.md --request examples/railiance-platform/check_request_deny_wrong_tenant.json
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"id": "check:credential-grant-wrong-tenant-http-shape",
|
||||||
|
"tenant": "tenant:other",
|
||||||
|
"subject": {
|
||||||
|
"id": "agent:codex/railiance-platform",
|
||||||
|
"type": "Agent"
|
||||||
|
},
|
||||||
|
"action": "issue",
|
||||||
|
"resource": {
|
||||||
|
"id": "credential-grant:rapp-postgres/audit-core-runtime",
|
||||||
|
"type": "credential-grant",
|
||||||
|
"system": "railiance-platform"
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"actor_type": "approved-agent",
|
||||||
|
"bound_subject": "agent:codex/railiance-platform",
|
||||||
|
"purpose": "audit-core-runtime",
|
||||||
|
"delivery_mode": "exec-env",
|
||||||
|
"requested_ttl_seconds": 900
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,3 +57,9 @@
|
||||||
type: credential-grant
|
type: credential-grant
|
||||||
system: railiance-platform
|
system: railiance-platform
|
||||||
expect: {effect: deny, reason: unknown_grant}
|
expect: {effect: deny, reason: unknown_grant}
|
||||||
|
- id: fixture:credential-grant-wrong-tenant-deny
|
||||||
|
request:
|
||||||
|
<<: *allow_request
|
||||||
|
id: check:credential-grant-wrong-tenant-deny
|
||||||
|
tenant: tenant:other
|
||||||
|
expect: {effect: deny, reason: wrong_tenant}
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ func TestOpsWardenPolicyPackageMarkdownValidates(t *testing.T) {
|
||||||
if pkg.Metadata.Namespace != "ops-warden:ssh-certificate" {
|
if pkg.Metadata.Namespace != "ops-warden:ssh-certificate" {
|
||||||
t.Fatalf("metadata.Namespace = %q; want ops-warden:ssh-certificate", pkg.Metadata.Namespace)
|
t.Fatalf("metadata.Namespace = %q; want ops-warden:ssh-certificate", pkg.Metadata.Namespace)
|
||||||
}
|
}
|
||||||
if len(pkg.Validation.Fixtures) != 9 {
|
if len(pkg.Validation.Fixtures) != 10 {
|
||||||
t.Fatalf("Validation.Fixtures len = %d; want 9", len(pkg.Validation.Fixtures))
|
t.Fatalf("Validation.Fixtures len = %d; want 10", len(pkg.Validation.Fixtures))
|
||||||
}
|
}
|
||||||
for _, fixture := range pkg.Validation.Fixtures {
|
for _, fixture := range pkg.Validation.Fixtures {
|
||||||
if !fixture.Passed {
|
if !fixture.Passed {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ type: workplan
|
||||||
title: "Tenant scoping is unstated in tenant-engine and untested in two more packages"
|
title: "Tenant scoping is unstated in tenant-engine and untested in two more packages"
|
||||||
domain: infotech
|
domain: infotech
|
||||||
repo: flex-auth
|
repo: flex-auth
|
||||||
status: proposed
|
status: active
|
||||||
flavor: planning
|
flavor: implementation
|
||||||
depends_on:
|
depends_on:
|
||||||
- FLEX-WP-0021
|
- FLEX-WP-0021
|
||||||
owner: claude
|
owner: claude
|
||||||
|
|
@ -18,7 +18,7 @@ related_workplans:
|
||||||
- FLEX-WP-0010
|
- FLEX-WP-0010
|
||||||
- FLEX-WP-0014
|
- FLEX-WP-0014
|
||||||
created: "2026-09-06"
|
created: "2026-09-06"
|
||||||
updated: "2026-09-06"
|
updated: "2026-09-15"
|
||||||
state_hub_workstream_id: "804c588c-f47a-50c4-bdd7-51b24bbf9539"
|
state_hub_workstream_id: "804c588c-f47a-50c4-bdd7-51b24bbf9539"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ look identical in the artifact. That is the same publishing-shape argument
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: FLEX-WP-0022-T01
|
id: FLEX-WP-0022-T01
|
||||||
status: todo
|
status: progress
|
||||||
priority: high
|
priority: high
|
||||||
state_hub_task_id: "a84dcee5-9426-5b30-8dd3-f4c076d00174"
|
state_hub_task_id: "a84dcee5-9426-5b30-8dd3-f4c076d00174"
|
||||||
```
|
```
|
||||||
|
|
@ -75,6 +75,11 @@ Owner: `flex-auth` to ask; `tenant-engine` owns the answer.
|
||||||
Gate: the relation is named by `tenant-engine`, not inferred here. This is the
|
Gate: the relation is named by `tenant-engine`, not inferred here. This is the
|
||||||
`FLEX-WP-0021-T01` rule applied to a field rather than to an action list.
|
`FLEX-WP-0021-T01` rule applied to a field rather than to an action list.
|
||||||
|
|
||||||
|
2026-09-15: asked `tenant-engine` to name the relation
|
||||||
|
(`e8ba6a53-0093-4dc0-ad70-01f6b8c8e76b`). Their live
|
||||||
|
`FlexAuthWriteAuthorizer.authorize` copies `tenant_id` onto both
|
||||||
|
`CheckRequest.tenant` and `resource.id`. That is observation, not admission.
|
||||||
|
|
||||||
## 2. Encode the relation, or record that there is none
|
## 2. Encode the relation, or record that there is none
|
||||||
|
|
||||||
```task
|
```task
|
||||||
|
|
@ -100,7 +105,7 @@ Either way the fixtures must vary `tenant`, so the suite reports on the field.
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: FLEX-WP-0022-T03
|
id: FLEX-WP-0022-T03
|
||||||
status: todo
|
status: done
|
||||||
priority: medium
|
priority: medium
|
||||||
state_hub_task_id: "3058f171-99d2-526b-a1bb-bd7aed87d10a"
|
state_hub_task_id: "3058f171-99d2-526b-a1bb-bd7aed87d10a"
|
||||||
```
|
```
|
||||||
|
|
@ -113,3 +118,9 @@ fixture suite covers what the rule claims. No policy change and no version bump:
|
||||||
the behaviour is already correct, only the evidence is thin.
|
the behaviour is already correct, only the evidence is thin.
|
||||||
|
|
||||||
Gate: no package's fixture suite holds `tenant` constant.
|
Gate: no package's fixture suite holds `tenant` constant.
|
||||||
|
|
||||||
|
2026-09-15: added `fixture:ops-warden-wrong-tenant-deny` and
|
||||||
|
`fixture:credential-grant-wrong-tenant-deny` plus matching
|
||||||
|
`check_request_deny_wrong_tenant.json` files. Both suites now vary `tenant`.
|
||||||
|
`test-policy` and `flex-auth check` return `deny` / `wrong_tenant`. No policy
|
||||||
|
or version change.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue