๐ŸŽฏ

rust-xacml

๐ŸŽฏSkill

from huiali/rust-skills

VibeIndex|
What it does

Implements a flexible Rust-based policy decision engine for XACML authorization, supporting RBAC, policy chaining, and context-based access control.

๐Ÿ“ฆ

Part of

huiali/rust-skills(30 items)

rust-xacml

Installation

๐Ÿ“‹ No install commands found in docs. Showing default command. Check GitHub for actual instructions.
Quick InstallInstall with npx
npx skills add huiali/rust-skills --skill rust-xacml
2Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

"็ญ–็•ฅๅผ•ๆ“Žใ€ๆƒ้™ๅ†ณ็ญ–ใ€RBACใ€็ญ–็•ฅๆจกๅผใ€่ดฃไปป้“พ"

Overview

# Rust XACML - ็ญ–็•ฅๅผ•ๆ“ŽๆŠ€่ƒฝ

> ๆœฌๆŠ€่ƒฝๆไพ›็ญ–็•ฅๅ†ณ็ญ–ๅผ•ๆ“Ž็š„้€š็”จ่งฃๅ†ณๆ–นๆกˆ๏ผŒๅŒ…ๆ‹ฌ RBACใ€่ดฃไปป้“พใ€็ญ–็•ฅๆจกๅผ็ญ‰ใ€‚

ๆ ธๅฟƒๆฆ‚ๅฟต

1. ็ญ–็•ฅๅผ•ๆ“Žๆžถๆž„

```

็ญ–็•ฅๅ†ณ็ญ–ๆต็จ‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ ่ฏทๆฑ‚ไธŠไธ‹ๆ–‡ โ”‚

โ”‚ (ไธปไฝ“ใ€่ต„ๆบใ€ๆ“ไฝœใ€็Žฏๅขƒ) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ ็ญ–็•ฅๅ†ณ็ญ–็‚น (PDP) โ”‚

โ”‚ โ”œโ”€โ”€ ็ญ–็•ฅๅŠ ่ฝฝ โ”‚

โ”‚ โ”œโ”€โ”€ ็ญ–็•ฅ่ฏ„ไผฐ โ”‚

โ”‚ โ””โ”€โ”€ ๅ†ณ็ญ–็ป„ๅˆ โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ ๅ†ณ็ญ–็ป“ๆžœ โ”‚

โ”‚ (Permit / Deny / NotApplicable / Indeterminate) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

```

2. ๅ†ณ็ญ–็ฑปๅž‹

| ็ป“ๆžœ | ๅซไน‰ | ๅค„็† |

|-----|------|-----|

| Permit | ๅ…่ฎธ่ฎฟ้—ฎ | ๆ‰ง่กŒๆ“ไฝœ |

| Deny | ๆ‹’็ป่ฎฟ้—ฎ | ่ฟ”ๅ›ž 403 |

| NotApplicable | ๆ— ๅŒน้…็ญ–็•ฅ | ไฝฟ็”จ้ป˜่ฎค่ง„ๅˆ™ |

| Indeterminate | ่ฏ„ไผฐ้”™่ฏฏ | ่ฟ”ๅ›ž 500 |

---

ๆ ธๅฟƒๆจกๅผ

1. ็ญ–็•ฅ่ฏ„ไผฐๅ™จ

