Expand description
§entelix-policy
Multi-tenant operational primitives that LangChain / LangGraph leave to
the host: token-bucket rate limiting, bidirectional PII redaction
(F5 mitigation), rust_decimal-backed transactional cost accounting
(F4 mitigation), composite quota enforcement, and the per-tenant
aggregate (TenantPolicy) plus the runtime registry
(PolicyRegistry) that indexes them by tenant_id.
§Surface in one screen
RateLimiter(trait) +TokenBucketLimiter— async, per-key, time-injectable for deterministic tests.PiiRedactor(trait) +RegexRedactor— runs on bothpre_requestandpost_responseso leaks can’t slip past in either direction.CostMeter+PricingTable/ModelPricing—rust_decimalfor float-free arithmetic; charges are recorded only after the response decoder succeeds (transactional — F4).QuotaLimiter— composite: rate (RPS) + budget ceiling (per-tenant cumulative spend cap).TenantPolicy— per-tenant aggregate of optional handles to the four primitives above.PolicyRegistry—DashMap<tenant_id, Arc<TenantPolicy>>with a fallback default policy.PolicyLayer—tower::Layer<S>that wires every primitive into bothService<ModelInvocation>andService<ToolInvocation>pipelines. Compose viaChatModel::layer(PolicyLayer::new(mgr))for model calls andToolRegistry::layer(PolicyLayer::new(mgr))for tool calls — same struct on both sides.
§Layer lifecycle (model calls)
- before inner.call (
Service<ModelInvocation>):PiiRedactor::redact_request— outbound scrub.QuotaLimiter::check_pre_request— rate + budget gate. ReturnsError::Provider { status: 429 | 402, ... }on refusal.
- after inner.call:
PiiRedactor::redact_response— inbound scrub.CostMeter::charge— transactional charge (F4 — only here, after a successful inner call).
§Layer lifecycle (tool calls)
- before inner.call (
Service<ToolInvocation>):PiiRedactor::redact_json(input)— scrub tool input JSON.
- after inner.call:
PiiRedactor::redact_json(output)— scrub tool output JSON.
§Tenant scoping
Every primitive looks up state by ExecutionContext::tenant_id()
. A request without an explicit tenant uses the
entelix_core::DEFAULT_TENANT_ID scope; the default
tenant gets the PolicyRegistry’s default policy (typically
“no policy” — pass-through).
Structs§
- Budget
- Per-tenant cumulative spend ceiling. Compared against
CostMeter::spent_by(tenant)at pre-request time. - Cost
Meter - Per-tenant cost ledger. Records the cumulative spend for every tenant that has ever been charged.
- Model
Pricing - Per-model pricing, in cost units per 1000 tokens. The unit is
caller-defined (USD cents, GBP pence, internal credits) — the
meter is unit-blind and just sums
Decimals. - PiiPattern
- One named redaction pattern.
- Policy
Layer - Layer that wraps an inner service with per-tenant policy enforcement.
- Policy
Registry - Runtime registry mapping
tenant_id→TenantPolicy. - Policy
Service Serviceproduced byPolicyLayer. Generic over the inner service type; specialisedService<ModelInvocation>andService<ToolInvocation>impls below.- Pricing
Table - Lookup of model name →
ModelPricing. Keys are the same model strings the codecs send to the wire (e.g."claude-opus-4-7","gpt-4.1"). Lookup is exact; aliases are the caller’s responsibility. - Quota
Limiter - Composite quota gate.
- Regex
Redactor - Regex-driven PII redactor.
- Tenant
Policy - Per-tenant aggregate of policy handles.
- Token
Bucket Limiter - Per-key token-bucket limiter. Buckets are created lazily on first
try_acquire; a key never seen before starts full.
Enums§
- Policy
Error - Policy-layer failures.
- Unknown
Model Policy - Behavior when
CostMeter::chargeis called with amodelthat has no entry in thePricingTable.
Constants§
- DEFAULT_
MAX_ TENANTS - Default cap on distinct tenant ledger entries.
- MAX_
WARNED_ MODELS - Cap on distinct model names tracked under
WarnOnce.
Traits§
- PiiRedactor
- Bidirectional PII redaction surface.
- Rate
Limiter - Backend-agnostic rate-limit surface.
- Unknown
Model Sink - Observer notified on every unknown-model charge attempt.
Functions§
- default_
pii_ patterns - A small starter set of PII patterns. Production deployments
almost always extend or replace these per jurisdiction; this
list exists so a
RegexRedactor::default()is non-trivial out of the box. - luhn_
valid - Luhn-checksum validator — reject candidate runs that aren’t well-formed payment-card numbers. Strips spaces, dashes, and non-digit noise before computing.
Type Aliases§
- Policy
Result - Result alias used inside
entelix-policy.