qubit-redact 0.9.0

Rule-driven redaction for fields, diagnostics, HTTP data, and Rust domain objects
Documentation

qubit-redact

Rust CI Coverage Crates.io Rust License 中文文档

qubit-redact gives application and library authors a consistent redaction boundary for logs, errors, and support diagnostics. Redact individual fields or JSON payloads with the built-in policy, customize rules with RedactionPolicy, or attach #[derive(Redact)] so domain types produce redacted Debug, Display, and Serde output. Borrowed views and redact_text() never change the source value; add #[redact(serde)] only when the source object's own Serde output must also be redacted.

Installation

Requires Rust 1.94+. The Cargo package is qubit-redact; import it as qubit_redact in Rust. Scalar fields, custom policies, and hand-written Redact implementations need no optional features.

[dependencies]
qubit-redact = "0.9"
Feature Adds
derive #[derive(Redact)], #[derive(RedactScalar)]
serde Structured Serde adapters for domain views
bigdecimal BigDecimal scalar support (includes serde)
json JSON text and borrowed serde_json::Value handling
http URL, headers, form, multipart, and body capture
uri Generic URI parsing and redaction

Structured domain examples below use derive, Serde, and JSON:

[dependencies]
qubit-redact = { version = "0.9", features = ["derive", "serde", "json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"

Quick Start

An authentication failure is logged. The standard policy already treats common field names such as password as secret, so you can redact one scalar without configuring rules or enabling optional features.

use qubit_redact::Redactor;

fn main() {
    let output = Redactor::standard().redact_field("password", "raw-secret");
    assert_eq!(output.text().as_str(), "<redacted>");
}

Redact JSON payloads

Enable the json feature when the input is already JSON. The borrowed value stays unchanged; only the rendered diagnostic text is redacted.

[dependencies]
qubit-redact = { version = "0.9", features = ["json"] }
serde_json = "1"
use qubit_redact::Redactor;

fn main() {
    let value = serde_json::json!({"user": "ada", "password": "raw-secret"});
    let output = Redactor::standard().redact_json_value(&value);
    assert!(!output.text().as_str().contains("raw-secret"));
    assert_eq!(value["password"], "raw-secret");
}

Structured domain types

With #[redact(serde)], business JSON and diagnostic JSON both replace the password with <redacted>. The generated Debug implementation also redacts ordinary diagnostic formatting.

use qubit_redact::{Redact, Redactor};

#[derive(Redact)]
#[redact(serde, debug)]
struct Login {
    user: String,
    #[redact(level = "secret")]
    password: String,
}

fn main() {
    let login = Login { user: "ada".into(), password: "raw-secret".into() };
    let redactor = Redactor::standard();
    let view = redactor.redact_view(&login);
    assert!(!format!("{view}").contains("raw-secret"));
    assert!(!format!("{login:?}").contains("raw-secret"));
    let json = redactor.to_json(&login).expect("redacted JSON");
    assert_eq!(json, r#"{"user":"ada","password":"<redacted>"}"#);
    assert!(!serde_json::to_string(&login).expect("business JSON").contains("raw-secret"));
    let output = redactor.redact_text(&login);
    assert!(!output.text().as_str().contains("raw-secret"));
}

See the derive guide for attribute and type tables. Custom field rules, HTTP, URI, argv/env, batches, and budgets are covered in the user guide.

Choose an Entry Point

Need Entry point
Redact one named scalar field redact_field(field, value)
Lazy formatting or serialization under a fixed policy redact_view(&value)
Final text and completeness summary now redact_text(&value)
Compact redacted JSON string to_json(&value)
Redact input that is already JSON redact_json(text) / redact_json_value(&value)
Share one budget across independent values diagnostic_batch()
Compose one diagnostic message text_composer()

Why This Project Exists

Configure classification, masking, format handling, and resource budgets in one place instead of implementing them at every log site. Views retain policy snapshots and execute on each use; finalized text can be displayed repeatedly.

What It Provides

Fields, domain objects, JSON, HTTP, URI, environment and process arguments, inspection, and shared budgets. RedactScalar supports scalar newtypes; third-party values can explicitly select Display representation. Unmarked fields remain ordinary output; explicit levels belong to the business type and are not overridden by strict policy. For hand-written domain implementations, fields.keyed_nested(...) keeps a public business-key wrapper structurally redacted, so rules inside its nested payload still apply. Disabled policy is a raw-value debugging escape hatch. The library does not erase source memory or protect output that bypasses its redaction entry points.

max_serde_payload_bytes bounds logical scalar payloads in structured Serde; max_output_bytes bounds final text or to_json() JSON retained by the library. Both default to 16 KiB and are independent. When serializing a view or derived source directly, the caller's serializer/writer controls final encoded length. See the guide's budget matrix.

Learn More

See the English user guide and Chinese user guide for feature configuration, complete attribute/type tables, policy precedence, HTTP, and batch scenarios. See also the derive guide and API docs.

Testing

# Run tests with the default feature set
cargo test

# Run tests with all declared features
cargo test --all-features

# Project CI checks
./ci-check.sh

# Check code coverage
./coverage.sh

License

Copyright (c) 2025 - 2026. Haixing Hu. All rights reserved.

Licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

Contributing

Contributions are welcome. Please follow the Rust API guidelines, keep public API documentation and tests current, and run ./align-ci.sh to format code and ./ci-check.sh to satisfy CI requirements before submitting a pull request.

Author

Haixing Hu - Qubit Co. Ltd.

Repository: https://github.com/qubit-ltd/rs-redact