```rust

//! ็ญ–็•ฅ่ฏ„ไผฐๅ™จ

use serde::{Deserialize, Serialize};

use std::collections::HashMap;

/// ่ฏทๆฑ‚ไธŠไธ‹ๆ–‡

#[derive(Debug, Clone, Serialize, Deserialize)]

pub struct RequestContext {

pub subject: Subject, // ไธปไฝ“

pub resource: Resource, // ่ต„ๆบ

pub action: String, // ๆ“ไฝœ

pub environment: HashMap, // ็Žฏๅขƒ

}

/// ไธปไฝ“

#[derive(Debug, Clone, Serialize, Deserialize)]

pub struct Subject {

pub id: String,

pub roles: Vec,

pub attributes: HashMap,

}

/// ่ต„ๆบ

#[derive(Debug, Clone, Serialize, Deserialize)]

pub struct Resource {

pub id: String,

pub r#type: String,

pub attributes: HashMap,

}

/// ๅ†ณ็ญ–็ป“ๆžœ

#[derive(Debug, Clone, PartialEq)]

pub enum Decision {

Permit,

Deny,

NotApplicable,

Indeterminate(String),

}

/// ็ญ–็•ฅๅฎšไน‰

#[derive(Debug, Clone)]

pub struct Policy {

pub id: String,

pub target: PolicyTarget,

pub rules: Vec,

pub combining_algorithm: CombiningAlgorithm,

}

/// ็ญ–็•ฅ็›ฎๆ ‡๏ผˆๅŒน้…ๆกไปถ๏ผ‰

#[)]

pub struct PolicyTarget {

pubderive(Debug, Clone subjects: Vec>, // ่ง’่‰ฒ็ป„ๅˆ

pub resources: Vec,

pub actions: Vec,

}

/// ่ฎฟ้—ฎ่ง„ๅˆ™

#[derive(Debug, Clone)]

pub struct Rule {

pub id: String,

pub effect: RuleEffect,

pub condition: Option bool + Send>>,

}

#[derive(Debug, Clone, Copy)]

pub enum RuleEffect {

Permit,

Deny,

}

/// ็ญ–็•ฅ็ป„ๅˆ็ฎ—ๆณ•

#[derive(Debug, Clone, Copy)]

pub enum CombiningAlgorithm {

DenyOverrides, // Deny ไผ˜ๅ…ˆ

PermitOverrides, // Permit ไผ˜ๅ…ˆ

FirstApplicable, // ้ฆ–ไธช้€‚็”จ

OnlyOneApplicable, // ไป…ไธ€ไธช้€‚็”จ

}

/// ็ญ–็•ฅ่ฏ„ไผฐๅ™จ

pub struct PolicyEvaluator {

policies: Vec,

}

impl PolicyEvaluator {

pub fn new(policies: Vec) -> Self {

Self { policies }

}

/// ่ฏ„ไผฐ่ฏทๆฑ‚

pub fn evaluate(&self, context: &RequestContext) -> Decision {

let mut applicable_policies: Vec<&Policy> = self.policies

.iter()

.filter(|p| self.is_target_matched(p, context))

.collect();

if applicable_policies.is_empty() {

return Decision::NotApplicable;

}

// ๆ นๆฎ็ป„ๅˆ็ฎ—ๆณ•่ฎก็ฎ—ๆœ€็ปˆๅ†ณ็ญ–

match applicable_policies.first().map(|p| p.combining_algorithm).unwrap_or(CombiningAlgorithm::FirstApplicable) {

CombiningAlgorithm::DenyOverrides => self.deny_overrides(&applicable_policies, context),

CombiningAlgorithm::PermitOverrides => self.permit_overrides(&applicable_policies, context),

CombiningAlgorithm::FirstApplicable => self.first_applicable(&applicable_policies, context),

CombiningAlgorithm::OnlyOneApplicable => {

if applicable_policies.len() == 1 {

self.evaluate_policy(applicable_policies[0], context)

} else {

Decision::Indeterminate("Multiple applicable policies".to_string())

}

}

}

}

fn is_target_matched(&self, policy: &Policy, context: &RequestContext) -> bool {

// ๆฃ€ๆŸฅ Subjects

let subject_matches = policy.target.subjects.is_empty() ||

policy.target.subjects.iter().any(|roles| {

roles.iter().all(|r| context.subject.roles.contains(r))

});

// ๆฃ€ๆŸฅ Resources

let resource_matches = policy.target.resources.is_empty() ||

policy.target.resources.contains(&context.resource.r#type);

// ๆฃ€ๆŸฅ Actions

let action_matches = policy.target.actions.is_empty() ||

policy.target.actions.contains(&context.action);

subject_matches && resource_matches && action_matches

}

fn deny_overrides(&self, policies: &[&Policy], context: &RequestContext) -> Decision {

let mut has_error = false;

let mut error_msg = String::new();

for policy in policies {

match self.evaluate_policy(policy, context) {

Decision::Deny => return Decision::Deny,

Decision::Indeterminate(msg) => {

has_error = true;

error_msg = msg;

}

_ => {}

}

}

if has_error {

Decision::Indeterminate(error_msg)

} else {

Decision::Permit

}

}

fn permit_overrides(&self, policies: &[&Policy], context: &RequestContext) -> Decision {

let mut has_error = false;

let mut error_msg = String::new();

for policy in policies {

match self.evaluate_policy(policy, context) {

Decision::Permit => return Decision::Permit,

Decision::Indeterminate(msg) => {

has_error = true;

error_msg = msg;

}

_ => {}

}

}

if has_error {

Decision::Indeterminate(error_msg)

} else {

Decision::Deny

}

}

fn first_applicable(&self, policies: &[&Policy], context: &RequestContext) -> Decision {

for policy in policies {

let decision = self.evaluate_policy(policy, context);

if decision != Decision::NotApplicable {

return decision;

}

}

Decision::Deny

}

fn evaluate_policy(&self, policy: &Policy, context: &RequestContext) -> Decision {

for rule in &policy.rules {

if let Some(ref condition) = rule.condition {

if !condition(context) {

continue;

}

}

return match rule.effect {

RuleEffect::Permit => Decision::Permit,

RuleEffect::Deny => Decision::Deny,

};

}

Decision::NotApplicable

}

}

```

