Admit initial decision lifecycle audience and patch evaluator dependencies
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
Build and Publish Container Image / build-and-push (push) Successful in 1m37s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a10780-6d41-7952-9718-dfbc1f41236f
This commit is contained in:
tegwick 2026-10-04 21:40:39 +02:00
parent c0f3f25be2
commit d2d0b6feeb
25 changed files with 2644 additions and 102 deletions

View file

@ -17,7 +17,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: "1.22" go-version-file: go.mod
- name: Verify dependencies - name: Verify dependencies
run: go mod verify run: go mod verify
@ -43,7 +43,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: "1.22" go-version-file: go.mod
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v6 uses: golangci/golangci-lint-action@v6

View file

@ -1,11 +1,11 @@
FROM golang:1.23-alpine AS build FROM golang:1.26.7-alpine@sha256:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468 AS build
WORKDIR /src WORKDIR /src
COPY go.mod go.sum ./ COPY go.mod go.sum ./
RUN go mod download RUN go mod download
COPY . . COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/flex-auth ./cmd/flex-auth RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/flex-auth ./cmd/flex-auth
FROM gcr.io/distroless/static-debian12:nonroot FROM gcr.io/distroless/static-debian12:nonroot@sha256:afa5c872c891853ca7fcf1f12c3edb23f7eeef36189728842dd51042ff57f7ab
COPY --from=build /out/flex-auth /usr/local/bin/flex-auth COPY --from=build /out/flex-auth /usr/local/bin/flex-auth
COPY examples /opt/flex-auth/examples COPY examples /opt/flex-auth/examples
EXPOSE 8080 EXPOSE 8080

14
Containerfile.lifecycle Normal file
View file

@ -0,0 +1,14 @@
# Same pinned engine build; candidate policies are included by COPY examples.
FROM golang:1.26.7-alpine@sha256:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/flex-auth ./cmd/flex-auth
FROM gcr.io/distroless/static-debian12:nonroot@sha256:afa5c872c891853ca7fcf1f12c3edb23f7eeef36189728842dd51042ff57f7ab
COPY --from=build /out/flex-auth /usr/local/bin/flex-auth
COPY examples /opt/flex-auth/examples
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/flex-auth"]
CMD ["serve", "--addr", "0.0.0.0:8080", "--registry", "/opt/flex-auth/examples/tenant-engine/registry_snapshot.json", "--policy", "/opt/flex-auth/examples/tenant-engine/policy_package.md"]

View file

