Prepare closed service task execution input and policy contract
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 59s

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
tegwick 2026-10-11 19:48:53 +02:00
parent 077eb0a63c
commit bc92f95e5f
12 changed files with 639 additions and 57 deletions

View file

@ -0,0 +1,20 @@
{
"schema": "source-fixture-compatibility/v1",
"previous_service_manifest_sha256": "98142d4b03d13eccde813483c88ada7d5412c397334e086df6ba64ee89f79d86",
"original_human_generator_sha256": "3015561cd4b1120177605a23f874220bb34a90548ea0fee5a158f3d16a9b5743",
"original_human_policy_sha256": "a790ecfbc8906c5a30e3eb066f391330d73d19b8cd46814d1d9778f24774d9e7",
"original_shape": {
"field": "task_execution_projection.not_after_ns",
"representation": "int(epoch_seconds)*1000000000",
"exact_profile": "unsupported Python integer magnitude > 2^53-1"
},
"resolution": "Preserve original projection as explicitly refused counterexample; descriptor-only canonical generator, unchanged closed human policy. No schema relabeling/rounding/RFC3339 identity rewrite.",
"source_tests_pass_events": 133,
"source_tests_failures": 0,
"source_test_command": "SECRETS_ENGINE_SOURCE=/tmp/access-secrets-canonical-review/source GOCACHE=/tmp/access-taskexecution-go-cache go test -json ./internal/taskexecution ./internal/policy ./pkg/api -count=1",
"identity_contract_changed": false,
"human_policy_changed": false,
"policy_constant_flipped": false,
"native_execution": false,
"service_scope": "structural characterization and TokenReview input preparation; no exact approval/PDP/consume/journal/grant join or operational readiness"
}

View file

