tower-guard-rs
tower-guard-rs is application-layer security middleware for
tower-based services, powered by the
guard-core-rs detection engine.
It is part of the Guard ecosystem. It works
with any framework built on tower::Service, including
axum (axum-guard-rs
composes this crate), hyper, and
warp.
The crate holds framework glue only: every detection decision comes from the
engine. GuardLayer is a working tower::Layer and GuardService a working
tower::Service over http::Request<B>. The adapter is fail-secure: any
failure to complete the security check answers 500, never an uninspected
passthrough.
Ecosystem position
guard-core (Python) <- Reference implementation, spec owner
├── guard-core-rs <- Rust engine: detection, preprocessing, semantics
│ ├── tower-guard-rs <- Adapter: tower middleware (this repo)
│ ├── axum-guard-rs <- Adapter: axum layer over tower-guard-rs
│ ├── actix-guard-rs <- Adapter: actix-web middleware
│ └── rocket-guard-rs <- Adapter: rocket fairing and guards
├── guard-core-go <- Go port
└── guard-core-ts <- TypeScript port
The adapter translates native request content into engine inputs (path, query string, header values, buffered body), runs one engine call per request view, and translates a threat verdict into a native block response.
Installation
cargo add tower-guard-rs
The published crate is 1.0.0 and depends on the published
guard-core-engine 4.0.4. Requires Rust 1.92 or later (edition 2024) and
tower 0.5. See Installation for details.
Quick start
use tower::Layer;
let layer = tower_guard_rs::GuardLayer::new(tower_guard_rs::default_config());
// Any `Service<Request<B>>` works; `axum::Router` is the usual one.
let service = layer.layer(my_service);
For axum, axum-guard-rs wraps
this layer with with_guard(config).
What it inspects
One engine call per request view, mirroring the mapping used by the sibling adapters:
| Request part | Engine context | Notes |
|---|---|---|
| Path | url_path |
Skipped for / |
| Query string | query_param |
Skipped when empty |
| Header values | header |
Skips sec-* and the negotiation/routing headers |
| Body | request_body |
Buffered first, capped |
The HTTP method is not fed to the engine: the engine's
detect(content, context, config) takes content plus a context, and the
reference adapters do not scan the method either.
Responses
| Situation | Status | Body |
|---|---|---|
| Engine flags a view | 400 Bad Request |
Suspicious activity detected |
| Body exceeds the cap | 413 Payload Too Large |
Payload too large |
| Body read error or engine panic | 500 Internal Server Error |
Security check failed |
Where to go next
- Installation for requirements and dependency setup
- API for the full public surface and behavior tables
- Examples for runnable applications