pub trait Authorizer:
Send
+ Sync
+ Debug {
// Required method
fn authorize(
&self,
source: &dyn AclSource,
req: &AuthorizationRequest<'_>,
) -> AuthorizationResult;
// Provided methods
fn authorize_quiet(
&self,
source: &dyn AclSource,
req: &AuthorizationRequest<'_>,
) -> AuthorizationResult { ... }
fn is_configured(&self) -> bool { ... }
fn decision_ttl(&self) -> Option<Duration> { ... }
fn authorize_by_resource_type(
&self,
_source: &dyn AclSource,
_principal: &Principal,
_host: &SocketAddr,
_resource_type: ResourceType,
_operation: AclOperation,
) -> AuthorizationResult { ... }
}Expand description
Pluggable per-broker or per-gateway authorization decision point.
Implementations own whatever state they need to make a decision, for example
a super-user set, an HTTP client, or a decision cache. The caller holds a
single Arc<dyn Authorizer>.
Implementations MUST be Send + Sync + Debug: handler code paths
are async and the broker logs configs at startup.
The decision consults a AclSource. The broker passes its
MetadataImage and the gateway passes an AclCache. ACL-free
implementations (AllowAll, OPA) ignore it.
Required Methods§
Decide whether req.principal may do req.operation on
(req.resource_type, req.resource_name) from req.host.
The authorizer may consult source, as the ACL-backed implementations
do, or ignore it entirely, as AllowAll and Opa do.
Provided Methods§
The decision of Authorizer::authorize for a check that Kafka makes
with logIfDenied = false: a probe whose Deny is not a refusal, such
as the cluster-wide Create shortcut of CreateTopics that falls back
to a per-topic check, or the operations bit field a Describe reports.
The decision is the same. What differs is what a Deny leaves behind:
none of the audit records and counters that authorize may write. The
default forwards to authorize, which is right for an implementation
that writes none. A decorator that audits a Deny MUST override this to
forward to the authorizer it wraps without auditing, and one that only
forwards MUST forward this method too.
Sourcefn is_configured(&self) -> bool
fn is_configured(&self) -> bool
Whether this implementation is a real authorization decision point,
the way Kafka’s authorizer.class.name names one.
Only AllowAllAuthorizer answers false: it is what a deployment
gets when it configures no authorizer at all, so a stored ACL would
never be consulted. The ACL administration RPCs read this to answer
SECURITY_DISABLED, as Kafka’s KafkaApis does under
authorizer.isEmpty. A decorator must forward it to the authorizer it
wraps.
Sourcefn decision_ttl(&self) -> Option<Duration>
fn decision_ttl(&self) -> Option<Duration>
Upper bound on how long a caller-side cache may reuse a decision from
this authorizer without asking again, or None if a decision is
exactly as fresh as whatever source snapshot it was computed
against – true of the ACL-backed implementations, whose grants live
in the metadata log a caller can already key a cache on.
An authorizer whose decisions can go stale independently of source
– an HTTP-backed policy engine such as OPA is the motivating case –
overrides this to its own decision-cache TTL, so a caller-side cache
keyed on metadata alone cannot outlive it and silently miss a policy
change the metadata log never saw. A decorator MUST forward the
wrapped authorizer’s answer, as is_configured does.
Whether principal holds operation on at least one resource pattern
of resource_type – Kafka’s AuthorizerUtils.authorizeByResourceType,
used where a request is not itself scoped to one resource name. KIP-599
motivates the check: InitProducerId with no transactional id accepts
either cluster-wide IdempotentWrite or Write on any topic, so a
principal that can produce need not also hold a cluster-wide grant.
The default answers AuthorizationResult::Deny: an implementation
that cannot enumerate its ACL space (an HTTP-backed policy engine, for
example) has no cheap way to answer this honestly, and understating a
grant is the safe direction. AllowAllAuthorizer overrides this to
always answer Allow, since it never denies anything.
SimpleAclAuthorizer overrides it with a real scan. A decorator MUST
forward the wrapped authorizer’s answer, as it does for is_configured
and decision_ttl.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".