@ -0,0 +1,141 @@
# Proposed faithful Secrets service task execution successor
Source component for existing SECRETS-WP-0013 and RPF-WP-0035-T12.
Based on accepted-intent technical assessment in
/tmp/execute-ccr-accepted-intent-assessment.json. This is neither foreign owner
acceptance nor a new doctrine choice, live caller mapping or native permission.
## Principal and scope
The initiating/represented principal for this first pilot is the admitted Secrets
service itself. It does not claim to represent a named human. The operation still
declares human-control approval; the authenticated human approver is a separate
principal and cannot supply service caller authentication. Accepted v0.8/GH013/
GH016 do not impose universal human initiation/User/Tenant membership on every
metadata action. Operations deliberately representing a human or relying on human
membership need their own verified initiating/delegation/provider contract.
The prior proposed human package secrets-engine.task-execution v1 and its literal
false gate remain byte-for-byte unchanged. This separate proposed
secrets-engine.task-execution.service-pilot v1 package is not a toggle of that
variant, not legacy lifecycle v2 apply and not whole successor-standard acceptance.
Its literal runtime_admission=false keeps every runtime policy evaluation closed.
Candidate-predicate characterization never flips that constant or grants an act.
## Concrete authenticated source input component
internal/taskexecution.ServicePilotInputs uses actual existing callerauth
Authenticator.Authorize/TokenReview machinery, fixed enforce mode, flex-auth
audience and the explicitly proposed mapping:
system:serviceaccount:secrets-engine:secrets-engine -> secrets-engine/type service,
protected system secrets-engine, tenant:platform.
The transport/system association is present in current values/secrets-engine.yaml;
the explicit transport-to-subject association here is new proposed source and still
needs owner/runtime admission. A2 system mapping alone does not prove arbitrary
request subjects. The source constructor accepts only an owner-installed reviewer,
never a request-selected principal or warn/disabled mode. The unexported ServiceInput
records actual successful review, fixed matching subject/type and nonzero future
transport expiry; zero/default input refuses. Its detached request snapshot never
contains a bearer token or an unsigned authenticated flag.
service_actor_binding is PUBLIC DECLARED metadata included before approval issue:
version proposed-service-task-caller/v1, exact principal/subject/type/tenant. It is
not authentication evidence. Prepare compares it to the independently authenticated
caller and source mapping. Incorrect/missing/extra binding fields refuse. Claimed
human/delegation/projection/verified/owner_admission fields refuse rather than being
interpreted as authority. Deadline must be live and no later than actual reviewed
transport expiry. The returned input is eligibility preparation, not a PDP allow,
trusted served approval, consume confirmation or operational entitlement.
Maker tests use a synthetic TokenReviewer, not actual Kubernetes authentication.
Actual deployed TokenReview origin/CA/RBAC/audience/projection rotation and mapping
admission must be proved before runtime use. The adapter is not wired into HTTP
routes, decision engine evaluation or a native executor; source package remains
hard-closed. A forged public service_actor_binding alone remains insufficient.
## Exact operation and independent gates
Owner compiler derives exact metadata CCR/catalogue/source/body/target plan. Whole
SECRETS-EXEC-20261011-v1 descriptor binds unique operation UUID, CCR/grant immutable
hashes, consumer thirteen-field local catalogue fingerprint, independently pinned
source roles, estate/origin, expected before/after states, six GET/PUT/GET reader
ACL then GET/PUT/GET role operations, bounded deadline and 120s/12-use ceilings.
Platform rederives exact body bytes before each call. This source package models
shape, service declaration, production tenant/stage and human-control claim shape;
it neither authenticates sources nor compiles full baseline/grant/estate/deadline.
Required sequence remains:
1. Authenticate the admitted service caller and explicitly bind its subject; obtain
exact owner-derived complete request before approval issue. Local/public discovery
only precedes consume. No caller projection or founder bootstrap substitutes.
2. Obtain live served approval from independently authenticated Approval Engine
origin; require declared human_control with verified human approver under GH016,
fresh validity and canonical PDP path. Approval is a fact, never a decision.
3. Access renders fresh exact package/version result over authenticated caller,
owner operation and served facts; decision binds full enriched request, exact
submitted request, and approval-free request. The claim's recorded pdp_digest
must equal served binding.approval_binding_digest. Use repaired Go-compatible
canonical serialization; do not translate Approval native digest or rewrite old
claims. Server must make trusted input provenance reconstructable and prevent
caller substitution. This source candidate does not install that server join.
4. PEP obtains authenticated successful consume for exactly approval/request/decision
before any protected consumer login/effect. Platform independently confirms original
consumption using trusted provider transport; supplied booleans/receipts and
same-digest CAS retry are not a fresh execution grant.
5. Owner-private durable journal reserves the same operation once, maintains exclusive
admission and pending intent before each exact phase/call, and refuses replay or
unknown recovery. Whole canonical request, caller mapping, body/plan and source
correspondence remain unchanged across reserve/consume/applying/native phases.
6. Independently authenticate CCR38/OpenBao service provenance after consume. Owner
separately admits task-execution-grant CCR, exact disposable target/estate/route
and bounded owner-held ephemeral token. Token is never exported to the consumer;
native ACL alone cannot constrain policy/role bodies. Mediator enforces exact body
equality, real expiry/use budget, native readback, revoke and temporary cleanup.
7. Lost/uncertain response, crash, incomplete revoke or cleanup records unknown and
does not auto-retry. Owner reconciliation plus fresh exact authorization governs
another action. Actual positive/negative/interruption proofs and owner acceptance
are required before pilot completion, then separately reviewed lifecycle adoption.
The pure candidate predicate's syntactic pdp_digest/freshness checks do not validate
live provider provenance, exact digest equality, human approver identity or consume.
They are source shape characterization only. Literal runtime_admission=false enforces
that absence. Authentication plus approval alone cannot enable it. Future source
successor must integrate all applicable gates, not expose an enable flag.
## Verification and limits
Maker source tests verify supported synthetic authenticated-service input binding,
wrong transport/subject/type/audience/tenant, missing/expired transport, deadline,
forged binding/delegation/flags and detached snapshot/zero-input refusal. Actual
Secrets ExecutionContract parser generates complete six-call synthetic input;
OPA candidate predicate is queried directly for eligible/negative shapes while
normal policy evaluation remains deny. Old human gate is unchanged. Source
fixtures register synthetic attributes solely for package-validation checks,
not an actual live catalogue or estate registry. No runtime image, credential,
provider admission, API change or native effect occurs.
## Exact component omissions (not completion evidence)
This source candidate is STRUCTURAL CHARACTERIZATION and authenticated-input
preparation only. Its predicate checks a syntactically tagged pdp_digest, not its
actual equality to enriched approval_binding_digest. It does not prove served
claim origin or verified approver identity, reconstruct canonical native claim
binding, validate full submitted/enriched DecisionEnvelope or consumption triplet,
bind actual compiler bytes to the whole descriptor, enforce journal phase/order,
admit grant/baseline/estate or perform an effect. Those are explicit implementation
requirements; a matching predicate and reviewed TokenReview input are insufficient.
The service adapter carries authenticated transport evidence outside the canonical
request but is not connected to HTTP evaluation/provider validation. A caller's
service_actor_binding remains a public declaration independently compared by the
adapter, never a substitute for runtime provenance or exact operation authority.
The old human fixture's epoch nanosecond integer exceeds the repaired consumer's
safe integer profile. Compatibility repair preserves that original projection as
an explicitly refused counterexample and tests descriptor-only canonical parity.
The old human package/identity schema are unchanged; no nanoseconds are rounded or
relabeled, no RFC3339 projection contract is invented, and no constant is flipped.
Any future human identity shape needs separate owner-reviewed source integration.

View file

