Add Markitect check fixtures
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 06:32:05 +02:00
parent 96e53bf1d9
commit 7e09a21c5f
5 changed files with 457 additions and 4 deletions

View File

@@ -0,0 +1,239 @@
- id: fixture:markitect-public-document-allow
request:
id: check:markitect-public-document
subject:
id: user:visitor
type: Human
tenant: tenant:alpha
action: read
resource:
id: document:public-note
type: document
system: markitect-tool
tenant: tenant:alpha
attributes:
labels:
- public
trust_zone: public
caring_context:
id: descriptor:public-document-reader
profile: caring-0.4.0-rc2
subject_type: Human
organization_relation: Customer
canonical_role: Doer
scope:
level: Resource
id: document:public-note
tenant: tenant:alpha
planes:
- Data
capabilities:
- View
exposure_modes:
- Plaintext
conditions:
- Logged
expect:
effect: allow
reason: public_document
metadata:
expected_caring_descriptor: descriptor:public-document-reader
expected_conformance_findings: []
expected_exposure_modes:
- Plaintext
expected_audit_behavior: sampled_allow
- id: fixture:markitect-internal-document-deny
request:
id: check:markitect-internal-document-deny
subject:
id: user:visitor
type: Human
tenant: tenant:alpha
attributes:
groups: []
action: read
resource:
id: document:internal-note
type: document
system: markitect-tool
tenant: tenant:alpha
attributes:
labels:
- internal
trust_zone: internal
expect:
effect: deny
reason: no_matching_rule
metadata:
expected_caring_descriptor: null
expected_conformance_findings: []
expected_exposure_modes:
- None
expected_audit_behavior: always_record
- id: fixture:markitect-internal-document-reader-allow
request:
id: check:markitect-internal-document-reader
subject:
id: user:alice
type: Human
tenant: tenant:alpha
attributes:
groups:
- group:platform-architecture
action: read
resource:
id: document:internal-note
type: document
system: markitect-tool
tenant: tenant:alpha
attributes:
labels:
- internal
trust_zone: internal
caring_context:
id: descriptor:internal-document-reader
profile: caring-0.4.0-rc2
subject_type: Human
organization_relation: Customer
canonical_role: Doer
scope:
level: Resource
id: document:internal-note
tenant: tenant:alpha
planes:
- Data
capabilities:
- View
exposure_modes:
- Masked
- Plaintext
conditions:
- Logged
restrictions:
- ExportBlocked
expect:
effect: allow
reason: reader_group
metadata:
expected_caring_descriptor: descriptor:internal-document-reader
expected_conformance_findings: []
expected_exposure_modes:
- Masked
- Plaintext
expected_audit_behavior: sampled_allow
- id: fixture:markitect-restricted-export-steward-mfa
request:
id: check:markitect-restricted-export
subject:
id: user:steward
type: Human
tenant: tenant:alpha
attributes:
roles:
- steward
action: export
resource:
id: export:internal-note-review-bundle
type: export
system: markitect-tool
tenant: tenant:alpha
attributes:
labels:
- export
trust_zone: external
context:
mfa: true
reason: customer-approved export
caring_context:
id: descriptor:restricted-export-steward
profile: caring-0.4.0-rc2
subject_type: Human
organization_relation: Customer
canonical_role: Maintainer
scope:
level: Record
id: export:internal-note-review-bundle
tenant: tenant:alpha
planes:
- Data
- Audit
capabilities:
- Export
exposure_modes:
- Exportable
- Plaintext
conditions:
- MFARequired
- Logged
expect:
effect: allow
reason: steward_export_mfa
conformance_findings:
- code: MARKITECT-EXPORT-MFA-LOGGED
severity: info
message: Export is allowed only with steward role, MFA, and logging.
metadata:
expected_caring_descriptor: descriptor:restricted-export-steward
expected_exposure_modes:
- Exportable
- Plaintext
expected_audit_behavior: always_record
- id: fixture:markitect-context-package-activation
request:
id: check:markitect-context-package-activation
subject:
id: user:alice
type: Human
tenant: tenant:alpha
action: activate_context
resource:
id: context-package:internal-note-review
type: context_package
system: markitect-tool
tenant: tenant:alpha
attributes:
labels:
- internal
- generated
context:
freshness_seconds: 600
policy_version: markitect-gateway-v1
caring_context:
id: descriptor:context-package-activation
profile: caring-0.4.0-rc2
subject_type: Human
organization_relation: Customer
canonical_role: Verifier
scope:
level: Dataset
id: context-package:internal-note-review
tenant: tenant:alpha
planes:
- Intent
- Policy
capabilities:
- Use
- Execute
exposure_modes:
- Metadata
- Masked
conditions:
- PurposeBound
- Logged
expect:
effect: allow
reason: fresh_context_package
obligations:
- type: record_context_activation
parameters:
freshness_seconds: 600
conformance_findings:
- code: MARKITECT-CONTEXT-FRESHNESS
severity: info
message: Context package activation includes policy version and freshness metadata.
metadata:
expected_caring_descriptor: descriptor:context-package-activation
expected_exposure_modes:
- Metadata
- Masked
expected_audit_behavior: always_record

