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,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")
}
}