@ -0,0 +1,8 @@
- id: unsigned-service-caller-not-authority
request:
tenant: tenant:platform
subject: {id: secrets-engine, type: service}
action: execute-ccr
resource: {id: catalog:test, type: secret-catalog-lane, system: secrets-engine}
context: {human_control: true, runtime_admission: true, verified: true}
expect: {effect: deny, reason: service_execution_integration_unadmitted}

View file

@ -0,0 +1,118 @@
---
id: secrets-engine.task-execution.service-pilot
name: Secrets admitted service task execution
namespace: secrets-engine:secret-catalog-lane
version: v1
status: proposed
package: flexauth.secrets_engine.service_task_execution
allow_ttl: 15s
actions: [execute-ccr]
owner: team:platform-security
fixtures: [policy_fixtures.yaml]
caring:
profile: caring-0.4.0-rc2
enforce: false
activation:
mode: local
---
# Proposed faithful service pilot successor
A separate source package for an admitted Secrets service as the initiating and
represented principal. It imposes no universal human initiator/User/Tenant gate.
It still requires the operation's declared human-control approval. The human
approver is not the service caller and does not supply service authentication.
Current runtime_admission is literal false because authenticated server mapping,
served claim validation, exact PDP joins and Platform executor integration are not
installed. Request flags cannot enable it. candidate_matches is source contract
characterization, not authority; positive predicate tests never flip the constant.
Raw caller metadata is not a verified identity. See docs/service-task-execution-contract.md.
```rego
runtime_admission := false
default decision := {"effect": "deny", "reason": "service_execution_integration_unadmitted"}
decision := {"effect": "allow", "reason": "exact_task_execution_matched"} {
runtime_admission
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()
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)
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}}
}
```

View file

@ -0,0 +1,6 @@
# Synthetic source-validation fixture only; no estate registry admission.
resources:
- id: catalog:synthetic
system: secrets-engine
type: secret-catalog-lane
attributes: {stage: prod}

View file

@ -0,0 +1,69 @@
package policy_test
import (
"context"
"encoding/json"
"github.com/netkingdom/access-engine/internal/policy"
"github.com/netkingdom/access-engine/pkg/api"
"github.com/open-policy-agent/opa/rego"
"os/exec"
"path/filepath"
"testing"
)
func TestServiceTaskExecutionSourcePredicateAndHardRefusal(t *testing.T) {
p, e := policy.LoadAndValidateFile(context.Background(), filepath.Join("..", "..", "examples", "secrets-engine-service-task-execution", "policy_package.md"))
if e != nil || !p.Valid {
t.Fatalf("package %v %+v", e, p.Validation)
}
out, e := exec.Command("/home/worsch/secrets-engine/.venv/bin/python", "../../tools/service_task_execution_fixture.py").Output()
if e != nil {
t.Fatal("actual Secrets descriptor generator", e)
}
var f struct {
Request api.CheckRequest `json:"request"`
}
if json.Unmarshal(out, &f) != nil {
t.Fatal("fixture")
}
candidate := func(r api.CheckRequest) bool {
b, _ := json.Marshal(r)
var input map[string]any
json.Unmarshal(b, &input)
result, e := rego.New(rego.Query("data.flexauth.secrets_engine.service_task_execution.candidate_matches"), rego.Module("candidate.rego", p.RegoModule), rego.Input(input)).Eval(context.Background())
if e != nil {
t.Fatal(e)
}
return len(result) > 0
}
if !candidate(f.Request) {
t.Fatal("supported synthetic service contract failed predicate")
}
d, e := p.Evaluate(context.Background(), f.Request)
if e != nil || d.Effect != api.DecisionEffectDeny || d.Reason != "service_execution_integration_unadmitted" {
t.Fatal("unintegrated source package opened")
}
cases := map[string]func(*api.CheckRequest){"human": func(r *api.CheckRequest) { r.Subject.Type = "human" }, "foreigntenant": func(r *api.CheckRequest) { r.Tenant = "tenant:coulomb" }, "apply": func(r *api.CheckRequest) { r.Action = "apply" }, "servicecaller": func(r *api.CheckRequest) {
r.Context["service_actor_binding"].(map[string]any)["transport_principal"] = "another"
}, "missing human control": func(r *api.CheckRequest) {
r.Context["approval"].(map[string]any)["binding"].(map[string]any)["human_control"] = false
}, "consumed": func(r *api.CheckRequest) { r.Context["approval"].(map[string]any)["consumed"] = true }, "PDP digest": func(r *api.CheckRequest) {
r.Context["approval"].(map[string]any)["binding"].(map[string]any)["pdp_digest"] = ""
}, "expired observation": func(r *api.CheckRequest) {
r.Context["approval"].(map[string]any)["freshness"].(map[string]any)["not_after"] = "2000-01-01T00:00:00Z"
}, "wrong operation": func(r *api.CheckRequest) {
r.Context["execution_contract"].(map[string]any)["operation"] = "generic-apply"
}}
for name, mutate := range cases {
t.Run(name, func(t *testing.T) {
var f struct {
Request api.CheckRequest `json:"request"`
}
json.Unmarshal(out, &f)
mutate(&f.Request)
if candidate(f.Request) {
t.Fatal("unsupported source contract matched")
}
})
}
}