View File

@@ -0,0 +1,152 @@
---
id: markitect.gateway.check-fixtures
name: Markitect gateway check fixtures
namespace: markitect:gateway
version: v1
status: draft
package: flexauth.markitect.gateway
actions:
- read
- export
- activate_context
owner: team:platform-architecture
fixtures:
- check_fixtures.yaml
caring:
profile: caring-0.4.0-rc2
enforce: false
canonical_roles:
- Doer
- Maintainer
- Verifier
organization_relations:
- Customer
scopes:
- level: Resource
id: document:public-note
tenant: tenant:alpha
- level: Resource
id: document:internal-note
tenant: tenant:alpha
- level: Dataset
id: context-package:internal-note-review
tenant: tenant:alpha
planes:
- Intent
- Data
- Audit
capabilities:
- View
- Export
- Use
- Execute
exposure_modes:
- Metadata
- Masked
- Plaintext
- Exportable
conditions:
- MFARequired
- PurposeBound
- Logged
restrictions:
- ExportBlocked
metadata:
source: examples/markitect/check_policy_package.md
---
# Markitect Gateway Check Fixtures
This package captures the first Markitect gateway scenarios as executable Rego
and external fixtures.
## Rules
```rego
import future.keywords.if
import future.keywords.in
default decision := {"effect": "deny", "reason": "no_matching_rule"}
decision := {"effect": "allow", "reason": "public_document"} if {
input.action == "read"
input.resource.type == "document"
"public" in object.get(input.resource.attributes, "labels", [])
}
decision := {"effect": "allow", "reason": "reader_group"} if {
input.action == "read"
input.resource.type == "document"
"internal" in object.get(input.resource.attributes, "labels", [])
"group:platform-architecture" in object.get(input.subject.attributes, "groups", [])
"View" in input.caring_context.capabilities
}
decision := {
"effect": "allow",
"reason": "steward_export_mfa",
"conformance_findings": [{
"code": "MARKITECT-EXPORT-MFA-LOGGED",
"severity": "info",
"message": "Export is allowed only with steward role, MFA, and logging."
}]
} if {
input.action == "export"
"steward" in object.get(input.subject.attributes, "roles", [])
input.context.mfa == true
"Export" in input.caring_context.capabilities
"Exportable" in input.caring_context.exposure_modes
}
decision := {
"effect": "allow",
"reason": "fresh_context_package",
"obligations": [{
"type": "record_context_activation",
"parameters": {"freshness_seconds": input.context.freshness_seconds}
}],
"conformance_findings": [{
"code": "MARKITECT-CONTEXT-FRESHNESS",
"severity": "info",
"message": "Context package activation includes policy version and freshness metadata."
}]
} if {
input.action == "activate_context"
input.resource.type == "context_package"
input.policy_version != ""
input.context.freshness_seconds <= 900
"Use" in input.caring_context.capabilities
"Execute" in input.caring_context.capabilities
}
```
## Tests
```rego test
package flexauth.markitect.gateway_test
import future.keywords.if
import data.flexauth.markitect.gateway
test_public_document_allows if {
gateway.decision.effect == "allow" with input as {
"action": "read",
"resource": {
"type": "document",
"attributes": {"labels": ["public"]}
}
}
}
test_export_requires_mfa if {
gateway.decision.effect == "deny" with input as {
"action": "export",
"subject": {"attributes": {"roles": ["steward"]}},
"context": {"mfa": false},
"caring_context": {
"capabilities": ["Export"],
"exposure_modes": ["Exportable"]
}
}
}
```

