generated from coulomb/repo-seed
Implement canonical schema foundation
This commit is contained in:
249
pkg/api/canonical.go
Normal file
249
pkg/api/canonical.go
Normal 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
130
pkg/api/canonical_test.go
Normal 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
335
pkg/api/caring.go
Normal 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"`
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user