View file

@ -35,70 +35,47 @@ func TestTaskExecutionSourceHasNoActivationSwitch(t *testing.T) {
}
}
func TestTaskExecutionPythonDescriptorAndSyntheticFutureProjection(t *testing.T) {
// The prior human projection contains epoch nanoseconds outside the exact
// cross-runtime integer profile. Preserve/refuse it; no identity schema change.
func TestTaskExecutionDescriptorOnlyAndRefusedHumanProjection(t *testing.T) {
output, e := exec.Command("/home/worsch/secrets-engine/.venv/bin/python", "../../tools/task_execution_interop_fixture.py").Output()
if e != nil {
t.Fatal("Python actual descriptor/canonical generator failed:", e)
t.Fatal("actual descriptor/canonical generator failed:", e)
}
var fixture struct {
Request api.CheckRequest `json:"request"`
RequestDigest string `json:"request_digest"`
ApprovalDigest string `json:"approval_binding_digest"`
DescriptorDigest string `json:"descriptor_digest"`
var f struct {
Request api.CheckRequest `json:"request"`
RequestDigest string `json:"request_digest"`
ApprovalDigest string `json:"approval_binding_digest"`
DescriptorDigest string `json:"descriptor_digest"`
OriginalProjection map[string]any `json:"original_nanosecond_projection"`
Refused bool `json:"original_projection_refused"`
IdentityChanged bool `json:"identity_contract_changed"`
}
if json.Unmarshal(output, &fixture) != nil {
if json.Unmarshal(output, &f) != nil {
t.Fatal("fixture JSON")
}
r := fixture.Request
if api.RequestDigest(r) != fixture.RequestDigest || api.ApprovalBindingDigest(r) != fixture.ApprovalDigest || api.CanonicalDigest(r.Context["execution_contract"]) != fixture.DescriptorDigest {
t.Fatal("actual Python/Go canonical mismatch")
if !f.Refused || f.IdentityChanged || f.OriginalProjection["not_after_ns"].(float64) <= float64(1<<53) {
t.Fatal("unsupported original nanosecond projection was not explicitly preserved/refused")
}
raw, e := os.ReadFile(filepath.Join("..", "..", "examples", "secrets-engine-task-execution", "policy_package.md"))
if e != nil {
t.Fatal(e)
if _, found := f.Request.Context["task_execution_projection"]; found {
t.Fatal("unsupported projection entered descriptor-only request")
}
// This source replacement is intentionally test-only; no caller/config flag
// can change the production package's hard admission=false constant.
raw = []byte(strings.Replace(string(raw), "owner_admission := false", "owner_admission := true", 1))
p, e := policy.Load(raw, "synthetic-future-provider-test.md")
if e != nil {
t.Fatal(e)
if api.RequestDigest(f.Request) != f.RequestDigest || api.ApprovalBindingDigest(f.Request) != f.ApprovalDigest || api.CanonicalDigest(f.Request.Context["execution_contract"]) != f.DescriptorDigest {
t.Fatal("actual descriptor-only Python/Go mismatch")
}
d, e := p.Evaluate(context.Background(), r)
if e != nil || d.Effect != api.DecisionEffectAllow {
t.Fatalf("synthetic future projection did not match: %v %+v", e, d)
p, e := policy.LoadAndValidateFile(context.Background(), filepath.Join("..", "..", "examples", "secrets-engine-task-execution", "policy_package.md"))
if e != nil || !p.Valid {
t.Fatal("unchanged human source package")
}
cases := map[string]func(*api.CheckRequest){
"action": func(r *api.CheckRequest) { r.Action = "apply" }, "service subject": func(r *api.CheckRequest) { r.Subject.ID = "other" }, "foreign tenant": func(r *api.CheckRequest) { r.Tenant = "tenant:coulomb" },
"plan hash": func(r *api.CheckRequest) {
r.Context["execution_contract"].(map[string]any)["expected_after"] = "sha256:" + strings.Repeat("b", 64)
},
"unsigned human": func(r *api.CheckRequest) { delete(r.Context, "task_execution_projection") },
"registered tenant": func(r *api.CheckRequest) {
r.Context["task_execution_projection"].(map[string]any)["tenant_source"] = "registration"
},
"membership": func(r *api.CheckRequest) {
r.Context["task_execution_projection"].(map[string]any)["member_active"] = false
},
"transport": func(r *api.CheckRequest) {
r.Context["task_execution_projection"].(map[string]any)["transport_principal"] = "other"
},
"expiry": func(r *api.CheckRequest) {
r.Context["task_execution_projection"].(map[string]any)["not_after_ns"] = float64(1)
},
"no human control": func(r *api.CheckRequest) { r.Context["human_control"] = false },
d, e := p.Evaluate(context.Background(), f.Request)
if e != nil || d.Effect != api.DecisionEffectDeny || d.Reason != "initiating_provider_unadmitted" {
t.Fatal("closed human package was enabled")
}
for name, mutate := range cases {
t.Run(name, func(t *testing.T) {
var f struct {
Request api.CheckRequest `json:"request"`
}
json.Unmarshal(output, &f)
mutate(&f.Request)
d, e := p.Evaluate(context.Background(), f.Request)
if e != nil || d.Effect != api.DecisionEffectDeny {
t.Fatalf("mutation allowed: %v %+v", e, d)
}
})
// No literal is flipped. Restoring the unsupported caller projection does
// not turn the unchanged package into a grant either.
f.Request.Context["task_execution_projection"] = f.OriginalProjection
d, e = p.Evaluate(context.Background(), f.Request)
if e != nil || d.Effect != api.DecisionEffectDeny {
t.Fatal("old caller projection opened package")
}
}

View file

@ -0,0 +1,101 @@
package taskexecution
import (
"context"
"encoding/json"
"errors"
"github.com/netkingdom/access-engine/internal/callerauth"
"github.com/netkingdom/access-engine/pkg/api"
"time"
)
var ErrServiceInput = errors.New("service task execution input refused")
const ServicePilotMappingVersion = "proposed-service-task-caller/v1"
const ServicePilotPrincipal = "system:serviceaccount:secrets-engine:secrets-engine"
// ServicePilotInputs is source preparation only. It installs the explicit
// proposed fixed subject-to-transport mapping, never a request-selected mapping.
// No constructor parameter can select warn/disabled mode or another subject.
type ServicePilotInputs struct{ auth *callerauth.Authenticator }
func NewServicePilotInputs(reviewer callerauth.TokenReviewer) (*ServicePilotInputs, error) {
a, e := callerauth.New(callerauth.ModeEnforce, reviewer, "flex-auth", map[string]string{"secrets-engine": ServicePilotPrincipal}, nil)
if e != nil {
return nil, ErrServiceInput
}
return &ServicePilotInputs{auth: a}, nil
}
// ServiceInput cannot be fabricated through exported fields. It proves only
// source input preparation through TokenReview, not approval provenance/consume
// or execution authority. Default zero value is not an authenticated input.
type ServiceInput struct {
serialized []byte
caller callerauth.Record
}
func (s ServiceInput) Request() (api.CheckRequest, error) {
if s.caller.Mode != callerauth.ModeEnforce || s.caller.Principal != ServicePilotPrincipal || len(s.serialized) == 0 {
return api.CheckRequest{}, ErrServiceInput
}
var r api.CheckRequest
if json.Unmarshal(s.serialized, &r) != nil {
return r, ErrServiceInput
}
return r, nil
}
func (s ServiceInput) Caller() callerauth.Record { return s.caller }
// DeclaredServiceBinding is public immutable metadata to bind at approval issue.
// It is not authentication evidence; Prepare independently verifies its principal.
func DeclaredServiceBinding() map[string]any {
return map[string]any{"version": ServicePilotMappingVersion, "transport_principal": ServicePilotPrincipal, "subject_id": "secrets-engine", "subject_type": "service", "tenant": "tenant:platform"}
}
func (s *ServicePilotInputs) Prepare(ctx context.Context, authorization string, r api.CheckRequest, now time.Time) (ServiceInput, error) {
refuse := func() (ServiceInput, error) { return ServiceInput{}, ErrServiceInput }
if s == nil || s.auth == nil || now.IsZero() || r.Action != "execute-ccr" || r.Tenant != "tenant:platform" || r.Subject.ID != "secrets-engine" || r.Subject.Type != "service" || r.Resource.System != "secrets-engine" || r.Resource.Type != "secret-catalog-lane" || r.Resource.Attributes["stage"] != "prod" || r.Context["human_control"] != true {
return refuse()
}
for _, key := range []string{"task_execution_projection", "initiator", "represented_principal", "delegation", "verified", "owner_admission"} {
if _, found := r.Context[key]; found {
return refuse()
}
}
if _, found := r.Subject.Attributes["principal"]; found {
return refuse()
}
supplied, err := json.Marshal(r.Context["service_actor_binding"])
if err != nil {
return refuse()
}
wanted, _ := json.Marshal(DeclaredServiceBinding())
if string(supplied) != string(wanted) {
return refuse()
}
identity, err := s.auth.Authorize(ctx, authorization, []string{r.Resource.System})
if err != nil {
return refuse()
}
record := s.auth.Record(identity)
if record.Mode != callerauth.ModeEnforce || record.Principal != ServicePilotPrincipal || record.Audience != "flex-auth" || record.NotAfter.IsZero() || !record.NotAfter.After(now) {
return refuse()
}
c, ok := r.Context["execution_contract"].(map[string]any)
if !ok || c["contract_version"] != "SECRETS-EXEC-20261011-v1" || c["operation"] != "metadata-apply-ccr" || c["execution_actor"] != "service:secrets-engine" {
return refuse()
}
deadline, ok := c["operation_deadline"].(string)
if !ok {
return refuse()
}
end, err := time.Parse(time.RFC3339Nano, deadline)
if err != nil || !end.After(now) || end.After(record.NotAfter) {
return refuse()
}
raw, err := json.Marshal(r)
if err != nil {
return refuse()
}
return ServiceInput{serialized: raw, caller: record}, nil
}

View file

@ -0,0 +1,81 @@
package taskexecution
import (
"context"
"github.com/netkingdom/access-engine/internal/callerauth"
"github.com/netkingdom/access-engine/pkg/api"
"testing"
"time"
)
type serviceReviewer struct {
identity callerauth.Identity
err error
calls int
}
func (r *serviceReviewer) Review(_ context.Context, _ string) (callerauth.Identity, error) {
r.calls++
return r.identity, r.err
}
func serviceRequest(t *testing.T, now time.Time) api.CheckRequest {
t.Helper()
r := api.CheckRequest{Tenant: "tenant:platform", Subject: api.SubjectRef{ID: "secrets-engine", Type: "service"}, Action: "execute-ccr", Resource: api.ResourceRef{ID: "catalog:synthetic", Type: "secret-catalog-lane", System: "secrets-engine", Attributes: map[string]any{"stage": "prod"}}, Context: map[string]any{"human_control": true, "service_actor_binding": DeclaredServiceBinding(), "execution_contract": map[string]any{"contract_version": "SECRETS-EXEC-20261011-v1", "operation": "metadata-apply-ccr", "execution_actor": "service:secrets-engine", "operation_deadline": now.Add(60 * time.Second).Format(time.RFC3339Nano)}}}
return r
}
func TestServicePilotAuthenticatedBinding(t *testing.T) {
now := time.Now()
reviewer := &serviceReviewer{identity: callerauth.Identity{Username: ServicePilotPrincipal, Audiences: []string{"flex-auth"}, NotAfter: now.Add(120 * time.Second)}}
a, e := NewServicePilotInputs(reviewer)
if e != nil {
t.Fatal(e)
}
r := serviceRequest(t, now)
s, e := a.Prepare(context.Background(), "Bearer synthetic", r, now)
if e != nil || reviewer.calls != 1 {
t.Fatal("source TokenReview path")
}
out, e := s.Request()
if e != nil || api.RequestDigest(out) != api.RequestDigest(r) || s.Caller().Principal != ServicePilotPrincipal {
t.Fatal("binding changed")
}
r.Context["service_actor_binding"].(map[string]any)["subject_id"] = "mutated"
again, _ := s.Request()
if again.Context["service_actor_binding"].(map[string]any)["subject_id"] != "secrets-engine" {
t.Fatal("opaque input retained mutable caller map")
}
if _, e := (ServiceInput{}).Request(); e == nil {
t.Fatal("zero input trusted")
}
}
func TestServicePilotRefusals(t *testing.T) {
now := time.Now()
cases := map[string]func(*api.CheckRequest, *serviceReviewer){"human": func(r *api.CheckRequest, _ *serviceReviewer) { r.Subject.Type = "human" }, "subject": func(r *api.CheckRequest, _ *serviceReviewer) { r.Subject.ID = "another" }, "legacy apply": func(r *api.CheckRequest, _ *serviceReviewer) { r.Action = "apply" }, "foreigntenant": func(r *api.CheckRequest, _ *serviceReviewer) { r.Tenant = "tenant:coulomb" }, "wrong service principal": func(_ *api.CheckRequest, p *serviceReviewer) {
p.identity.Username = "system:serviceaccount:other:other"
}, "wrong audience": func(_ *api.CheckRequest, p *serviceReviewer) { p.identity.Audiences = []string{"openbao"} }, "expired transport": func(_ *api.CheckRequest, p *serviceReviewer) { p.identity.NotAfter = now }, "missing expiry": func(_ *api.CheckRequest, p *serviceReviewer) { p.identity.NotAfter = time.Time{} }, "caller verified": func(r *api.CheckRequest, _ *serviceReviewer) { r.Context["verified"] = true }, "human projection": func(r *api.CheckRequest, _ *serviceReviewer) {
r.Context["task_execution_projection"] = map[string]any{"subject": "human"}
}, "delegation": func(r *api.CheckRequest, _ *serviceReviewer) { r.Context["delegation"] = false }, "forged binding": func(r *api.CheckRequest, _ *serviceReviewer) {
r.Context["service_actor_binding"].(map[string]any)["subject_id"] = "other"
}, "lifetime": func(r *api.CheckRequest, _ *serviceReviewer) {
r.Context["execution_contract"].(map[string]any)["operation_deadline"] = now.Add(240 * time.Second).Format(time.RFC3339Nano)
}}
for name, mutate := range cases {
t.Run(name, func(t *testing.T) {
r := serviceRequest(t, now)
p := &serviceReviewer{identity: callerauth.Identity{Username: ServicePilotPrincipal, Audiences: []string{"flex-auth"}, NotAfter: now.Add(120 * time.Second)}}
mutate(&r, p)
a, _ := NewServicePilotInputs(p)
if _, e := a.Prepare(context.Background(), "Bearer synthetic", r, now); e == nil {
t.Fatal("invalid input accepted")
}
})
}
p := &serviceReviewer{identity: callerauth.Identity{Username: ServicePilotPrincipal, Audiences: []string{"flex-auth"}, NotAfter: now.Add(time.Minute)}}
a, _ := NewServicePilotInputs(p)
if _, e := a.Prepare(context.Background(), "", serviceRequest(t, now), now); e == nil {
t.Fatal("missing header accepted")
}
if _, e := NewServicePilotInputs(nil); e == nil {
t.Fatal("missing owner reviewer accepted")
}
}

View file

@ -0,0 +1,13 @@
"""Synthetic interoperability generator; never obtains credentials or native state."""
import hashlib, json, sys
from datetime import datetime, timedelta, timezone
sys.path.insert(0, '/home/worsch/secrets-engine/src')
from secrets_engine.execution_contract import ExecutionContract, catalog_target_digest
from secrets_engine.authorization import request_digest, approval_binding_digest
h='sha256:'+'a'*64
catalog={'lane':'synthetic','stage':'prod'}
c={'contract_version':'SECRETS-EXEC-20261011-v1','operation_id':'cbfbced0-09d5-48c8-a1e7-a2ea4dc69153','operation':'metadata-apply-ccr','execution_actor':'service:secrets-engine','ccr_id':'CCR-2099-0001','execution_grant_ccr_id':'CCR-2099-0002','ccr_immutable_sha256':h,'grant_immutable_sha256':h,'catalog_sha256':catalog_target_digest(catalog),'expected_before':h,'expected_after':h,'source_bundle':{r:{'path':'/synthetic/'+r+'.py','sha256':h} for r in ['engine_dispatcher','platform_mediator','typed_ccr','policy_auth']},'backend_origin':'http://127.0.0.1:18200','cluster_uid':'synthetic-not-native','backend_budget':{'ttl_seconds':120,'uses':12},'operation_deadline':(datetime.now(timezone.utc)+timedelta(seconds=100)).isoformat(),'operations':[{'method':method,'path':path,'payload_sha256':h} for path in ['sys/policies/acl/synthetic','auth/synthetic/role/synthetic'] for method in ['GET','PUT','GET']]}
c=ExecutionContract.parse(c).as_dict()
p={'version':'proposed-service-task-caller/v1','transport_principal':'system:serviceaccount:secrets-engine:secrets-engine','subject_id':'secrets-engine','subject_type':'service','tenant':'tenant:platform'}
r={'tenant':'tenant:platform','subject':{'id':'secrets-engine','type':'service'},'action':'execute-ccr','resource':{'id':'catalog:synthetic','type':'secret-catalog-lane','system':'secrets-engine','attributes':{'stage':'prod'}},'context':{'execution_contract':c,'catalog_target':catalog,'human_control':True,'service_actor_binding':p,'approval':{'schema_version':'0.1','kind':'approval-claim','issuer':'approval-engine','approval_id':'synthetic','valid_now':True,'consumed':False,'reason_code':'ok','binding':{'human_control':True,'pdp_path':True,'pdp_digest':h},'freshness':{'not_after':(datetime.now(timezone.utc)+timedelta(seconds=60)).isoformat()},'validity':{'expires_at':(datetime.now(timezone.utc)+timedelta(seconds=120)).isoformat()}}}}
print(json.dumps({'request':r,'request_digest':request_digest(r),'approval_binding_digest':approval_binding_digest(r),'descriptor_digest':catalog_target_digest(c)}))

View file

@ -1,13 +1,29 @@
"""Synthetic interoperability generator; never obtains credentials or native state."""
import hashlib, json, sys
import hashlib, json, os, sys
from datetime import datetime, timedelta, timezone
sys.path.insert(0, '/home/worsch/secrets-engine/src')
sys.path.insert(0, os.environ.get('SECRETS_ENGINE_SOURCE', '/home/worsch/secrets-engine') + '/src')
from secrets_engine.execution_contract import ExecutionContract, catalog_target_digest
from secrets_engine.authorization import request_digest, approval_binding_digest
from secrets_engine.errors import DecisionError
h='sha256:'+'a'*64
catalog={'lane':'synthetic','stage':'prod'}
c={'contract_version':'SECRETS-EXEC-20261011-v1','operation_id':'cbfbced0-09d5-48c8-a1e7-a2ea4dc69153','operation':'metadata-apply-ccr','execution_actor':'service:secrets-engine','ccr_id':'CCR-2099-0001','execution_grant_ccr_id':'CCR-2099-0002','ccr_immutable_sha256':h,'grant_immutable_sha256':h,'catalog_sha256':catalog_target_digest(catalog),'expected_before':h,'expected_after':h,'source_bundle':{r:{'path':'/synthetic/'+r+'.py','sha256':h} for r in ['engine_dispatcher','platform_mediator','typed_ccr','policy_auth']},'backend_origin':'http://127.0.0.1:18200','cluster_uid':'synthetic-not-native','backend_budget':{'ttl_seconds':120,'uses':12},'operation_deadline':(datetime.now(timezone.utc)+timedelta(seconds=100)).isoformat(),'operations':[{'method':method,'path':path,'payload_sha256':h} for path in ['sys/policies/acl/synthetic','auth/synthetic/role/synthetic'] for method in ['GET','PUT','GET']]}
c=ExecutionContract.parse(c).as_dict()
p={'version':'proposed-task-execution-projection/v1','subject':'synthetic-human','principal_type':'human','tenant':'tenant:platform','tenant_source':'directory','mfa':True,'transport_principal':'system:serviceaccount:secrets-engine:secrets-engine','execution_contract_digest':catalog_target_digest(c),'resource_id':'catalog:synthetic','membership_source':'user-engine','tenant_state_source':'tenant-engine','member_active':True,'tenant_active':True,'not_after_ns':int((datetime.now(timezone.utc)+timedelta(seconds=60)).timestamp())*1000000000}
r={'tenant':'tenant:platform','subject':{'id':'secrets-engine','type':'service'},'action':'execute-ccr','resource':{'id':'catalog:synthetic','type':'secret-catalog-lane','system':'secrets-engine'},'context':{'execution_contract':c,'catalog_target':catalog,'human_control':True,'task_execution_projection':p,'approval':{'kind':'approval-claim','binding':{'human_control':True}}}}
print(json.dumps({'request':r,'request_digest':request_digest(r),'approval_binding_digest':approval_binding_digest(r),'descriptor_digest':catalog_target_digest(c)}))
# Preserve the exact earlier shape as an explicit unsupported counterexample.
# It is NOT rounded, relabeled as RFC3339 or admitted into the old human policy.
original_projection = p
try:
request_digest(r)
original_projection_refused = False
except DecisionError:
original_projection_refused = True
# Descriptor-only interoperability is independent of a missing identity contract.
del r['context']['task_execution_projection']
print(json.dumps({'request':r,'request_digest':request_digest(r),
'approval_binding_digest':approval_binding_digest(r),
'descriptor_digest':catalog_target_digest(c),
'original_nanosecond_projection':original_projection,
'original_projection_refused':original_projection_refused,
'identity_contract_changed':False}))

View file

@ -138,3 +138,35 @@ Any formal source receipt must follow persistence of this exact own-repo record.
No operational milestone closes; authoritative issuer/client, User/Tenant
membership and representation/server injection, served approval joins and native
execution remain on the existing drivers.
## Prepare faithful service task execution source successor
```task
id: FLEX-WP-ADHOC-2026-10-11-T05
status: done
priority: high
```
Completed bounded source preparation based on accepted v0.8/GH013/GH016 intent
assessment for existing SECRETS-WP-0013/RPF-WP-0035-T12 drivers. Prepared separate
proposed service-pilot package with literal runtime-admission refusal, concrete
source TokenReview enforce adapter binding exact admitted service transport to
Secrets subject/type and immutable public declared mapping before approval issue,
plus maker positive-input/refusal and pure candidate-shape tests. No universal
human initiator/User/Tenant gate is imposed; a declared human-control approver
remains distinct from service initiator. Old proposed human package stays unchanged.
This completes source component preparation only. No formal owner receipt, live
mapping/provider admission, policy activation, exact served approval/PDP/consume/
journal/task-grant/executor integration, credential or native action is completed.
Operational drivers remain open; no clone workplan or source-policy enable switch
is introduced. Synthetic successful input eligibility is not runtime allowance.
T05 preparation refinement: preserved the original unadmitted human nanosecond
projection as explicitly refused by the repaired canonical profile; converted its
interop test to descriptor-only parity and unchanged hard-denial evidence. No old
human policy or identity contract changes and no source constant flips. Service
candidate remains structural characterization, not served approval/PDP/consume/
compiler/journal/grant correspondence or operational readiness.