2. RBAC ๆƒ้™ๆฃ€ๆŸฅ

```rust

//! RBAC ๆƒ้™ๆฃ€ๆŸฅ

use std::collections::HashMap;

/// RBAC ้…็ฝฎ

#[derive(Debug, Clone)]

pub struct RbacConfig {

/// ่ง’่‰ฒๅฑ‚็บง

pub role_hierarchy: HashMap>,

/// ่ง’่‰ฒๆƒ้™ๆ˜ ๅฐ„

pub role_permissions: HashMap>,

/// ๆƒ้™ๅฎšไน‰

pub permissions: HashMap,

}

/// ๆƒ้™ๅฎšไน‰

#[derive(Debug, Clone)]

pub struct PermissionDef {

pub resource: String,

pub actions: Vec,

}

/// RBAC ๆฃ€ๆŸฅๅ™จ

pub struct RbacChecker {

config: RbacConfig,

}

impl RbacChecker {

pub fn new(config: RbacConfig) -> Self {

Self { config }

}

/// ๆฃ€ๆŸฅ็”จๆˆทๆ˜ฏๅฆๆœ‰ๆƒ้™

pub fn check_permission(

&self,

user_roles: &[String],

resource: &str,

action: &str,

) -> bool {

// ่Žทๅ–ๆ‰€ๆœ‰็ปงๆ‰ฟ็š„่ง’่‰ฒ

let all_roles = self.expand_roles(user_roles);

// ๆฃ€ๆŸฅๆ˜ฏๅฆๆœ‰ๆƒ้™

for role in &all_roles {

if let Some(perms) = self.config.role_permissions.get(role) {

for perm_id in perms {

if let Some(perm) = self.config.permissions.get(perm_id) {

if perm.resource == resource && perm.actions.contains(&action) {

return true;

}

}

}

}

}

false

}

/// ๅฑ•ๅผ€่ง’่‰ฒๅฑ‚็บง

fn expand_roles(&self, roles: &[String]) -> Vec {

let mut expanded = Vec::new();

let mut visited = std::collections::HashSet::new();

let mut queue = Vec::new();

for role in roles {

if !visited.contains(role) {

queue.push(role.clone());

visited.insert(role.clone());

}

}

while let Some(role) = queue.pop() {

expanded.push(role.clone());

if let Some(parents) = self.config.role_hierarchy.get(&role) {

for parent in parents {

if !visited.contains(parent) {

visited.insert(parent.clone());

queue.push(parent.clone());

}

}

}

}

expanded

}

/// ่Žทๅ–็”จๆˆท็š„ๆ‰€ๆœ‰ๆƒ้™

pub fn get_user_permissions(&self, user_roles: &[String]) -> Vec {

let all_roles = self.expand_roles(user_roles);

let mut permissions = std::collections::HashSet::new();

for role in &all_roles {

if let Some(role_perms) = self.config.role_permissions.get(role) {

for perm in role_perms {

permissions.insert(perm.clone());

}

}

}

permissions.into_iter().collect()

}

}

```

