A lightweight, explainable authorization policy engine for MoonBit.
///|
test {
let policy = @moon_policy.Policy(
role_permissions={ "editor": ["document:read"] },
bindings=[RoleBinding(subject="alice", role="editor")],
)
let decision = policy.authorize(
Request(subject="alice", action="document:read", resource="document:42"),
)
assert_true(decision.allowed)
}moon run --target native cmd/main -- demo
moon run --target native cmd/main -- check '{"rules":[]}'
moon run --target native cmd/main -- lint '{"rules":[]}'
moon run --target native cmd/main -- eval '{"rules":[]}' '{"subject":"alice","action":"read","resource":"doc:1"}'
moon run --target native cmd/main -- explain '{"rules":[]}' '{"subject":"alice","action":"read","resource":"doc:1"}'
moon run --target native cmd/main -- diff '{"rules":[]}' '{"rules":[]}' '[{"subject":"alice","action":"read","resource":"doc:1"}]'
moon run --target native cmd/main -- verify '{"rules":[]}' '[{"name":"deny unknown","request":{"subject":"alice","action":"read","resource":"doc:1"},"expected_allowed":false}]'
moon run --target native cmd/main -- coverage '{"rules":[]}' '[{"subject":"alice","action":"read","resource":"doc:1"}]'
moon run --target native cmd/main -- batch '{"rules":[]}' '[{"subject":"alice","action":"read","resource":"doc:1"}]'moon fmt --check
moon info
moon check --target all
moon build --target all
moon test --target all///|
test {
let policy = policy_from_json(
(
#|{
#| "roles": { "viewer": ["document:read"] },
#| "bindings": [{ "subject": "bob", "role": "viewer" }]
#|}
),
)
let decision = policy.authorize(
Request(subject="bob", action="document:read", resource="document:1"),
)
assert_true(decision.allowed)
}pub(all) enum AttributeValue {
StringValue(String)
StringListValue(Array[String])
ObjectValue(Map[String, AttributeValue])
BoolValue(Bool)
IntValue(Int)
} derive(Eq, Debug)pub(all) enum Condition {
Always
Exists(String)
Equals(path~ : String, value~ : AttributeValue)
Same(left~ : String, right~ : String)
OneOf(path~ : String, values~ : Array[AttributeValue])
Contains(path~ : String, value~ : String)
StringMatches(path~ : String, matcher~ : Matcher)
ContainsAny(path~ : String, values~ : Array[String])
ContainsAll(path~ : String, values~ : Array[String])
Compare(path~ : String, op~ : Comparison, value~ : Int)
AllOf(Array[Condition])
AnyOf(Array[Condition])
Not(Condition)
} derive(Eq, Debug)pub(all) struct Decision {
allowed : Bool
reason : DecisionReason
trace : Array[String]
} derive(Eq, Debug)pub(all) struct EvaluationReport {
decision : Decision
rules : Array[RuleEvaluation]
} derive(Eq, Debug)fn PolicyCase::PolicyCase(name~ : String, request~ : Request, expected_allowed~ : Bool) -> PolicyCasepub(all) struct PolicyCoverage {
total_requests : Int
allowed : Int
explicit_denies : Int
default_denies : Int
rules : Array[RuleCoverage]
} derive(Eq, Debug)pub(all) struct PolicySuiteResult {
results : Array[PolicyCaseResult]
passed : Int
failed : Int
} derive(Eq, Debug)pub(all) struct Request {
subject : String
action : String
resource : String
subject_attributes : Map[String, AttributeValue]
resource_attributes : Map[String, AttributeValue]
context : Map[String, AttributeValue]
} derive(Eq, Debug)fn Request::Request(subject~ : String, action~ : String, resource~ : String, subject_attributes? : Map[String, AttributeValue], resource_attributes? : Map[String, AttributeValue], context? : Map[String, AttributeValue]) -> Requestpub(all) struct RuleEvaluation {
id : String
effect : Effect
subject_matches : Bool
action_matches : Bool
resource_matches : Bool
condition_status : ConditionStatus
applied : Bool
} derive(Eq, Debug)fn glob_matches(pattern : String, value : String) -> BoolInstall
Download zipA lightweight, explainable authorization policy engine for MoonBit.