pub struct Consumer {
pub name: String,
pub credentials: Vec<Credential>,
pub policies: Vec<String>,
pub consumer_type: ConsumerType,
pub tool_allowlist: Vec<String>,
pub token_budget: Option<TokenBudget>,
pub priority: Option<u8>,
pub groups: Vec<String>,
pub authorization: Option<Authz>,
pub quotas: Option<ConsumerQuotas>,
pub ai_logging: Option<bool>,
pub agent: Option<AgentPrincipal>,
}Expand description
Identity of an API caller (app/team/user); owns credentials, quotas, and the analytics identity.
Fields§
§name: String§credentials: Vec<Credential>§policies: Vec<String>§consumer_type: ConsumerTypeThe principal kind (DW-113): user (default) or agent.
Agent consumers gain a tool allowlist, a per-agent token
budget, and typed analytics attribution. The field is renamed
to type in YAML (type is a Rust keyword).
tool_allowlist: Vec<String>MCP tool allowlist (DW-113): when non-empty, the consumer may
only call the named tools through the MCP gateway. Empty (the
default) = no restriction. Validation checks that every name
references a configured ai.mcp.tools entry.
token_budget: Option<TokenBudget>Per-agent AI token budget (DW-113): when set, this consumer’s
AI traffic is bounded by this budget BEFORE the policy chain
(the most-specific budget). Same shape as a policy’s
token_budget. None (the default) = no per-agent budget;
the policy chain governs as before.
priority: Option<u8>Consumer priority class for load shedding (DW-016): 0 (lowest) to 10 (highest). Stored and validated now; it takes effect only once authentication (DW-019/DW-020) identifies the consumer on a request — until then, shedding priority comes from the matched route (or the default 5). Consumer priority overrides the route’s when known, but it does NOT trigger reserved-bucket carving today — only a high-priority route does.
groups: Vec<String>Consumer group memberships (DW-020): group names this consumer
belongs to, consulted by authorization allowed_groups /
denied_groups rules. Empty (the default) = no groups. Group
names are free-form strings; validation checks that authorization
rules referencing groups resolve against at least one consumer’s
membership. Store-managed consumers carry their own groups in the
state store (#124) — the group NAMESPACE is shared, but
config-time validation can only see config consumers, so a rule
referencing a group that exists solely on store consumers is
flagged (grant at least one config consumer the same group name,
or accept the issue is a false positive for store-only groups).
Consumer-level authorization rules (#123): the MOST specific link
of the frozen chain consumer > route > service > listener >
global — applies to every request authenticated as this consumer
(naturally only once authentication has identified it). A deny at
any level wins; otherwise the most specific level with rules
governs (see Authz and the authz module). Same validation
rules as route-level authorization.
quotas: Option<ConsumerQuotas>Request budgets for this consumer (DW-033): a daily and/or
monthly request cap counted in fixed UTC calendar windows
(midnight-to-midnight UTC; the first through the last instant of
the UTC month). Budgets are DISTINCT from rate limits: a rate
limit shapes traffic inside seconds or minutes, a budget bounds
total volume across a day or month, and the two mechanisms run
independently (both apply when both are configured). Enforcement
needs the state store (DWARA_STATE_DB) for durable counters —
without one, quota config is inert (logged at request time, see
the state::quotas module docs). Store-managed consumers have no
config record, so budgets are config-consumer-only in this
edition; a distributed shared-counter variant is the Ent
follow-up (issue “DW-155”).
ai_logging: Option<bool>AI prompt/response logging override (DW-081). None = inherit
the global ai.logging.enabled setting; Some(false) = disable
capture for this consumer even if global is on; Some(true) =
enable capture for this consumer even if global is off
(requires the ai.logging block to exist — the redactor and
retention are always needed). The per-consumer toggle respects
tenant preference: a consumer with capture disabled produces
no stored prompts/responses.
agent: Option<AgentPrincipal>AI-16 (#204): agent principal metadata. Only meaningful when
consumer_type is agent; ignored otherwise. Carries the
agent’s display name, description, owner, and permission level
for first-class agent principal attribution.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Consumer
impl<'de> Deserialize<'de> for Consumer
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for Consumer
impl JsonSchema for Consumer
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreimpl StructuralPartialEq for Consumer
Auto Trait Implementations§
impl Freeze for Consumer
impl RefUnwindSafe for Consumer
impl Send for Consumer
impl Sync for Consumer
impl Unpin for Consumer
impl UnwindSafe for Consumer
Blanket Implementations§
§impl<T> AnyExt for T
impl<T> AnyExt for T
§fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
T behind reference§fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
T behind mutable reference§fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
T behind Rc pointer§fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
T behind Arc pointer§fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
T behind Box pointer§fn downcast_move<T>(this: Self) -> Option<T>
fn downcast_move<T>(this: Self) -> Option<T>
Self to T,
useful only in generic context as a workaround for specializationSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
fn coerce_rc_to(self: Rc<X>) -> Rc<T>
fn coerce_box_to(self: Box<X>) -> Box<T>
fn coerce_ref_to(&self) -> &T
fn coerce_mut_to(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more