3. ็ญ–็•ฅ็ผ“ๅญ˜

```rust

//! ็ญ–็•ฅ็ผ“ๅญ˜

use crate::{Policy, PolicyEvaluator};

use std::sync::Arc;

use tokio::sync::RwLock;

use std::time::{Duration, Instant};

/// ็ผ“ๅญ˜้…็ฝฎ

#[derive(Debug, Clone)]

pub struct PolicyCacheConfig {

pub ttl: Duration,

pub max_size: usize,

}

/// ็ผ“ๅญ˜ๆก็›ฎ

struct CacheEntry {

policy: Policy,

inserted_at: Instant,

}

/// ็ญ–็•ฅ็ผ“ๅญ˜

pub struct PolicyCache {

config: PolicyCacheConfig,

cache: Arc>>,

}

impl PolicyCache {

pub fn new(config: PolicyCacheConfig) -> Self {

Self {

config,

cache: Arc::new(RwLock::new(HashMap::new())),

}

}

/// ่Žทๅ–็ญ–็•ฅ

pub async fn get(&self, policy_id: &str) -> Option {

let cache = self.cache.read().await;

cache.get(policy_id).map(|entry| entry.policy.clone())

}

/// ๅญ˜ๅ‚จ็ญ–็•ฅ

pub async fn set(&self, policy: Policy) {

let mut cache = self.cache.write().await;

// ๆธ…็†่ฟ‡ๆœŸๆก็›ฎ

let now = Instant::now();

cache.retain(|_, v| now.duration_since(v.inserted_at) < self.config.ttl);

// ๆธ…็†่ถ…ๅ‡บๅคงๅฐ็š„ๆก็›ฎ

if cache.len() >= self.config.max_size {

let to_remove = cache.len() - self.config.max_size + 1;

let keys: Vec = cache.keys().take(to_remove).cloned().collect();

for key in keys {

cache.remove(&key);

}

}

cache.insert(policy.id.clone(), CacheEntry {

policy,

inserted_at: Instant::now(),

});

}

/// ๅคฑๆ•ˆ็ญ–็•ฅ

pub async fn invalidate(&self, policy_id: &str) {

let mut cache = self.cache.write().await;

cache.remove(policy_id);

}

/// ๆธ…็†ๆ‰€ๆœ‰

pub async fn clear(&self) {

let mut cache = self.cache.write().await;

cache.clear();

}

}

```

---

ๆœ€ไฝณๅฎž่ทต

1. ็ญ–็•ฅๅฎšไน‰ DSL

```rust

//! ็ญ–็•ฅๆž„ๅปบๅ™จ

use crate::{Policy, PolicyTarget, Rule, RuleEffect, CombiningAlgorithm};

/// ็ญ–็•ฅๆž„ๅปบๅ™จ

pub struct PolicyBuilder {

policy: Policy,

}

impl PolicyBuilder {

pub fn new(id: &str) -> Self {

Self {

policy: Policy {

id: id.to_string(),

target: PolicyTarget {

subjects: Vec::new(),

resources: Vec::new(),

actions: Vec::new(),

},

rules: Vec::new(),

combining_algorithm: CombiningAlgorithm::DenyOverrides,

},

}

}

pub fn with_subject_roles(mut self, roles: &[&str]) -> Self {

self.policy.target.subjects = vec![roles.iter().map(|s| s.to_string()).collect()];

self

}

pub fn with_resource(mut self, resource: &str) -> Self {

self.policy.target.resources = vec![resource.to_string()];

self

}

pub fn with_action(mut self, action: &str) -> Self {

self.policy.target.actions = vec![action.to_string()];

self

}

pub fn add_rule(

mut self,

id: &str,

effect: RuleEffect,

condition: impl Fn(&crate::RequestContext) -> bool + Send + 'static,

) -> Self {

self.policy.rules.push(Rule {

id: id.to_string(),

effect,

condition: Some(Box::new(condition)),

});

self

}

pub fn with_combining_algorithm(mut self, algo: CombiningAlgorithm) -> Self {

self.policy.combining_algorithm = algo;

self

}

pub fn build(self) -> Policy {

self.policy

}

}

/// ไฝฟ็”จ็คบไพ‹

fn example_policy() -> Policy {

PolicyBuilder::new("read-policy")

.with_subject_roles(&["user", "admin"])

.with_resource("document")

.with_action("read")

.add_rule("own-document", RuleEffect::Permit, |ctx| {

// ่‡ชๅทฑๅˆ›ๅปบ็š„ๆ–‡ๆกฃๅฏไปฅ่ฏปๅ–

ctx.resource.attributes.get("owner") == Some(&ctx.subject.id)

})

.add_rule("public-document", RuleEffect::Permit, |ctx| {

// ๅ…ฌๅผ€ๆ–‡ๆกฃๅฏไปฅ่ฏปๅ–

ctx.resource.attributes.get("visibility") == Some(&"public".to_string())

})

.with_combining_algorithm(CombiningAlgorithm::DenyOverrides)

.build()

}

```