View File

@@ -0,0 +1,57 @@
package markitect_test
import (
"context"
"path/filepath"
"testing"
"github.com/netkingdom/flex-auth/internal/policy"
"github.com/netkingdom/flex-auth/pkg/api"
)
func TestMarkitectCheckFixturePackageValidates(t *testing.T) {
pkg, err := policy.LoadAndValidateFile(context.Background(), filepath.Join("..", "..", "examples", "markitect", "check_policy_package.md"))
if err != nil {
t.Fatalf("LoadAndValidateFile: %v", err)
}
if !pkg.Valid {
t.Fatalf("pkg.Valid = false: %+v", pkg.Validation)
}
if len(pkg.Fixtures) != 5 {
t.Fatalf("Fixtures len = %d; want 5", len(pkg.Fixtures))
}
wantEffects := map[string]api.DecisionEffect{
"fixture:markitect-public-document-allow": api.DecisionEffectAllow,
"fixture:markitect-internal-document-deny": api.DecisionEffectDeny,
"fixture:markitect-internal-document-reader-allow": api.DecisionEffectAllow,
"fixture:markitect-restricted-export-steward-mfa": api.DecisionEffectAllow,
"fixture:markitect-context-package-activation": api.DecisionEffectAllow,
}
for _, fixture := range pkg.Fixtures {
if fixture.Expect.Effect != wantEffects[fixture.ID] {
t.Fatalf("%s effect = %q; want %q", fixture.ID, fixture.Expect.Effect, wantEffects[fixture.ID])
}
assertFixtureMetadata(t, fixture)
}
for _, result := range pkg.Validation.Fixtures {
if !result.Passed {
t.Fatalf("fixture %s failed: %s actual=%+v", result.ID, result.Error, result.Actual)
}
}
}
func assertFixtureMetadata(t *testing.T, fixture api.PolicyFixture) {
t.Helper()
if _, ok := fixture.Metadata["expected_caring_descriptor"]; !ok {
t.Fatalf("%s missing expected_caring_descriptor metadata", fixture.ID)
}
if _, ok := fixture.Metadata["expected_exposure_modes"]; !ok {
t.Fatalf("%s missing expected_exposure_modes metadata", fixture.ID)
}
if _, ok := fixture.Metadata["expected_audit_behavior"]; !ok {
t.Fatalf("%s missing expected_audit_behavior metadata", fixture.ID)
}
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"os"
"path/filepath"
"reflect"
"sort"
"strings"
@@ -413,15 +412,21 @@ func expectationMatches(expected, actual api.DecisionExpectation) bool {
if expected.Reason != "" && expected.Reason != actual.Reason {
return false
}
if len(expected.Obligations) > 0 && !reflect.DeepEqual(expected.Obligations, actual.Obligations) {
if len(expected.Obligations) > 0 && !jsonEqual(expected.Obligations, actual.Obligations) {
return false
}
if len(expected.ConformanceFindings) > 0 && !reflect.DeepEqual(expected.ConformanceFindings, actual.ConformanceFindings) {
if len(expected.ConformanceFindings) > 0 && !jsonEqual(expected.ConformanceFindings, actual.ConformanceFindings) {
return false
}
return true
}
func jsonEqual(left, right any) bool {
leftData, leftErr := json.Marshal(left)
rightData, rightErr := json.Marshal(right)
return leftErr == nil && rightErr == nil && string(leftData) == string(rightData)
}
func toRegoInput(value any) (map[string]any, error) {
data, err := json.Marshal(value)
if err != nil {

View File

@@ -103,7 +103,7 @@ metadata-only exposure explicit.
```task
id: FLEX-WP-0003-T004
status: todo
status: done
priority: high
state_hub_task_id: "1d5de3b2-c581-4ca3-9107-93211eb02c6b"
```