pub struct AuthzKeycloakPlugin {
token_endpoint: String,
client_id: String,
permissions: Vec<String>,
enforcing: bool,
http_method_as_scope: bool,
ssl_verify: bool,
timeout: Duration,
outbound: Arc<OutboundClient>,
}Expand description
Performs a Keycloak UMA permission check per request.
Fields§
§token_endpoint: StringKeycloak token endpoint (.../protocol/openid-connect/token).
client_id: StringOAuth client id, sent as the UMA audience.
permissions: Vec<String>Statically configured permissions (resource or resource#scope).
enforcing: boolENFORCING (default) denies when no permission is configured;
PERMISSIVE allows.
http_method_as_scope: boolWhen true, the request method is appended as the permission scope.
ssl_verify: boolTLS certificate verification for the callout.
timeout: DurationWhole-call timeout for the callout.
outbound: Arc<OutboundClient>Shared pooled outbound HTTP client.
Implementations§
Source§impl AuthzKeycloakPlugin
impl AuthzKeycloakPlugin
Sourcepub fn from_config(
config: &HashMap<String, Value>,
resources: &Arc<PluginResources>,
) -> Result<Self, String>
pub fn from_config( config: &HashMap<String, Value>, resources: &Arc<PluginResources>, ) -> Result<Self, String>
Builds the plugin from node config.
Accepted keys:
token_endpoint(string, required): Keycloak token endpoint URL. (APISIX’sdiscoveryauto-resolution is not supported.)client_id(string, required): OAuth client id, sent as the UMAaudience.permissions(array of strings, default[]): requested permissions, eachresourceorresource#scope.policy_enforcement_mode(string, default"ENFORCING"):ENFORCINGdenies whenpermissionsis empty;PERMISSIVEallows without a callout.http_method_as_scope(bool, defaultfalse): append the request method as the scope of each permission.ssl_verify(bool, defaulttrue): verify the endpoint’s TLS certificate.timeout(integer ms, default3000): callout timeout.
- id: authz
type: authz-keycloak
config:
token_endpoint: https://kc.example.com/realms/myrealm/protocol/openid-connect/token
client_id: my-api
permissions: ["Default Resource#read"]
policy_enforcement_mode: ENFORCING
ssl_verify: true
timeout: 3000Sourcefn deny(
ctx: Context,
message: impl Into<String>,
) -> Result<PluginOutput, PluginExecutionError>
fn deny( ctx: Context, message: impl Into<String>, ) -> Result<PluginOutput, PluginExecutionError>
Builds the 403 denial and exits on the denied port. Reserved for
deliberate denials — a missing bearer token, no permission configured
under ENFORCING, or Keycloak actively refusing the UMA decision.
Sourcefn callout_error(
ctx: Context,
message: String,
) -> Result<PluginOutput, PluginExecutionError>
fn callout_error( ctx: Context, message: String, ) -> Result<PluginOutput, PluginExecutionError>
Builds a genuine infrastructure-failure Err (the Keycloak token
endpoint unreachable, timed out, or answering with a status that is not
a decision) — exits through the error port because the node could not
do its job, unlike deny which is a deliberate, client-facing decision.
The prepared response is the shared 502 provider_error shape, not a
403 that would hide a broken deployment behind a plausible denial.
Trait Implementations§
Source§impl Plugin for AuthzKeycloakPlugin
impl Plugin for AuthzKeycloakPlugin
Source§fn plugin_type(&self) -> &str
fn plugin_type(&self) -> &str
Source§fn execute<'life0, 'async_trait>(
&'life0 self,
ctx: Context,
) -> Pin<Box<dyn Future<Output = Result<PluginOutput, PluginExecutionError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn execute<'life0, 'async_trait>(
&'life0 self,
ctx: Context,
) -> Pin<Box<dyn Future<Output = Result<PluginOutput, PluginExecutionError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn reads_response_body(&self) -> bool
fn reads_response_body(&self) -> bool
context.response.body. Read moreSource§fn cache_target(&self) -> Option<CacheTarget>
fn cache_target(&self) -> Option<CacheTarget>
proxy-cache half. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for AuthzKeycloakPlugin
impl !UnwindSafe for AuthzKeycloakPlugin
impl Freeze for AuthzKeycloakPlugin
impl Send for AuthzKeycloakPlugin
impl Sync for AuthzKeycloakPlugin
impl Unpin for AuthzKeycloakPlugin
impl UnsafeUnpin for AuthzKeycloakPlugin
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§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
§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