rskit-authz 0.2.0-alpha.3

RBAC and ABAC authorization engine
Documentation
# rskit-authz

Canonical RBAC + ABAC authorization engine with role hierarchy, deny override, and default deny.

## Highlights

- `Engine` evaluates RBAC roles and ABAC policies together
- role inheritance with wildcard resource/action permissions
- object-level role permissions via permission-local attribute conditions
- explicit deny policies always win
- unmatched requests resolve to `default deny`
- `AuthorizationLayer` composes policy checks as Tower middleware and denies missing request context
- `match_pattern` / `match_any` mirror gokit and pykit wildcard semantics

## Example

```rust
use std::collections::HashMap;

use rskit_authz::{Checker, Engine, Permission, Request, Resource, Role, Subject};

let engine = Engine::new(
    vec![Role {
        name: "editor".into(),
        inherits: vec!["viewer".into()],
        permissions: vec![Permission {
            resource: "article".into(),
            action: "write".into(),
            conditions: vec![],
        }],
    }],
    vec![],
)?;

let allowed = engine.check(&Request {
    subject: Subject {
        id: "user-1".into(),
        roles: vec!["editor".into()],
        attributes: HashMap::new(),
    },
    resource: Resource {
        resource_type: "article".into(),
        id: "article-1".into(),
        attributes: HashMap::new(),
    },
    action: "write".into(),
    context: HashMap::new(),
});

assert!(allowed);
# Ok::<(), rskit_errors::AppError>(())
```

Object-level constraints that limit a role grant should be attached to the `Permission::conditions` for that grant. Use explicit deny policies for constraints that must override every broad role or policy allow.