eggrd
Sheet 1 of 1  ·  Section through the request path  ·  Apache-2.0

The front door
your app shipped
without.

One static binary in front of your app. It owns the way in: authentication, rate limiting, TLS, input rules. It also owns the way out: redaction, hardened response headers, and hard ceilings on what your LLM calls may spend.

No changes to the app behind it.

Project
eggrd
Drawn as
Section A–A
Licence
Apache-2.0
Status
v2 landed · v2.5 underway
Read the source crates.io

What each chamber does

Schedules · both directions
Request path schedule — inbound
StageConfigBehaviour
TLS · ACME[tls]Terminates TLS. Automatic issuance is △ UNPROVEN — see the revision block.
Authentication[auth.jwt]Validates a JWT before the request reaches your app.
Rate limit[ratelimit]Per-IP and per-key ceilings. store = "redis" shares one ceiling across replicas
Input rules[waf]WAF-lite inspection. Off by default — you turn it on deliberately.
IP access[access]allow and deny lists evaluated before anything downstream.
Response path schedule — outbound
StageConfigBehaviour
Headers[headers]CSP, HSTS and cookie hardening applied to what your app returns.
Compression[validation]compress_responses — negotiated response compression.
CORS preflight[cors]Preflight answered at the edge, with the allow-list held in config.

Three details, drawn larger

Callouts A · B · C
A

Shared-store rate limit

A per-process counter stops meaning anything the moment you run two replicas. eggrd can hold the limit in a store both replicas read, so the ceiling is the ceiling rather than the ceiling times your replica count.

[ratelimit] store = "redis" △ UNPROVEN

B

Reversible redaction

An irreversible [REDACTED] protects the provider's view and destroys yours. On the LLM lane eggrd keeps a per-request mask map: the provider sees a placeholder, and the response is unmasked back to that caller's own values — buffered or streamed.

[llm.dlp] mode = "redact" · reversible = true

C

Budgets that hold

A ceiling checked after the fact is a report, not a limit. eggrd reserves against the budget before the provider call and reconciles after, so a burst of concurrent requests cannot walk past the number together.

[[llm.budgets]] · fail-closed

The metered line

Detail C · LLM traffic

The same binary sitting in front of your app can sit in front of your model provider. It parses OpenAI-compatible traffic, counts input, output, cached and reasoning tokens separately, then prices them against a book you supply.

Metering is observe-only until you say otherwise: with no price book and no budgets it counts and reports, and changes nothing about the request. Turn on a budget and the line becomes a ceiling, enforced before the call rather than after the invoice.

An unknown model is a decision, not a default. on_unpriced_model either counts it and flags it, or rejects the request outright, so a model you never priced cannot quietly bill at zero.

# edgeguard.toml
[llm]
enabled = true
on_unpriced_model = "block"

[llm.models."gpt-4o"]
input_per_1m  = 2.5
output_per_1m = 10.0

[[llm.budgets]]
name  = "team-platform"
scope = "key"
unit  = "usd"
limit = 250.0
window = "30d"

[alerts]
budget_consumed_threshold = 0.8

Revision block

Compiled · not yet proven
ItemStateWhat that means
ACME certificate issuance △ UNPROVEN Implemented and compiled. It can only be proven against a live certificate authority, and that has not been done.
Shared-store rate limiter △ UNPROVEN Compiled and covered by in-process tests. Proven behaviour under a real multi-replica deploy is still outstanding.
WASM edge worker △ UNPROVEN Compiles to WebAssembly. Not yet demonstrated running on a live edge platform.

Drawings carry a revision block because the honest state of a design is part of the design. These three are real capabilities in the source. They have not been exercised against live infrastructure, and this page will not imply otherwise. Everything in the schedules above is tested in-process.

Put it in front of something

Two commands
# install
cargo install eggrd

# scaffold a starter config (and a Dockerfile) beside your app
edgeguard init

# edit edgeguard.toml, then check it before it sees traffic
edgeguard doctor

The crate is eggrd; the binary it installs is still named edgeguard, an earlier working title kept so existing deployments keep working.

init scaffolds a starter edgeguard.toml and a Dockerfile rather than handing you a blank file, and refuses to clobber one that already exists. doctor then lints that config and validates the boot path, so a bad setting fails at your terminal instead of in front of traffic.

It is one static binary and one TOML file. There is no agent to install in your app, no SDK to import, and no library call to make. That is the point: the app behind it does not change.