access-engine/internal/markitect/decision.go
tegwick f758381cea
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 6s
Build and Publish Container Image / build-and-push (push) Successful in 1m23s
FLEX-WP-0036: Go module is github.com/netkingdom/access-engine; T02 consumer inventory
- module path renamed (no external importers); golangci local-prefixes
- ACCESS_ENGINE_RUN_TOPAZ_INTEGRATION replaces FLEX_AUTH_RUN_TOPAZ_INTEGRATION
- README title and identity paragraph reflect the landed renames
- docs/runtime-rename-inventory.md: per-consumer references by kind and order
- chart name, image package and /opt paths deliberately left for T05

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 735967@bnt-lap001
Assistant-Session: 5971967f-77f8-4ced-9e02-c6ef67040ffc
2026-10-10 15:29:00 +02:00

75 lines
3 KiB
Go

package markitect
import "github.com/netkingdom/access-engine/pkg/api"
const (
GatewayEffectAllow = "allow"
GatewayEffectDeny = "deny"
GatewayEffectRedact = "redact"
GatewayEffectAuditDenied = "audit_denied"
)
// GatewayDecision is the Markitect-facing decision contract.
type GatewayDecision struct {
ID string `json:"id"`
Effect string `json:"effect"`
Reason string `json:"reason,omitempty"`
RuleID string `json:"rule_id,omitempty"`
PolicyVersion string `json:"policy_version,omitempty"`
Resource api.ResourceRef `json:"resource"`
ResourceMetadata map[string]any `json:"resource_metadata,omitempty"`
Subject api.SubjectRef `json:"subject"`
Obligations []api.Obligation `json:"obligations,omitempty"`
Diagnostics map[string]any `json:"diagnostics,omitempty"`
CaringDescriptor *api.CaringAccessDescriptor `json:"caring_descriptor,omitempty"`
ConformanceFindings []api.CaringConformanceFinding `json:"conformance_findings,omitempty"`
ExposureModes []api.ExposureMode `json:"exposure_modes,omitempty"`
}
// ToGatewayDecision projects a flex-auth decision envelope into the shape
// consumed by the Markitect policy gateway.
func ToGatewayDecision(decision api.DecisionEnvelope) GatewayDecision {
out := GatewayDecision{
ID: decision.ID,
Effect: gatewayEffect(decision),
Reason: decision.Reason,
RuleID: decision.MatchedRule,
PolicyVersion: decision.MatchedPolicyVersion,
Resource: decision.Resource,
ResourceMetadata: copyMap(decision.Resource.Attributes),
Subject: decision.Subject,
Obligations: append([]api.Obligation(nil), decision.Obligations...),
Diagnostics: copyMap(decision.Diagnostics),
}
if out.PolicyVersion == "" {
out.PolicyVersion = decision.Provenance.PolicyVersion
}
if decision.Caring != nil {
if decision.Caring.Descriptor != nil {
descriptor := *decision.Caring.Descriptor
out.CaringDescriptor = &descriptor
}
out.ConformanceFindings = append([]api.CaringConformanceFinding(nil), decision.Caring.ConformanceFindings...)
out.ExposureModes = append([]api.ExposureMode(nil), decision.Caring.ExposureModes...)
}
return out
}
func gatewayEffect(decision api.DecisionEnvelope) string {
if value, ok := decision.Diagnostics["markitect_effect"].(string); ok && value != "" {
return value
}
if auditDenied, ok := decision.Diagnostics["audit_denied"].(bool); ok && auditDenied {
return GatewayEffectAuditDenied
}
switch decision.Effect {
case api.DecisionEffectAllow:
return GatewayEffectAllow
case api.DecisionEffectRedact:
return GatewayEffectRedact
case api.DecisionEffectAuditOnly:
return GatewayEffectAuditDenied
default:
return GatewayEffectDeny
}
}