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

4.9 KiB

id name namespace version status package allow_ttl actions owner fixtures caring activation
secrets-engine.task-execution.service-pilot Secrets admitted service task execution secrets-engine:secret-catalog-lane v2 proposed flexauth.secrets_engine.service_task_execution 120s
execute-ccr
team:platform-security
policy_fixtures.yaml
profile enforce
caring-0.4.0-rc2 false
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.

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
}
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}}
}