access-engine/pkg/api/execution_contract_test.go

53 lines
3.5 KiB
Go
Raw Normal View History

package api
import (
"encoding/json"
"testing"
)
func executionRequest(t *testing.T) CheckRequest {
t.Helper()
var r CheckRequest
err := json.Unmarshal([]byte(`{"tenant":"tenant:platform","subject":{"id":"secrets-engine","type":"service"},"action":"execute-ccr","resource":{"id":"catalog:test","type":"secret-catalog-lane","system":"secrets-engine","attributes":{"stage":"prod"}},"context":{"purpose":"metadata-apply-ccr","human_control":true,"execution_contract":{"contract_version":"SECRETS-EXEC-20261011-v1","operation_id":"018b3ff9-7470-470b-bf37-36d8b9b67eb1","catalog_sha256":"catalog-original","ccr_immutable_sha256":"ccr-original","source_bundle":[{"path":"/owner/mediator.py","sha256":"source-original"}],"operations":[{"method":"POST","path":"/v1/sys/policies/acl/exact","payload_sha256":"body-original"}]}}}`), &r)
if err != nil { t.Fatal(err) }
return r
}
func TestExecutionContractExactSemanticChangesInvalidateBinding(t *testing.T) {
original := executionRequest(t)
digest := RequestDigest(original)
cases := map[string]func(*CheckRequest){
"operation id":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["operation_id"]="other"},
"catalog":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["catalog_sha256"]="other"},
"ccr":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["ccr_immutable_sha256"]="other"},
"source":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["source_bundle"].([]any)[0].(map[string]any)["sha256"]="other"},
"method":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["operations"].([]any)[0].(map[string]any)["method"]="DELETE"},
"target":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["operations"].([]any)[0].(map[string]any)["path"]="/v1/sys/policies/acl/sibling"},
"body":func(r *CheckRequest){r.Context["execution_contract"].(map[string]any)["operations"].([]any)[0].(map[string]any)["payload_sha256"]="other"},
"principal":func(r *CheckRequest){r.Subject.ID="other"},
"action":func(r *CheckRequest){r.Action="apply"},
"tenant":func(r *CheckRequest){r.Tenant="other"},
}
for name, change := range cases {t.Run(name,func(t *testing.T){r:=executionRequest(t);change(&r);if RequestDigest(r)==digest || ApprovalBindingDigest(r)==digest {t.Fatal("semantic mutation retained binding")}})}
}
func TestExecutionContractApprovalJoinAndEnrichment(t *testing.T) {
issue:=executionRequest(t)
// Model the actual evaluator's tenant/registry overlay before issue Check.
issue.Subject.Tenant=issue.Tenant
issue.Subject.Attributes=map[string]any{"display_name":"Engine owner"}
issue.Resource.Tenant=issue.Tenant
submitted:=executionRequest(t)
submitted.Context["approval"]=map[string]any{"kind":"approval-claim","binding":map[string]any{"pdp_digest":RequestDigest(issue)}}
evaluated:=issue
evaluated.Context=map[string]any{}
for k,v:=range issue.Context {evaluated.Context[k]=v}
evaluated.Context["approval"]=submitted.Context["approval"]
binding:=NewDecisionBindingFor(evaluated,submitted)
if binding.SubmittedRequestDigest!=RequestDigest(submitted) {t.Fatal("submitted request not bound")}
if binding.ApprovalBindingDigest!=RequestDigest(issue) {t.Fatal("claim-free issue digest does not join")}
if binding.RequestDigest==binding.SubmittedRequestDigest {t.Fatal("test did not exercise enriched request")}
submitted.ID="different-correlation-id"
if RequestDigest(submitted)!=binding.SubmittedRequestDigest {t.Fatal("correlation id unexpectedly authorizes")}
}