@ -0,0 +1,88 @@
{
"valid": true,
"caring_findings": [
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed canonical roles",
"fields": [
"caring.canonical_roles"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed organization relations",
"fields": [
"caring.organization_relations"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed scopes",
"fields": [
"caring.scopes"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed planes",
"fields": [
"caring.planes"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed capabilities",
"fields": [
"caring.capabilities"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed exposure modes",
"fields": [
"caring.exposure_modes"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed conditions",
"fields": [
"caring.conditions"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed restrictions",
"fields": [
"caring.restrictions"
]
}
],
"tests": [
{
"name": "test_empty_denied",
"passed": true
}
],
"fixtures": [
{
"id": "unknown-request-denied",
"passed": true,
"expected": {
"effect": "deny"
},
"actual": {
"effect": "deny",
"reason": "lifecycle_scope_or_identity_refused"
}
}
]
}

View file

@ -0,0 +1,17 @@
{
"scanner": "aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969",
"scanner_version": "0.74.0",
"scanned_at": "2026-10-04T19:35:45.454792771Z",
"artifact": "flex-auth:wp0007-candidate",
"image_id": "sha256:f6ed8af69af766d7e9498465a23c292d91185b79352065736a2132216aac1d37",
"severities": [
"HIGH",
"CRITICAL"
],
"vulnerabilities": 0,
"full_report_sha256": "e41d19c961f0e0d3a4051362c6769edc3069b4286612239861818d403c16ee6a",
"warnings": [
"vendor severity selection"
],
"scope": "candidate artifact scan; not a general security attestation"
}

View file

@ -0,0 +1,232 @@
{
"valid": true,
"caring_findings": [
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed canonical roles",
"fields": [
"caring.canonical_roles"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed organization relations",
"fields": [
"caring.organization_relations"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed scopes",
"fields": [
"caring.scopes"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed planes",
"fields": [
"caring.planes"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed capabilities",
"fields": [
"caring.capabilities"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed exposure modes",
"fields": [
"caring.exposure_modes"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed conditions",
"fields": [
"caring.conditions"
]
},
{
"code": "CARING-POLICY-MISSING-DIMENSION",
"severity": "warning",
"message": "policy package should declare governed restrictions",
"fields": [
"caring.restrictions"
]
}
],
"tests": [
{
"name": "test_allow_does_not_prove_the_pin",
"passed": true
},
{
"name": "test_approval_id_malformed",
"passed": true
},
{
"name": "test_attribute_acts_are_eligible_only_when_sets_admit",
"passed": true
},
{
"name": "test_bad_memo_id_refused",
"passed": true
},
{
"name": "test_digest_mismatch",
"passed": true
},
{
"name": "test_exact_pin_mismatch_is_not_rescued",
"passed": true
},
{
"name": "test_exact_record_ignores_attribute_context",
"passed": true
},
{
"name": "test_future_mfa_is_identity_refused",
"passed": true
},
{
"name": "test_human_control_false",
"passed": true
},
{
"name": "test_initial_release_allows_only_decision_record_class",
"passed": true
},
{
"name": "test_initial_release_sets",
"passed": true
},
{
"name": "test_list_does_not_use_attribute_admission",
"passed": true
},
{
"name": "test_listable_is_exact_union",
"passed": true
},
{
"name": "test_memo_review_group_is_not_hardcoded",
"passed": true
},
{
"name": "test_memo_version_refused",
"passed": true
},
{
"name": "test_requester_mismatch",
"passed": true
},
{
"name": "test_review_group_must_be_verified",
"passed": true
},
{
"name": "test_service_subject_is_identity_refused",
"passed": true
},
{
"name": "test_six_exact_metered_memos_allow_human_review",
"passed": true
},
{
"name": "test_stale_mfa_on_attribute_branch",
"passed": true
},
{
"name": "test_t03_records_not_in_act_scope",
"passed": true
},
{
"name": "test_tool_proof_exact_record_allowed",
"passed": true
},
{
"name": "test_tool_proof_without_mfa_denied",
"passed": true
},
{
"name": "test_tool_proof_wrong_digest_denied",
"passed": true
},
{
"name": "test_tool_proof_wrong_native_id_denied",
"passed": true
},
{
"name": "test_unknown_class",
"passed": true
},
{
"name": "test_unknown_request_denied",
"passed": true
},
{
"name": "test_unknown_submitter",
"passed": true
}
],
"fixtures": [
{
"id": "unknown-request-denied",
"passed": true,
"expected": {
"effect": "deny"
},
"actual": {
"effect": "deny",
"reason": "compact_sitting_scope_or_identity_refused"
}
},
{
"id": "attribute-non-human-refused",
"passed": true,
"expected": {
"effect": "deny",
"reason": "identity_refused"
},
"actual": {
"effect": "deny",
"reason": "identity_refused"
}
},
{
"id": "attribute-stale-mfa",
"passed": true,
"expected": {
"effect": "deny",
"reason": "stale_mfa"
},
"actual": {
"effect": "deny",
"reason": "stale_mfa"
}
},
{
"id": "attribute-future-mfa",
"passed": true,
"expected": {
"effect": "deny",
"reason": "identity_refused"
},
"actual": {
"effect": "deny",
"reason": "identity_refused"
}
}
]
}

View file

@ -0,0 +1,303 @@
{
"policy_id": "informed-decision.compact-sitting",
"policy_version": "v11",
"note": "Offline request/response fixtures. Shipped admitted sets are empty, so attribute_eligible is not in this file. An allow here is an exact-record pin, not proof of a live approval.",
"cases": [
{
"id": "exact-record-allow",
"kind": "exact",
"assurance": "now",
"expect": {"effect": "allow", "reason": "operator_admitted_compact_sitting"},
"request": {
"id": "exact-record-allow",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "accept",
"resource": {"id": "memo:infd-20260927-b02", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"memo_version": 1,
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"approval_binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773"
},
"policy_version": "v8"
}
},
{
"id": "exact-record-wrong-digest",
"kind": "exact",
"assurance": "now",
"expect": {"effect": "deny", "reason": "compact_sitting_scope_or_identity_refused"},
"request": {
"id": "exact-record-wrong-digest",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "accept",
"resource": {"id": "memo:infd-20260927-b02", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"memo_version": 1,
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"approval_binding_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000"
},
"policy_version": "v8"
}
},
{
"id": "exact-record-with-attribute-context",
"kind": "attribute",
"assurance": "now",
"expect": {"effect": "allow", "reason": "operator_admitted_compact_sitting"},
"request": {
"id": "exact-record-with-attribute-context",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "read",
"resource": {"id": "memo:infd-20260927-b02", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"approval_binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773"
},
"policy_version": "v8"
}
},
{
"id": "exact-pin-mismatch-not-rescued",
"kind": "attribute",
"assurance": "now",
"expect": {"effect": "deny", "reason": "compact_sitting_scope_or_identity_refused"},
"request": {
"id": "exact-pin-mismatch-not-rescued",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "accept",
"resource": {"id": "memo:infd-20260927-b02", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"approval_binding_digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
},
"policy_version": "v8"
}
},
{
"id": "attribute-unknown-class",
"kind": "attribute",
"assurance": "now",
"expect": {"effect": "deny", "reason": "unknown_class"},
"request": {
"id": "attribute-unknown-class",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "decline",
"resource": {"id": "memo:intake-new-memo", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
}
},
{
"id": "attribute-stale-mfa",
"kind": "attribute",
"assurance": "stale",
"expect": {"effect": "deny", "reason": "stale_mfa"},
"request": {
"id": "attribute-stale-mfa",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "accept",
"resource": {"id": "memo:intake-new-memo", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": false,
"memo_version": 1,
"approval_id": "not-a-uuid",
"approval_binding_digest": "sha256:wrong"
},
"policy_version": "v8"
}
},
{
"id": "attribute-review-group",
"kind": "attribute",
"assurance": "now",
"expect": {"effect": "deny", "reason": "review_group_not_verified"},
"request": {
"id": "attribute-review-group",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["other-group"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "discuss",
"resource": {"id": "memo:intake-new-memo", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 2,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
}
},
{
"id": "attribute-bad-memo-id",
"kind": "attribute",
"assurance": "now",
"expect": {"effect": "deny", "reason": "resource_refused"},
"request": {
"id": "attribute-bad-memo-id",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "return",
"resource": {"id": "memo:NO", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
}
},
{
"id": "attribute-list-stays-exact",
"kind": "attribute",
"assurance": "now",
"expect": {"effect": "deny", "reason": "compact_sitting_scope_or_identity_refused"},
"request": {
"id": "attribute-list-stays-exact",
"tenant": "tenant:platform",
"subject": {
"id": "synthetic-reviewer",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape", "methods": ["pwd", "otp"], "at": 0}
}
},
"action": "list",
"resource": {"id": "memo:intake-new-memo", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
}
}
]
}

View file

@ -0,0 +1,140 @@
[
{
"id": "attribute-non-human-refused",
"request": {
"id": "attribute-non-human",
"tenant": "tenant:platform",
"subject": {
"id": "not-a-person",
"type": "service",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {
"level": "aal2",
"mfa": true,
"source": "key-cape",
"methods": ["pwd", "otp"],
"at": 1
}
}
},
"action": "accept",
"resource": {
"id": "memo:intake-new-memo",
"type": "decision-memo",
"system": "informed-decision",
"tenant": "tenant:platform"
},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
},
"expect": {
"effect": "deny",
"reason": "identity_refused"
}
},
{
"id": "attribute-stale-mfa",
"request": {
"id": "attribute-stale-mfa",
"tenant": "tenant:platform",
"subject": {
"id": "test-human",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {
"level": "aal2",
"mfa": true,
"source": "key-cape",
"methods": ["pwd", "otp"],
"at": 1
}
}
},
"action": "accept",
"resource": {
"id": "memo:intake-new-memo",
"type": "decision-memo",
"system": "informed-decision",
"tenant": "tenant:platform"
},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
},
"expect": {
"effect": "deny",
"reason": "stale_mfa"
}
},
{
"id": "attribute-future-mfa",
"request": {
"id": "attribute-future-mfa",
"tenant": "tenant:platform",
"subject": {
"id": "test-human",
"type": "human",
"tenant": "tenant:platform",
"attributes": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"groups": ["net-kingdom-admins"],
"assurance": {
"level": "aal2",
"mfa": true,
"source": "key-cape",
"methods": ["pwd", "otp"],
"at": 9999999999
}
}
},
"action": "read",
"resource": {
"id": "memo:intake-new-memo",
"type": "decision-memo",
"system": "informed-decision",
"tenant": "tenant:platform"
},
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"policy_version": "v8"
},
"expect": {
"effect": "deny",
"reason": "identity_refused"
}
}
]

View file

@ -0,0 +1,21 @@
[
{
"id": "unknown-request-denied",
"request": {
"id": "unknown",
"subject": {
"id": "unknown",
"type": "human"
},
"action": "accept",
"resource": {
"id": "memo:unrelated",
"type": "decision-memo",
"system": "informed-decision"
}
},
"expect": {
"effect": "deny"
}
}
]

View file

@ -0,0 +1,12 @@
{
"system:serviceaccount:state-hub:state-hub": {
"submitter_id": "state-hub",
"memo_classes": [
"decision-record"
],
"review_groups": [
"net-kingdom-admins"
],
"daily_limit": 50
}
}

View file

@ -0,0 +1,20 @@
{
"memo:SECRETS-WP-0010-T03-apply": {
"approval_id": "b5fcbfcc-ad56-456f-bc36-c823052e9917",
"binding_digest": "sha256:03cc5b37437f14e86b686ce4054f976556334eff3fa260b03e8014ed3d9217e5",
"memo_version": 3,
"label": "t03-apply"
},
"memo:SECRETS-WP-0010-T03-verify": {
"approval_id": "4e9ff881-d59f-4143-9155-929afbe8dd43",
"binding_digest": "sha256:72d9267d038c17107c880ffc9009793ce9c70defbddfe2219628854b811a04b2",
"memo_version": 3,
"label": "t03-verify"
},
"memo:SECRETS-WP-0010-T03-exec": {
"approval_id": "a24e0898-b3c5-4e50-85a8-18a2c2aa229e",
"binding_digest": "sha256:f2cf0fb53b740900756ccde5587c3578fcff44beef2f1edab17b9a198a4033d8",
"memo_version": 3,
"label": "t03-exec"
}
}

View file

@ -0,0 +1,5 @@
{
"package": "informed-decision.compact-sitting",
"version": "v12",
"package_digest": "sha256:c5387f7d198dc39ab5967e0c218ce05cc779693565c8875e3035e45ec002a2db"
}

View file

@ -0,0 +1,708 @@
---
id: informed-decision.compact-sitting
name: Compact sitting exact-record human review
namespace: informed-decision:decision-memo
version: v12
status: ready
package: flexauth.informed_decision.compact_sitting
allow_ttl: 30s
actions: [read, acknowledge, accept, return, discuss, decline, list]
owner: flex-auth
fixtures: [fixtures.json, attribute_fixtures.json]
caring:
profile: caring-0.4.0-rc2
enforce: false
activation:
mode: local
---
# Lifecycle review release candidate
This v12 candidate retains the deployed v11 exact records and adds only
State Hub / decision-record attribute admission for INFD-WP-0007. The unchanged
sitting directory and deployed values remain the v11 rollback reference. New
lifecycle decisions use this attribute branch without package regeneration.
Review groups remain verified by the consumer and the subject identity.
# Compact sitting review mandate
This is a new exact-record package for seven 2026-09-14 sitting memos.
v2 (2026-09-21) adds exactly one record, `memo:infd-20260921-b01` (the
SECRETS-WP-0009-T03 spend envelope), with native pins from informed-decision
`docs/evidence/2026-09-21-budget-approval-create.json`. The seven v1 records
and the identity bar are unchanged.
It is not an expansion of `examples/informed-decision-t03` / FLEX-WP-0027.
`memo:infd-20260914-c01` is omitted (create-client still undecided).
v3 (2026-09-21, `FLEX-WP-0032`, `FLEX-DEC-2026-017`) adds one action, `list`,
for informed-decision's decision overview (`INFD-IN-0008`). It is a separate
rule, not an extra member of the act set, and it changes nothing else:
- `read` and the five acts keep the v2 rule unchanged — the same eight records,
the same 900-second MFA window. A `list` allow satisfies no other action.
- `list` covers the **union** of this package's eight records and the three
`SECRETS-WP-0010-T03-*` records from `informed-decision.t03-review`, each
pinned by approval id, binding digest and its own memo version (T03 at 3).
Scope stays exact-record: a memo is listable only once someone admitted it.
The operator declined resource-type-wide scope because the PDP checks no
recipient, and a type-wide rule would have left consumer code — which the
consumer itself says is not an entitlement — as the only scope.
- `list` carries the same identity bar with a **12-hour** MFA window instead of
900 seconds. Looking back at your own outcomes is not binding a new one. The
bar is lighter, not absent: the PDP still states a bound.
- The KeyCape stale-timestamp defect (`INFD-IN-0005`) is **not** worked around
here. `read` stays strict; that defect is key-cape's to fix.
v4 (2026-09-27, REINAH-WP-0003-T06) adds exactly one record for the
EUR 10 single-attempt tool proof. Native pins come from informed-decision
`docs/evidence/2026-09-27-tool-budget-approval-create.json`. Existing records,
actions and identity requirements remain unchanged.
v5 (2026-09-27, REINAH-WP-0003-T06) admits the replacement-window memo
`memo:infd-20260927-b02` with fresh native pins. The accepted b01 record is
preserved; this change does not extend its signed execution window.
v6 (2026-09-27, REINAH-WP-0003-T06) admits six exact native metered
credential requests, apply/verify/exec per provider and worker lane. All acts
still require the authenticated human and fresh MFA. Ordinary worker approvals
retain their native control type and require exact-ID consumer configuration.
v7 (2026-10-03, INFD-WP-ADHOC-2026-10-03-T02) adds the exact
`memo:infd-20261003-p01` delivery-proof acceptance record. Native pins come
from informed-decision `docs/evidence/2026-10-03-provisioning-window-approval-create.json`.
Existing records and identity requirements are preserved.
v8 (2026-10-03, offline attribute admission) adds one branch beside those
exact-record rules. It is not the deployed sitting pin. Requests whose
resource id is in `records` or `listable` still take only the exact-record
rules, including when they also carry attribute fields, so an exact-record
decision does not change. `list` stays on the exact-record rule.
The attribute branch may allow `read`, `acknowledge`, `accept`, `return`,
`discuss` and `decline` for any other memo id. `attribute_eligible` is
eligibility only. It checks that the carried approval id is a UUID and the
carried digest matches `sha256:` plus 64 lowercase hex digits. It does not
read an approval and it does not prove the memo pin. The effect owner still
reads the approval live and compares that id and the engine's native digest
with the memo. `approval_human_control` must be boolean true. No presentation
hash is read. Context fields are `review_group`, `memo_class`,
`intake_submitter`, `approval_requester`, `approval_human_control`,
`memo_version`, `approval_id` and `approval_binding_digest`.
v9 (2026-10-04, EMERGENT-WP-0002 profile adoption) adds exactly one record,
`memo:emergent-profile-adoption-0-2-6`. Native pins come from informed-decision
`docs/evidence/2026-10-04-emergent-profile-approval-create.json`, approval
`05751e09-3a5b-4a41-a4e8-b79e96de6484`. Existing exact records stay. The v8
attribute branch remains beside them and still admits nobody, because the
shipped submitter and class sets are empty.
v10 (2026-10-04, STATE-WP-0094 production-steps sitting) adds exactly four
records: `memo:state-hub-edge-receiving-rollout-c287ed8`,
`memo:owner-return-pickup-plan-b6222af`,
`memo:freshness-runner-deploy-trial-e77f8b4` and
`memo:freshness-schedule-enable-retire-sweep`. Native pins come from
informed-decision `docs/evidence/2026-10-04-state-hub-wp0094-approval-create.json`,
approvals `974eae4d-782d-41ed-93be-e34433b5fe59`,
`77993081-1db2-4bba-99f2-74ca1f8652b1`, `4ae04c8e-d604-4d8b-b166-693eef855da8`
and `b75752d1-bab6-4cf3-9308-5368c1d5aa91`. Existing exact records, including
v9's, stay. The v8 attribute branch still admits nobody.
v11 (2026-10-04, IR-WP-0005-T02) lets the three `list_only_records` be
reviewed. `read`, `acknowledge`, `accept`, `return`, `discuss` and
`decline` allow when the memo id, memo version 3, approval id and binding
digest match those records, with the same 900-second KeyCape bar as the
version-1 act rule. `list` is unchanged. A version other than 3, a foreign
approval id, or a different digest is refused. The version-1 `records` set
is unchanged, and these three ids stay out of it.
`admitted_submitters` and `admitted_classes` are generated from
informed-decision `deploy/intake-submitters.json`. The shipped registry is
empty, so both sets are empty and this branch admits nobody. Regenerate with
`python3 tools/gen_informed_decision_admission.py`; `--check` reports drift.
The identity bar matches T03: authenticated informed-decision caller,
`net-kingdom-admins`, fresh KeyCape AAL2 MFA. No permission follows from
memo content or presentation state. TokenReview must admit
`system:serviceaccount:informed-decision:review` before this package is
served. Membership tenant provenance may follow the accepted registration
route; it does not assert directory membership in tenant:platform.
Only a real human uses accept. This package neither issues nor consumes
approval. Native pins: `docs/evidence/2026-09-15-sitting-approval-creates.json`.
```rego
import rego.v1
records := {
"memo:state-hub-edge-receiving-rollout-c287ed8": {
"approval_id": "974eae4d-782d-41ed-93be-e34433b5fe59",
"binding_digest": "sha256:84735b88b2db20d9445af369e28a8d40bd495dd20c0303ff3a764666ec976dde"
},
"memo:owner-return-pickup-plan-b6222af": {
"approval_id": "77993081-1db2-4bba-99f2-74ca1f8652b1",
"binding_digest": "sha256:e745ef64658e77e41b2a5ef569ec0f6986e120d338656d75749425f5f29b7ca0"
},
"memo:freshness-runner-deploy-trial-e77f8b4": {
"approval_id": "4ae04c8e-d604-4d8b-b166-693eef855da8",
"binding_digest": "sha256:f8ff89dd353c1d2006622c45996c0f05f050865f8c203373dc74da1ba3f05e24"
},
"memo:freshness-schedule-enable-retire-sweep": {
"approval_id": "b75752d1-bab6-4cf3-9308-5368c1d5aa91",
"binding_digest": "sha256:cc3e8fe6ace5438f19d647d3de226407c8b009985c82ad9a993e81226e6f316f"
},
"memo:infd-20261003-p01": {
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
"memo:emergent-profile-adoption-0-2-6": {
"approval_id": "05751e09-3a5b-4a41-a4e8-b79e96de6484",
"binding_digest": "sha256:7843e660694dcd7c806dc02ee0cca05dd3a96488f614b1946291496259a02001"
},
"memo:infd-20260914-c02": {
"approval_id": "ccfd8007-2061-48fd-9356-99b16279dac1",
"binding_digest": "sha256:942cf7d5e6805987df2077a0cc6cde75b148e1729a96dd0692153287820b6a0a"
},
"memo:infd-20260914-c03": {
"approval_id": "a0611d0d-b9ef-4b9a-aa79-e94a9e3fcd5f",
"binding_digest": "sha256:95cae135b994acea6dad9da978dd3df1aa3354de900a1f43c2e5a03a20e8e844"
},
"memo:infd-20260914-c04": {
"approval_id": "22ac6df3-e6a9-472b-a68e-c8caca4289a7",
"binding_digest": "sha256:dec960b30efaf654abbdcd8a2cdd20d4ff6bf52e170744f817dc55845d9cb192"
},
"memo:infd-20260914-d01": {
"approval_id": "9f7c3506-68de-4826-86ff-e301f428408d",
"binding_digest": "sha256:8cb7cc93f38db9d19b49e201e0554b50af1891fec853fef333a06ea078541d15"
},
"memo:infd-20260914-d02": {
"approval_id": "b3ce2c01-0a3b-401e-b4ed-c1954af169c9",
"binding_digest": "sha256:be0c7de123216740d2c2eeaed80384e03e6b6d1668104f94bb8f9cbae7dfe30f"
},
"memo:infd-20260914-d03": {
"approval_id": "3b483e6b-0b92-45ff-83b6-bc5057c0a496",
"binding_digest": "sha256:3c562278e86bb5e7f747452cf2e99d3a136853ab748676e8359262b835cd1425"
},
"memo:infd-20260914-d04": {
"approval_id": "356e67a3-5539-46a1-922a-f5591fd38ee5",
"binding_digest": "sha256:3c2d7759679d871cb7c5cac8999542a365e64c918d59d0c4ce864ffb837453e4"
},
"memo:infd-20260921-b01": {
"approval_id": "ba5ce2d8-8b6d-40be-af89-2e8c147029a3",
"binding_digest": "sha256:e9eaf454e94871ec2060855fcfbd327bcaec873d2c61cae031bec9f95a34bcae"
},
"memo:infd-20260927-b01": {
"approval_id": "e9521804-8fce-4fbc-bfdf-8a1aa959fd61",
"binding_digest": "sha256:7aefcee9b79eb3285997066b323ae1772e13d58f875aacc6eb5e9407bd1c1185"
},
"memo:infd-20260927-b02": {
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773"
},
"memo:metered-20260927-provider-apply": {
"approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
"binding_digest": "sha256:a36b88244c26b1ffcd765cbadc201ff79260c7bcbd71d20d1584c3c0a3b1c3de"
},
"memo:metered-20260927-provider-verify": {
"approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
"binding_digest": "sha256:98636335ccd36286c02fe018f296fd7d4dfd091ee89d27fe1b629e3db00cf121"
},
"memo:metered-20260927-provider-exec": {
"approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
"binding_digest": "sha256:8b31dd5911552b901b1f807a8cd6348d09547f3dbb2a52e3b42ad9fd948a2b01"
},
"memo:metered-20260927-worker-apply": {
"approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
"binding_digest": "sha256:412b79fb537d4444e52e3358820b6ea204fa17173a4420ab6372c52d010ee018"
},
"memo:metered-20260927-worker-verify": {
"approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
"binding_digest": "sha256:bce6e2091ed076ec0040804d24c822078ac1eda18cd62703801fc9da77898303"
},
"memo:metered-20260927-worker-exec": {
"approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
"binding_digest": "sha256:ae261c9271a21b626be354646054f493d0951f69aecdbde3cfce3ac0c5667e8f"
}
}
list_only_records := {
"memo:SECRETS-WP-0010-T03-apply": {
"approval_id": "b5fcbfcc-ad56-456f-bc36-c823052e9917",
"binding_digest": "sha256:03cc5b37437f14e86b686ce4054f976556334eff3fa260b03e8014ed3d9217e5",
"memo_version": 3
},
"memo:SECRETS-WP-0010-T03-verify": {
"approval_id": "4e9ff881-d59f-4143-9155-929afbe8dd43",
"binding_digest": "sha256:72d9267d038c17107c880ffc9009793ce9c70defbddfe2219628854b811a04b2",
"memo_version": 3
},
"memo:SECRETS-WP-0010-T03-exec": {
"approval_id": "a24e0898-b3c5-4e50-85a8-18a2c2aa229e",
"binding_digest": "sha256:f2cf0fb53b740900756ccde5587c3578fcff44beef2f1edab17b9a198a4033d8",
"memo_version": 3
}
}
# listable is the union list may range over. Sitting records are memo version 1.
# T03 records carry memo version 3 and are acted on only through list_only_records.
listable := object.union(
{id: object.union(r, {"memo_version": 1}) | some id, r in records},
list_only_records,
)
# BEGIN GENERATED admitted_sets (tools/gen_informed_decision_admission.py; do not edit by hand)
admitted_submitters := {
"state-hub",
}
admitted_classes := {
"decision-record",
}
# END GENERATED admitted_sets
exact_id if {
id := object.get(object.get(input, "resource", {}), "id", "")
listable[id]
}
attribute_attempt if {
not exact_id
input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"}
ctx := object.get(input, "context", {})
some key in {"review_group", "memo_class", "intake_submitter", "approval_requester", "approval_human_control"}
object.get(ctx, key, null) != null
}
identity_core if {
input.tenant == "tenant:platform"
input.subject.tenant == "tenant:platform"
input.subject.type == "human"
is_string(input.subject.id)
input.subject.id != ""
input.subject.attributes.principal_type_source == "authentication-derived"
input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
assurance := input.subject.attributes.assurance
assurance.level == "aal2"
assurance.mfa == true
assurance.source == "key-cape"
assurance.methods == ["pwd", "otp"]
is_number(assurance.at)
assurance.at > 0
}
mfa_fresh if {
identity_core
age := time.now_ns() / 1000000000 - input.subject.attributes.assurance.at
age >= -30
age <= 900
}
stale_mfa if {
identity_core
age := time.now_ns() / 1000000000 - input.subject.attributes.assurance.at
age > 900
}
resource_ok if {
input.resource.tenant == "tenant:platform"
input.resource.system == "informed-decision"
input.resource.type == "decision-memo"
is_string(input.resource.id)
regex.match(`^memo:[a-z0-9][a-z0-9-]{2,62}$`, input.resource.id)
}
review_group_ok if {
group := input.context.review_group
is_string(group)
group != ""
group in input.subject.attributes.groups
}
class_ok if {
is_string(input.context.memo_class)
input.context.memo_class in admitted_classes
}
submitter_ok if {
is_string(input.context.intake_submitter)
input.context.intake_submitter in admitted_submitters
}
requester_ok if {
input.context.approval_requester == "informed-decision"
}
human_control_ok if {
input.context.approval_human_control == true
}
approval_id_ok if {
is_string(input.context.approval_id)
regex.match(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`, input.context.approval_id)
}
digest_ok if {
is_string(input.context.approval_binding_digest)
regex.match(`^sha256:[0-9a-f]{64}$`, input.context.approval_binding_digest)
}
version_ok if {
is_number(input.context.memo_version)
input.context.memo_version >= 1
}
decision := {"effect": "allow", "reason": "operator_admitted_compact_sitting"} if {
input.tenant == "tenant:platform"
input.subject.tenant == "tenant:platform"
input.subject.type == "human"
is_string(input.subject.id)
input.subject.id != ""
input.subject.attributes.principal_type_source == "authentication-derived"
input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
"net-kingdom-admins" in input.subject.attributes.groups
assurance := input.subject.attributes.assurance
assurance.level == "aal2"
assurance.mfa == true
assurance.source == "key-cape"
assurance.methods == ["pwd", "otp"]
is_number(assurance.at)
assurance.at > 0
age := time.now_ns() / 1000000000 - assurance.at
age >= -30
age <= 900
input.resource.tenant == "tenant:platform"
input.resource.system == "informed-decision"
input.resource.type == "decision-memo"
record := records[input.resource.id]
input.context.memo_version == 1
input.context.approval_id == record.approval_id
input.context.approval_binding_digest == record.binding_digest
input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"}
} else := {"effect": "allow", "reason": "operator_admitted_t03_review_act"} if {
input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"}
input.tenant == "tenant:platform"
input.subject.tenant == "tenant:platform"
input.subject.type == "human"
is_string(input.subject.id)
input.subject.id != ""
input.subject.attributes.principal_type_source == "authentication-derived"
input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
"net-kingdom-admins" in input.subject.attributes.groups
assurance := input.subject.attributes.assurance
assurance.level == "aal2"
assurance.mfa == true
assurance.source == "key-cape"
assurance.methods == ["pwd", "otp"]
is_number(assurance.at)
assurance.at > 0
age := time.now_ns() / 1000000000 - assurance.at
age >= -30
age <= 900
input.resource.tenant == "tenant:platform"
input.resource.system == "informed-decision"
input.resource.type == "decision-memo"
record := list_only_records[input.resource.id]
input.context.memo_version == record.memo_version
input.context.approval_id == record.approval_id
input.context.approval_binding_digest == record.binding_digest
} else := {"effect": "allow", "reason": "operator_admitted_overview_list"} if {
input.action == "list"
input.tenant == "tenant:platform"
input.subject.tenant == "tenant:platform"
input.subject.type == "human"
is_string(input.subject.id)
input.subject.id != ""
input.subject.attributes.principal_type_source == "authentication-derived"
input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
"net-kingdom-admins" in input.subject.attributes.groups
assurance := input.subject.attributes.assurance
assurance.level == "aal2"
assurance.mfa == true
assurance.source == "key-cape"
assurance.methods == ["pwd", "otp"]
is_number(assurance.at)
assurance.at > 0
age := time.now_ns() / 1000000000 - assurance.at
age >= -30
age <= 43200
input.resource.tenant == "tenant:platform"
input.resource.system == "informed-decision"
input.resource.type == "decision-memo"
record := listable[input.resource.id]
input.context.memo_version == record.memo_version
input.context.approval_id == record.approval_id
input.context.approval_binding_digest == record.binding_digest
} else := {"effect": "allow", "reason": "attribute_eligible"} if {
attribute_attempt
mfa_fresh
resource_ok
review_group_ok
class_ok
submitter_ok
requester_ok
human_control_ok
approval_id_ok
digest_ok
version_ok
} else := {"effect": "deny", "reason": "identity_refused"} if {
attribute_attempt
not identity_core
} else := {"effect": "deny", "reason": "stale_mfa"} if {
attribute_attempt
stale_mfa
} else := {"effect": "deny", "reason": "identity_refused"} if {
attribute_attempt
not mfa_fresh
} else := {"effect": "deny", "reason": "resource_refused"} if {
attribute_attempt
not resource_ok
} else := {"effect": "deny", "reason": "review_group_not_verified"} if {
attribute_attempt
not review_group_ok
} else := {"effect": "deny", "reason": "unknown_class"} if {
attribute_attempt
not class_ok
} else := {"effect": "deny", "reason": "unknown_submitter"} if {
attribute_attempt
not submitter_ok
} else := {"effect": "deny", "reason": "requester_mismatch"} if {
attribute_attempt
not requester_ok
} else := {"effect": "deny", "reason": "human_control_false"} if {
attribute_attempt
not human_control_ok
} else := {"effect": "deny", "reason": "approval_id_malformed"} if {
attribute_attempt
not approval_id_ok
} else := {"effect": "deny", "reason": "digest_mismatch"} if {
attribute_attempt
not digest_ok
} else := {"effect": "deny", "reason": "memo_version_refused"} if {
attribute_attempt
not version_ok
} else := {"effect": "deny", "reason": "compact_sitting_scope_or_identity_refused"} if {
true
}
```
```rego test
package flexauth.informed_decision.compact_sitting_test
import rego.v1
import data.flexauth.informed_decision.compact_sitting
test_unknown_request_denied if {
compact_sitting.decision.effect == "deny" with input as {}
}
test_listable_is_exact_union if {
count(compact_sitting.listable) == count(compact_sitting.records) + count(compact_sitting.list_only_records)
}
test_t03_records_not_in_act_scope if {
every id, _ in compact_sitting.list_only_records {
not compact_sitting.records[id]
}
}
tool_proof_input := {
"tenant": "tenant:platform",
"subject": {"id": "test-human", "type": "human", "tenant": "tenant:platform",
"attributes": {"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied", "groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape",
"methods": ["pwd", "otp"], "at": time.now_ns() / 1000000000}}},
"resource": {"tenant": "tenant:platform", "system": "informed-decision",
"type": "decision-memo", "id": "memo:infd-20260927-b02"},
"action": "accept",
"context": {"memo_version": 1,
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"approval_binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773"},
}
test_tool_proof_exact_record_allowed if {
compact_sitting.decision.effect == "allow" with input as tool_proof_input
}
test_tool_proof_wrong_native_id_denied if {
compact_sitting.decision.effect == "deny" with input as tool_proof_input
with input.context.approval_id as "another-approval"
}
test_tool_proof_wrong_digest_denied if {
compact_sitting.decision.effect == "deny" with input as tool_proof_input
with input.context.approval_binding_digest as "sha256:wrong"
}
test_tool_proof_without_mfa_denied if {
compact_sitting.decision.effect == "deny" with input as tool_proof_input
with input.subject.attributes.assurance.mfa as false
}
test_six_exact_metered_memos_allow_human_review if {
every id in ["memo:metered-20260927-provider-apply", "memo:metered-20260927-provider-verify", "memo:metered-20260927-provider-exec", "memo:metered-20260927-worker-apply", "memo:metered-20260927-worker-verify", "memo:metered-20260927-worker-exec"] {
record := compact_sitting.records[id]
request := object.union(tool_proof_input, {
"resource": object.union(tool_proof_input.resource, {"id": id}),
"context": {"memo_version": 1, "approval_id": record.approval_id,
"approval_binding_digest": record.binding_digest},
})
compact_sitting.decision.effect == "allow" with input as request
}
}
attribute_input := {
"tenant": "tenant:platform",
"subject": {"id": "test-human", "type": "human", "tenant": "tenant:platform",
"attributes": {"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied", "groups": ["net-kingdom-admins"],
"assurance": {"level": "aal2", "mfa": true, "source": "key-cape",
"methods": ["pwd", "otp"], "at": time.now_ns() / 1000000000}}},
"resource": {"tenant": "tenant:platform", "system": "informed-decision",
"type": "decision-memo", "id": "memo:intake-new-memo"},
"action": "accept",
"context": {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"memo_version": 1,
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
},
}
patched_context(req, patch) := object.union(req, {"context": object.union(req.context, patch)})
with_at(req, at) := object.union(req, {"subject": object.union(req.subject, {"attributes": object.union(req.subject.attributes, {"assurance": object.union(req.subject.attributes.assurance, {"at": at})})})})
eligible(req) := result if {
result := compact_sitting.decision with input as req
with data.flexauth.informed_decision.compact_sitting.admitted_classes as {"credential-lane"}
with data.flexauth.informed_decision.compact_sitting.admitted_submitters as {"state-hub"}
}
classes_only(req) := result if {
result := compact_sitting.decision with input as req
with data.flexauth.informed_decision.compact_sitting.admitted_classes as {"credential-lane"}
}
test_initial_release_sets if {
compact_sitting.admitted_classes == {"decision-record"}
compact_sitting.admitted_submitters == {"state-hub"}
compact_sitting.decision.reason == "unknown_class" with input as attribute_input
}
test_initial_release_allows_only_decision_record_class if {
every action in ["read", "acknowledge", "accept", "return", "discuss", "decline"] {
req := object.union(patched_context(attribute_input, {"memo_class": "decision-record"}), {"action": action})
compact_sitting.decision.reason == "attribute_eligible" with input as req
}
}
test_attribute_acts_are_eligible_only_when_sets_admit if {
every action in ["read", "acknowledge", "accept", "return", "discuss", "decline"] {
eligible(object.union(attribute_input, {"action": action})).reason == "attribute_eligible"
}
}
test_allow_does_not_prove_the_pin if {
other := "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
attribute_input.context.approval_binding_digest != other
eligible(attribute_input).reason == "attribute_eligible"
eligible(patched_context(attribute_input, {"approval_binding_digest": other})).reason == "attribute_eligible"
}
test_unknown_class if {
eligible(patched_context(attribute_input, {"memo_class": "not-a-class"})).reason == "unknown_class"
}
test_unknown_submitter if {
classes_only(patched_context(attribute_input, {"intake_submitter": "unknown"})).reason == "unknown_submitter"
}
test_requester_mismatch if {
eligible(patched_context(attribute_input, {"approval_requester": "other-service"})).reason == "requester_mismatch"
}
test_human_control_false if {
eligible(patched_context(attribute_input, {"approval_human_control": false})).reason == "human_control_false"
eligible(patched_context(attribute_input, {"approval_human_control": "true"})).reason == "human_control_false"
}
test_digest_mismatch if {
eligible(patched_context(attribute_input, {"approval_binding_digest": "sha256:wrong"})).reason == "digest_mismatch"
eligible(patched_context(attribute_input, {"approval_binding_digest": "sha256:C8A1A9C8FB22616E3AACFB877BA7974FEB5EEDAED491F856A6C90719C502EBE4"})).reason == "digest_mismatch"
}
test_approval_id_malformed if {
eligible(patched_context(attribute_input, {"approval_id": "not-a-uuid"})).reason == "approval_id_malformed"
}
test_memo_version_refused if {
eligible(patched_context(attribute_input, {"memo_version": 0})).reason == "memo_version_refused"
}
test_stale_mfa_on_attribute_branch if {
eligible(with_at(attribute_input, time.now_ns() / 1000000000 - 901)).reason == "stale_mfa"
}
test_future_mfa_is_identity_refused if {
eligible(with_at(attribute_input, time.now_ns() / 1000000000 + 300)).reason == "identity_refused"
}
test_service_subject_is_identity_refused if {
eligible(object.union(attribute_input, {"subject": object.union(attribute_input.subject, {"type": "service"})})).reason == "identity_refused"
}
test_review_group_must_be_verified if {
req := object.union(attribute_input, {"subject": object.union(attribute_input.subject, {"attributes": object.union(attribute_input.subject.attributes, {"groups": ["other-group"]})})})
eligible(req).reason == "review_group_not_verified"
}
test_memo_review_group_is_not_hardcoded if {
req := object.union(attribute_input, {
"subject": object.union(attribute_input.subject, {"attributes": object.union(attribute_input.subject.attributes, {"groups": ["cabinet-reviewers"]})}),
"context": object.union(attribute_input.context, {"review_group": "cabinet-reviewers"}),
})
eligible(req).reason == "attribute_eligible"
}
test_bad_memo_id_refused if {
eligible(object.union(attribute_input, {"resource": object.union(attribute_input.resource, {"id": "memo:NO"})})).reason == "resource_refused"
}
test_list_does_not_use_attribute_admission if {
got := eligible(object.union(attribute_input, {"action": "list"}))
got.effect == "deny"
got.reason == "compact_sitting_scope_or_identity_refused"
}
test_exact_record_ignores_attribute_context if {
req := object.union(tool_proof_input, {"context": object.union(tool_proof_input.context, {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"view_hash": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
})})
got := compact_sitting.decision with input as req
got.effect == "allow"
got.reason == "operator_admitted_compact_sitting"
}
test_exact_pin_mismatch_is_not_rescued if {
req := object.union(tool_proof_input, {"context": object.union(tool_proof_input.context, {
"review_group": "net-kingdom-admins",
"memo_class": "credential-lane",
"intake_submitter": "state-hub",
"approval_requester": "informed-decision",
"approval_human_control": true,
"approval_binding_digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
})})
got := eligible(req)
got.effect == "deny"
got.reason == "compact_sitting_scope_or_identity_refused"
}
```

View file

@ -0,0 +1,444 @@
{
"memo:infd-20260914-c02": {
"approval_id": "ccfd8007-2061-48fd-9356-99b16279dac1",
"binding_digest": "sha256:942cf7d5e6805987df2077a0cc6cde75b148e1729a96dd0692153287820b6a0a",
"label": "c02",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "railiance-platform",
"purpose": "Accept provisioning of the secrets-engine service JWT login on the reviewed credential lane",
"target": {
"id": "rpf-wp-0035-t02",
"type": "credential-lane",
"system": "railiance-platform"
}
},
"memo_version": 1
},
"memo:infd-20260914-c03": {
"approval_id": "a0611d0d-b9ef-4b9a-aa79-e94a9e3fcd5f",
"binding_digest": "sha256:95cae135b994acea6dad9da978dd3df1aa3354de900a1f43c2e5a03a20e8e844",
"label": "c03",
"binding": {
"action": "apply",
"actor": "informed-decision",
"principal": "netkingdom",
"purpose": "Apply the live OpenBao role addition already specified for the operator-tunneled browser callback",
"target": {
"id": "nk-wp-0032-t03",
"type": "openbao-role",
"system": "netkingdom"
}
},
"memo_version": 1
},
"memo:infd-20260914-c04": {
"approval_id": "22ac6df3-e6a9-472b-a68e-c8caca4289a7",
"binding_digest": "sha256:dec960b30efaf654abbdcd8a2cdd20d4ff6bf52e170744f817dc55845d9cb192",
"label": "c04",
"binding": {
"action": "attend",
"actor": "informed-decision",
"principal": "ops-warden",
"purpose": "Attend the graded lockdown / break-glass seal for ops-warden trust-root work",
"target": {
"id": "warden-wp-0027-t02",
"type": "trust-root",
"system": "ops-warden"
}
},
"memo_version": 1
},
"memo:infd-20260914-d01": {
"approval_id": "9f7c3506-68de-4826-86ff-e301f428408d",
"binding_digest": "sha256:8cb7cc93f38db9d19b49e201e0554b50af1891fec853fef333a06ea078541d15",
"label": "d01",
"binding": {
"action": "retire",
"actor": "informed-decision",
"principal": "the-custodian",
"purpose": "After HA failover and restore drills pass, retire WSL2 as a State Hub fallback",
"target": {
"id": "cust-wp-0038-t08",
"type": "operating-model",
"system": "the-custodian"
}
},
"memo_version": 1
},
"memo:infd-20260914-d02": {
"approval_id": "b3ce2c01-0a3b-401e-b4ed-c1954af169c9",
"binding_digest": "sha256:be0c7de123216740d2c2eeaed80384e03e6b6d1668104f94bb8f9cbae7dfe30f",
"label": "d02",
"binding": {
"action": "confirm",
"actor": "informed-decision",
"principal": "helixforge-factory",
"purpose": "Confirm the existing operator-group claim for CCR-2026-0019 as required by the factory identity/audit/approval path",
"target": {
"id": "ccr-2026-0019",
"type": "ccr",
"system": "helixforge-factory"
}
},
"memo_version": 1
},
"memo:infd-20260914-d03": {
"approval_id": "3b483e6b-0b92-45ff-83b6-bc5057c0a496",
"binding_digest": "sha256:3c562278e86bb5e7f747452cf2e99d3a136853ab748676e8359262b835cd1425",
"label": "d03",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "mason",
"purpose": "Accept the fluid-telegram operator credential lane plan so construction may proceed",
"target": {
"id": "mason-wp-0005",
"type": "workplan",
"system": "mason"
}
},
"memo_version": 1
},
"memo:infd-20260914-d04": {
"approval_id": "356e67a3-5539-46a1-922a-f5591fd38ee5",
"binding_digest": "sha256:3c2d7759679d871cb7c5cac8999542a365e64c918d59d0c4ce864ffb837453e4",
"label": "d04",
"binding": {
"action": "confirm",
"actor": "informed-decision",
"principal": "railiance-clock",
"purpose": "Confirm ecosystem ownership and the security role for Railiance Clock as specified",
"target": {
"id": "rclk-wp-0002-t01",
"type": "workplan",
"system": "railiance-clock"
}
},
"memo_version": 1
},
"memo:infd-20260921-b01": {
"approval_id": "ba5ce2d8-8b6d-40be-af89-2e8c147029a3",
"binding_digest": "sha256:e9eaf454e94871ec2060855fcfbd327bcaec873d2c61cae031bec9f95a34bcae",
"label": "b01",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "helixforge-factory",
"purpose": "Accept the spend envelope for metered Glas runs on the Anthropic key",
"target": {
"id": "spend-envelope:hfact-glas-anthropic-2026-09",
"type": "spend-envelope",
"system": "rein-aharness"
}
},
"memo_version": 1
},
"memo:infd-20260927-b01": {
"approval_id": "e9521804-8fce-4fbc-bfdf-8a1aa959fd61",
"binding_digest": "sha256:7aefcee9b79eb3285997066b323ae1772e13d58f875aacc6eb5e9407bd1c1185",
"label": "20260927-b01",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "helixforge-factory",
"purpose": "Accept one EUR 10 metered tool proof; no retry or publication; 2026-09-27T16:35:00Z through 2026-09-27T17:35:00Z",
"target": {
"id": "spend-envelope:hfact-glas-tool-proof-20260927-one-attempt",
"system": "rein-aharness",
"type": "spend-envelope"
}
},
"memo_version": 1
},
"memo:infd-20260927-b02": {
"approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
"binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773",
"label": "20260927-b02",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "helixforge-factory",
"purpose": "Accept one EUR 10 metered tool proof; no retry or publication; 2026-09-27T18:20:00Z through 2026-09-28T18:20:00Z",
"target": {
"id": "spend-envelope:hfact-glas-tool-proof-20260927-renewed-one-attempt",
"system": "rein-aharness",
"type": "spend-envelope"
}
},
"memo_version": 1
},
"memo:metered-20260927-provider-apply": {
"approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
"binding_digest": "sha256:a36b88244c26b1ffcd765cbadc201ff79260c7bcbd71d20d1584c3c0a3b1c3de",
"label": "metered-20260927-provider-apply",
"binding": {
"action": "apply",
"actor": "secrets-engine",
"principal": "secrets-engine",
"purpose": "Owner-admitted glas-harness agt run through the reviewed local profile; no caller-facing key fetch",
"target": {
"attributes": {
"auth_targets": [
"se-prod-glas-claude-agent-dev-anthropic"
],
"fields": [],
"policy_targets": [
"se-prod-glas-claude-agent-dev-anthropic"
],
"stage": "prod"
},
"id": "catalog:glas-claude-agent-dev-anthropic",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"memo_version": 1
},
"memo:metered-20260927-provider-verify": {
"approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
"binding_digest": "sha256:98636335ccd36286c02fe018f296fd7d4dfd091ee89d27fe1b629e3db00cf121",
"label": "metered-20260927-provider-verify",
"binding": {
"action": "verify",
"actor": "secrets-engine",
"principal": "secrets-engine",
"purpose": "Owner-admitted glas-harness agt run through the reviewed local profile; no caller-facing key fetch",
"target": {
"attributes": {
"auth_targets": [
"se-prod-glas-claude-agent-dev-anthropic"
],
"fields": [
"ANTHROPIC_API_KEY"
],
"policy_targets": [
"se-prod-glas-claude-agent-dev-anthropic"
],
"stage": "prod"
},
"id": "catalog:glas-claude-agent-dev-anthropic",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"memo_version": 1
},
"memo:metered-20260927-provider-exec": {
"approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
"binding_digest": "sha256:8b31dd5911552b901b1f807a8cd6348d09547f3dbb2a52e3b42ad9fd948a2b01",
"label": "metered-20260927-provider-exec",
"binding": {
"action": "exec",
"actor": "secrets-engine",
"principal": "secrets-engine",
"purpose": "Owner-admitted glas-harness agt run through the reviewed local profile; no caller-facing key fetch",
"target": {
"attributes": {
"auth_targets": [
"se-prod-glas-claude-agent-dev-anthropic"
],
"fields": [
"ANTHROPIC_API_KEY"
],
"policy_targets": [
"se-prod-glas-claude-agent-dev-anthropic"
],
"stage": "prod"
},
"id": "catalog:glas-claude-agent-dev-anthropic",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"memo_version": 1
},
"memo:metered-20260927-worker-apply": {
"approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
"binding_digest": "sha256:412b79fb537d4444e52e3358820b6ea204fa17173a4420ab6372c52d010ee018",
"label": "metered-20260927-worker-apply",
"binding": {
"action": "apply",
"actor": "secrets-engine",
"principal": "secrets-engine",
"purpose": "Claim the admitted hfact-metered ops_run as rein-aharness-metered@railiance01 inside the catalog-bound Glas metered owner",
"target": {
"attributes": {
"auth_targets": [
"se-prod-activity-core-metered-worker-token"
],
"fields": [],
"policy_targets": [
"se-prod-activity-core-metered-worker-token"
],
"stage": "prod"
},
"id": "catalog:activity-core-metered-worker-token",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"memo_version": 1
},
"memo:metered-20260927-worker-verify": {
"approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
"binding_digest": "sha256:bce6e2091ed076ec0040804d24c822078ac1eda18cd62703801fc9da77898303",
"label": "metered-20260927-worker-verify",
"binding": {
"action": "verify",
"actor": "secrets-engine",
"principal": "secrets-engine",
"purpose": "Claim the admitted hfact-metered ops_run as rein-aharness-metered@railiance01 inside the catalog-bound Glas metered owner",
"target": {
"attributes": {
"auth_targets": [
"se-prod-activity-core-metered-worker-token"
],
"fields": [
"token"
],
"policy_targets": [
"se-prod-activity-core-metered-worker-token"
],
"stage": "prod"
},
"id": "catalog:activity-core-metered-worker-token",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"memo_version": 1
},
"memo:metered-20260927-worker-exec": {
"approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
"binding_digest": "sha256:ae261c9271a21b626be354646054f493d0951f69aecdbde3cfce3ac0c5667e8f",
"label": "metered-20260927-worker-exec",
"binding": {
"action": "exec",
"actor": "secrets-engine",
"principal": "secrets-engine",
"purpose": "Claim the admitted hfact-metered ops_run as rein-aharness-metered@railiance01 inside the catalog-bound Glas metered owner",
"target": {
"attributes": {
"auth_targets": [
"se-prod-activity-core-metered-worker-token"
],
"fields": [
"token"
],
"policy_targets": [
"se-prod-activity-core-metered-worker-token"
],
"stage": "prod"
},
"id": "catalog:activity-core-metered-worker-token",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"memo_version": 1
},
"memo:emergent-profile-adoption-0-2-6": {
"approval_id": "05751e09-3a5b-4a41-a4e8-b79e96de6484",
"binding_digest": "sha256:7843e660694dcd7c806dc02ee0cca05dd3a96488f614b1946291496259a02001",
"label": "emergent-profile-0-2-6",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "emergent-security",
"purpose": "Accept only the non-normative knowledge profile boundary",
"target": {
"id": "emergent-security:knowledge:0.2.6:8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02",
"type": "knowledge-profile",
"system": "emergent-security"
}
},
"memo_version": 1
},
"memo:infd-20261003-p01": {
"approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
"binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4",
"label": "p01",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "railiance-platform",
"purpose": "Accept the 2026-09-13 scoped delivery proof for the CCR-2026-0019 secrets-engine approval-client reader",
"target": {
"id": "ccr:CCR-2026-0019-delivery-proof",
"type": "credential-lane",
"system": "railiance-platform"
}
},
"memo_version": 1
},
"memo:state-hub-edge-receiving-rollout-c287ed8": {
"approval_id": "974eae4d-782d-41ed-93be-e34433b5fe59",
"binding_digest": "sha256:84735b88b2db20d9445af369e28a8d40bd495dd20c0303ff3a764666ec976dde",
"label": "wp0094-m1-state-hub-c287ed8",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "state-hub",
"purpose": "Production rollout of tested source; rollback is helm rollback to revision 72 without schema downgrade.",
"target": {
"id": "state-hub:source:c287ed82594313394ca8e67ce40714c90e744af6",
"system": "state-hub",
"type": "service-release"
}
},
"memo_version": 1
},
"memo:owner-return-pickup-plan-b6222af": {
"approval_id": "77993081-1db2-4bba-99f2-74ca1f8652b1",
"binding_digest": "sha256:e745ef64658e77e41b2a5ef569ec0f6986e120d338656d75749425f5f29b7ca0",
"label": "wp0094-m2-owner-return-b6222af",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "activity-core",
"purpose": "Plan approval plus a gated single-repo trial; the definition stays disabled and wakeups never clear waits.",
"target": {
"id": "activity-core:source:b6222af2cfd1094360a0d430e3907e8788a3acf9:owner-return-pickup",
"system": "activity-core",
"type": "activity-plan"
}
},
"memo_version": 1
},
"memo:freshness-runner-deploy-trial-e77f8b4": {
"approval_id": "4ae04c8e-d604-4d8b-b166-693eef855da8",
"binding_digest": "sha256:f8ff89dd353c1d2006622c45996c0f05f050865f8c203373dc74da1ba3f05e24",
"label": "wp0094-m3-freshness-runner-e77f8b4",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "repo-manager",
"purpose": "Deployment and limited data-writing trials; no schedule.",
"target": {
"id": "repo-manager:source:e77f8b457647ff23697e45a74615edde5f42d39d",
"system": "repo-manager",
"type": "service-release"
}
},
"memo_version": 1
},
"memo:freshness-schedule-enable-retire-sweep": {
"approval_id": "b75752d1-bab6-4cf3-9308-5368c1d5aa91",
"binding_digest": "sha256:cc3e8fe6ace5438f19d647d3de226407c8b009985c82ad9a993e81226e6f316f",
"label": "wp0094-m4-freshness-schedule",
"binding": {
"action": "accept",
"actor": "informed-decision",
"principal": "activity-core",
"purpose": "Recurring schedule activation after clean trials, and permanent retirement of the legacy sweep.",
"target": {
"id": "activity-core:definition:repo-manager-bounded-freshness:b2c6c5613218dea9dbaef303aff22a8d1b07f074",
"system": "activity-core",
"type": "activity-schedule"
}
},
"memo_version": 1
}
}

View file

@ -0,0 +1,17 @@
{
"subjects": [
{
"id": "sitting-reviewer",
"type": "Human",
"display_name": "Compact sitting reviewer",
"organization_relation": "ServiceProvider",
"groups": ["net-kingdom-admins"],
"claims": {
"assurance": "aal2",
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied"
}
}
],
"resources": []
}

View file

@ -0,0 +1,21 @@
[
{
"id": "unknown-request-denied",
"request": {
"id": "unknown",
"subject": {
"id": "unknown",
"type": "human"
},
"action": "lifecycle.register",
"resource": {
"id": "memo:unknown",
"type": "decision-memo",
"system": "informed-decision"
}
},
"expect": {
"effect": "deny"
}
}
]

View file

@ -0,0 +1,5 @@
{
"package": "informed-decision.lifecycle",
"version": "v1",
"package_digest": "sha256:cee6a79f74e81d0d389a2c2e2451a92be3434ea9dfcee4986e8c7e6cfdbb1827"
}

View file

@ -0,0 +1,186 @@
---
id: informed-decision.lifecycle
name: Decision lifecycle authoring and collaboration
namespace: informed-decision:decision-memo
version: v1
status: ready
package: flexauth.informed_decision.lifecycle
allow_ttl: 30s
actions: [lifecycle.register, lifecycle.read, lifecycle.search, lifecycle.revise, lifecycle.source, lifecycle.evaluation, lifecycle.comment, lifecycle.events, lifecycle.packet, lifecycle.publish, lifecycle.request_review, lifecycle.outcomes]
owner: flex-auth
fixtures: [fixtures.json]
caring:
profile: caring-0.4.0-rc2
enforce: false
activation:
mode: local
---
# Initial lifecycle audience
Founder direction, 2026-10-04, INFD-WP-0007: net-kingdom-admins humans and
system:serviceaccount:state-hub:state-hub. This package is evaluated by Access
Engine; the consumer supplies authenticated identity and immutable record facts.
The evaluator's workload caller remains informed-decision/review, audience
flex-auth. The State Hub subject is authenticated separately for audience
informed-decision-lifecycle using CA-verified TokenReview, never a browser token.
Humans require KeyCape AAL2 MFA within 12 hours for authoring. Actual human binding
retains the separate review policy's 900-second MFA requirement. This package
has no accept action. An initial caller can register and search; record access
requires original authorship or an explicit publication audience. Published
collaborators may research, discuss and refine. Publication and requesting review
require original authorship or an admitted human collaborator. Publication may
name only the initial human group; explicit subjects still require admitted
identity. Review routing is fixed to State Hub, decision-record class and
net-kingdom-admins. Every operation is fresh; neither content nor evaluation
assertions confer permission. Command digests correlate commands, not signatures.
No presentation/view hash enters this policy.
The sibling registry declares identity contract profiles, following the existing
review packages. These are not real human or workload identifiers and mint no
identity. Authentication-derived values still come from the enforced consumer
boundary (KeyCape sessions or CA-verified TokenReview). This remains a consumer
claim trust boundary; a registry declaration is not independent verification.
```rego
import rego.v1
common if {
input.tenant == "tenant:platform"
input.subject.tenant == input.tenant
input.resource.tenant == input.tenant
input.resource.system == "informed-decision"
input.context.contract == "informed-decision.lifecycle.v1"
regex.match("^sha256:[0-9a-f]{64}$", input.context.command_digest)
input.subject.attributes.principal_type_source == "authentication-derived"
input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
}
human if {
input.subject.type == "human"
"net-kingdom-admins" in input.subject.attributes.groups
assurance := input.subject.attributes.assurance
assurance.level == "aal2"
assurance.mfa == true
assurance.source == "key-cape"
assurance.methods == ["pwd", "otp"]
is_number(assurance.at)
age := time.now_ns()/1000000000 - assurance.at
age >= -30
age <= 43200
}
workload if {
input.subject.type == "service"
input.subject.id == "system:serviceaccount:state-hub:state-hub"
input.subject.attributes.authentication_audience == "informed-decision-lifecycle"
is_string(input.subject.attributes.workload_uid)
input.subject.attributes.workload_uid != ""
}
identity if human
identity if workload
memo_resource if {
input.resource.type == "decision-memo"
regex.match("^memo:[A-Za-z0-9._:-]{1,256}$", input.resource.id)
}
owner if {
input.context.record.registered == true
some author in [input.context.record.registered_by, input.context.record.revision_by]
author.sub == input.subject.id
author.kind == "person"
human
}
owner if {
input.context.record.registered == true
some author in [input.context.record.registered_by, input.context.record.revision_by]
author.sub == input.subject.id
author.kind == "service"
workload
}
readable if owner
readable if {
input.context.record.registered == true
input.subject.id in input.context.record.published_audience.subjects
}
readable if {
human
"net-kingdom-admins" in input.context.record.published_audience.groups
}
may_publish if owner
may_publish if {
human
readable
}
audience_ok if {
a := input.context.publication_audience
is_array(a.subjects)
is_array(a.groups)
count(a.subjects) <= 32
count(a.groups) <= 32
count(a.subjects)+count(a.groups) > 0
every group in a.groups { group == "net-kingdom-admins" }
every subject in a.subjects { is_string(subject); subject != ""; subject != "*" }
}
operation if {
input.action == "lifecycle.register"
memo_resource
not input.context.record.registered
input.context.memo_version == 1
}
operation if {
input.action == "lifecycle.register"
memo_resource
owner
input.context.memo_version == 1
}
operation if {
input.action == "lifecycle.search"
input.resource.type == "decision-collection"
input.resource.id == "decisions"
}
operation if {
input.action in {"lifecycle.read", "lifecycle.events", "lifecycle.packet", "lifecycle.outcomes",
"lifecycle.revise", "lifecycle.source", "lifecycle.evaluation", "lifecycle.comment"}
memo_resource
readable
}
operation if {
input.action == "lifecycle.publish"
memo_resource
may_publish
audience_ok
}
operation if {
input.action == "lifecycle.request_review"
memo_resource
may_publish
routing := input.context.review_routing
routing.submitter == "state-hub"
routing.memo_class == "decision-record"
routing.review_group == "net-kingdom-admins"
}
decision := {"effect":"allow", "reason":"lifecycle_collaboration"} if {
common
identity
operation
} else := {"effect":"deny", "reason":"lifecycle_scope_or_identity_refused"}
```
```rego test
package flexauth.informed_decision.lifecycle_test
import rego.v1
import data.flexauth.informed_decision.lifecycle
test_empty_denied if {
lifecycle.decision.effect == "deny" with input as {}
}
```

View file

@ -0,0 +1,29 @@
{
"subjects": [
{
"id": "lifecycle-human-profile",
"type": "Human",
"display_name": "Human identity contract profile",
"groups": [
"net-kingdom-admins"
],
"claims": {
"assurance": "aal2",
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied"
}
},
{
"id": "lifecycle-workload-profile",
"type": "Service",
"display_name": "TokenReview identity contract profile",
"claims": {
"principal_type_source": "authentication-derived",
"tenant_source": "registration-supplied",
"authentication_audience": "informed-decision-lifecycle",
"workload_uid": "TokenReview response UID"
}
}
],
"resources": []
}

28
go.mod
View file

@ -1,41 +1,41 @@
module github.com/netkingdom/flex-auth module github.com/netkingdom/flex-auth
go 1.22 go 1.26.7
require ( require (
github.com/open-policy-agent/opa v0.70.0 github.com/open-policy-agent/opa v1.4.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
require ( require (
github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/agnivade/levenshtein v1.2.1 // indirect
github.com/agnivade/levenshtein v1.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/go-ini/ini v1.67.0 // indirect github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect github.com/gobwas/glob v0.2.3 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/mux v1.8.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_golang v1.21.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/tchap/go-patricia/v2 v2.3.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/yashtewari/glob-intersection v0.2.0 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel v1.43.0 // indirect
go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.43.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.43.0 // indirect
golang.org/x/sys v0.26.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect golang.org/x/sys v0.42.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect
) )

158
go.sum
View file

@ -1,7 +1,5 @@
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY=
github.com/agnivade/levenshtein v1.2.0/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -10,22 +8,20 @@ github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HV
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y=
github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA=
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
@ -35,35 +31,25 @@ github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY=
github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -72,78 +58,82 @@ github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/open-policy-agent/opa v0.70.0 h1:B3cqCN2iQAyKxK6+GI+N40uqkin+wzIrM7YA60t9x1U= github.com/open-policy-agent/opa v1.4.0 h1:IGO3xt5HhQKQq2axfa9memIFx5lCyaBlG+fXcgHpd3A=
github.com/open-policy-agent/opa v0.70.0/go.mod h1:Y/nm5NY0BX0BqjBriKUiV81sCl8XOjjvqQG7dXrggtI= github.com/open-policy-agent/opa v1.4.0/go.mod h1:DNzZPKqKh4U0n0ANxcCVlw8lCSv2c+h5G/3QvSYdWZ8=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM=
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg= github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg=
github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0=
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View file

@ -0,0 +1,137 @@
package policy_test
import (
"context"
"encoding/json"
"os"
"path/filepath"
"testing"
"time"
"github.com/netkingdom/flex-auth/internal/policy"
"github.com/netkingdom/flex-auth/pkg/api"
)
func TestInformedDecisionLifecycle(t *testing.T) {
pkg, err := policy.LoadAndValidateFile(context.Background(), filepath.Join("..", "..", "examples", "informed-decision-lifecycle", "policy.md"))
if err != nil {
t.Fatal(err)
}
if !pkg.Valid {
t.Fatalf("invalid package: %+v", pkg.Validation)
}
base := map[string]any{
"id": "fixture", "tenant": "tenant:platform", "policy_version": "v1",
"subject": map[string]any{"id": "human-one", "type": "human", "tenant": "tenant:platform", "attributes": map[string]any{
"principal_type_source": "authentication-derived", "tenant_source": "registration-supplied", "groups": []any{"net-kingdom-admins"},
"assurance": map[string]any{"level": "aal2", "mfa": true, "source": "key-cape", "methods": []any{"pwd", "otp"}, "at": time.Now().Unix()},
}},
"resource": map[string]any{"id": "memo:new-record", "type": "decision-memo", "system": "informed-decision", "tenant": "tenant:platform"},
"action": "lifecycle.register",
"context": map[string]any{"contract": "informed-decision.lifecycle.v1", "memo_version": 1, "command_digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "record": map[string]any{"registered": false}},
}
human := func(d map[string]any) map[string]any { return d["subject"].(map[string]any) }
ctx := func(d map[string]any) map[string]any { return d["context"].(map[string]any) }
attrs := func(d map[string]any) map[string]any { return human(d)["attributes"].(map[string]any) }
owned := func(d map[string]any) {
ctx(d)["record"] = map[string]any{"registered": true, "registered_by": map[string]any{"sub": "human-one", "kind": "person"}, "revision_by": nil, "published_audience": nil, "current_version": 1}
d["action"] = "lifecycle.read"
}
hub := func(d map[string]any) {
human(d)["id"] = "system:serviceaccount:state-hub:state-hub"
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"}
}
tests := []struct {
name string
effect string
change func(map[string]any)
}{
{"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" }},
{"wrong workload audience", "deny", func(d map[string]any) { hub(d); attrs(d)["authentication_audience"] = "informed-decision-intake" }},
{"missing workload UID", "deny", func(d map[string]any) { hub(d); delete(attrs(d), "workload_uid") }},
{"wrong tenant", "deny", func(d map[string]any) { d["tenant"] = "tenant:foreign" }},
{"outside human group", "deny", func(d map[string]any) { attrs(d)["groups"] = []any{"other"} }},
{"stale author MFA", "deny", func(d map[string]any) { attrs(d)["assurance"].(map[string]any)["at"] = time.Now().Unix() - 43201 }},
{"future author MFA", "deny", func(d map[string]any) { attrs(d)["assurance"].(map[string]any)["at"] = time.Now().Unix() + 301 }},
{"asserted identity", "deny", func(d map[string]any) { attrs(d)["principal_type_source"] = "asserted" }},
{"owner read", "allow", owned},
{"foreign unpublished read", "deny", func(d map[string]any) { owned(d); human(d)["id"] = "another-admin" }},
{"published collaborator", "allow", func(d map[string]any) {
owned(d)
human(d)["id"] = "another-admin"
ctx(d)["record"].(map[string]any)["published_audience"] = map[string]any{"subjects": []any{}, "groups": []any{"net-kingdom-admins"}}
}},
{"new revision editor", "allow", func(d map[string]any) {
owned(d)
human(d)["id"] = "editor"
ctx(d)["record"].(map[string]any)["revision_by"] = map[string]any{"sub": "editor", "kind": "person"}
}},
{"unknown action", "deny", func(d map[string]any) { owned(d); d["action"] = "lifecycle.delete" }},
{"agent acceptance", "deny", func(d map[string]any) { hub(d); d["action"] = "accept" }},
{"human acceptance excluded", "deny", func(d map[string]any) { owned(d); d["action"] = "lifecycle.accept" }},
{"publish initial group", "allow", func(d map[string]any) {
owned(d)
d["action"] = "lifecycle.publish"
ctx(d)["publication_audience"] = map[string]any{"subjects": []any{}, "groups": []any{"net-kingdom-admins"}}
}},
{"publish other group", "deny", func(d map[string]any) {
owned(d)
d["action"] = "lifecycle.publish"
ctx(d)["publication_audience"] = map[string]any{"subjects": []any{}, "groups": []any{"other"}}
}},
{"review routing", "allow", func(d map[string]any) {
owned(d)
d["action"] = "lifecycle.request_review"
ctx(d)["review_routing"] = map[string]any{"submitter": "state-hub", "memo_class": "decision-record", "review_group": "net-kingdom-admins"}
}},
{"wrong review routing", "deny", func(d map[string]any) {
owned(d)
d["action"] = "lifecycle.request_review"
ctx(d)["review_routing"] = map[string]any{"submitter": "unknown", "memo_class": "decision-record", "review_group": "net-kingdom-admins"}
}},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
encoded, _ := json.Marshal(base)
var d map[string]any
json.Unmarshal(encoded, &d)
tc.change(d)
encoded, _ = json.Marshal(d)
var request api.CheckRequest
if err := json.Unmarshal(encoded, &request); err != nil {
t.Fatal(err)
}
got, err := pkg.Evaluate(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if string(got.Effect) != tc.effect {
t.Fatalf("got %+v, want %s", got, tc.effect)
}
})
}
}
func TestInformedDecisionLifecycleReleasePins(t *testing.T) {
for _, name := range []string{"informed-decision-lifecycle", "informed-decision-lifecycle-review"} {
dir := filepath.Join(repoRoot(t), "examples", name)
pkg, err := policy.LoadAndValidateFile(context.Background(), filepath.Join(dir, "policy.md"))
if err != nil || !pkg.Valid {
t.Fatalf("%s invalid: %v %+v", name, err, pkg)
}
raw, err := os.ReadFile(filepath.Join(dir, "pin.json"))
if err != nil {
t.Fatal(err)
}
var pin map[string]string
if err := json.Unmarshal(raw, &pin); err != nil {
t.Fatal(err)
}
if pin["package_digest"] != pkg.Digest() || pin["version"] != pkg.Metadata.Version || pin["package"] != pkg.Metadata.ID {
t.Fatalf("%s stale pin: %+v", name, pin)
}
}
}

View file

@ -0,0 +1,28 @@
# INFD-WP-0007 / FLEX-WP-0033 review proposal; no live grant.
name: flex-auth-informed-decision-sitting
image:
repository: forgejo.coulomb.social/coulomb/flex-auth
digest: sha256:f6ed8af69af766d7e9498465a23c292d91185b79352065736a2132216aac1d37
args:
- serve
- --addr
- 0.0.0.0:8080
- --registry
- /opt/flex-auth/examples/informed-decision-lifecycle-review/registry.json
- --policy
- /opt/flex-auth/examples/informed-decision-lifecycle-review/policy.md
callerAuth:
mode: enforce
kubernetesURL: https://10.43.0.1
binding: informed-decision=system:serviceaccount:informed-decision:review
consumer:
isolated: false
namespace: informed-decision
podName: informed-decision
resources:
requests:
cpu: 5m
memory: 32Mi
limits:
cpu: 300m
memory: 192Mi

View file

@ -0,0 +1,28 @@
# INFD-WP-0007 / FLEX-WP-0033 review proposal; no live grant.
name: flex-auth-informed-decision-lifecycle
image:
repository: forgejo.coulomb.social/coulomb/flex-auth
digest: sha256:f6ed8af69af766d7e9498465a23c292d91185b79352065736a2132216aac1d37
args:
- serve
- --addr
- 0.0.0.0:8080
- --registry
- /opt/flex-auth/examples/informed-decision-lifecycle/registry.json
- --policy
- /opt/flex-auth/examples/informed-decision-lifecycle/policy.md
callerAuth:
mode: enforce
kubernetesURL: https://10.43.0.1
binding: informed-decision=system:serviceaccount:informed-decision:review
consumer:
isolated: false
namespace: informed-decision
podName: informed-decision
resources:
requests:
cpu: 5m
memory: 32Mi
limits:
cpu: 300m
memory: 192Mi

View file

@ -0,0 +1,97 @@
---
id: FLEX-WP-0033
type: workplan
title: "Initial Informed Decision lifecycle policy and production candidate"
domain: infotech
repo: access-engine
status: active
owner: codex
topic_slug: netkingdom
created: "2026-10-04"
updated: "2026-10-04"
related: [INFD-WP-0007, INFD-WP-0005, FLEX-WP-0028]
---
Founder selected net-kingdom-admins humans and the State Hub workload for the
first release. Source work is on infd-wp0007-lifecycle; no live grants applied.
## Define and prove the initial lifecycle authorization contract
```task
id: FLEX-WP-0033-T01
status: done
priority: high
```
Separate informed-decision.lifecycle v1 package admits twelve authoring/retrieval
operations. It requires platform tenant, authenticated identity provenance,
KeyCape AAL2 for humans or the exact State Hub service account and lifecycle
audience for workloads. Immutable owner/editor/publication facts scope access.
No accept action. Contract profiles declare fact keys; they do not authenticate
real identities. Consumer attribution remains unsigned (FLEX-WP-0024).
21 Go cases and actual HTTP evaluator integration prove authoring, publication,
human refinement, successor draft access, restart and rejection of other callers.
## Prepare human review admission without per-decision policy rollout
```task
id: FLEX-WP-0033-T02
status: done
priority: high
```
examples/informed-decision-lifecycle-review is the v12 candidate of compact-sitting.
It preserves all v11 exact mandates and adds generated state-hub / decision-record
sets from the candidate intake registry. The deployed v11 directory/values remain
unchanged rollback references. New records are admitted by verified attributes,
not ids. Consumer checks the live Approval Engine requester/human-control and pin.
28 embedded tests and four fixtures pass; policy pins are checked by Go tests.
## Produce a scanned immutable policy image and deployment proposal
```task
id: FLEX-WP-0033-T03
status: done
priority: high
```
The inherited production binary failed its HIGH/CRITICAL scan (25 findings in Go,
OPA and telemetry). Fix dependency/build pins, run full engine regression, rebuild,
scan and retain immutable image/package pins. Render the separate lifecycle PDP
and v12 review proposal. CARING remains advisory as in deployed review packages;
no new claim of signed attribution or complete production close-down.
## Approved policy deployment and native verification
```task
id: FLEX-WP-0033-T04
status: todo
priority: high
```
Part of the concrete INFD-WP-0007 rollout approval. Verify actual consumer caller
TokenReview and positive/negative lifecycle/human review behavior. No agent binds.
Retain v11 rollback while preserving decisions and audit evidence. Do not mark
finished while live acceptance or security findings remain open.
## Published candidate evidence — 2026-10-04
Patched Go 1.26.7, OPA 1.4.0 and telemetry SDK 1.43.0; pinned builder/runtime
images and aligned CI setup with go.mod. Full engine tests, race-enabled tests and vet pass. Both
container-loaded policy packages validate; review has 28 tests/four fixtures.
Actual consumer-to-PDP tests pass after rebuilding this binary.
Published image:
forgejo.coulomb.social/coulomb/flex-auth@sha256:f6ed8af69af766d7e9498465a23c292d91185b79352065736a2132216aac1d37
HIGH/CRITICAL scan: zero findings, retained under
docs/evidence/2026-10-04-infd-lifecycle/. Candidate Helm values passed server
dry-run for both PDPs (12 objects); no cluster state changed. Full review packet
and migration/recovery procedure are in informed-decision deploy/lifecycle.
The existing chart's port-only API egress, advisory CARING dimensions and unsigned
consumer assertions are explicitly retained limitations, not newly enforced
controls. T04 remains open; requester projection and State Hub production
forwarding also remain prerequisites in their owner workplans.