liteguard 0.2.20260314

Feature guards, observability, and security response in a single import — evaluated locally, zero network overhead per check
Documentation

liteguard

Rust SDK crates.io docs.rs License

Feature guards, observability, and security response in a single import — evaluated locally, zero network overhead per check.

Liteguard for Rust. Initialize one process-scoped Client, then create explicit immutable request Scopes for per-request properties and protected context.


Installation

[dependencies]
liteguard = "0.2"

Quick Start

use liteguard::{Client, ClientOptions, Options, Properties, ProtectedContext};
use std::collections::HashMap;

#[tokio::main]
async fn main() {
    let client = Client::init("pckid-...", ClientOptions {
        environment: Some("production".into()),
        ..Default::default()
    })
    .await
    .unwrap();

    let scope = client.create_scope(
        Properties::new()
            .set("user_id", "user-123")
            .set("plan", "pro")
            .set("region", "us-east-1"),
    );

    if scope.is_open("payments.checkout") {
        // guard is open
    }

    let protected_scope = scope
        .bind_protected_context(ProtectedContext {
            properties: HashMap::from([("email".to_string(), "alice@acme.com".to_string())]),
            signature: "sig-123".into(),
        })
        .await
        .unwrap();

    let session = protected_scope.execute_if_open("payments.checkout", || {
        create_checkout_session()
    });

    if session.is_none() {
        // guard was closed
    }

    client.shutdown().await.unwrap();
}

Request Scoping

The core Rust API is scope-first:

  • Client is process-scoped and shared
  • Scope is immutable and request-scoped
  • ordinary properties live on Scope
  • protected context binds a derived Scope and may fetch or reuse a cached protected bundle

Create derived scopes with ordinary properties:

use liteguard::Properties;

let base = client.create_scope(Properties::new().set("request_id", "req-123"));
let pro_scope = base.with_properties(Properties::new().set("plan", "pro"));
let cleared = pro_scope.clear_properties(&["plan"]);

Bind protected context per request:

use liteguard::ProtectedContext;
use std::collections::HashMap;

let protected = scope
    .bind_protected_context(ProtectedContext {
        properties: HashMap::from([("email".to_string(), "alice@acme.com".to_string())]),
        signature: "sig-123".into(),
    })
    .await?;

let public_again = protected.clear_protected_context().await?;

API Reference

Client::init(project_client_key_id, options) -> Result<Client>

Initializes the SDK, performs the initial public-bundle fetch, then starts background refresh and signal flush tasks.

client.create_scope(properties) -> Scope

Creates a request scope with the provided ordinary properties.

scope.is_open(name) -> bool

Evaluates a guard for that request scope and emits a guard_check signal.

scope.is_open_with_options(name, options) -> bool

Evaluates a guard with per-call property overrides merged on top of the scope's properties.

scope.peek_is_open(name) -> bool

Read-only evaluation without emitting telemetry or consuming a rate-limit slot.

scope.execute_if_open(name, f) -> Option<T>

Evaluates the guard and executes f only when it is open. Emits both guard_check and guard_execution telemetry.

scope.try_execute_if_open(name, f) -> Result<Option<T>, E>

Explicit fallible variant of guarded execution. Returns Ok(None) when the guard is closed, Ok(Some(value)) when the guard is open and f succeeds, and Err(error) when the guard is open but f fails.

scope.bind_protected_context(protected_context).await -> Result<Scope>

Returns a derived request scope using a protected bundle keyed by the protected-context fingerprint.

scope.clear_protected_context().await -> Result<Scope>

Returns a derived request scope back on the public bundle.

client.flush().await

Flushes buffered signals immediately.

client.shutdown().await

Stops background tasks and flushes buffered signals.


Guard Evaluation

Rules are evaluated in order — first matching rule wins. If no rule matches, the guard's default applies.

Operators

Operator Description
EQUALS Exact match
NOT_EQUALS Negated exact match
IN Value in a set
NOT_IN Value not in a set
REGEX Regular expression match
GT / GTE Greater than / greater or equal
LT / LTE Less than / less or equal

Development

make test-rust

License

Apache 2.0 — see LICENSE.