claw-guard 0.1.2

Security, session, and policy engine for ClawDB.
Documentation

claw-guard

claw-guard is the security, session, and policy engine for ClawDB. It provides API key management, JWT-backed sessions, TOML policy loading, risk-aware authorization, batched audit logging, and field masking over a SQLite-backed control plane.

Features

  • API key creation, validation, revocation, and listing with BLAKE3 hashing.
  • Session issuance and validation with HS256 JWTs and revocation checks.
  • Policy evaluation with allow, deny, and mask rules loaded from SQLite or TOML files.
  • Batched audit persistence with filtering and CSV export.
  • JSON masking with redact, hash, truncate, email, and nested field masking strategies.
  • Optional gRPC service for remote authorization and administration.

Installation

[dependencies]
claw-guard = "0.1.2"

Configuration

GuardConfig::from_env() reads these variables:

  • CLAW_GUARD_JWT_SECRET (required)
  • CLAW_GUARD_DB_PATH (default: claw_guard.db)
  • CLAW_GUARD_POLICY_DIR (optional)
  • CLAW_GUARD_SENSITIVE_RESOURCES (comma-separated)
  • CLAW_GUARD_AUDIT_FLUSH_INTERVAL_MS (default: 100)
  • CLAW_GUARD_AUDIT_BATCH_SIZE (default: 500)
  • CLAW_GUARD_BUSINESS_HOURS_START (default: 8)
  • CLAW_GUARD_BUSINESS_HOURS_END (default: 18)

Quick Start

use claw_guard::{Guard, GuardConfig, PolicyDecision};
use secrecy::SecretString;
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let guard = Guard::new(GuardConfig {
        db_path: PathBuf::from("claw_guard.db"),
        jwt_secret: SecretString::new("replace-me".to_owned().into_boxed_str()),
        policy_dir: Some(PathBuf::from("./policies")),
        sensitive_resources: vec!["finance_records".to_owned()],
        audit_flush_interval_ms: 100,
        audit_batch_size: 500,
        business_hours_start_hour: 8,
        business_hours_end_hour: 18,
    })
    .await?;

    let session = guard
        .sessions()
        .create_session(
            uuid::Uuid::new_v4(),
            uuid::Uuid::new_v4(),
            "admin",
            vec!["tool:*".to_owned()],
            3600,
        )
        .await?;

    match guard.check_access(&session, "read", "users").await? {
        PolicyDecision::Allow => println!("allowed"),
        PolicyDecision::Deny { reason } => println!("denied: {reason}"),
        PolicyDecision::Mask { fields } => println!("mask fields: {fields:?}"),
    }

    Ok(())
}

Policy Files

Policy files support single-policy or multi-policy TOML documents. Example:

[[policies]]
name = "deny-finance-during-scheduling"
priority = 100

[[policies.rules]]
type = "deny_if"
reason = "Finance data not accessible during scheduling tasks"
[policies.rules.condition]
and = [{ task_matches = "scheduling" }, { resource_is = "finance_records" }]

Supported condition operators are task_matches, role_is, scope_contains, risk_above, resource_is, workspace_is, and, or, and not.

Development

cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features

License

Apache-2.0. See LICENSE.