Implement canonical schema foundation
Some checks failed
CI / Build and Test (push) Has been cancelled
CI / Lint (push) Has been cancelled

This commit is contained in:
2026-05-17 04:59:18 +02:00
parent dd0b9663c4
commit 7fdf6d63d5
29 changed files with 1905 additions and 15 deletions

249
pkg/api/canonical.go Normal file
View File

@@ -0,0 +1,249 @@
package api
// ProtectedSystemManifest describes a system that delegates authorization to
// flex-auth.
type ProtectedSystemManifest struct {
ID string `json:"id" yaml:"id"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
ResourceTypes []ResourceType `json:"resource_types,omitempty" yaml:"resource_types,omitempty"`
Actions []ActionDefinition `json:"actions,omitempty" yaml:"actions,omitempty"`
CaringProfiles []string `json:"caring_profiles,omitempty" yaml:"caring_profiles,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// ResourceType describes a resource namespace entry owned by a protected system.
type ResourceType struct {
Name string `json:"name" yaml:"name"`
ParentTypes []string `json:"parent_types,omitempty" yaml:"parent_types,omitempty"`
ScopeLevel ScopeLevel `json:"scope_level,omitempty" yaml:"scope_level,omitempty"`
Planes []Plane `json:"planes,omitempty" yaml:"planes,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// ActionDefinition maps a protected-system action to CARING capabilities.
type ActionDefinition struct {
Name string `json:"name" yaml:"name"`
Capabilities []Capability `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
Planes []Plane `json:"planes,omitempty" yaml:"planes,omitempty"`
ExposureModes []ExposureMode `json:"exposure_modes,omitempty" yaml:"exposure_modes,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// SubjectManifest declares subjects, groups, teams, and tenants for local
// registry loading.
type SubjectManifest struct {
ID string `json:"id" yaml:"id"`
Subjects []Subject `json:"subjects,omitempty" yaml:"subjects,omitempty"`
Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"`
Teams []Team `json:"teams,omitempty" yaml:"teams,omitempty"`
Tenants []Tenant `json:"tenants,omitempty" yaml:"tenants,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// Subject is a human, service, automation, agent, or other acting identity.
type Subject struct {
ID string `json:"id" yaml:"id"`
Type SubjectType `json:"type" yaml:"type"`
DisplayName string `json:"display_name,omitempty" yaml:"display_name,omitempty"`
OrganizationRelation OrganizationRelation `json:"organization_relation,omitempty" yaml:"organization_relation,omitempty"`
Roles []CanonicalRole `json:"roles,omitempty" yaml:"roles,omitempty"`
Groups []string `json:"groups,omitempty" yaml:"groups,omitempty"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
Claims map[string]any `json:"claims,omitempty" yaml:"claims,omitempty"`
CaringDescriptors []CaringAccessDescriptor `json:"caring_descriptors,omitempty" yaml:"caring_descriptors,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// Group is an assignment convenience, not a canonical role.
type Group struct {
ID string `json:"id" yaml:"id"`
DisplayName string `json:"display_name,omitempty" yaml:"display_name,omitempty"`
Members []string `json:"members,omitempty" yaml:"members,omitempty"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
CaringDescriptors []CaringAccessDescriptor `json:"caring_descriptors,omitempty" yaml:"caring_descriptors,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// Team is a group-like ownership unit used by protected systems.
type Team struct {
ID string `json:"id" yaml:"id"`
DisplayName string `json:"display_name,omitempty" yaml:"display_name,omitempty"`
Members []string `json:"members,omitempty" yaml:"members,omitempty"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
CaringDescriptors []CaringAccessDescriptor `json:"caring_descriptors,omitempty" yaml:"caring_descriptors,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// Tenant is a structural isolation boundary.
type Tenant struct {
ID string `json:"id" yaml:"id"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// RelationshipFact records a relation between subjects, groups, teams, tenants,
// and resources.
type RelationshipFact struct {
ID string `json:"id" yaml:"id"`
System string `json:"system,omitempty" yaml:"system,omitempty"`
Subject string `json:"subject" yaml:"subject"`
Relation string `json:"relation" yaml:"relation"`
Object string `json:"object" yaml:"object"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"`
Caring *CaringAccessDescriptor `json:"caring,omitempty" yaml:"caring,omitempty"`
Provenance map[string]any `json:"provenance,omitempty" yaml:"provenance,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// PolicyPackageMetadata is the frontmatter contract for Rego-in-Markdown
// policy packages.
type PolicyPackageMetadata struct {
ID string `json:"id" yaml:"id"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Version string `json:"version" yaml:"version"`
Status string `json:"status,omitempty" yaml:"status,omitempty"`
Package string `json:"package" yaml:"package"`
Caring CaringPolicyMetadata `json:"caring" yaml:"caring"`
Activation map[string]any `json:"activation,omitempty" yaml:"activation,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// CaringPolicyMetadata declares the CARING envelope a policy governs.
type CaringPolicyMetadata struct {
Profile string `json:"profile" yaml:"profile"`
CanonicalRoles []CanonicalRole `json:"canonical_roles,omitempty" yaml:"canonical_roles,omitempty"`
OrganizationRelations []OrganizationRelation `json:"organization_relations,omitempty" yaml:"organization_relations,omitempty"`
Scopes []CaringScope `json:"scopes,omitempty" yaml:"scopes,omitempty"`
Planes []Plane `json:"planes,omitempty" yaml:"planes,omitempty"`
Capabilities []Capability `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
ExposureModes []ExposureMode `json:"exposure_modes,omitempty" yaml:"exposure_modes,omitempty"`
Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"`
Restrictions []Restriction `json:"restrictions,omitempty" yaml:"restrictions,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// PolicyFixture binds a check request to an expected decision.
type PolicyFixture struct {
ID string `json:"id" yaml:"id"`
Request CheckRequest `json:"request" yaml:"request"`
Expect DecisionExpectation `json:"expect" yaml:"expect"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// DecisionExpectation is the compact fixture expectation for policy tests.
type DecisionExpectation struct {
Effect DecisionEffect `json:"effect" yaml:"effect"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
Obligations []Obligation `json:"obligations,omitempty" yaml:"obligations,omitempty"`
ConformanceFindings []CaringConformanceFinding `json:"conformance_findings,omitempty" yaml:"conformance_findings,omitempty"`
}
// CheckRequest is the stable protected-system-facing decision request.
type CheckRequest struct {
ID string `json:"id,omitempty" yaml:"id,omitempty"`
Subject SubjectRef `json:"subject" yaml:"subject"`
Action string `json:"action" yaml:"action"`
Resource ResourceRef `json:"resource" yaml:"resource"`
Context map[string]any `json:"context,omitempty" yaml:"context,omitempty"`
CaringContext *CaringAccessDescriptor `json:"caring_context,omitempty" yaml:"caring_context,omitempty"`
PolicyVersion string `json:"policy_version,omitempty" yaml:"policy_version,omitempty"`
}
// BatchCheckRequest evaluates one subject/action against multiple resources.
type BatchCheckRequest struct {
ID string `json:"id,omitempty" yaml:"id,omitempty"`
Subject SubjectRef `json:"subject" yaml:"subject"`
Action string `json:"action" yaml:"action"`
Resources []ResourceRef `json:"resources" yaml:"resources"`
Context map[string]any `json:"context,omitempty" yaml:"context,omitempty"`
PolicyVersion string `json:"policy_version,omitempty" yaml:"policy_version,omitempty"`
}
// SubjectRef is a normalized subject reference in request and decision shapes.
type SubjectRef struct {
ID string `json:"id" yaml:"id"`
Type SubjectType `json:"type,omitempty" yaml:"type,omitempty"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
Attributes map[string]any `json:"attributes,omitempty" yaml:"attributes,omitempty"`
}
// ResourceRef is a normalized resource reference in request and decision shapes.
type ResourceRef struct {
ID string `json:"id" yaml:"id"`
Type string `json:"type,omitempty" yaml:"type,omitempty"`
System string `json:"system,omitempty" yaml:"system,omitempty"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
Attributes map[string]any `json:"attributes,omitempty" yaml:"attributes,omitempty"`
}
// DecisionEffect is the stable decision outcome vocabulary.
type DecisionEffect string
const (
DecisionEffectAllow DecisionEffect = "allow"
DecisionEffectDeny DecisionEffect = "deny"
DecisionEffectRedact DecisionEffect = "redact"
DecisionEffectAuditOnly DecisionEffect = "audit_only"
DecisionEffectNotApplicable DecisionEffect = "not_applicable"
)
// DecisionEnvelope is the stable response produced by standalone and delegated
// evaluators.
type DecisionEnvelope struct {
ID string `json:"id" yaml:"id"`
RequestID string `json:"request_id,omitempty" yaml:"request_id,omitempty"`
Effect DecisionEffect `json:"effect" yaml:"effect"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
MatchedPolicyVersion string `json:"matched_policy_version,omitempty" yaml:"matched_policy_version,omitempty"`
MatchedRule string `json:"matched_rule,omitempty" yaml:"matched_rule,omitempty"`
Resource ResourceRef `json:"resource" yaml:"resource"`
Subject SubjectRef `json:"subject" yaml:"subject"`
Obligations []Obligation `json:"obligations,omitempty" yaml:"obligations,omitempty"`
Diagnostics map[string]any `json:"diagnostics,omitempty" yaml:"diagnostics,omitempty"`
Provenance DecisionProvenance `json:"provenance" yaml:"provenance"`
Caring *CaringDecisionMetadata `json:"caring,omitempty" yaml:"caring,omitempty"`
}
// Obligation describes a follow-up behavior required by a decision.
type Obligation struct {
Type string `json:"type" yaml:"type"`
Parameters map[string]any `json:"parameters,omitempty" yaml:"parameters,omitempty"`
}
// DecisionProvenance captures evaluator and policy provenance.
type DecisionProvenance struct {
Evaluator string `json:"evaluator" yaml:"evaluator"`
Mode string `json:"mode" yaml:"mode"`
PolicyPackage string `json:"policy_package,omitempty" yaml:"policy_package,omitempty"`
PolicyVersion string `json:"policy_version,omitempty" yaml:"policy_version,omitempty"`
DirectoryETag string `json:"directory_etag,omitempty" yaml:"directory_etag,omitempty"`
DecisionTime string `json:"decision_time,omitempty" yaml:"decision_time,omitempty"`
}
// CaringDecisionMetadata carries CARING descriptor and conformance details in
// a decision envelope.
type CaringDecisionMetadata struct {
Profile string `json:"profile" yaml:"profile"`
Descriptor *CaringAccessDescriptor `json:"descriptor,omitempty" yaml:"descriptor,omitempty"`
RestrictionsEvaluated []Restriction `json:"restrictions_evaluated,omitempty" yaml:"restrictions_evaluated,omitempty"`
ExposureModes []ExposureMode `json:"exposure_modes,omitempty" yaml:"exposure_modes,omitempty"`
DerivedCapabilities []CaringDerivedCapability `json:"derived_capabilities,omitempty" yaml:"derived_capabilities,omitempty"`
ConformanceFindings []CaringConformanceFinding `json:"conformance_findings,omitempty" yaml:"conformance_findings,omitempty"`
ExposureEvent *CaringExposureEvent `json:"exposure_event,omitempty" yaml:"exposure_event,omitempty"`
}
// AuditEvent is the local log shape for decisions and exposure events.
type AuditEvent struct {
ID string `json:"id" yaml:"id"`
Type string `json:"type" yaml:"type"`
DecisionID string `json:"decision_id,omitempty" yaml:"decision_id,omitempty"`
Subject SubjectRef `json:"subject" yaml:"subject"`
Resource ResourceRef `json:"resource,omitempty" yaml:"resource,omitempty"`
Action string `json:"action,omitempty" yaml:"action,omitempty"`
Effect DecisionEffect `json:"effect,omitempty" yaml:"effect,omitempty"`
Timestamp string `json:"timestamp,omitempty" yaml:"timestamp,omitempty"`
ExposureEvent *CaringExposureEvent `json:"exposure_event,omitempty" yaml:"exposure_event,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}

130
pkg/api/canonical_test.go Normal file
View File

@@ -0,0 +1,130 @@
package api_test
import (
"encoding/json"
"os"
"path/filepath"
"testing"
"gopkg.in/yaml.v3"
"github.com/netkingdom/flex-auth/pkg/api"
)
func TestCaringAccessDescriptorExampleParses(t *testing.T) {
var got api.CaringAccessDescriptor
loadYAML(t, filepath.Join("..", "..", "examples", "caring", "access_descriptor.yaml"), &got)
if got.Profile != api.CaringProfileCaring040RC2 {
t.Fatalf("Profile = %q; want %q", got.Profile, api.CaringProfileCaring040RC2)
}
if got.CanonicalRole != api.CanonicalRoleDoer {
t.Errorf("CanonicalRole = %q; want Doer", got.CanonicalRole)
}
if got.Scope.Level != api.ScopeLevelResource || got.Scope.Tenant != "tenant:alpha" {
t.Errorf("Scope = %+v; want resource scope in tenant:alpha", got.Scope)
}
if len(got.Restrictions) != 1 || got.Restrictions[0] != api.RestrictionExportBlocked {
t.Errorf("Restrictions = %v; want [ExportBlocked]", got.Restrictions)
}
}
func TestCheckRequestExampleParses(t *testing.T) {
var got api.CheckRequest
loadYAML(t, filepath.Join("..", "..", "examples", "caring", "check_request.yaml"), &got)
if got.Subject.ID != "user:alice" {
t.Errorf("Subject.ID = %q; want user:alice", got.Subject.ID)
}
if got.Resource.ID != "document:internal-note" {
t.Errorf("Resource.ID = %q; want document:internal-note", got.Resource.ID)
}
if got.CaringContext == nil {
t.Fatal("CaringContext is nil")
}
if got.CaringContext.AccessPath != api.AccessPathDirect {
t.Errorf("CaringContext.AccessPath = %q; want direct", got.CaringContext.AccessPath)
}
}
func TestRegistryExamplesParse(t *testing.T) {
var subjects api.SubjectManifest
loadYAML(t, filepath.Join("..", "..", "examples", "caring", "subject_manifest.yaml"), &subjects)
if len(subjects.Subjects) != 1 || subjects.Subjects[0].Type != api.SubjectTypeHuman {
t.Fatalf("subjects did not parse as expected: %+v", subjects.Subjects)
}
var relationship api.RelationshipFact
loadYAML(t, filepath.Join("..", "..", "examples", "caring", "relationship_fact.yaml"), &relationship)
if relationship.Caring == nil {
t.Fatal("RelationshipFact.Caring is nil")
}
if relationship.Caring.SubjectType != api.SubjectTypeGroup {
t.Errorf("RelationshipFact.Caring.SubjectType = %q; want Group", relationship.Caring.SubjectType)
}
}
func TestDecisionAndAuditExamplesParse(t *testing.T) {
var decision api.DecisionEnvelope
loadJSON(t, filepath.Join("..", "..", "examples", "caring", "decision_envelope.json"), &decision)
if decision.Effect != api.DecisionEffectAllow {
t.Errorf("Decision.Effect = %q; want allow", decision.Effect)
}
if decision.Caring == nil || decision.Caring.Profile != api.CaringProfileCaring040RC2 {
t.Fatalf("Decision.Caring = %+v; want CARING profile metadata", decision.Caring)
}
if len(decision.Caring.ConformanceFindings) != 1 {
t.Errorf("ConformanceFindings len = %d; want 1", len(decision.Caring.ConformanceFindings))
}
var audit api.AuditEvent
loadJSON(t, filepath.Join("..", "..", "examples", "caring", "audit_event.json"), &audit)
if audit.DecisionID != decision.ID {
t.Errorf("Audit.DecisionID = %q; want %q", audit.DecisionID, decision.ID)
}
}
func TestSchemaFilesAreJSON(t *testing.T) {
schemaDir := filepath.Join("..", "..", "schemas")
entries, err := os.ReadDir(schemaDir)
if err != nil {
t.Fatalf("read schema dir: %v", err)
}
for _, entry := range entries {
if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" {
continue
}
t.Run(entry.Name(), func(t *testing.T) {
var got map[string]any
loadJSON(t, filepath.Join(schemaDir, entry.Name()), &got)
if got["$schema"] == "" || got["$id"] == "" {
t.Fatalf("%s missing $schema or $id", entry.Name())
}
})
}
}
func loadYAML(t *testing.T, path string, out any) {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read %s: %v", path, err)
}
if err := yaml.Unmarshal(data, out); err != nil {
t.Fatalf("unmarshal %s: %v", path, err)
}
}
func loadJSON(t *testing.T, path string, out any) {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read %s: %v", path, err)
}
if err := json.Unmarshal(data, out); err != nil {
t.Fatalf("unmarshal %s: %v", path, err)
}
}

335
pkg/api/caring.go Normal file
View File

@@ -0,0 +1,335 @@
package api
// CaringProfileCaring040RC2 is the executable profile identifier for the
// CARING 0.4.0-RC2 standard pinned by flex-auth.
const CaringProfileCaring040RC2 = "caring-0.4.0-rc2"
// SubjectType is the CARING subject dimension.
type SubjectType string
const (
SubjectTypeHuman SubjectType = "Human"
SubjectTypeGroup SubjectType = "Group"
SubjectTypeOrganization SubjectType = "Organization"
SubjectTypeService SubjectType = "Service"
SubjectTypeAutomation SubjectType = "Automation"
SubjectTypeAgent SubjectType = "Agent"
SubjectTypeSystem SubjectType = "System"
SubjectTypeDevice SubjectType = "Device"
SubjectTypeProcess SubjectType = "Process"
SubjectTypeAnonymous SubjectType = "Anonymous"
SubjectTypeUnknown SubjectType = "Unknown"
)
// OrganizationRelation is the CARING organization-relation dimension.
type OrganizationRelation string
const (
OrganizationRelationVendor OrganizationRelation = "Vendor"
OrganizationRelationServiceProvider OrganizationRelation = "ServiceProvider"
OrganizationRelationDistributor OrganizationRelation = "Distributor"
OrganizationRelationConsultant OrganizationRelation = "Consultant"
OrganizationRelationCustomer OrganizationRelation = "Customer"
OrganizationRelationCommunity OrganizationRelation = "Community"
OrganizationRelationAuthority OrganizationRelation = "Authority"
OrganizationRelationUnknown OrganizationRelation = "Unknown"
)
// CanonicalRole is the CARING lifecycle responsibility posture.
type CanonicalRole string
const (
CanonicalRoleCreator CanonicalRole = "Creator"
CanonicalRoleBuilder CanonicalRole = "Builder"
CanonicalRoleVerifier CanonicalRole = "Verifier"
CanonicalRoleMaintainer CanonicalRole = "Maintainer"
CanonicalRoleIntegrator CanonicalRole = "Integrator"
CanonicalRoleOperator CanonicalRole = "Operator"
CanonicalRoleManager CanonicalRole = "Manager"
CanonicalRoleCoach CanonicalRole = "Coach"
CanonicalRoleDoer CanonicalRole = "Doer"
)
// ScopeLevel is the CARING scope ladder.
type ScopeLevel string
const (
ScopeLevelEcosystem ScopeLevel = "Ecosystem"
ScopeLevelProduct ScopeLevel = "Product"
ScopeLevelPlatform ScopeLevel = "Platform"
ScopeLevelCluster ScopeLevel = "Cluster"
ScopeLevelEnvironment ScopeLevel = "Environment"
ScopeLevelTenant ScopeLevel = "Tenant"
ScopeLevelNamespace ScopeLevel = "Namespace"
ScopeLevelDomain ScopeLevel = "Domain"
ScopeLevelWorkspace ScopeLevel = "Workspace"
ScopeLevelProject ScopeLevel = "Project"
ScopeLevelProcess ScopeLevel = "Process"
ScopeLevelDataset ScopeLevel = "Dataset"
ScopeLevelResource ScopeLevel = "Resource"
ScopeLevelSubresource ScopeLevel = "Subresource"
ScopeLevelRecord ScopeLevel = "Record"
ScopeLevelField ScopeLevel = "Field"
ScopeLevelAction ScopeLevel = "Action"
)
// Plane is the CARING access-surface dimension.
type Plane string
const (
PlaneIntent Plane = "Intent"
PlaneBuild Plane = "Build"
PlaneRuntime Plane = "Runtime"
PlaneExecution Plane = "Execution"
PlaneConfiguration Plane = "Configuration"
PlaneData Plane = "Data"
PlaneIdentity Plane = "Identity"
PlanePolicy Plane = "Policy"
PlaneSecret Plane = "Secret"
PlaneAudit Plane = "Audit"
PlaneCommercial Plane = "Commercial"
PlaneCommunity Plane = "Community"
)
// Capability is a CARING capability verb.
type Capability string
const (
CapabilityView Capability = "View"
CapabilityViewCollection Capability = "ViewCollection"
CapabilityObserve Capability = "Observe"
CapabilityCreate Capability = "Create"
CapabilityEditOwn Capability = "EditOwn"
CapabilityEditAssigned Capability = "EditAssigned"
CapabilityEditAny Capability = "EditAny"
CapabilityDeleteOwn Capability = "DeleteOwn"
CapabilityDeleteAny Capability = "DeleteAny"
CapabilityBulkDelete Capability = "BulkDelete"
CapabilitySubmit Capability = "Submit"
CapabilityComment Capability = "Comment"
CapabilityReview Capability = "Review"
CapabilityApprove Capability = "Approve"
CapabilityReject Capability = "Reject"
CapabilityPublish Capability = "Publish"
CapabilityArchive Capability = "Archive"
CapabilityRestore Capability = "Restore"
CapabilityExecute Capability = "Execute"
CapabilityConfigure Capability = "Configure"
CapabilityOperate Capability = "Operate"
CapabilityDeploy Capability = "Deploy"
CapabilityIntegrate Capability = "Integrate"
CapabilityGrant Capability = "Grant"
CapabilityRevoke Capability = "Revoke"
CapabilityDelegate Capability = "Delegate"
CapabilityImpersonate Capability = "Impersonate"
CapabilityExport Capability = "Export"
CapabilityImport Capability = "Import"
CapabilityReplicate Capability = "Replicate"
CapabilityEncrypt Capability = "Encrypt"
CapabilityDecrypt Capability = "Decrypt"
CapabilityMask Capability = "Mask"
CapabilityInspect Capability = "Inspect"
CapabilityAudit Capability = "Audit"
CapabilityOverride Capability = "Override"
CapabilityEscalate Capability = "Escalate"
CapabilityBind Capability = "Bind"
CapabilityUse Capability = "Use"
)
// ExposureMode describes how much information becomes visible or extractable.
type ExposureMode string
const (
ExposureModeNone ExposureMode = "None"
ExposureModeMetadata ExposureMode = "Metadata"
ExposureModeMasked ExposureMode = "Masked"
ExposureModeAggregated ExposureMode = "Aggregated"
ExposureModeSynthetic ExposureMode = "Synthetic"
ExposureModePseudonymous ExposureMode = "Pseudonymous"
ExposureModeEncrypted ExposureMode = "Encrypted"
ExposureModePlaintext ExposureMode = "Plaintext"
ExposureModeSecretMaterial ExposureMode = "SecretMaterial"
ExposureModeExportable ExposureMode = "Exportable"
ExposureModeCrossTenantAggregate ExposureMode = "CrossTenantAggregate"
)
// Condition is a CARING runtime or governance condition.
type Condition string
const (
ConditionMFARequired Condition = "MFARequired"
ConditionDeviceTrusted Condition = "DeviceTrusted"
ConditionNetworkTrusted Condition = "NetworkTrusted"
ConditionTicketRequired Condition = "TicketRequired"
ConditionTenantConsentRequired Condition = "TenantConsentRequired"
ConditionCustomerApprovalRequired Condition = "CustomerApprovalRequired"
ConditionDualApprovalRequired Condition = "DualApprovalRequired"
ConditionTimeLimited Condition = "TimeLimited"
ConditionBusinessHoursOnly Condition = "BusinessHoursOnly"
ConditionEmergencyOnly Condition = "EmergencyOnly"
ConditionTrainingRequired Condition = "TrainingRequired"
ConditionContractRequired Condition = "ContractRequired"
ConditionNDARequired Condition = "NDARequired"
ConditionPurposeBound Condition = "PurposeBound"
ConditionCaseBound Condition = "CaseBound"
ConditionEnvironmentBound Condition = "EnvironmentBound"
ConditionNamespaceBound Condition = "NamespaceBound"
ConditionPipelineBound Condition = "PipelineBound"
ConditionChangeWindowBound Condition = "ChangeWindowBound"
ConditionLogged Condition = "Logged"
ConditionRecorded Condition = "Recorded"
ConditionNotificationRequired Condition = "NotificationRequired"
ConditionPostReviewRequired Condition = "PostReviewRequired"
ConditionHumanReviewRequired Condition = "HumanReviewRequired"
ConditionPolicyReviewRequired Condition = "PolicyReviewRequired"
ConditionWorkloadIdentityRequired Condition = "WorkloadIdentityRequired"
)
// LifecycleState describes why access exists now.
type LifecycleState string
const (
LifecycleStateDesign LifecycleState = "Design"
LifecycleStateBuild LifecycleState = "Build"
LifecycleStateTest LifecycleState = "Test"
LifecycleStateReview LifecycleState = "Review"
LifecycleStateRelease LifecycleState = "Release"
LifecycleStateOnboard LifecycleState = "Onboard"
LifecycleStateIntegrate LifecycleState = "Integrate"
LifecycleStateMigrate LifecycleState = "Migrate"
LifecycleStateOperate LifecycleState = "Operate"
LifecycleStateSupport LifecycleState = "Support"
LifecycleStateImprove LifecycleState = "Improve"
LifecycleStateDeprecate LifecycleState = "Deprecate"
LifecycleStateArchive LifecycleState = "Archive"
LifecycleStateIncident LifecycleState = "Incident"
LifecycleStateLegal LifecycleState = "Legal"
LifecycleStateTerminate LifecycleState = "Terminate"
)
// Restriction is an overriding CARING deny or limiting policy effect.
type Restriction string
const (
RestrictionNoAccess Restriction = "NoAccess"
RestrictionSuspended Restriction = "Suspended"
RestrictionTerminated Restriction = "Terminated"
RestrictionQuarantined Restriction = "Quarantined"
RestrictionScopeExcluded Restriction = "ScopeExcluded"
RestrictionDataClassRestricted Restriction = "DataClassRestricted"
RestrictionLegalHold Restriction = "LegalHold"
RestrictionExportBlocked Restriction = "ExportBlocked"
RestrictionImpersonationBlocked Restriction = "ImpersonationBlocked"
RestrictionCrossTenantBlocked Restriction = "CrossTenantBlocked"
RestrictionSecretAccessBlocked Restriction = "SecretAccessBlocked"
RestrictionPolicyFrozen Restriction = "PolicyFrozen"
RestrictionEmergencyLocked Restriction = "EmergencyLocked"
RestrictionRiskDenied Restriction = "RiskDenied"
RestrictionExecutionBlocked Restriction = "ExecutionBlocked"
RestrictionWorkloadCreationBlocked Restriction = "WorkloadCreationBlocked"
RestrictionPrivilegeEscalationBlocked Restriction = "PrivilegeEscalationBlocked"
)
// ExposureEventType is a CARING exceptional or irregular access class.
type ExposureEventType string
const (
ExposureEventSupport ExposureEventType = "X-Support"
ExposureEventBreakGlass ExposureEventType = "X-BreakGlass"
ExposureEventSecurityTest ExposureEventType = "X-SecurityTest"
ExposureEventIncident ExposureEventType = "X-Incident"
ExposureEventLegalDemand ExposureEventType = "X-LegalDemand"
ExposureEventComplianceAudit ExposureEventType = "X-ComplianceAudit"
ExposureEventMigration ExposureEventType = "X-Migration"
ExposureEventRecovery ExposureEventType = "X-Recovery"
ExposureEventAdversarial ExposureEventType = "X-Adversarial"
ExposureEventMisconfiguration ExposureEventType = "X-Misconfiguration"
ExposureEventInducedAccess ExposureEventType = "X-InducedAccess"
ExposureEventPrivilegeEscalation ExposureEventType = "X-PrivilegeEscalation"
)
// AccessPath describes how access is exercised.
type AccessPath string
const (
AccessPathDirect AccessPath = "direct"
AccessPathDelegated AccessPath = "delegated"
AccessPathMediated AccessPath = "mediated"
AccessPathInduced AccessPath = "induced"
)
// CaringScope identifies where a CARING descriptor applies.
type CaringScope struct {
Level ScopeLevel `json:"level" yaml:"level"`
ID string `json:"id" yaml:"id"`
Parent string `json:"parent,omitempty" yaml:"parent,omitempty"`
Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"`
Resource string `json:"resource,omitempty" yaml:"resource,omitempty"`
Attributes map[string]any `json:"attributes,omitempty" yaml:"attributes,omitempty"`
}
// CaringAccessDescriptor is the executable flex-auth representation of a
// CARING access assignment.
type CaringAccessDescriptor struct {
ID string `json:"id,omitempty" yaml:"id,omitempty"`
Profile string `json:"profile" yaml:"profile"`
SubjectType SubjectType `json:"subject_type" yaml:"subject_type"`
OrganizationRelation OrganizationRelation `json:"organization_relation" yaml:"organization_relation"`
CanonicalRole CanonicalRole `json:"canonical_role" yaml:"canonical_role"`
Scope CaringScope `json:"scope" yaml:"scope"`
Planes []Plane `json:"planes" yaml:"planes"`
Capabilities []Capability `json:"capabilities" yaml:"capabilities"`
ExposureModes []ExposureMode `json:"exposure_modes,omitempty" yaml:"exposure_modes,omitempty"`
Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"`
LifecycleState LifecycleState `json:"lifecycle_state,omitempty" yaml:"lifecycle_state,omitempty"`
Restrictions []Restriction `json:"restrictions,omitempty" yaml:"restrictions,omitempty"`
ExposureEvent ExposureEventType `json:"exposure_event,omitempty" yaml:"exposure_event,omitempty"`
DerivedCapabilities []CaringDerivedCapability `json:"derived_capabilities,omitempty" yaml:"derived_capabilities,omitempty"`
AccessPath AccessPath `json:"access_path,omitempty" yaml:"access_path,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// CaringDerivedCapability records effective authority created by another grant.
type CaringDerivedCapability struct {
Capability Capability `json:"capability" yaml:"capability"`
Reason string `json:"reason" yaml:"reason"`
Source string `json:"source,omitempty" yaml:"source,omitempty"`
Planes []Plane `json:"planes,omitempty" yaml:"planes,omitempty"`
ExposureModes []ExposureMode `json:"exposure_modes,omitempty" yaml:"exposure_modes,omitempty"`
}
// CaringConformanceFinding is a diagnostic emitted by descriptive or
// prescriptive CARING validation.
type CaringConformanceFinding struct {
Code string `json:"code" yaml:"code"`
Severity string `json:"severity" yaml:"severity"`
Message string `json:"message" yaml:"message"`
Fields []string `json:"fields,omitempty" yaml:"fields,omitempty"`
Descriptor string `json:"descriptor,omitempty" yaml:"descriptor,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// CaringExposureEvent records exceptional or irregular information exposure.
type CaringExposureEvent struct {
ID string `json:"id" yaml:"id"`
Type ExposureEventType `json:"type" yaml:"type"`
Actor string `json:"actor" yaml:"actor"`
Subject string `json:"subject" yaml:"subject"`
Descriptor *CaringAccessDescriptor `json:"descriptor,omitempty" yaml:"descriptor,omitempty"`
Scope *CaringScope `json:"scope,omitempty" yaml:"scope,omitempty"`
Planes []Plane `json:"planes,omitempty" yaml:"planes,omitempty"`
CapabilitiesUsed []Capability `json:"capabilities_used,omitempty" yaml:"capabilities_used,omitempty"`
DerivedCapabilities []CaringDerivedCapability `json:"derived_capabilities,omitempty" yaml:"derived_capabilities,omitempty"`
ExposureModes []ExposureMode `json:"exposure_modes,omitempty" yaml:"exposure_modes,omitempty"`
Reason string `json:"reason" yaml:"reason"`
AuthoritySource string `json:"authority_source,omitempty" yaml:"authority_source,omitempty"`
Approval string `json:"approval,omitempty" yaml:"approval,omitempty"`
StartTime string `json:"start_time,omitempty" yaml:"start_time,omitempty"`
EndTime string `json:"end_time,omitempty" yaml:"end_time,omitempty"`
ResourcesAccessed []string `json:"resources_accessed,omitempty" yaml:"resources_accessed,omitempty"`
Evidence []string `json:"evidence,omitempty" yaml:"evidence,omitempty"`
NotificationStatus string `json:"notification_status,omitempty" yaml:"notification_status,omitempty"`
PostReview string `json:"post_review,omitempty" yaml:"post_review,omitempty"`
ConformanceFindings []CaringConformanceFinding `json:"conformance_findings,omitempty" yaml:"conformance_findings,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}

View File

@@ -6,23 +6,25 @@ package api
// schemas/resource_manifest.schema.json for the JSON Schema and
// examples/markitect/resource_manifest.yaml for the canonical example.
type ResourceManifest struct {
ID string `json:"id" yaml:"id"`
System string `json:"system" yaml:"system"`
Resources []Resource `json:"resources" yaml:"resources"`
Actions []string `json:"actions,omitempty" yaml:"actions,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
ID string `json:"id" yaml:"id"`
System string `json:"system" yaml:"system"`
Resources []Resource `json:"resources" yaml:"resources"`
Actions []string `json:"actions,omitempty" yaml:"actions,omitempty"`
CaringProfile string `json:"caring_profile,omitempty" yaml:"caring_profile,omitempty"`
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
// Resource is one entry in a ResourceManifest.
type Resource struct {
ID string `json:"id" yaml:"id"`
Type string `json:"type" yaml:"type"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
Parent string `json:"parent,omitempty" yaml:"parent,omitempty"`
Labels []string `json:"labels,omitempty" yaml:"labels,omitempty"`
TrustZone string `json:"trust_zone,omitempty" yaml:"trust_zone,omitempty"`
Owner string `json:"owner,omitempty" yaml:"owner,omitempty"`
Attributes map[string]any `json:"attributes,omitempty" yaml:"attributes,omitempty"`
ID string `json:"id" yaml:"id"`
Type string `json:"type" yaml:"type"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
Parent string `json:"parent,omitempty" yaml:"parent,omitempty"`
Labels []string `json:"labels,omitempty" yaml:"labels,omitempty"`
TrustZone string `json:"trust_zone,omitempty" yaml:"trust_zone,omitempty"`
Owner string `json:"owner,omitempty" yaml:"owner,omitempty"`
Caring *CaringAccessDescriptor `json:"caring,omitempty" yaml:"caring,omitempty"`
Attributes map[string]any `json:"attributes,omitempty" yaml:"attributes,omitempty"`
}
// FlexAuthContractV0 is the metadata.flex_auth_contract value that