---

ๅธธ่ง้—ฎ้ข˜

| ้—ฎ้ข˜ | ๅŽŸๅ›  | ่งฃๅ†ณๆ–นๆกˆ |

|-----|------|---------|

| ๅ†ณ็ญ–ไธไธ€่‡ด | ็ป„ๅˆ็ฎ—ๆณ•้€‰ๆ‹ฉไธๅฝ“ | ๆ นๆฎไธšๅŠก้€‰ๆ‹ฉๅˆ้€‚็š„็ฎ—ๆณ• |

| ๆ€ง่ƒฝๅทฎ | ็ญ–็•ฅ่ฟ‡ๅคš | ไฝฟ็”จ็ผ“ๅญ˜ๅ’Œ็ดขๅผ• |

| ๆƒ้™็ป•่ฟ‡ | ่ง„ๅˆ™้กบๅบ้—ฎ้ข˜ | DenyOverrides ไผ˜ๅ…ˆ |

---

ๅ…ณ่”ๆŠ€่ƒฝ

  • rust-auth - ่ฎค่ฏๆŽˆๆƒ
  • rust-web - Web ้›†ๆˆ
  • rust-cache - ็ญ–็•ฅ็ผ“ๅญ˜
  • rust-performance - ๆ€ง่ƒฝไผ˜ๅŒ–

More from this repository10

๐ŸŽฏ
rust-skill๐ŸŽฏSkill

Provides expert Rust programming assistance, solving compilation errors, ownership, lifetimes, concurrency, and performance optimization challenges.

๐ŸŽฏ
rust-skill-index๐ŸŽฏSkill

Indexes and provides quick navigation for 35 Rust skills across core, advanced, and expert categories.

๐ŸŽฏ
rust-error๐ŸŽฏSkill

Expertly handles Rust error scenarios by providing comprehensive guidance on Result, Option, error types, propagation, and panic strategies.

๐ŸŽฏ
rust-async๐ŸŽฏSkill

Handles advanced Rust async patterns like Stream processing, backpressure, select, cancellation, and concurrency management with Tokio.

๐ŸŽฏ
rust-concurrency๐ŸŽฏSkill

Expertly handles Rust concurrency challenges by safely managing threads, async operations, and preventing race conditions and deadlocks.

๐ŸŽฏ
rust-anti-pattern๐ŸŽฏSkill

Identifies and helps refactor Rust anti-patterns like unnecessary cloning, unwrapping, and inefficient iterations to improve code quality.

๐ŸŽฏ
rust-web๐ŸŽฏSkill

Builds robust Rust web services using frameworks like axum and actix, handling routing, database interactions, and API design with type-safe, performant code.

๐ŸŽฏ
rust-ownership๐ŸŽฏSkill

Skill

๐ŸŽฏ
rust-zero-cost๐ŸŽฏSkill

Analyzes and optimizes Rust generic abstractions and dispatch strategies for zero-cost performance and compile-time flexibility.

๐ŸŽฏ
rust-mutability๐ŸŽฏSkill

Expertly manages Rust mutability challenges, resolving borrowing conflicts and providing safe interior mutability strategies across different contexts.