access-engine/examples/secrets-engine-service-task-execution-v2/policy_package.md
tegwick 2b064eee51
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Container Image / build-and-push (push) Failing after 1m10s
Bind trusted task approval to exact producer facts and lifetime
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 17:27:30 +02:00

120 lines
4.9 KiB
Markdown

---
id: secrets-engine.task-execution.service-pilot
name: Secrets admitted service task execution
namespace: secrets-engine:secret-catalog-lane
version: v2
status: proposed
package: flexauth.secrets_engine.service_task_execution
allow_ttl: 120s
actions: [execute-ccr]
owner: team:platform-security
fixtures: [policy_fixtures.yaml]
caring:
profile: caring-0.4.0-rc2
enforce: false
activation:
mode: local
---
# Trusted service task source successor
This source package is evaluated exclusively by the typed v2 HTTP path. That
path requires exact TokenReview caller mapping, immutable numeric source
representations, a fixed authenticated Approval reader, separate original and
fresh claim validation and native/PDP correspondence before policy evaluation.
Its 120s declared TTL is a hard source ceiling, not a blanket grant. The typed
path derives actual expiry exactly from the immutable operation deadline and
requires the entire declared backend TTL plus the existing 5s cleanup reserve
within original/fresh claim, approval and caller bounds. Budgets that cannot fit
refuse; the 120s structural backend maximum is not guaranteed admissible.
Generic check, batch and list routes refuse task execution. Selecting this source
package alone cannot bypass those joins. No deployment or trust admission is
established by this package. The v1 package remains unchanged and DENY-only.
```rego
default decision := {"effect": "deny", "reason": "service_execution_contract_unmatched"}
decision := {"effect": "allow", "reason": "exact_task_execution_matched"} {
candidate_matches
}
hash_ok(x) { is_string(x); regex.match("^sha256:[0-9a-f]{64}$", x) }
candidate_matches {
input.action == "execute-ccr"
input.tenant == "tenant:platform"
input.subject.id == "secrets-engine"
input.subject.type == "service"
input.resource.system == "secrets-engine"
input.resource.type == "secret-catalog-lane"
input.context.human_control == true
c := input.context.execution_contract
c.contract_version == "SECRETS-EXEC-20261011-v1"
c.operation == "metadata-apply-ccr"
c.execution_actor == "service:secrets-engine"
regex.match("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", c.operation_id)
c.ccr_id != c.execution_grant_ccr_id
hash_ok(c.ccr_immutable_sha256)
hash_ok(c.grant_immutable_sha256)
hash_ok(c.catalog_sha256)
hash_ok(c.expected_before)
hash_ok(c.expected_after)
c.backend_budget.ttl_seconds <= 120
c.backend_budget.ttl_seconds >= 30
c.backend_budget.uses == 12
count(c.operations) == 6
c.operations[0].method == "GET"
c.operations[1].method == "PUT"
c.operations[2].method == "GET"
c.operations[3].method == "GET"
c.operations[4].method == "PUT"
c.operations[5].method == "GET"
regex.match("^sys/policies/acl/[A-Za-z0-9_-]+$", c.operations[0].path)
regex.match("^auth/[A-Za-z0-9_-]+/role/[A-Za-z0-9_-]+$", c.operations[3].path)
c.operations[0].path == c.operations[1].path
c.operations[1].path == c.operations[2].path
c.operations[3].path == c.operations[4].path
c.operations[4].path == c.operations[5].path
every_operation_hash_valid
b := input.context.service_actor_binding
count(b) == 5
b.version == "proposed-service-task-caller/v1"
b.transport_principal == "system:serviceaccount:secrets-engine:secrets-engine"
b.subject_id == input.subject.id
b.subject_type == "service"
b.tenant == input.tenant
not input.context.task_execution_projection
not input.context.initiator
not input.context.represented_principal
not input.context.delegation
input.resource.attributes.stage == "prod"
time.parse_rfc3339_ns(c.operation_deadline) > time.now_ns()
time.parse_rfc3339_ns(c.operation_deadline) <= time.now_ns() + 120000000000
time.parse_rfc3339_ns(c.operation_deadline) >= time.now_ns() + (c.backend_budget.ttl_seconds + 5) * 1000000000
input.context.approval.schema_version == "0.1"
input.context.approval.kind == "approval-claim"
input.context.approval.issuer == "approval-engine"
input.context.approval.valid_now == true
input.context.approval.consumed == false
input.context.approval.reason_code == "ok"
input.context.approval.binding.pdp_path == true
hash_ok(input.context.approval.binding.pdp_digest)
time.parse_rfc3339_ns(input.context.approval.freshness.not_after) > time.now_ns()
time.parse_rfc3339_ns(input.context.approval.validity.expires_at) >= time.parse_rfc3339_ns(c.operation_deadline)
time.parse_rfc3339_ns(input.context.approval.freshness.not_after) >= time.parse_rfc3339_ns(c.operation_deadline)
input.context.approval.binding.human_control == true
}
every_operation_hash_valid {
count([x | x := input.context.execution_contract.operations[_]; hash_ok(x.payload_sha256)]) == 6
}
```
```rego test
import data.flexauth.secrets_engine.service_task_execution
test_unsigned_flags_cannot_enable {
service_task_execution.decision.effect == "deny"
with input as {"context": {"runtime_admission": true, "verified": true}}
}
```