istio_request_auth¶
Istio request authentication interface library.
This library provides the provider and requirer sides of the istio-request-auth
relation interface for configuring Istio
RequestAuthentication
resources via relation data (JWT rules, JWKS endpoints, claim-to-header mapping).
What is this library for?¶
The istio-ingress-k8s charm
wraps a Kubernetes Gateway API of class istio. It
can connect to an OAuth 2.0 provider like the oauth2-proxy charm via the forward-auth
relation to forward requests via an authentication stack for user authentication.
Istio also natively supports validating a pre-generated JWT against an issuer using a
RequestAuthentication Kubernetes resource. This means a request containing a JWT in
the header can be natively authenticated by Istio instead of taking a detour via the
authentication stack, and the claims from the token are parsed and added as headers to
the downstream request. The RequestAuthentication resource is purely an Istio concept
offered by the CRDs native to Istio. Hence the interface is named with an istio- prefix.
For applications to take advantage of this feature, they need to tell Istio which issuers
they trust and which headers they want the claims in the token to be mapped to. To enable
this information exchange and add the appropriate RequestAuthentication resource, the
istio-request-auth interface library is introduced.
Security note¶
If a requirer is connected but has not provided valid (non-empty) jwt_rules, no
RequestAuthentication resource is created. This could allow unauthenticated
traffic. The provider exposes get_connected_apps
so the ingress charm can detect such applications and drop their ingress until valid
rules are provided.
Requirer usage:
from charmlibs.interfaces.istio_request_auth import (
ClaimToHeader,
JWTRule,
IstioRequestAuthRequirer,
)
class MyAppCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self.request_auth = IstioRequestAuthRequirer(self)
def _publish_rules(self):
self.request_auth.publish_data([
JWTRule(
issuer="https://accounts.example.com",
claim_to_headers=[
ClaimToHeader(header="x-user-email", claim="email"),
],
),
])
Provider usage:
from charmlibs.interfaces.istio_request_auth import IstioRequestAuthProvider
class MyIngressCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self.request_auth = IstioRequestAuthProvider(self)
def _reconcile(self):
valid = self.request_auth.get_data()
connected = self.request_auth.get_connected_apps()
invalid_apps = connected - set(valid.keys())
# Drop ingress for invalid_apps, create RequestAuthentication for valid
- class ClaimToHeader(*, header: str, claim: str)¶
Bases:
BaseModelMaps a JWT claim to a request header.
- class FromHeader(*, name: str, prefix: str | None = None)¶
Bases:
BaseModelSpecifies a header location from which to extract a JWT.
- class IstioRequestAuthProvider(
- charm: CharmBase,
- relation_name: str = 'istio-request-auth',
Bases:
ObjectProvider side of the istio-request-auth interface.
Used by the ingress charm to read JWT authentication rules from all related applications.
Applications that are connected but have not provided valid (non-empty)
jwt_rulesare excluded fromget_databut included inget_connected_apps. Consumers can compare the two sets to identify applications that have not yet provided data:valid = provider.get_data() connected = provider.get_connected_apps() apps_without_data = connected - set(valid.keys())
- property is_ready: bool¶
Check if any related application has provided valid request auth data.
- Returns:
True if at least one requirer has published non-empty jwt_rules.
- get_connected_apps() set[str]¶
Return the names of all applications connected over the relation.
This includes apps that have not yet provided valid data.
- get_data() dict[str, list[JWTRule]]¶
Retrieve valid JWT rules from all related applications.
Uses
ops.Relation.loadto deserialise each application’s databag intoRequestAuthData. Only applications whose databag contains a non-emptyjwt_ruleslist are included.- Returns:
A dict mapping application name to its list of
JWTRuleobjects.
- class IstioRequestAuthRequirer(
- charm: CharmBase,
- relation_name: str = 'istio-request-auth',
Bases:
ObjectRequirer side of the istio-request-auth interface.
Used by downstream applications to publish their JWT authentication rules to the ingress charm.
- class JWTRule(
- *,
- issuer: str,
- jwks_uri: str | None = None,
- audiences: list[str] | None = None,
- forward_original_token: bool | None = None,
- claim_to_headers: list[ClaimToHeader] | None = None,
- from_headers: list[FromHeader] | None = None,
Bases:
BaseModelA single JWT validation rule provided by the requiring app.
- claim_to_headers: list[ClaimToHeader] | None¶
- from_headers: list[FromHeader] | None¶