diff --git a/0.10.0/404.html b/0.10.0/404.html index b6723d1fe..e81035406 100644 --- a/0.10.0/404.html +++ b/0.10.0/404.html @@ -1493,7 +1493,7 @@
AuthConfig
Custom Resource Definition (CRD)There are a few concepts to understand Authorino's architecture. The main components are: Authorino, Envoy and the Upstream service to be protected. Envoy proxies requests to the the configured virtual host upstream service, first contacting with Authorino to decide on authN/authZ.
+There are a few concepts to understand Authorino's architecture. The main components are: Authorino, Envoy and the Upstream service to be protected. Envoy proxies requests to the configured virtual host upstream service, first contacting with Authorino to decide on authN/authZ.
The topology can vary from centralized proxy and centralized authorization service, to dedicated sidecars, with the nuances in between. Read more about the topologies in the Topologies section below.
Authorino is deployed using the Authorino Operator, from an Authorino
Kubernetes custom resource. Then, from another kind of custom resource, the AuthConfig
CRs, each Authorino instance reads and adds to the index the exact rules of authN/authZ to enforce for each protected host ("index reconciliation").
Everything that the AuthConfig reconciler can fetch in reconciliation-time is stored in the index. This is the case of static parameters such as signing keys, authentication secrets and authorization policies from external policy registries.
AuthConfig
s can refer to identity providers (IdP) and trusted auth servers whose access tokens will be accepted to authenticate to the protected host. Consumers obtain an authentication token (short-lived access token or long-lived API key) and send those in the requests to the protected service.
When Authorino is triggered by Envoy via the gRPC interface, it starts evaluating the Auth Pipeline, i.e. it applies to the request the parameters to verify the identity and to enforce authorization, as found in the index for the requested host (See host lookup for details).
Apart from static rules, these parameters can include instructions to contact online with external identity verifiers, external sources of metadata and policy decision points (PDPs).
-On every request, Authorino's "working memory" is called Authorization JSON, a data structure that holds information about the context (the HTTP request) and objects from each phase of the auth pipeline: i.e., identity verification (phase i), ad-hoc metadata fetching (phase ii), authorization policy enforcement (phase iii) and dynamic response (phase iv). The evaluators in each of these phases can both read and write from the Authorization JSON for dynamic steps and decisions of authN/authZ.
+On every request, Authorino's "working memory" is called Authorization JSON, a data structure that holds information about the context (the HTTP request) and objects from each phase of the auth pipeline: i.e., authentication verification (phase i), ad-hoc metadata fetching (phase ii), authorization policy enforcement (phase iii), dynamic response (phase iv), and callbacks (phase v). The evaluators in each of these phases can both read and write from the Authorization JSON for dynamic steps and decisions of authN/authZ.
Typically, upstream APIs are deployed to the same Kubernetes cluster and namespace where the Envoy proxy and Authorino is running (although not necessarily). Whatever is the case, Envoy must be proxying to the upstream API (see Envoy's HTTP route components and virtual hosts) and pointing to Authorino in the external authorization filter.
This can be achieved with different topologies:
@@ -3855,7 +3830,7 @@Recommended in the protected services to validate the origin of the traffic. It must have been proxied by Envoy. See Authorino JSON injection for an extra validation option using a shared secret passed in HTTP header.
+Recommended in the protected services to validate the origin of the traffic. It must have been proxied by Envoy. See Authorino JSON injection for an extra validation option using a shared secret passed in HTTP header.
Protected service should only listen on localhost
and all traffic can be considered safe.
namespaced
instances of Authorino with fine-grained label selectors to avoid unnecessary caching of AuthConfig
s.
Apart from that, protected service should only listen on localhost
and all traffic can be considered safe.
Auhorino instances can run in either cluster-wide or namespaced mode.
-Namespace-scoped instances only watch resources (AuthConfig
s and Secret
s) created in a given namespace. This deployment mode does not require admin privileges over the Kubernetes cluster to deploy the instance of the service (given Authorino's CRDs have been installed beforehand, such as when Authorino is installed using the Authorino Operator).
Authorino instances can run in either cluster-wide or namespaced mode.
+Namespace-scoped instances only watch resources (AuthConfig
s and Secret
s) created in a given namespace. This deployment mode does not require admin privileges over the Kubernetes cluster to deploy the instance of the service (given Authorino's CRDs have been installed beforehand, such as when Authorino is installed using the Authorino Operator).
Cluster-wide deployment mode, in contraposition, deploys instances of Authorino that watch resources across the entire cluster, consolidating all resources into a multi-namespace index of auth configs. Admin privileges over the Kubernetes cluster is required to deploy Authorino in cluster-wide mode.
Be careful to avoid superposition when combining multiple Authorino instances and instance modes in the same Kubernetes cluster. Apart from caching unnecessary auth config data in the instances depending on your routing settings, the leaders of each instance (set of replicas) may compete for updating the status of the custom resources that are reconciled. See Resource reconciliation and status update for more information.
If necessary, use label selectors to narrow down the space of resources watched and reconciled by each Authorino instance. Check out the Sharding section below for details.
AuthConfig
Custom Resource Definition (CRD)¶The desired protection for a service is declaratively stated by applying an AuthConfig
Custom Resource to the Kubernetes cluster running Authorino.
An AuthConfig
resource typically looks like the following:
apiVersion: authorino.kuadrant.io/v1beta1
+apiVersion: authorino.kuadrant.io/v1beta2
kind: AuthConfig
metadata:
name: my-api-protection
spec:
- # List of one or more hostname[:port] entries, lookup keys to find this config in request-time
- # Authorino will try to prevent hostname collision by rejecting a hostname already taken.
- hosts:
-
- - my-api.io # north-south traffic
- - my-api.ns.svc.cluster.local # east-west traffic
-
- # List of one or more trusted sources of identity:
- # - Endpoints of issuers of OpenId Connect ID tokens (JWTs)
- # - Endpoints for OAuth 2.0 token introspection
- # - Attributes for the Kubernetes `TokenReview` API
- # - Label selectors for API keys (stored in Kubernetes `Secret`s)
- # - mTLS trusted certificate issuers
- # - HMAC secrets
- identity: […]
-
- # List of sources of external metadata for the authorization (optional):
- # - Endpoints for HTTP GET or GET-by-POST requests
- # - OIDC UserInfo endpoints (associated with an OIDC token issuer)
- # - User-Managed Access (UMA) resource registries
- metadata: […]
-
- # List of authorization policies to be enforced (optional):
- # - JSON pattern-matching rules (e.g. `context.request.http.path eq '/pets'`)
- # - Open Policy Agent (OPA) inline or external Rego policies
- # - Attributes for the Kubernetes `SubjectAccessReview` API
- authorization: […]
-
- # List of dynamic response elements, to inject post-external authorization data into the request (optional):
- # - JSON objects
- # - Festival Wristbands (signed JWTs issued by Authorino)
- # - Envoy Dynamic Metadata
- response: […]
-
- # Custom HTTP status code, message and headers to replace the default `401 Unauthorized` and `403 Forbidden` (optional)
- denyWith:
- unauthenticated:
- code: 302
- message: Redirecting to login
- headers:
-
- - name: Location
- value: https://my-app.io/login
- unauthorized: {…}
+ # The list of public host names of the services protected by this AuthConfig resource.
+ # Authorino uses the host name provided in the payload of external authorization request to lookup for the corresponding AuthConfig to enforce.
+ # Hostname collisions are prevented by rejecting to index a hostname already taken by another AuthConfig.
+ # Format: hostname[:port]
+ hosts:
+
+ - my-api.io:443 # north-south traffic
+ - my-api.ns.svc.cluster.local # east-west traffic
+
+ # Set of stored named patterns to be reused in conditions and pattern-matching authorization rules
+ patterns: {"name" → {selector, operator, value}, …}
+
+ # Top-level conditions for the AuthConfig to be enforced.
+ # If omitted, the AuthConfig will be enforced at all requests.
+ # If present, all conditions must match for the AuthConfig to be enforced; otherwise, Authorino skips the AuthConfig and returns to the auth request with status OK.
+ when: [{selector, operator, value | named pattern ref}, …]
+
+ # List of one or more trusted sources of identity:
+ # - Configurations to verify JSON Web Tokens (JWTs) issued by an OpenID Connect (OIDC) server
+ # - Endpoints for OAuth 2.0 token introspection
+ # - Attributes for the Kubernetes `TokenReview` API
+ # - Label selectors for API keys (stored in Kubernetes `Secret`s)
+ # - Label selectors trusted x509 issuer certificates (stored in Kubernetes `Secret`s)
+ # - Selectors for plain identity objects supplied in the payload of the authorization request
+ # - Anonymous access configs
+ authentication: {"name" → {…}, …}
+
+ # List of sources of external metadata for the authorization (optional):
+ # - Endpoints for HTTP GET or GET-by-POST requests
+ # - OIDC UserInfo endpoints (associated with an OIDC token issuer specified in the authentication configs)
+ # - User-Managed Access (UMA) resource registries
+ metadata: {"name" → {…}, …}
+
+ # List of authorization policies to be enforced (optional):
+ # - Pattern-matching rules (e.g. `context.request.http.path eq '/pets'`)
+ # - Open Policy Agent (OPA) inline or external Rego policies
+ # - Attributes for the Kubernetes `SubjectAccessReview` API
+ # – Attributes for authorization with an external SpiceDB server
+ authorization: {"name" → {…}, …}
+
+ # Customization to the response to the external authorization request (optional)
+ response:
+ # List of dynamic response elements into the request on success authoization (optional):
+ # - Plain text
+ # - JSON objects
+ # - Festival Wristbands (signed JWTs issued by Authorino)
+ success:
+ # List of HTTP headers to inject into the request post-authorization (optional):
+ headers: {"name" → {…}, …}
+
+ # List of Envoy Dynamic Metadata to inject into the request post-authorization (optional):
+ dynamicMetadata: {"name" → {…}, …}
+
+ # Custom HTTP status code, message and headers to replace the default `401 Unauthorized` response (optional)
+ unauthenticated:
+ code: 302
+ message: Redirecting to login
+ headers:
+ "Location":
+ value: https://my-app.io/login
+
+ # Custom HTTP status code, message and headers to replace the default `and `403 Forbidden` response (optional)
+ unauthorized: {code, message, headers, body}
+
+ # List of callback targets:
+ # - Endpoints for HTTP requests
+ callbacks: {"name" → {…}, …}
-Check out the OAS of the AuthConfig
CRD for a formal specification of the options for identity
verification, external metadata
fetching, authorization
policies, and dynamic response
, as well as any other host protection capability implemented by Authorino.
-You can also read the specification from the CLI using the kubectl explain
command. The Authorino CRD is required to have been installed in Kubernetes cluster. E.g. kubectl explain authconfigs.spec.identity.extendedProperties
.
+Check out the OAS of the AuthConfig
CRD for a formal specification of the options for authentication
verification, external metadata
fetching, authorization
policies, and dynamic response
, as well as any other host protection capability implemented by Authorino.
+You can also read the specification from the CLI using the kubectl explain
command. The Authorino CRD is required to have been installed in Kubernetes cluster. E.g. kubectl explain authconfigs.spec.authentication.overrides
.
A complete description of supported features and corresponding configuration options within an AuthConfig
CR can be found in the Features page.
More concrete examples of AuthConfig
s for specific use-cases can be found in the User guides.
Resource reconciliation and status update¶
The instances of the Authorino authorization service workload, following the Operator pattern, watch events related to the AuthConfig
custom resources, to build and reconcile an in-memory index of configs. Whenever a replica receives traffic for authorization request, it looks up in the index of AuthConfig
s and then triggers the "Auth Pipeline", i.e. enforces the associated auth spec onto the request.
-An instance can be a single authorization service workload or a set of replicas. All replicas watch and reconcile the same set of resources that match the AUTH_CONFIG_LABEL_SELECTOR
and SECRET_LABEL_SELECTOR
configuration options. (See both Cluster-wide vs. Namespaced instances and Sharding, for details about defining the reconciliation space of Authorino instances.)
+An instance can be a single authorization service workload or a set of replicas. All replicas watch and reconcile the same set of resources that match the --auth-config-label-selector
and --secret-label-selector
configuration options. (See both Cluster-wide vs. Namespaced instances and Sharding, for details about defining the reconciliation space of Authorino instances.)
The above means that all replicas of an Authorino instance should be able to receive traffic for authorization requests.
Among the multiple replicas of an instance, Authorino elects one replica to be leader. The leader is responsible for updating the status of reconciled AuthConfig
s. If the leader eventually becomes unavailable, the instance will automatically elect another replica take its place as the new leader.
-The status of an AuthConfig
tells whether the resource is "ready" (i.e. indexed). It also includes summary information regarding the numbers of identity configs, metadata configs, authorization configs and response configs within the spec, as well as whether Festival Wristband tokens are being issued by the Authorino instance as by spec.
-Apart from watching events related to AuthConfig
custom resources, Authorino also watches events related to Kubernetes Secret
s, as part of Authorino's API key authentication feature. Secret
resources that store API keys are linked to their corresponding AuthConfig
s in the index. Whenever the Authorino instance detects a change in the set of API key Secret
s linked to an AuthConfig
s, the instance reconciles the index.
-Authorino only watches events related to Secret
s whose metadata.labels
match the label selector SECRET_LABEL_SELECTOR
of the Authorino instance. The default values of the label selector for Kubernetes Secret
s representing Authorino API keys is authorino.kuadrant.io/managed-by=authorino
.
+The status of an AuthConfig
tells whether the resource is "ready" (i.e. indexed). It also includes summary information regarding the numbers of authentication configs, metadata configs, authorization configs and response configs within the spec, as well as whether Festival Wristband tokens are being issued by the Authorino instance as by spec.
+Apart from watching events related to AuthConfig
custom resources, Authorino also watches events related to Kubernetes Secret
s, as part of Authorino's API key authentication feature. Secret
resources that store API keys are linked to their corresponding AuthConfig
s in the index. Whenever the Authorino instance detects a change in the set of API key Secret
s linked to an AuthConfig
s, the instance reconciles the index.
+Authorino only watches events related to Secret
s whose metadata.labels
match the label selector --secret-label-selector
of the Authorino instance. The default values of the label selector for Kubernetes Secret
s representing Authorino API keys is authorino.kuadrant.io/managed-by=authorino
.
The "Auth Pipeline" (aka: enforcing protection in request-time)¶
-
-In each request to the protected API, Authorino triggers the so-called "Auth Pipeline", a set of configured evaluators that are organized in a 4-phase pipeline:
+
+In each request to the protected API, Authorino triggers the so-called "Auth Pipeline", a set of configured evaluators that are organized in a 5-phase pipeline:
-- (i) Identity phase: at least one source of identity (i.e., one identity evaluator) must resolve the supplied credential in the request into a valid identity or Authorino will otherwise reject the request as unauthenticated (401 HTTP response status).
-- (ii) Metadata phase: optional fetching of additional data from external sources, to add up to context and identity information, and used in authorization policies and dynamic responses (phases iii and iv).
+- (i) Authentication phase: at least one source of identity (i.e., one authentication config) must resolve the supplied credential in the request into a valid identity or Authorino will otherwise reject the request as unauthenticated (401 HTTP response status).
+- (ii) Metadata phase: optional fetching of additional data from external sources, to add up to context and identity information, and used in authorization policies, dynamic responses and callback requests (phases iii to v).
- (iii) Authorization phase: all unskipped policies must evaluate to a positive result ("authorized"), or Authorino will otherwise reject the request as unauthorized (403 HTTP response code).
- (iv) Response phase – Authorino builds all user-defined response items (dynamic JSON objects and/or Festival Wristband OIDC tokens), which are supplied back to the external authorization client within added HTTP headers or as Envoy Dynamic Metadata
+- (v) Callbacks phase – Authorino sends callbacks to specified HTTP endpoints.
-Each phase is sequential to the other, from (i) to (iv), while the evaluators within each phase are triggered concurrently or as prioritized. The Identity phase (i) is the only one required to list at least one evaluator (i.e. one identity source or more); Metadata, Authorization and Response phases can have any number of evaluators (including zero, and even be omitted in this case).
+Each phase is sequential to the other, from (i) to (v), while the evaluators within each phase are triggered concurrently or as prioritized. The Authentication phase (i) is the only one required to list at least one evaluator (i.e. 1+ authentication configs); Metadata, Authorization and Response phases can have any number of evaluators (including zero, and even be omitted in this case).
Host lookup¶
Authorino reads the request host from Attributes.Http.Host
of Envoy's CheckRequest
type, and uses it as key to lookup in the index of AuthConfig
s, matched against spec.hosts
.
Alternatively to Attributes.Http.Host
, a host
entry can be supplied in the Attributes.ContextExtensions
map of the external authorino request. This will take precedence before the host attribute of the HTTP request.
The host
context extension is useful to support use cases such as of path prefix-based lookup and wildcard subdomains lookup with lookup strongly dictated by the external authorization client (e.g. Envoy), which often knows about routing and the expected AuthConfig
to enforce beyond what Authorino can infer strictly based on the host name.
-Wildcards can also be used in the host names specified in the AuthConfig
, resolved by Authorino. E.g. if *.pets.com
is in spec.hosts
, Authorino will match the concrete host names dogs.pets.com
, cats.pets.com
, etc. In case, of multiple possible matches, Authorino will try the longest match first (in terms of host name labels) and fall back to closest wildcard upwards in the domain tree (if any).
+Wildcards can also be used in the host names specified in the AuthConfig
, resolved by Authorino. E.g. if *.pets.com
is in spec.hosts
, Authorino will match the concrete host names dogs.pets.com
, cats.pets.com
, etc. In case, of multiple possible matches, Authorino will try the longest match first (in terms of host name labels) and fall back to the closest wildcard upwards in the domain tree (if any).
When more than one host name is specified in the AuthConfig
, all of them can be used as key, i.e. all of them can be requested in the authorization request and will be mapped to the same config.
Example. Host lookup with wildcards.
@@ -3962,13 +3961,14 @@ Host lookupfoo.org
→ 404 Not found
-The host can include the port number (i.e. hostname:port
) or it can be just the name of the host name. Authorino will first try finding in the index a config associated to hostname:port
, as supplied in the authorization request; if the index misses an entry for hostname:port
, Authorino will then remove the :port
suffix and repeate the lookup using just hostname
as key. This provides implicit support for multiple port numbers for a same host without having to list all combinations in the AuthConfig
.
+The host can include the port number (i.e. hostname:port
) or it can be just the name of the host name. Authorino will first try finding in the index a config associated to hostname:port
, as supplied in the authorization request; if the index misses an entry for hostname:port
, Authorino will then remove the :port
suffix and repeat the lookup using just hostname
as key. This provides implicit support for multiple port numbers for a same host without having to list all combinations in the AuthConfig
.
Avoiding host name collision¶
-Authorino tries to prevent host name collision between AuthConfig
s by rejecting to link in the index any AuthConfig
and host name if the host name is already linked to a different AuthConfig
in the index. This was intentionally designed to prevent users from surperseding each others' AuthConfig
s, partially or fully, by just picking the same host names or overlapping host names as others.
+Authorino tries to prevent host name collision between AuthConfig
s by rejecting to link in the index any AuthConfig
and host name if the host name is already linked to a different AuthConfig
in the index. This was intentionally designed to prevent users from superseding each other's AuthConfig
s, partially or fully, by just picking the same host names or overlapping host names as others.
When wildcards are involved, a host name that matches a host wildcard already linked in the index to another AuthConfig
will be considered taken, and therefore the newest AuthConfig
will be rejected to be linked to that host.
+This behavior can be disabled to allow AuthConfig
s to partially supersede each others' host names (limited to strict host subsets), by supplying the --allow-superseding-host-subsets
command-line flag when running the Authorino instance.
The Authorization JSON¶
-On every Auth Pipeline, Authorino builds the Authorization JSON, a "working-memory" data structure composed of context
(information about the request, as supplied by the Envoy proxy to Authorino) and auth
(objects resolved in phases (i), (ii) and (iii) of the pipeline). The evaluators of each phase can read from the Authorization JSON and implement dynamic properties and decisions based on its values.
-At phase (iii), the authorization evaluators count on an Auhtorization JSON payload that looks like the following:
+On every Auth Pipeline, Authorino builds the Authorization JSON, a "working-memory" data structure composed of context
(information about the request, as supplied by the Envoy proxy to Authorino) and auth
(objects resolved in phases (i) to (v) of the pipeline). The evaluators of each phase can read from the Authorization JSON and implement dynamic properties and decisions based on its values.
+At phase (iii), the authorization evaluators count on an Authorization JSON payload that looks like the following:
// The authorization JSON combined along Authorino's auth pipeline for each request
{
"context": { // the input from the proxy
@@ -4022,8 +4022,8 @@ The Authorization JSON }
}
-Festival Wristbands and Dynamic JSON responses can include dynamic values (custom claims/properties) fetched from the authorization JSON. These can be returned to the external authorization client in added HTTP headers or as Envoy Well Known Dynamic Metadata. Check out Dynamic response features for details.
-For information about reading and fetching data from the Authorization JSON (syntax, functions, etc), check out JSON paths.
+Festival Wristbands and Dynamic JSON responses can include dynamic values (custom claims/properties) fetched from the authorization JSON. These can be returned to the external authorization client in added HTTP headers or as Envoy Well Known Dynamic Metadata. Check out Custom response features for details.
+For information about reading and fetching data from the Authorization JSON (syntax, functions, etc), check out JSON paths.
Raw HTTP Authorization interface¶
Besides providing the gRPC authorization interface – that implements the Envoy gRPC authorization server –, Authorino also provides another interface for raw HTTP authorization. This second interface responds to GET
and POST
HTTP requests sent to :5001/check
, and is suitable for other forms of integration, such as:
@@ -4035,8 +4035,8 @@ Raw HTTP Authorization interfaceCaching¶
OpenID Connect and User-Managed Access configs¶
OpenID Connect and User-Managed Access configurations, discovered usually at reconciliation-time from well-known discovery endpoints.
-Cached individual OpenID Connect configurations discovered by Authorino can be configured to be auto-refreshed, by setting the corresponding spec.identity.oidc.ttl
field in the AuthConfig (given in seconds, default: 0
– i.e. no cache update).
-JSON Web Keys (JWKs) and JSON Web Ket Sets (JWKS)¶
+Cached individual OpenID Connect configurations discovered by Authorino can be configured to be auto-refreshed, by setting the corresponding spec.authentication.jwt.ttl
field in the AuthConfig (given in seconds, default: 0
– i.e. no cache update).
+JSON Web Keys (JWKs) and JSON Web Key Sets (JWKS)¶
JSON signature verification certificates linked by discovered OpenID Connect configurations, fetched usually at reconciliation-time.
Revoked access tokens¶
@@ -4073,13 +4073,13 @@ ShardingKubernetes label selectors, defined for the Authorino instance via AUTH_CONFIG_LABEL_SELECTOR
environment variable. By default, AUTH_CONFIG_LABEL_SELECTOR
is empty, meaning all AuthConfig
s in the space are watched; this variable can be set to any value parseable as a valid label selector, causing Authorino to then watch only events of AuthConfig
s whose metadata.labels
match the selector.
+
Authorino's custom controllers filter the AuthConfig
-related events to be reconciled using Kubernetes label selectors, defined for the Authorino instance via --auth-config-label-selector
command-line flag. By default, --auth-config-label-selector
is empty, meaning all AuthConfig
s in the space are watched; this variable can be set to any value parseable as a valid label selector, causing Authorino to then watch only events of AuthConfig
s whose metadata.labels
match the selector.
The following are all valid examples of AuthConfig
label selector filters:
-AUTH_CONFIG_LABEL_SELECTOR="authorino.kuadrant.io/managed-by=authorino"
-AUTH_CONFIG_LABEL_SELECTOR="authorino.kuadrant.io/managed-by=authorino,other-label=other-value"
-AUTH_CONFIG_LABEL_SELECTOR="authorino.kuadrant.io/managed-by in (authorino,kuadrant)"
-AUTH_CONFIG_LABEL_SELECTOR="authorino.kuadrant.io/managed-by!=authorino-v0.4"
-AUTH_CONFIG_LABEL_SELECTOR="!disabled"
+--auth-config-label-selector="authorino.kuadrant.io/managed-by=authorino"
+--auth-config-label-selector="authorino.kuadrant.io/managed-by=authorino,other-label=other-value"
+--auth-config-label-selector="authorino.kuadrant.io/managed-by in (authorino,kuadrant)"
+--auth-config-label-selector="authorino.kuadrant.io/managed-by!=authorino-v0.4"
+--auth-config-label-selector="!disabled"
RBAC¶
The table below describes the roles and role bindings defined by the Authorino service:
@@ -4147,7 +4147,7 @@ RBAC&par
(*) C - Cluster-wide | N - Authorino namespace | C/N - Cluster-wide or Authorino namespace (depending on the deployment mode).
Observability¶
-Please refer to the respective user guides for info about Metrics & Observability and Logging & Tracing.
+Please refer to the Observability user guide for info on Prometheus metrics exported by Authorino, readiness probe, logging, tracing, etc.
diff --git a/0.10.0/authorino/docs/auth-pipeline.gif b/0.10.0/authorino/docs/auth-pipeline.gif
new file mode 100644
index 000000000..98ef6b750
Binary files /dev/null and b/0.10.0/authorino/docs/auth-pipeline.gif differ
diff --git a/0.10.0/authorino/docs/auth-pipeline.png b/0.10.0/authorino/docs/auth-pipeline.png
deleted file mode 100644
index 4bc0d9c6f..000000000
Binary files a/0.10.0/authorino/docs/auth-pipeline.png and /dev/null differ
diff --git a/0.10.0/authorino/docs/code_of_conduct/index.html b/0.10.0/authorino/docs/code_of_conduct/index.html
index 031ef97af..378f0a33f 100644
--- a/0.10.0/authorino/docs/code_of_conduct/index.html
+++ b/0.10.0/authorino/docs/code_of_conduct/index.html
@@ -62,7 +62,7 @@
-
+
Skip to content
@@ -1500,7 +1500,7 @@
-
-
+
@@ -1859,7 +1859,7 @@
-
-
+
@@ -3286,9 +3286,9 @@
-
-
+
- Authorino Code of Conduct v1.0
+ Code of Conduct
@@ -3319,15 +3319,9 @@
Code of conduct
-Authorino Code of Conduct v1.0¶
-This document provides community guidelines for a safe, respectful, productive, and collaborative place for any person who is willing to contribute to Authorino.
-
-- Participants will be tolerant of opposing views.
-- Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
-- When interpreting the words and actions of others, participants should always assume good intentions.
-- Behaviour which can be reasonably considered harassment will not be tolerated.
-
-This Code of Conduct is adapted from the The Ruby Community Conduct Guideline
+Code of Conduct¶
+Autorino follows the Kuadrant Community Code of Conduct, which is based on the CNCF Code of Conduct.
+Please refer to this page for a description of the standards and values we stand for in our relationship with the community.
diff --git a/0.10.0/authorino/docs/contributing/index.html b/0.10.0/authorino/docs/contributing/index.html
index 391ba92f3..97034b924 100644
--- a/0.10.0/authorino/docs/contributing/index.html
+++ b/0.10.0/authorino/docs/contributing/index.html
@@ -1504,7 +1504,7 @@
-
-
+
@@ -1863,7 +1863,7 @@
-
-
+
@@ -3653,50 +3653,35 @@
Developer's Guide¶
-
-- Technology stack for developers
-- Workflow
-- Check the issues
-- Clone the repo and setup the local environment
-- Make your changes
-- Run the tests
-- Try locally
-
-- Sign your commits
-- Logging policy
-- Additional resources
-- Reach out
-
Technology stack for developers¶
Minimum requirements to contribute to Authorino are:
Authorino's code was originally bundled using the Operator SDK (v1.9.0).
The following tools can be installed as part of the development workflow:
-- Installed with
go install
to the $PROJECT_DIR/bin
directory:
+-
+
Installed with go install
to the $PROJECT_DIR/bin
directory:
+
- controller-gen: for building custom types and manifests
- Kustomize: for assembling flavoured manifests and installing/deploying
-- setup-envtest: for running the tests – extra tools installed to
./testbin
-- [benchstat]https://cs.opensource.google/go/x/perf): for human-friendly test benchmark reports
-- mockgen: to generate mocks for tests – e.g.
./bin/mockgen -source=pkg/auth/auth.go -destination=pkg/auth/mocks/mock_auth.go
--
-
Kind: for deploying a containerized Kubernetes cluster for integration testing purposes
+ - setup-envtest: for running the tests – extra tools installed to
./testbin
+- benchstat: for human-friendly test benchmark reports
+- mockgen: to generate mocks for tests – e.g.
./bin/mockgen -source=pkg/auth/auth.go -destination=pkg/auth/mocks/mock_auth.go
+- Kind: for deploying a containerized Kubernetes cluster for integration testing purposes
+
-
Other recommended tools to have installed:
-
+
+
+
Workflow¶
Check the issues¶
@@ -3717,7 +3702,7 @@ Make your changesGolang conventions
- have proper test coverage
-- address corresponding updates to the docs
+- address corresponding updates to the docs
- help us fix wherever we failed to do the above 😜
Run the tests¶
@@ -3729,10 +3714,10 @@ Build, deploy and try
The following command will:
- Start a local Kubernetes cluster (using Kind)
+- Install cert-manager in the cluster
- Install the Authorino Operator and Authorino CRDs
- Build an image of Authorino based on the current branch
- Push the freshly built image to the cluster's registry
-- Install cert-manager in the cluster
- Generate TLS certificates for the Authorino service
- Deploy an instance of Authorino
- Deploy the example application Talker API, a simple HTTP API that echoes back whatever it gets in the request
@@ -3746,103 +3731,98 @@ Build, deploy and try
- Pro tips
-
-
- 1. Change the default workload namespace by supplying the `NAMESPACE` argument to your `make local-setup` and other deployment, apps and local cluster related targets. If the namespace does not exist, it will be created.
- 2. Switch to TLS disabled by default when deploying locally by supplying `TLS_ENABLED=0` to your `make local-setup` and `make deploy` commands. E.g. `make local-setup TLS_ENABLED=0`.
- 3. Skip being prompted to edit the `Authorino` CR and default to an Authorino deployment with TLS enabled, debug/development log level/mode, and standard name 'authorino', by supplying `FF=1` to your `make local-setup` and `make deploy` commands. E.g. `make local-setup FF=1`
- 4. Supply `DEPLOY_IDPS=1` to `make local-setup` and `make user-apps` to deploy Keycloak and Dex to the cluster. `DEPLOY_KEYCLOAK` and `DEPLOY_DEX` are also available. Read more about additional tools for specific use cases in the section below.
- 5. Saving the ID of the process (PID) of the port-forward command spawned in the background can be useful to later kill and restart the process. E.g. `kubectl port-forward deployment/envoy 8000:8000 &;PID=$!`; then `kill $PID`.
+Pro tips
+
+- Change the default workload namespace by supplying the
NAMESPACE
argument to your make local-setup
and other deployment, apps and local cluster related targets. If the namespace does not exist, it will be created.
+- Switch to TLS disabled by default when deploying locally by supplying
TLS_ENABLED=0
to your make local-setup
and make deploy
commands. E.g. make local-setup TLS_ENABLED=0
.
+- Skip being prompted to edit the
Authorino
CR and default to an Authorino deployment with TLS enabled, debug/development log level/mode, and standard name 'authorino', by supplying FF=1
to your make local-setup
and make deploy
commands. E.g. make local-setup FF=1
+- Supply
DEPLOY_IDPS=1
to make local-setup
and make user-apps
to deploy Keycloak and Dex to the cluster. DEPLOY_KEYCLOAK
and DEPLOY_DEX
are also available. Read more about additional tools for specific use cases in the section below.
+- Saving the ID of the process (PID) of the port-forward command spawned in the background can be useful to later kill and restart the process. E.g.
kubectl port-forward deployment/envoy 8000:8000 &;PID=$!
; then kill $PID
.
+
-
Additional tools (for specific use-cases)¶
- Limitador
-
- To deploy [Limitador](https://github.com/kuadrant/limitador) – pre-configured in Envoy for rate-limiting the Talker API to 5 hits per minute per `user_id` when available in the cluster workload –, run:
-
- kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/limitador/limitador-deploy.yaml
+Limitador
+To deploy Limitador – pre-configured in Envoy for rate-limiting the Talker API to 5 hits per minute per user_id
when available in the cluster workload –, run:
+kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/limitador/limitador-deploy.yaml
-
- Keycloak
-
- Authorino examples include a bundle of [Keycloak](https://www.keycloak.org) preloaded with the following realm setup:
-
- - Admin console: http://localhost:8080/auth/admin (admin/p)
- - Preloaded realm: **kuadrant**
- - Preloaded clients:
- - **demo**: to which API consumers delegate access and therefore the one which access tokens are issued to
- - **authorino**: used by Authorino to fetch additional user info with `client_credentials` grant type
- - **talker-api**: used by Authorino to fetch UMA-protected resource data associated with the Talker API
- - Preloaded resources:
- - `/hello`
- - `/greetings/1` (owned by user jonh)
- - `/greetings/2` (owned by user jane)
- - `/goodbye`
- - Realm roles:
- - member (default to all users)
- - admin
- - Preloaded users:
- - john/p (member)
- - jane/p (admin)
- - peter/p (member, email not verified)
-
- To deploy, run:
-
- kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/keycloak/keycloak-deploy.yaml
+Keycloak
+Authorino examples include a bundle of Keycloak preloaded with the following realm setup:
+
+- Admin console: http://localhost:8080/admin (admin/p)
+- Preloaded realm: kuadrant
+- Preloaded clients:
+- demo: to which API consumers delegate access and therefore the one which access tokens are issued to
+- authorino: used by Authorino to fetch additional user info with
client_credentials
grant type
+- talker-api: used by Authorino to fetch UMA-protected resource data associated with the Talker API
+
+
+- Preloaded resources:
+/hello
+/greetings/1
(owned by user john)
+/greetings/2
(owned by user jane)
+/goodbye
+
+
+- Realm roles:
+- member (default to all users)
+- admin
+
+
+- Preloaded users:
+- john/p (member)
+- jane/p (admin)
+- peter/p (member, email not verified)
+
+
+
+To deploy, run:
+kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/keycloak/keycloak-deploy.yaml
-
- Forward local requests to the instance of Keycloak running in the cluster:
-
- kubectl port-forward deployment/keycloak 8080:8080 &
+Forward local requests to the instance of Keycloak running in the cluster:
+
-
- Dex
-
- Authorino examples include a bundle of [Dex](https://dexidp.io) preloaded with the following setup:
-
- - Preloaded clients:
- - **demo**: to which API consumers delegate access and therefore the one which access tokens are issued to (Client secret: aaf88e0e-d41d-4325-a068-57c4b0d61d8e)
- - Preloaded users:
- - marta@localhost/password
-
- To deploy, run:
-
- kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/dex/dex-deploy.yaml
+Dex
+Authorino examples include a bundle of Dex preloaded with the following setup:
+
+- Preloaded clients:
+- demo: to which API consumers delegate access and therefore the one which access tokens are issued to (Client secret: aaf88e0e-d41d-4325-a068-57c4b0d61d8e)
+
+
+- Preloaded users:
+- marta@localhost/password
+
+
+
+To deploy, run:
+kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/dex/dex-deploy.yaml
-
- Forward local requests to the instance of Dex running in the cluster:
-
- kubectl port-forward deployment/dex 5556:5556 &
+Forward local requests to the instance of Dex running in the cluster:
+
-
- a12n-server
-
- Authorino examples include a bundle of [**a12n-server**](https://github.com/curveball/a12n-server) and corresponding MySQL database, preloaded with the following setup:
-
- - Admin console: http://a12n-server:8531 (admin/123456)
- - Preloaded clients:
- - **service-account-1**: to obtain access tokens via `client_credentials` OAuth2 grant type, to consume the Talker API (Client secret: DbgXROi3uhWYCxNUq_U1ZXjGfLHOIM8X3C2bJLpeEdE); includes metadata privilege: `{ "talker-api": ["read"] }` that can be used to write authorization policies
- - **talker-api**: to authenticate to the token introspect endpoint (Client secret: V6g-2Eq2ALB1_WHAswzoeZofJ_e86RI4tdjClDDDb4g)
-
- To deploy, run:
-
- kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/a12n-server/a12n-server-deploy.yaml
+a12n-server
+Authorino examples include a bundle of a12n-server and corresponding MySQL database, preloaded with the following setup:
+
+- Admin console: http://a12n-server:8531 (admin/123456)
+- Preloaded clients:
+- service-account-1: to obtain access tokens via
client_credentials
OAuth2 grant type, to consume the Talker API (Client secret: DbgXROi3uhWYCxNUq_U1ZXjGfLHOIM8X3C2bJLpeEdE); includes metadata privilege: { "talker-api": ["read"] }
that can be used to write authorization policies
+- talker-api: to authenticate to the token introspect endpoint (Client secret: V6g-2Eq2ALB1_WHAswzoeZofJ_e86RI4tdjClDDDb4g)
+
+
+
+To deploy, run:
+kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/a12n-server/a12n-server-deploy.yaml
-
- Forward local requests to the instance of a12n-server running in the cluster:
-
- kubectl port-forward deployment/a12n-server 8531:8531 &
+Forward local requests to the instance of a12n-server running in the cluster:
+
-
Re-build and rollout latest¶
Re-build and rollout latest Authorino image:
make local-rollout
@@ -3859,7 +3839,7 @@ Sign your commitsLogging policy¶
A few guidelines for adding logging messages in your code:
-- Make sure you understand Authorino's Logging architecture and policy regarding log levels, log modes, tracing IDs, etc.
+- Make sure you understand Authorino's Logging architecture and policy regarding log levels, log modes, tracing IDs, etc.
- Respect controller-runtime's Logging Guidelines.
- Do not add sensitive data to your
info
log messages; instead, redact all sensitive data in your log messages or use debug
log level by mutating the logger with V(1)
before outputting the message.
@@ -3877,7 +3857,7 @@ Additional resourcesAuthorino examples
Reach out¶
-
+#kuadrant channel on kubernetes.slack.com.
diff --git a/0.10.0/authorino/docs/features/index.html b/0.10.0/authorino/docs/features/index.html
index 6f7bcad97..6f33d3cf3 100644
--- a/0.10.0/authorino/docs/features/index.html
+++ b/0.10.0/authorino/docs/features/index.html
@@ -1504,7 +1504,7 @@
-
-
+
@@ -1863,7 +1863,7 @@
-
-
+
@@ -2618,13 +2618,13 @@
-
-
+
- Common feature: JSON paths (valueFrom.authJSON)
+ Common feature: JSON paths (selector)
-
"headers": {
"authorization": "Basic amFuZTpzZWNyZXQK" // jane:secret
- }
- }
- }
- },
- "auth": {
- "identity": {
- "username": "jane",
- "fullname": "Jane Smith"
- },
- },
-}
+ "baggage": "eyJrZXkxIjoidmFsdWUxIn0=" // {"key1":"value1"}
+ }
+ }
+ }
+ },
+ "auth": {
+ "identity": {
+ "username": "jane",
+ "fullname": "Jane Smith",
+ "email": "\u0006jane\u0012@petcorp.com\n"
+ },
+ },
+}
+@strip
+Strips out any non-printable characters such as carriage return. E.g. auth.identity.email.@strip
→ "jane@petcorp.com"
.
@case:upper|lower
Changes the case of a string. E.g. auth.identity.username.@case:upper
→ "JANE"
.
@replace:{"old":string,"new":string}
@@ -4201,15 +4223,15 @@
String modifiers → "jane"
.
Interpolation¶
JSON paths can be interpolated into strings to build template-like dynamic values. E.g. "Hello, {auth.identity.name}!"
.
-Identity verification & authentication features (identity
)¶
-API key (identity.apiKey
)¶
+Identity verification & authentication features (authentication
)¶
+API key (authentication.apiKey
)¶
Authorino relies on Kubernetes Secret
resources to represent API keys.
To define an API key, create a Secret
in the cluster containing an api_key
entry that holds the value of the API key.
-API key secrets must be created in the same namespace of the AuthConfig
(default) or spec.identity.apiKey.allNamespaces
must be set to true
(only works with cluster-wide Authorino instances).
-API key secrets must be labeled with the labels that match the selectors specified in spec.identity.apiKey.selector
in the AuthConfig
.
-Whenever an AuthConfig
is indexed, Authorino will also index all matching API key secrets. In order for Authorino to also watch events related to API key secrets individually (e.g. new Secret
created, updates, deletion/revocation), Secret
s must also include a label that matches Authorino's bootstrap configuration SECRET_LABEL_SELECTOR
(default: authorino.kuadrant.io/managed-by=authorino
). This label may or may not be present to spec.identity.apiKey.selector
in the AuthConfig
without implications for the caching of the API keys when triggered by the reconciliation of the AuthConfig
; however, if not present, individual changes related to the API key secret (i.e. without touching the AuthConfig
) will be ignored by the reconciler.
+API key secrets must be created in the same namespace of the AuthConfig
(default) or spec.authentication.apiKey.allNamespaces
must be set to true
(only works with cluster-wide Authorino instances).
+API key secrets must be labeled with the labels that match the selectors specified in spec.authentication.apiKey.selector
in the AuthConfig
.
+Whenever an AuthConfig
is indexed, Authorino will also index all matching API key secrets. In order for Authorino to also watch events related to API key secrets individually (e.g. new Secret
created, updates, deletion/revocation), Secret
s must also include a label that matches Authorino's bootstrap configuration --secret-label-selector
(default: authorino.kuadrant.io/managed-by=authorino
). This label may or may not be present to spec.authentication.apiKey.selector
in the AuthConfig
without implications for the caching of the API keys when triggered by the reconciliation of the AuthConfig
; however, if not present, individual changes related to the API key secret (i.e. without touching the AuthConfig
) will be ignored by the reconciler.
Example. For the following AuthConfig
:
-apiVersion: authorino.kuadrant.io/v1beta1
+apiVersion: authorino.kuadrant.io/v1beta2
kind: AuthConfig
metadata:
name: my-api-protection
@@ -4217,12 +4239,12 @@ API key (spec:
hosts:
- - my-api.io
- identity:
- - name: api-key-users
+ - my-api.io
+ authentication:
+ "api-key-users":
apiKey:
selector:
- matchLabels: # the key-value set used to select the matching `Secret`s; resources including these labels will be acepted as valid API keys to authenticate to this service
+ matchLabels: # the key-value set used to select the matching `Secret`s; resources including these labels will be accepted as valid API keys to authenticate to this service
group: friends # some custom label
allNamespaces: true # only works with cluster-wide Authorino instances; otherwise, create the API key secrets in the same namespace of the AuthConfig
@@ -4240,67 +4262,60 @@ API key (type: Opaque
The resolved identity object, added to the authorization JSON following an API key identity source evaluation, is the Kubernetes Secret
resource (as JSON).
-Kubernetes TokenReview (identity.kubernetes
)¶
+Kubernetes TokenReview (authentication.kubernetesTokenReview
)¶
Authorino can verify Kubernetes-valid access tokens (using Kubernetes TokenReview API).
These tokens can be either ServiceAccount
tokens such as the ones issued by kubelet as part of Kubernetes Service Account Token Volume Projection, or any valid user access tokens issued to users of the Kubernetes server API.
The list of audiences
of the token must include the requested host and port of the protected API (default), or all audiences specified in the Authorino AuthConfig
custom resource. For example:
For the following AuthConfig
CR, the Kubernetes token must include the audience my-api.io
:
-apiVersion: authorino.kuadrant.io/v1beta1
+apiVersion: authorino.kuadrant.io/v1beta2
kind: AuthConfig
metadata:
name: my-api-protection
spec:
hosts:
- - my-api.io
- identity:
- - name: cluster-users
- kubernetes: {}
+ - my-api.io
+ authentication:
+ "cluster-users":
+ kubernetesTokenReview: {}
Whereas for the following AuthConfig
CR, the Kubernetes token audiences must include foo and bar:
-apiVersion: authorino.kuadrant.io/v1beta1
+apiVersion: authorino.kuadrant.io/v1beta2
kind: AuthConfig
metadata:
name: my-api-protection
spec:
hosts:
- - my-api.io
- identity:
- - name: cluster-users
- kubernetes:
+ - my-api.io
+ authentication:
+ "cluster-users":
+ kubernetesTokenReview:
audiences:
- - foo
- - bar
+ - foo
+ - bar
-The resolved identity object, added to the authorization JSON following a Kubernetes authentication identity source evaluation, is the decoded JWT when the Kubernetes token is a valid JWT, or the value of status.user
in the response to the TokenReview request (see Kubernetes UserInfo for details).
-OpenID Connect (OIDC) JWT/JOSE verification and validation (identity.oidc
)¶
+The resolved identity object added to the authorization JSON following a successful Kubernetes authentication identity evaluation is the status
field of TokenReview response (see TokenReviewStatus for reference).
+JWT verification (authentication.jwt
)¶
In reconciliation-time, using OpenID Connect Discovery well-known endpoint, Authorino automatically discovers and caches OpenID Connect configurations and associated JSON Web Key Sets (JWKS) for all OpenID Connect issuers declared in an AuthConfig
. Then, in request-time, Authorino verifies the JSON Web Signature (JWS) and check the time validity of signed JSON Web Tokens (JWT) supplied on each request.
Important! Authorino does not implement OAuth2 grants nor OIDC authentication flows. As a common recommendation of good practice, obtaining and refreshing access tokens is for clients to negotiate directly with the auth servers and token issuers. Authorino will only validate those tokens using the parameters provided by the trusted issuer authorities.
The kid
claim stated in the JWT header must match one of the keys cached by Authorino during OpenID Connect Discovery, therefore supporting JWK rotation.
The decoded payload of the validated JWT is appended to the authorization JSON as the resolved identity.
-OpenID Connect configurations and linked JSON Web Ket Sets can be configured to be automatically refreshed (pull again from the OpenID Connect Discovery well-known endpoints), by setting the identity.oidc.ttl
field (given in seconds, default: 0
– i.e. auto-refresh disabled).
+OpenID Connect configurations and linked JSON Web Key Sets can be configured to be automatically refreshed (pull again from the OpenID Connect Discovery well-known endpoints), by setting the authentication.jwt.ttl
field (given in seconds, default: 0
– i.e. auto-refresh disabled).
For an excellent summary of the underlying concepts and standards that relate OpenID Connect and JSON Object Signing and Encryption (JOSE), see this article by Jan Rusnacko. For official specification and RFCs, see OpenID Connect Core, OpenID Connect Discovery, JSON Web Token (JWT) (RFC7519), and JSON Object Signing and Encryption (JOSE).
-OAuth 2.0 introspection (identity.oauth2
)¶
+OAuth 2.0 introspection (authentication.oauth2Introspection
)¶
For bare OAuth 2.0 implementations, Authorino can perform token introspection on the access tokens supplied in the requests to protected APIs.
Authorino does not implement any of OAuth 2.0 grants for the applications to obtain the token. However, it can verify supplied tokens with the OAuth server, including opaque tokens, as long as the server exposes the token_introspect
endpoint (RFC 7662).
Developers must set the token introspection endpoint in the AuthConfig
, as well as a reference to the Kubernetes secret storing the credentials of the OAuth client to be used by Authorino when requesting the introspect.
-The response returned by the OAuth2 server to the token introspection request is the the resolved identity appended to the authorization JSON.
-OpenShift OAuth (user-echo endpoint) (identity.openshift
)¶
-
-
- Not implemented - In analysis
-
-
-
-Online token introspection of OpenShift-valid access tokens based on OpenShift's user-echo endpoint.
-Mutual Transport Layer Security (mTLS) authentication (identity.mtls
)¶
-Authorino can verify x509 certificates presented by clients for authentication on the request to the protected APIs, at application level.
+The response returned by the OAuth2 server to the token introspection request is the resolved identity appended to the authorization JSON.
+X.509 client certificate authentication (authentication.x509
)¶
+Authorino can verify X.509 certificates presented by clients for authentication on the request to the protected APIs, at application level.
Trusted root Certificate Authorities (CA) are stored in Kubernetes Secrets labeled according to selectors specified in the AuthConfig, watched and indexed by Authorino. Make sure to create proper kubernetes.io/tls
-typed Kubernetes Secrets, containing the public certificates of the CA stored in either a tls.crt
or ca.crt
entry inside the secret.
-Truested root CA secrets must be created in the same namespace of the AuthConfig
(default) or spec.identity.mtls.allNamespaces
must be set to true
(only works with cluster-wide Authorino instances).
-The identitiy object resolved out of a client x509 certificate is equal to the subject field of the certificate, and it serializes as JSON within the Authorization JSON usually as follows:
+Trusted root CA secrets must be created in the same namespace of the AuthConfig
(default) or spec.authentication.x509.allNamespaces
must be set to true
(only works with cluster-wide Authorino instances).
+Client certificates must include x509 v3 extension specifying 'Client Authentication' extended key usage.
+The identity object resolved out of a client x509 certificate is equal to the subject field of the certificate, and it serializes as JSON within the Authorization JSON usually as follows:
-Hash Message Authentication Code (HMAC) authentication (identity.hmac
)¶
-
-
- Not implemented - Planned (#9)
-
-
-
-Authentication based on the validation of a hash code generated from the contextual information of the request to the protected API, concatenated with a secret known by the API consumer.
-Plain (identity.plain
)¶
+Plain (authentication.plain
)¶
Authorino can read plain identity objects, based on authentication tokens provided and verified beforehand using other means (e.g. Envoy JWT Authentication filter, Kubernetes API server authentication), and injected into the payload to the external authorization service.
-The plain identity object is retrieved from the Authorization JSON based on a JSON path specified in the AuthConfig
.
+The plain identity object is retrieved from the Authorization JSON based on a JSON path specified in the AuthConfig
.
This feature is particularly useful in cases where authentication/identity verification is handled before invoking the authorization service and its resolved value injected in the payload can be trusted. Examples of applications for this feature include:
- Authentication handled in Envoy leveraging the Envoy JWT Authentication filter (decoded JWT injected as 'metadata_context')
@@ -4343,14 +4350,13 @@ Plain (identity.plain
)spec:
- identity:
-
- - name: plain
- plain:
- authJSON: context.metadata_context.filter_metadata.envoy\.filters\.http\.jwt_authn|verified_jwt
+ authentication:
+ "pre-validated-jwt":
+ plain:
+ selector: context.metadata_context.filter_metadata.envoy\.filters\.http\.jwt_authn|verified_jwt
If the specified JSON path does not exist in the Authorization JSON or the value is null
, the identity verification will fail and, unless other identity config succeeds, Authorino will halt the Auth Pipeline with the usual 401 Unauthorized
.
-Anonymous access (identity.anonymous
)¶
+Anonymous access (authentication.anonymous
)¶
Literally a no-op evaluator for the identity verification phase that returns a static identity object {"anonymous":true}
.
It allows to implement AuthConfigs
that bypasses the identity verification phase of Authorino, to such as:
@@ -4359,278 +4365,342 @@ Anonymous access (identity.ano
Example of AuthConfig
spec that falls back to anonymous access when OIDC authentication fails, enforcing read-only access to the protected service in such cases:
spec:
- identity:
-
- - name: jwt
- oidc: { endpoint: ... }
- - name: anonymous
- priority: 1 # expired oidc token, missing creds, etc default to anonymous access
- anonymous: {}
+ authentication:
+ "jwt":
+ jwt:
+ issuerUrl: "…"
+ "anonymous":
+ priority: 1 # expired oidc token, missing creds, etc. default to anonymous access
+ anonymous: {}
authorization:
- - name: read-only-access-if-authn-fails
- when:
- - selector: auth.identity.anonymous
- operator: eq
- value: "true"
- json:
- rules:
- - selector: context.request.http.method
- operator: eq
- value: GET
+ "read-only-access-if-authn-fails":
+ when:
+
+ - selector: auth.identity.anonymous
+ operator: eq
+ value: "true"
+ patternMatching:
+ patterns:
+ - selector: context.request.http.method
+ operator: eq
+ value: GET
Festival Wristband authentication¶
-Authorino-issued Festival Wristband tokens can be validated as any other signed JWT using Authorino's OpenID Connect (OIDC) JWT/JOSE verification and validation.
+Authorino-issued Festival Wristband tokens can be validated as any other signed JWT using Authorino's JWT verification.
The value of the issuer must be the same issuer specified in the custom resource for the protected API originally issuing wristband. Eventually, this can be the same custom resource where the wristband is configured as a valid source of identity, but not necessarily.
-Extra: Auth credentials (credentials
)¶
+Extra: Auth credentials (authentication.credentials
)¶
All the identity verification methods supported by Authorino can be configured regarding the location where access tokens and credentials (i.e. authentication secrets) fly within the request.
-By default, authentication secrets are expected to be supplied in the Authorization
HTTP header, with the Bearer
prefix and plain authentication secret, separated by space. The full list of supported options for the location of authentication secrets and selector is specified in the table below:
-
-
-
-Location (credentials.in
)
-Description
-Selector (credentials.keySelector
)
-
-
-
-
-authorization_header
-Authorization
HTTP header
-Prefix (default: Bearer
)
-
-
-custom_header
-Custom HTTP header
-Name of the header. Value should have no prefix.
-
-
-query
-Query string parameter
-Name of the parameter
-
-
-cookie
-Cookie header
-ID of the cookie entry
-
-
-
-Extra: Identity extension (extendedProperties
)¶
-Resolved identity objects can be extended with user-defined JSON properties. Values can be static or fetched from the Authorization JSON
-A typical use-case for this feature is token normalization. Say you have more than one identity source listed in the your AuthConfig
but each source issues an access token with a different JSON structure – e.g. two OIDC issuers that use different names for custom JWT claims of similar meaning; when two different identity verification/authentication methods are combined, such as API keys (whose identity objects are the corresponding Kubernetes Secret
s) and Kubernetes tokens (whose identity objects are Kubernetes UserInfo data).
-In such cases, identity extension can be used to normalize the token so it always includes the same set of JSON properties of interest, regardless of the source of identity that issued the original token verified by Authorino. This simplifies the writing of authorization policies and configuration of dynamic responses.
-External auth metadata features (metadata
)¶
-HTTP GET/GET-by-POST (metadata.http
)¶
-Generic HTTP adapter that sends a request to an external service. It can be used to fetch external metadata for the authorization policies (phase ii of the Authorino Auth Pipeline), or as a web hook.
+By default, authentication secrets are expected to be supplied in the Authorization
HTTP header, with the default Bearer
prefix and the plain authentication secret separated by space.
+The full list of supported options is exemplified below:
+spec:
+ authentication:
+ "creds-in-the-authz-header":
+ credentials:
+ authorizationHeader:
+ prefix: JWT
+
+ "creds-in-a-custom-header":
+ credentials:
+ customHeader:
+ name: X-MY-CUSTOM-HEADER
+ prefix: ""
+
+ "creds-in-a-query-param":
+ queryString:
+ name: my_param
+
+ "creds-in-a-cookie-entry":
+ cookie:
+ name: cookie-key
+
+Extra: Identity extension (authentication.defaults
and authentication.overrides
)¶
+Resolved identity objects can be extended with user-defined JSON properties. Values can be static or fetched from the Authorization JSON.
+A typical use-case for this feature is token normalization. Say you have more than one identity source listed in your AuthConfig
but each source issues an access token with a different JSON structure – e.g. two OIDC issuers that use different names for custom JWT claims of similar meaning; when two different identity verification/authentication methods are combined, such as API keys (whose identity objects are the corresponding Kubernetes Secret
s) and Kubernetes tokens (whose identity objects are Kubernetes UserInfo data).
+In such cases, identity extension can be used to normalize the token to always include the same set of JSON properties of interest, regardless of the source of identity that issued the original token verified by Authorino. This simplifies the writing of authorization policies and configuration of dynamic responses.
+In case of extending an existing property of the identity object (replacing), the API allows to control whether to overwrite the value or not. This is particularly useful for normalizing tokens of a same identity source that nonetheless may occasionally differ in structure, such as in the case of JWT claims that sometimes may not be present but can be safely replaced with another (e.g. username
or sub
).
+External auth metadata features (metadata
)¶
+HTTP GET/GET-by-POST (metadata.http
)¶
+Generic HTTP adapter that sends a request to an external service. It can be used to fetch external metadata for the authorization policies (phase ii of the Authorino Auth Pipeline), or as a web hook.
The adapter allows issuing requests either by GET or POST methods; in both cases with URL and parameters defined by the user in the spec. Dynamic values fetched from the Authorization JSON can be used.
POST request parameters as well as the encoding of the content can be controlled using the bodyParameters
and contentType
fields of the config, respectively. The Content-Type of POST requests can be either application/x-www-form-urlencoded
(default) or application/json
.
-A shared secret between Authorino and the external HTTP service can be defined (see sharedSecretRef
field), and the service can use such secret to authenticate the origin of the request. The location where the secret travels in the request performed by Authorino to the HTTP service can be specified in a typical credentials
field.
+Authentication of Authorino with the external metadata server can be set either via long-lived shared secret stored in a Kubernetes Secret or via OAuth2 client credentials grant. For long-lived shared secret, set the sharedSecretRef
field. For OAuth2 client credentials grant, use the oauth2
option.
+In both cases, the location where the secret (long-lived or OAuth2 access token) travels in the request performed to the external HTTP service can be specified in the credentials
field. By default, the authentication secret is supplied in the Authorization
header with the Bearer
prefix.
Custom headers can be set with the headers
field. Nevertheless, headers such as Content-Type
and Authorization
(or eventual custom header used for carrying the authentication secret, set instead via the credentials
option) will be superseded by the respective values defined for the fields contentType
and sharedSecretRef
.
-OIDC UserInfo (metadata.userInfo
)¶
-Online fetching of OpenID Connect (OIDC) UserInfo data (phase ii of the Authorino Auth Pipeline), associated with an OIDC identity source configured and resolved in phase (i).
+OIDC UserInfo (metadata.userInfo
)¶
+Online fetching of OpenID Connect (OIDC) UserInfo data (phase ii of the Authorino Auth Pipeline), associated with an OIDC identity source configured and resolved in phase (i).
Apart from possibly complementing information of the JWT, fetching OpenID Connect UserInfo in request-time can be particularly useful for remote checking the state of the session, as opposed to only verifying the JWT/JWS offline.
-Implementation requires an OpenID Connect issuer (spec.identity.oidc
) configured in the same AuthConfig
.
+Implementation requires a JWT verification authentication config (spec.authentication.jwt
) in the same AuthConfig
, so the well-known configuration of the OpenId Connect (OIDC) issuer can be reused.
The response returned by the OIDC server to the UserInfo request is appended (as JSON) to auth.metadata
in the authorization JSON.
-User-Managed Access (UMA) resource registry (metadata.uma
)¶
+User-Managed Access (UMA) resource registry (metadata.uma
)¶
User-Managed Access (UMA) is an OAuth-based protocol for resource owners to allow other users to access their resources. Since the UMA-compliant server is expected to know about the resources, Authorino includes a client that fetches resource data from the server and adds that as metadata of the authorization payload.
This enables the implementation of resource-level Attribute-Based Access Control (ABAC) policies. Attributes of the resource fetched in a UMA flow can be, e.g., the owner of the resource, or any business-level attributes stored in the UMA-compliant server.
A UMA-compliant server is an external authorization server (e.g., Keycloak) where the protected resources are registered. It can be as well the upstream API itself, as long as it implements the UMA protocol, with initial authentication by client_credentials
grant to exchange for a Protected API Token (PAT).
-It's important to notice that Authorino does NOT manage resources in the UMA-compliant server. As shown in the flow above, Authorino's UMA client is only to fetch data about the requested resources. Authorino exchanges client credentials for a Protected API Token (PAT), then queries for resources whose URI match the path of the HTTP request (as passed to Authorino by the Envoy proxy) and fetches data of each macthing resource.
-The resources data is added as metadata of the authorization payload and passed as input for the configured authorization policies. All resources returned by the UMA-compliant server in the query by URI are passed along. They are available in the PDPs (authorization payload) as input.auth.metadata.custom-name => Array
. (See The "Auth Pipeline" for details.)
-Authorization features (authorization
)¶
-JSON pattern-matching authorization rules (authorization.json
)¶
-Grant/deny access based on simple pattern-matching expressions ("rules") compared against values selected from the Authorization JSON.
+It's important to notice that Authorino does NOT manage resources in the UMA-compliant server. As shown in the flow above, Authorino's UMA client is only to fetch data about the requested resources. Authorino exchanges client credentials for a Protected API Token (PAT), then queries for resources whose URI match the path of the HTTP request (as passed to Authorino by the Envoy proxy) and fetches data of each matching resource.
+The resources data is added as metadata of the authorization payload and passed as input for the configured authorization policies. All resources returned by the UMA-compliant server in the query by URI are passed along. They are available in the PDPs (authorization payload) as input.auth.metadata.custom-name => Array
. (See The "Auth Pipeline" for details.)
+Authorization features (authorization
)¶
+Pattern-matching authorization (authorization.patternMatching
)¶
+Grant/deny access based on simple pattern-matching expressions ("patterns") compared against values selected from the Authorization JSON.
Each expression is a tuple composed of:
-- a
selector
, to fetch from the Authorization JSON – see Common feature: JSON paths for details about syntax;
+- a
selector
, to fetch from the Authorization JSON – see Common feature: JSON paths for details about syntax;
- an
operator
– eq
(equals), neq
(not equal); incl
(includes) and excl
(excludes), for arrays; and matches
, for regular expressions;
- a fixed comparable
value
Rules can mix and combine literal expressions and references to expression sets ("named patterns") defined at the upper level of the AuthConfig
spec. (See Common feature: Conditions)
-spec:
- authorization:
-
- - name: my-simple-json-pattern-matching-policy
- json:
- rules: # All rules must match for access to be granted
- - selector: auth.identity.email_verified
- operator: eq
- value: "true"
- - patternRef: admin
-
- pattterns:
- admin: # a named pattern that can be reused in other sets of rules or conditions
-
- - selector: auth.identity.roles
- operator: incl
- value: admin
+spec:
+ authorization:
+ "my-simple-json-pattern-matching-policy":
+ patternMatching:
+ patterns: # All patterns must match for access to be granted
+
+ - selector: auth.identity.email_verified
+ operator: eq
+ value: "true"
+ - patternRef: admin
+
+ patterns:
+ admin: # a named pattern that can be reused in other sets of rules or conditions
+
+ - selector: auth.identity.roles
+ operator: incl
+ value: admin
-Open Policy Agent (OPA) Rego policies (authorization.opa
)¶
+Open Policy Agent (OPA) Rego policies (authorization.opa
)¶
You can model authorization policies in Rego language and add them as part of the protection of your APIs.
-Policies can be either declared in-line in Rego language (inlineRego
) or as an HTTP endpoint where Authorino will fetch the source code of the policy in reconciliation-time (externalRegistry
).
-Policies pulled from external registries can be configured to be automatically refreshed (pulled again from the external registry), by setting the authorization.opa.externalRegistry.ttl
field (given in seconds, default: 0
– i.e. auto-refresh disabled).
+Policies can be either declared in-line in Rego language (rego
) or as an HTTP endpoint where Authorino will fetch the source code of the policy in reconciliation-time (externalPolicy
).
+Policies pulled from external registries can be configured to be automatically refreshed (pulled again from the external registry), by setting the authorization.opa.externalPolicy.ttl
field (given in seconds, default: 0
– i.e. auto-refresh disabled).
Authorino's built-in OPA module precompiles the policies during reconciliation of the AuthConfig and caches the precompiled policies for fast evaluation in runtime, where they receive the Authorization JSON as input.
An optional field allValues: boolean
makes the values of all rules declared in the Rego document to be returned in the OPA output after policy evaluation. When disabled (default), only the boolean value allow
is returned. Values of internal rules of the Rego document can be referenced in subsequent policies/phases of the Auth Pipeline.
-Kubernetes SubjectAccessReview (authorization.kubernetes
)¶
+Kubernetes SubjectAccessReview (authorization.kubernetesSubjectAccessReview
)¶
Access control enforcement based on rules defined in the Kubernetes authorization system, i.e. Role
, ClusterRole
, RoleBinding
and ClusterRoleBinding
resources of Kubernetes RBAC.
-Authorino issues a SubjectAccessReview (SAR) inquiry that checks with the underlying Kubernetes server whether the user can access a particular resource, resurce kind or generic URL.
+Authorino issues a SubjectAccessReview (SAR) inquiry that checks with the underlying Kubernetes server whether the user can access a particular resource, resource kind or generic URL.
It supports resource attributes authorization check (parameters defined in the AuthConfig
) and non-resource attributes authorization check (HTTP endpoint inferred from the original request).
- Resource attributes: adequate for permissions set at namespace level, defined in terms of common attributes of operations on Kubernetes resources (namespace, API group, kind, name, subresource, verb)
- Non-resource attributes: adequate for permissions set at cluster scope, defined for protected endpoints of a generic HTTP API (URL path + verb)
Example of Kubernetes role for resource attributes authorization:
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- name: pet-reader
-rules:
-
-- apiGroups: ["pets.io"]
- resources: ["pets"]
- verbs: ["get"]
-
-Example of Kubernetes cluster role for non-resource attributes authorization:
apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
+kind: Role
metadata:
- name: pet-editor
+ name: pet-reader
rules:
-- nonResourceURLs: ["/pets/*"]
- verbs: ["put", "delete"]
+- apiGroups: ["pets.io"]
+ resources: ["pets"]
+ verbs: ["get"]
-Kubernetes authorization policy configs look like the following in an Authorino AuthConfig
:
-authorization:
-
- - name: kubernetes-rbac
- kubernetes:
- user:
- valueFrom: # values of the parameter can be fixed (`value`) or fetched from the Auhtorization JSON (`valueFrom.authJSON`)
- authJSON: auth.identity.metadata.annotations.userid
-
- groups: [] # user groups to test for.
-
- # for resource attributes permission checks; omit it to perform a non-resource attributes SubjectAccessReview with path and method/verb assumed from the original request
- # if included, use the resource attributes, where the values for each parameter can be fixed (`value`) or fetched from the Auhtorization JSON (`valueFrom.authJSON`)
- resourceAttributes:
- namespace:
- value: default
- group:
- value: pets.io # the api group of the protected resource to be checked for permissions for the user
- resource:
- value: pets # the resource kind
- name:
- valueFrom: { authJSON: context.request.http.path.@extract:{"sep":"/","pos":2} } # resource name – e.g., the {id} in `/pets/{id}`
- verb:
- valueFrom: { authJSON: context.request.http.method.@case:lower } # api operation – e.g., copying from the context to use the same http method of the request
+Example of Kubernetes cluster role for non-resource attributes authorization:
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: pet-editor
+rules:
+
+- nonResourceURLs: ["/pets/*"]
+ verbs: ["put", "delete"]
+
+Kubernetes' authorization policy configs look like the following in an Authorino AuthConfig
:
+authorization:
+ "kubernetes-rbac":
+ kubernetesSubjectAccessReview:
+ user: # values of the parameter can be fixed (`value`) or fetched from the Authorization JSON (`selector`)
+ selector: auth.identity.metadata.annotations.userid
+
+ groups: [] # user groups to test for.
+
+ # for resource attributes permission checks; omit it to perform a non-resource attributes SubjectAccessReview with path and method/verb assumed from the original request
+ # if included, use the resource attributes, where the values for each parameter can be fixed (`value`) or fetched from the Authorization JSON (`selector`)
+ resourceAttributes:
+ namespace:
+ value: default
+ group:
+ value: pets.io # the api group of the protected resource to be checked for permissions for the user
+ resource:
+ value: pets # the resource kind
+ name:
+ selector: context.request.http.path.@extract:{"sep":"/","pos":2} # resource name – e.g., the {id} in `/pets/{id}`
+ verb:
+ selector: context.request.http.method.@case:lower # api operation – e.g., copying from the context to use the same http method of the request
user
and properties of resourceAttributes
can be defined from fixed values or patterns of the Authorization JSON.
An array of groups
(optional) can as well be set. When defined, it will be used in the SubjectAccessReview
request.
-Keycloak Authorization Services (UMA-compliant Authorization API)¶
-
-
- Not implemented - In analysis
-
-
-
-Online delegation of authorization to a Keycloak server.
-Dynamic response features (response
)¶
-JSON injection (response.json
)¶
-User-defined dynamic JSON objects generated by Authorino in the response phase, from static or dynamic data of the auth pipeline, and passed back to the external authorization client within added HTTP headers or as Envoy Well Known Dynamic Metadata.
-The following Authorino AuthConfig
custom resource is an example that defines 3 dynamic JSON response items, where two items are returned to the client, stringified, in added HTTP headers, and the third is wrapped as Envoy Dynamic Metadata("emitted", in Envoy terminology). Envoy proxy can be configured to "pipe" dynamic metadata emitted by one filter into another filter – for example, from external authorization to rate limit.
-apiVersion: authorino.kuadrant.io/v1beta1
-kind: AuthConfig
-metadata:
- namespace: my-namespace
- name: my-api-protection
-spec:
- hosts:
-
- - my-api.io
- identity:
- - name: edge
- apiKey:
- selector:
- matchLabels:
- authorino.kuadrant.io/managed-by: authorino
- credentials:
- in: authorization_header
- keySelector: APIKEY
- response:
- - name: a-json-returned-in-a-header
- wrapper: httpHeader # can be omitted
- wrapperKey: x-my-custom-header # if omitted, name of the header defaults to the name of the config ("a-json-returned-in-a-header")
- json:
- properties:
- - name: prop1
- value: value1
- - name: prop2
- valueFrom:
- authJSON: some.path.within.auth.json
-
-
- - name: another-json-returned-in-a-header
- wrapperKey: x-ext-auth-other-json
- json:
- properties:
- - name: propX
- value: valueX
-
-
- - name: a-json-returned-as-envoy-metadata
- wrapper: envoyDynamicMetadata
- wrapperKey: auth-data
- json:
- properties:
- - name: api-key-ns
- valueFrom:
- authJSON: auth.identity.metadata.namespace
- - name: api-key-name
- valueFrom:
- authJSON: auth.identity.metadata.name
+SpiceDB (authorization.spicedb
)¶
+Check permission requests via gRPC with an external Google Zanzibar-inspired SpiceDB server, by Authzed.
+Subject, resource and permission parameters can be set to static values or read from the Authorization JSON.
+spec:
+ authorization:
+ "spicedb":
+ spicedb:
+ endpoint: spicedb:50051
+ insecure: true # disables TLS
+ sharedSecretRef:
+ name: spicedb
+ key: token
+ subject:
+ kind:
+ value: blog/user
+ name:
+ selector: auth.identity.sub
+ resource:
+ kind:
+ value: blog/post
+ name:
+ selector: context.request.http.path.@extract:{"sep":"/","pos":2} # /posts/{id}
+ permission:
+ selector: context.request.http.method
-Festival Wristband tokens (response.wristband
)¶
+Custom response features (response
)¶
+Custom response forms: successful authorization vs custom denial status¶
+The response to the external authorization request can be customized in the following fashion:
+
+- Successful authorization (
response.success
)
+- Added HTTP headers (
response.success.headers
)
+- Envoy Dynamic Metadata (
response.success.dynamicMetadata
)
+- Custom denial status
+- Unauthenticated (
response.unauthenticated
)
+- Unauthorized (
response.unauthorized
)
+
+Successful authorization custom responses can be set based on any of the supported custom authorization methods:
+
+- Plain text value
+- JSON injection
+- Festival Wristband Tokens
+
+Added HTTP headers¶
+Set custom responses as HTTP headers injected in the request post-successful authorization by specifying one of the supported methods under response.success.headers
.
+The name of the response config (default) or the value of the key
option (if provided) will used as the name of the header.
+Envoy Dynamic Metadata¶
+Authorino custom response methods can also be used to propagate Envoy Dynamic Metadata. To do so, set one of the supported methods under response.success.dynamicMetadata
.
+The name of the response config (default) or the value of the key
option (if provided) will used as the name of the root property of the dynamic metadata content.
+A custom response exported as Envoy Dynamic Metadata can be set in the Envoy route or virtual host configuration as input to a consecutive filter in the filter chain.
+E.g., to read metadata emitted by the authorization service with scheme { "auth-data": { "api-key-ns": string, "api-key-name": string } }
, as input in a rate limit configuration placed in the filter chain after the external authorization, the Envoy config may look like the following:
+# Envoy config snippet to inject `user_namespace` and `username` rate limit descriptors from metadata emitted by Authorino
+rate_limits:
+
+- actions:
+ - metadata:
+ metadata_key:
+ key: "envoy.filters.http.ext_authz"
+ path:
+ - key: auth-data # root of the dynamic metadata object, as declared in a custom response config of the AuthConfig (name or key)
+ - key: api-key-ns
+ descriptor_key: user_namespace
+ - metadata:
+ metadata_key:
+ key: "envoy.filters.http.ext_authz"
+ path:
+ - key: auth-data # root of the dynamic metadata object, as declared in a custom response config of the AuthConfig (name or key)
+ - key: api-key-name
+ descriptor_key: username
+
+Custom denial status (response.unauthenticated
and response.unauthorized
)¶
+By default, Authorino will inform Envoy to respond with 401 Unauthorized
or 403 Forbidden
respectively when the identity verification (phase i of the Auth Pipeline) or authorization (phase ii) fail. These can be customized respectively by specifying spec.response.unauthanticated
and spec.response.unauthorized
in the AuthConfig
.
+Custom response methods¶
+Plain text (response.success.<headers|dynamicMetadata>.plain
)¶
+Simpler, yet more generalized form, for extending the authorization response for header mutation and Envoy Dynamic Metadata, based on plain text values.
+The value can be static:
+
+or fetched dynamically from the Authorization JSON (which includes support for interpolation):
+
+JSON injection (response.success.<headers|dynamicMetadata>.json
)¶
+User-defined dynamic JSON objects generated by Authorino in the response phase, from static or dynamic data of the auth pipeline, and passed back to the external authorization client within added HTTP headers or Dynamic Metadata.
+The following Authorino AuthConfig
custom resource is an example that defines 3 dynamic JSON response items, where two items are returned to the client, stringified, in added HTTP headers, and the third as Envoy Dynamic Metadata. Envoy proxy can be configured to propagate the dynamic metadata emitted by Authorino into another filter – e.g. the rate limit filter.
+apiVersion: authorino.kuadrant.io/v1beta2
+kind: AuthConfig
+metadata:
+ namespace: my-namespace
+ name: my-api-protection
+spec:
+ hosts:
+
+ - my-api.io
+ authentication:
+ "edge":
+ apiKey:
+ selector:
+ matchLabels:
+ authorino.kuadrant.io/managed-by: authorino
+ credentials:
+ authorizationHeader:
+ prefix: APIKEY
+ response:
+ success:
+ headers:
+ "x-my-custom-header":
+ json:
+ properties:
+ "prop1":
+ value: value1
+ "prop2":
+ selector: some.path.within.auth.json
+ "x-ext-auth-other-json":
+ json:
+ properties:
+ "propX":
+ value: valueX
+
+ dynamicMetadata:
+ "auth-data":
+ json:
+ properties:
+ "api-key-ns":
+ seletor: auth.identity.metadata.namespace
+ "api-key-name":
+ selector: auth.identity.metadata.name
+
+Festival Wristband tokens (response.success.<headers|dynamicMetadata>.wristband
)¶
Festival Wristbands are signed OpenID Connect JSON Web Tokens (JWTs) issued by Authorino at the end of the auth pipeline and passed back to the client, typically in added HTTP response header. It is an opt-in feature that can be used to implement Edge Authentication Architecture (EAA) and enable token normalization. Authorino wristbands include minimal standard JWT claims such as iss
, iat
, and exp
, and optional user-defined custom claims, whose values can be static or dynamically fetched from the authorization JSON.
The Authorino AuthConfig
custom resource below sets an API protection that issues a wristband after a successful authentication via API key. Apart from standard JWT claims, the wristband contains 2 custom claims: a static value aud=internal
and a dynamic value born
that fetches from the authorization JSON the date/time of creation of the secret that represents the API key used to authenticate.
-apiVersion: authorino.kuadrant.io/v1beta1
-kind: AuthConfig
-metadata:
- namespace: my-namespace
- name: my-api-protection
-spec:
- hosts:
-
- - my-api.io
- identity:
- - name: edge
- apiKey:
- selector:
- matchLabels:
- authorino.kuadrant.io/managed-by: authorino
- credentials:
- in: authorization_header
- keySelector: APIKEY
- response:
- - name: my-wristband
- wristband:
- issuer: https://authorino-oidc.default.svc:8083/my-namespace/my-api-protection/my-wristband
- customClaims:
- - name: aud
- value: internal
- - name: born
- valueFrom:
- authJSON: auth.identity.metadata.creationTimestamp
- tokenDuration: 300
- signingKeyRefs:
- - name: my-signing-key
- algorithm: ES256
- - name: my-old-signing-key
- algorithm: RS256
- wrapper: httpHeader # can be omitted
- wrapperKey: x-ext-auth-wristband # whatever http header name desired - defaults to the name of the response config ("my-wristband")
+apiVersion: authorino.kuadrant.io/v1beta2
+kind: AuthConfig
+metadata:
+ namespace: my-namespace
+ name: my-api-protection
+spec:
+ hosts:
+
+ - my-api.io
+ authentication:
+ "edge":
+ apiKey:
+ selector:
+ matchLabels:
+ authorino.kuadrant.io/managed-by: authorino
+ credentials:
+ authorizationHeader:
+ prefix: APIKEY
+ response:
+ success:
+ headers:
+ "x-wristband":
+ wristband:
+ issuer: https://authorino-oidc.default.svc:8083/my-namespace/my-api-protection/x-wristband
+ customClaims:
+ "aud":
+ value: internal
+ "born":
+ selector: auth.identity.metadata.creationTimestamp
+ tokenDuration: 300
+ signingKeyRefs:
+ - name: my-signing-key
+ algorithm: ES256
+ - name: my-old-signing-key
+ algorithm: RS256
The signing key names listed in signingKeyRefs
must match the names of Kubernetes Secret
resources created in the same namespace, where each secret contains a key.pem
entry that holds the value of the private key that will be used to sign the wristbands issued, formatted as PEM. The first key in this list will be used to sign the wristbands, while the others are kept to support key rotation.
For each protected API configured for the Festival Wristband issuing, Authorino exposes the following OpenID Connect Discovery well-known endpoints (available for requests within the cluster):
@@ -4640,34 +4710,32 @@ Festival Wristband tokens (
- JSON Web Key Set (JWKS) well-known endpoint:
https://authorino-oidc.default.svc:8083/{namespace}/{api-protection-name}/{response-config-name}/.well-known/openid-connect/certs
-Extra: Response wrappers (wrapper
and wrapperKey
)¶
-Added HTTP headers¶
-By default, Authorino dynamic responses (injected JSON and Festival Wristband tokens) are passed back to Envoy, stringified, as injected HTTP headers. This can be made explicit by setting the wrapper
property of the response config to httpHeader
.
-The property wrapperKey
controls the name of the HTTP header, with default to the name of dynamic response config when omitted.
-Envoy Dynamic Metadata¶
-Authorino dynamic responses (injected JSON and Festival Wristband tokens) can be passed back to Envoy in the form of Envoy Dynamic Metadata. To do so, set the wrapper
property of the response config to envoyDynamicMetadata
.
-A response config with wrapper=envoyDynamicMetadata
and wrapperKey=auth-data
in the AuthConfig
can be configured in the Envoy route or virtual host setting to be passed to rate limiting filter as below. The metadata content is expected to be a dynamic JSON injected by Authorino containing { "auth-data": { "api-key-ns": string, "api-key-name": string } }
. (See the response config a-json-returned-as-envoy-metadata
in the example for the JSON injection feature above)
-# Envoy config snippet to inject `user_namespace` and `username` rate limit descriptors from metadata returned by Authorino
-rate_limits:
-
-- actions:
- - metadata:
- metadata_key:
- key: "envoy.filters.http.ext_authz"
- path:
- - key: auth-data
- - key: api-key-ns
- descriptor_key: user_namespace
- - metadata:
- metadata_key:
- key: "envoy.filters.http.ext_authz"
- path:
- - key: auth-data
- - key: api-key-name
- descriptor_key: username
+Callbacks (callbacks
)¶
+HTTP endpoints (callbacks.http
)¶
+Sends requests to specified HTTP endpoints at the end of the auth pipeline.
+The scheme of the http
field is the same as of metadata.http
.
+Example:
+spec:
+ authentication: […]
+ authorization: […]
+
+ callbacks:
+ "log":
+ http:
+ url: http://logsys
+ method: POST
+ body:
+ selector: |
+ \{"requestId":context.request.http.id,"username":"{auth.identity.username}","authorizationResult":{auth.authorization}\}
+ "important-forbidden":
+ when:
+
+ - selector: auth.authorization.important-policy
+ operator: eq
+ value: "false"
+ http:
+ url: "http://monitoring/important?forbidden-user={auth.identity.username}"
-Extra: Custom denial status (denyWith
)¶
-By default, Authorino will inform Envoy to respond with 401 Unauthorized
or 403 Forbidden
respectively when the identity verification (phase i of the Auth Pipeline) or authorization (phase ii) fail. These can be customized by specifying spec.denyWith
in the AuthConfig
.
Common feature: Priorities¶
Priorities allow to set sequence of execution for blocks of concurrent evaluators within phases of the Auth Pipeline.
Evaluators of same priority execute concurrently to each other "in a block". After syncing that block (i.e. after all evaluators of the block have returned), the next block of evaluator configs of consecutive priority is triggered.
@@ -4685,267 +4753,356 @@ Common feature: PrioritiesapiVersion: authorino.kuadrant.io/v1beta1
-kind: AuthConfig
-metadata:
- name: talker-api-protection
-spec:
- hosts:
-
- - talker-api
- identity:
- - name: tier-1
- priority: 0
- apiKey:
- selector:
- matchLabels:
- tier: "1"
- - name: tier-2
- priority: 1
- apiKey:
- selector:
- matchLabels:
- tier: "2"
- - name: tier-3
- priority: 1
- apiKey:
- selector:
- matchLabels:
- tier: "3"
- metadata:
- - name: first
- http:
- endpoint: http://talker-api:3000
- method: GET
- - name: second
- priority: 1
- http:
- endpoint: http://talker-api:3000/first_uuid={auth.metadata.first.uuid}
- method: GET
- authorization:
- - name: allowed-endpoints
- when:
- - selector: context.request.http.path
- operator: neq
- value: /hi
- - selector: context.request.http.path
- operator: neq
- value: /hello
- - selector: context.request.http.path
- operator: neq
- value: /aloha
- - selector: context.request.http.path
- operator: neq
- value: /ciao
- json:
- rules:
- - selector: deny
- operator: eq
- value: "true"
- - name: more-expensive-policy # no point in evaluating this one if it's not an allowed endpoint
- priority: 1
- opa:
- inlineRego: |
- allow { true }
- response:
- - name: x-auth-data
- json:
- properties:
- - name: tier
- valueFrom:
- authJSON: auth.identity.metadata.labels.tier
- - name: first-uuid
- valueFrom:
- authJSON: auth.metadata.first.uuid
- - name: second-uuid
- valueFrom:
- authJSON: auth.metadata.second.uuid
- - name: second-path
- valueFrom:
- authJSON: auth.metadata.second.path
+apiVersion: authorino.kuadrant.io/v1beta2
+kind: AuthConfig
+metadata:
+ name: talker-api-protection
+spec:
+ hosts:
+
+ - talker-api
+ authentication:
+ "tier-1":
+ priority: 0
+ apiKey:
+ selector:
+ matchLabels:
+ tier: "1"
+ "tier-2":
+ priority: 1
+ apiKey:
+ selector:
+ matchLabels:
+ tier: "2"
+ "tier-3":
+ priority: 1
+ apiKey:
+ selector:
+ matchLabels:
+ tier: "3"
+ metadata:
+ "first":
+ http:
+ url: http://talker-api:3000
+ "second":
+ priority: 1
+ http:
+ url: http://talker-api:3000/first_uuid={auth.metadata.first.uuid}
+ authorization:
+ "allowed-endpoints":
+ when:
+ - selector: context.request.http.path
+ operator: neq
+ value: /hi
+ - selector: context.request.http.path
+ operator: neq
+ value: /hello
+ - selector: context.request.http.path
+ operator: neq
+ value: /aloha
+ - selector: context.request.http.path
+ operator: neq
+ value: /ciao
+ patternMatching:
+ patterns:
+ - selector: deny
+ operator: eq
+ value: "true"
+ "more-expensive-policy": # no point in evaluating this one if it's not an allowed endpoint
+ priority: 1
+ opa:
+ rego: |
+ allow { true }
+ response:
+ success:
+ headers:
+ "x-auth-data":
+ json:
+ properties:
+ "tier":
+ selector: auth.identity.metadata.labels.tier
+ "first-uuid":
+ selector: auth.metadata.first.uuid
+ "second-uuid":
+ selector: auth.metadata.second.uuid
+ "second-path":
+ selector: auth.metadata.second.path
For the AuthConfig
above,
-
-
Identity configs tier-2
and tier-3
(priority 1) will only trigger (concurrently) in case tier-1
(priority 0) fails to validate the authentication token first. (This behavior happens without perjudice of context canceling between concurrent evaluators – i.e. evaluators that are triggered concurrently to another, such as tier-2
and tier-3
, continue to cancel the context of each other if any of them succeeds validating the token first.)
+Identity configs tier-2
and tier-3
(priority 1) will only trigger (concurrently) in case tier-1
(priority 0) fails to validate the authentication token first. (This behavior happens without prejudice of context canceling between concurrent evaluators – i.e. evaluators that are triggered concurrently to another, such as tier-2
and tier-3
, continue to cancel the context of each other if any of them succeeds validating the token first.)
-
Metadata source second
(priority 1) uses the response of the request issued by metadata source first
(priority 0), so it will wait for first
to finish by triggering only in the second block.
-
-
Authorization policy allowed-endpoints
(piority 0) is considered to be a lot less expensive than more-expensive-policy
(priority 1) and has a high chance of denying access to the protected service (if the path is not one of the allowed endpoints). By setting different priorities to these policies we ensure the more expensive policy if triggered in sequence of the less expensive one, instead of concurrently.
+Authorization policy allowed-endpoints
(priority 0) is considered to be a lot less expensive than more-expensive-policy
(priority 1) and has a high chance of denying access to the protected service (if the path is not one of the allowed endpoints). By setting different priorities to these policies we ensure the more expensive policy if triggered in sequence of the less expensive one, instead of concurrently.
Common feature: Conditions (when
)¶
-Conditions, named when
in the AUthCOnfig API, are sets of expressions (JSON patterns) that, whenever included, must evaluate to true against the Authorization JSON, so the scope where the expressions are defined is enforced. If any of the expressions in the set of conditions for a given scope does not match, Authorino will skip that scope in the Auth Pipeline.
-The scope for a set of when
conditions can be the entire AuthConfig
("top-level conditions") or a particular evaluator of any phase of the auth pipeline.
-Each expression is a tuple composed of:
+Conditions, named when
in the AuthConfig API, are logical expressions, composed of patterns and logical operator AND and OR, that can be used to condition the evaluation of a particular auth rule within an AuthConfig, as well as of the AuthConfig altogether ("top-level conditions").
+The patterns are evaluated against the Authorization JSON, where each pattern is a tuple composed of:
-- a
selector
, to fetch from the Authorization JSON – see Common feature: JSON paths for details about syntax;
-- an
operator
– eq
(equals), neq
(not equal); incl
(includes) and excl
(excludes), for arrays; and matches
, for regular expressions;
-- a fixed comparable
value
+selector
: a JSON path to fetch a value from the Authorization JSON
+operator
: one of: eq
(equals); neq
(not equal); incl
(includes) and excl
(excludes), for when the value fetched from the Authorization JSON is expected to be an array; matches
, for regular expressions
+value
: a static string value to compare the value selected from the Authorization JSON with.
-Literal expressions and references to expression sets (patterns
, defined at the upper level of the AuthConfig
spec) can be listed, mixed and combined in when
conditions sets.
-Conditions can be used, e.g.,:
-i) to skip an entire AuthConfig
based on the context:
-spec:
- when: # no authn/authz required on requests to /status
-
- - selector: context.request.http.path
- operator: neq
- value: /status
+An expression contains one or more patterns and they must either all evaluate to true ("AND" operator, declared by grouping the patterns within an all
block) or at least one of the patterns must be true ("OR" operator, when grouped within an any
block.) Patterns not explicitly grouped are AND'ed by default.
+To avoid repetitions when listing patterns, any set of literal { pattern, operator, value }
tuples can be stored at the top-level of the AuthConfig spec, indexed by name, and later referred within an expression by including a patternRef
in the block of conditions.
+Examples of when
conditions
+i) to skip an entire AuthConfig
based on the context (AND operator assumed by default):
+spec:
+ when: # auth enforced only on requests to POST /resources/*
+
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/resources/.*
-ii) to skip parts of an AuthConfig
(i.e. a specific evaluator):
-spec:
- metadata:
-
- - name: metadata-source
- http:
- endpoint: https://my-metadata-source.io
- when: # only fetch the external metadata if the context is HTTP method different than OPTIONS
- - selector: context.request.http.method
- operator: neq
- value: OPTIONS
+ii) equivalent to the above with explicit AND operator (i.e., all
block):
+spec:
+ when: # auth enforced only on requests to POST /resources/*
+
+ - all:
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/resources/.*
-iii) to enforce a particular evaluator only in certain contexts (really the same as the above, though to a different use case):
-spec:
- identity:
-
- - name: authn-meth-1
- apiKey: {...} # this authn method only valid for POST requests to /foo[/*]
- when:
- - selector: context.request.http.path
- operator: matches
- value: ^/foo(/.*)?$
- - selector: context.request.http.method
- operator: eq
- value: POST
-
-
- - name: authn-meth-2
- oidc: {...}
+iii) OR condition (i.e., any
block):
+spec:
+ when: # auth enforced only on requests with HTTP method equals to POST or PUT
+
+ - any:
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.method
+ operator: eq
+ value: PUT
-iv) to avoid repetition while defining patterns for conditions:
-spec:
- patterns:
- a-pet: # a named pattern that can be reused in sets of conditions
-
- - selector: context.request.http.path
- operator: matches
- value: ^/pets/\d+(/.*)$
-
- metadata:
-
- - name: pets-info
- when:
- - patternRef: a-pet
- http:
- endpoint: https://pets-info.io?petId={context.request.http.path.@extract:{"sep":"/","pos":2}}
-
- authorization:
-
- - name: pets-owners-only
- when:
- - patternRef: a-pet
- opa:
- inlineRego: |
- allow { input.metadata["pets-info"].ownerid == input.auth.identity.userid }
+iv) complex expression with nested operations:
+spec:
+ when: # auth enforced only on requests to POST /resources/* or PUT /resources/*
+
+ - any:
+ - all:
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/resources/.*
+ - all:
+ - selector: context.request.http.method
+ operator: eq
+ value: PUT
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/resources/.*
-v) mixing and combining literal expressions and refs:
-spec:
- patterns:
- foo:
-
- - selector: context.request.http.path
- operator: eq
- value: /foo
-
- when: # unauthenticated access to /foo always granted
-
- - patternRef: foo
- - selector: context.request.http.headers.authorization
- operator: eq
- value: ""
-
- authorization:
-
- - name: my-policy-1
- when: # authenticated access to /foo controlled by policy
- - patternRef: foo
- json: {...}
+v) more concise equivalent of the above (with implicit AND operator at the top level):
+spec:
+ when: # auth enforced only on requests to /resources/* path with method equals to POST or PUT
+
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/resources/.*
+ - any:
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.method
+ operator: eq
+ value: PUT
-vi) to avoid evaluating unnecessary identity checks when the user can indicate the preferred authentication method (again the pattern of skipping based upon the context):
-spec:
- identity:
-
- - name: jwt
- when:
- - selector: selector: context.request.http.headers.authorization
- operator: matches
- value: JWT .+
- oidc: {...}
-
-
- - name: api-key
- when:
- - selector: context.request.http.headers.authorization
- operator: matches
- value: APIKEY .+
- apiKey: {...}
+vi) to skip part of an AuthConfig (i.e., a specific auth rule):
+spec:
+ metadata:
+ "metadata-source":
+ http:
+ url: https://my-metadata-source.io
+ when: # only fetch the external metadata if the context is HTTP method other than OPTIONS
+
+ - selector: context.request.http.method
+ operator: neq
+ value: OPTIONS
+
+vii) skipping part of an AuthConfig will not affect other auth rules:
+spec:
+ authentication:
+ "authn-meth-1":
+ apiKey: {…} # this auth rule only triggers for POST requests to /foo[/*]
+ when:
+
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/foo(/.*)?$
+
+ "authn-meth-2": # this auth rule triggerred regardless
+ jwt: {…}
+
+viii) concrete use-case: evaluating only the necessary identity checks based on the user's indication of the preferred authentication method (prefix of the value supplied in the HTTP Authorization
request header):
+spec:
+ authentication:
+ "jwt":
+ when:
+
+ - selector: context.request.http.headers.authorization
+ operator: matches
+ value: JWT .+
+ jwt: {…}
+
+ "api-key":
+ when:
+
+ - selector: context.request.http.headers.authorization
+ operator: matches
+ value: APIKEY .+
+ apiKey: {…}
+
+ix) to avoid repetition while defining patterns for conditions:
+spec:
+ patterns:
+ a-pet: # a named pattern that can be reused in sets of conditions
+
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/pets/\d+(/.*)$
+
+ metadata:
+ "pets-info":
+ when:
+
+ - patternRef: a-pet
+ http:
+ url: https://pets-info.io?petId={context.request.http.path.@extract:{"sep":"/","pos":2}}
+
+ authorization:
+ "pets-owners-only":
+ when:
+
+ - patternRef: a-pet
+ opa:
+ rego: |
+ allow { input.metadata["pets-info"].ownerid == input.auth.identity.userid }
+
+x) combining literals and refs – concrete case: authentication required for selected operations:
+spec:
+ patterns:
+ api-base-path:
+
+ - selector: context.request.http.path
+ operator: matches
+ value: ^/api/.*
+
+ authenticated-user:
+
+ - selector: auth.identity.anonymous
+ operator: neq
+ value: "true"
+
+ authentication:
+ api-users: # tries to authenticate all requests to path /api/*
+ when:
+
+ - patternRef: api-base-path
+ jwt: {…}
+
+ others: # defaults to anonymous access when authentication fails or not /api/* path
+ anonymous: {}
+ priority: 1
+
+ authorization:
+ api-write-access-requires-authentication: # POST/PUT/DELETE requests to /api/* path cannot be anonymous
+ when:
+
+ - all:
+ - patternRef: api-base-path
+ - any:
+ - selector: context.request.http.method
+ operator: eq
+ value: POST
+ - selector: context.request.http.method
+ operator: eq
+ value: PUT
+ - selector: context.request.http.method
+ operator: eq
+ value: DELETE
+ opa:
+ patternMatching:
+ rules:
+ - patternRef: authenticated-user
+
+ response: # bonus: export user data if available
+ success:
+ dynamicMetadata:
+ "user-data":
+ when:
+
+ - patternRef: authenticated-user
+ json:
+ properties:
+ jwt-claims:
+ selector: auth.identity
Common feature: Caching (cache
)¶
Objects resolved at runtime in an Auth Pipeline can be cached "in-memory", and avoided being evaluated again at a subsequent request, until it expires. A lookup cache key and a TTL can be set individually for any evaluator config in an AuthConfig.
-Each cache config induces a completely independent cache table (or "cache namespace"). Consequently, different evaluator configs can use the same cache key and there will be no colision between entries from different evaluators.
+Each cache config induces a completely independent cache table (or "cache namespace"). Consequently, different evaluator configs can use the same cache key and there will be no collision between entries from different evaluators.
E.g.:
-spec:
- hosts:
-
- - my-api.io
-
- identity: [...]
-
- metadata:
-
- - name: external-metadata
- http:
- endpoint: http://my-external-source?search={context.request.http.path}
- cache:
- key:
- valueFrom: { authJSON: context.request.http.path }
- ttl: 300
-
- authorization:
-
- - name: complex-policy
- opa:
- externalRegistry:
- endpoint: http://my-policy-registry
- cache:
- key:
- valueFrom:
- authJSON: "{auth.identity.group}-{context.request.http.method}-{context.request.http.path}"
- ttl: 60
+spec:
+ hosts:
+
+ - my-api.io
+
+ authentication: […]
+
+ metadata:
+ "external-metadata":
+ http:
+ url: http://my-external-source?search={context.request.http.path}
+ cache:
+ key:
+ selector: context.request.http.path
+ ttl: 300
+
+ authorization:
+ "complex-policy":
+ opa:
+ externalPolicy:
+ url: http://my-policy-registry
+ cache:
+ key:
+ selector: "{auth.identity.group}-{context.request.http.method}-{context.request.http.path}"
+ ttl: 60
The example above sets caching for the 'external-metadata' metadata config and for the 'complex-policy' authorization policy. In the case of 'external-metadata', the cache key is the path of the original HTTP request being authorized by Authorino (fetched dynamically from the Authorization JSON); i.e., after obtaining a metadata object from the external source for a given contextual HTTP path one first time, whenever that same HTTP path repeats in a subsequent request, Authorino will use the cached object instead of sending a request again to the external source of metadata. After 5 minutes (300 seconds), the cache entry will expire and Authorino will fetch again from the source if requested.
-As for the 'complex-policy' authorization policy, the cache key is a string composed the 'group' the identity belongs to, the methodd of the HTTP request and the path of the HTTP request. Whenever these repeat, Authorino will use the result of the policy that was evaluated and cached priorly. Cache entries in this namespace expire after 60 seconds.
+As for the 'complex-policy' authorization policy, the cache key is a string composed the 'group' the identity belongs to, the method of the HTTP request and the path of the HTTP request. Whenever these repeat, Authorino will use the result of the policy that was evaluated and cached priorly. Cache entries in this namespace expire after 60 seconds.
Notes on evaluator caching
-Capacity - By default, each cache namespace is limited to 1 mb. Entries will be evicted following First-In-First-Out (FIFO) policy to release space. The individual capacity of cache namespaces is set at the level of the Authorino instance (via EVALUATOR_CACHE_SIZE
environment variable or spec.evaluatorCacheSize
field of the Authorino
CR).
+Capacity - By default, each cache namespace is limited to 1 mb. Entries will be evicted following First-In-First-Out (FIFO) policy to release space. The individual capacity of cache namespaces is set at the level of the Authorino instance (via --evaluator-cache-size
command-line flag or spec.evaluatorCacheSize
field of the Authorino
CR).
Usage - Avoid caching objects whose evaluation is considered to be relatively cheap. Examples of operations associated to Authorino auth features that are usually NOT worth caching: validation of JSON Web Tokens (JWT), Kubernetes TokenReviews and SubjectAccessReviews, API key validation, simple JSON pattern-matching authorization rules, simple OPA policies. Examples of operations where caching may be desired: OAuth2 token introspection, fetching of metadata from external sources (via HTTP request), complex OPA policies.
Common feature: Metrics (metrics
)¶
By default, Authorino will only export metrics down to the level of the AuthConfig. Deeper metrics at the level of each evaluator within an AuthConfig can be activated by setting the common field metrics: true
of the evaluator config.
E.g.:
-apiVersion: authorino.kuadrant.io/v1beta1
-kind: AuthConfig
-metadata:
- name: my-authconfig
- namespame: my-ns
-spec:
- metadata:
-
- - name: my-external-metadata
- http:
- endpoint: http://my-external-source?search={context.request.http.path}
- metrics: true
+apiVersion: authorino.kuadrant.io/v1beta2
+kind: AuthConfig
+metadata:
+ name: my-authconfig
+ namespace: my-ns
+spec:
+ metadata:
+ "my-external-metadata":
+ http:
+ url: http://my-external-source?search={context.request.http.path}
+ metrics: true
The above will enable the metrics auth_server_evaluator_duration_seconds
(histogram) and auth_server_evaluator_total
(counter) with labels namespace="my-ns"
, authconfig="my-authconfig"
, evaluator_type="METADATA_GENERIC_HTTP"
and evaluator_name="my-external-metadata"
.
The same pattern works for other types of evaluators. Find below the list of all types and corresponding label constant used in the metric:
@@ -4958,35 +5115,31 @@ Common feature: Metrics (metrics
-identity.apiKey
+authentication.apiKey
IDENTITY_APIKEY
-identity.kubernetes
+authentication.kubernetesTokenReview
IDENTITY_KUBERNETES
-identity.oidc
+authentication.jwt
IDENTITY_OIDC
-identity.oauth2
+authentication.oauth2Introspection
IDENTITY_OAUTH2
-identity.mtls
+authentication.x509
IDENTITY_MTLS
-identity.hmac
-IDENTITY_HMAC
-
-
-identity.plain
+authentication.plain
IDENTITY_PLAIN
-identity.anonymous
+authentication.anonymous
IDENTITY_NOOP
@@ -5002,7 +5155,7 @@ Common feature: Metrics (metrics
METADATA_UMA
-authorization.json
+authorization.patternMatching
AUTHORIZATION_JSON
@@ -5010,21 +5163,29 @@ Common feature: Metrics (metrics
AUTHORIZATION_OPA
-authorization.kubernetes
+authorization.kubernetesSubjectAccessReview
AUTHORIZATION_KUBERNETES
-response.json
+authorization.spicedb
+AUTHORIZATION_AUTHZED
+
+
+response.success..plain
+RESPONSE_PLAIN
+
+
+response.success..json
RESPONSE_JSON
-response.wristband
+response.success..wristband
RESPONSE_WRISTBAND
-Metrics at the level of the evaluators can also be enforced to an entire Authorino instance, by setting the DEEP_METRICS_ENABLED=true
environment variable. In this case, regardless of the value of the field spec.(identity|metadata|authorization|response).metrics
in the AuthConfigs, individual metrics for all evaluators of all AuthConfigs will be exported.
-For more information about observability metrics in Authorino, see the user guide Observability.
+Metrics at the level of the evaluators can also be enforced to an entire Authorino instance, by setting the --deep-metrics-enabled
command-line flag. In this case, regardless of the value of the field spec.(authentication|metadata|authorization|response).metrics
in the AuthConfigs, individual metrics for all evaluators of all AuthConfigs will be exported.
+For more information about metrics exported by Authorino, see Observability.
diff --git a/0.10.0/authorino/docs/getting-started/index.html b/0.10.0/authorino/docs/getting-started/index.html
index 53e95ea49..a6cc3f729 100644
--- a/0.10.0/authorino/docs/getting-started/index.html
+++ b/0.10.0/authorino/docs/getting-started/index.html
@@ -1504,7 +1504,7 @@
-
-
+
@@ -1863,7 +1863,7 @@
-
-
+
@@ -3659,36 +3659,27 @@
Getting started¶
-This page covers requirements and instructions to deploy Authorino on a Kubernetes cluster, as well as the steps to declare, apply and try out a protection layer of authentication and authorization over your service, clean-up and complete uninstall.
+This page covers requirements and instructions to deploy Authorino on a Kubernetes cluster, as well as the steps to declare, apply and try out a protection layer of authentication and authorization over your service, clean-up and complete uninstallation.
If you prefer learning with an example, check out our Hello World.
-
Requirements¶
Platform requirements¶
-These are the plarform requirements to use Authorino:
+These are the platform requirements to use Authorino:
-- Kubernetes server (recommended v1.20 or later), with permission to create Kubernetes Custom Resource Definitions (CRDs) (for bootstrapping Authorino and Authorino Operator)
-
-
- Alternative: K8s distros and platforms
-
- Alternatively to upstream Kubernetes, you should be able use any other Kubernetes distribution or Kubernetes Management Platform (KMP) with support for Kubernetes Custom Resources Definitions (CRD) and custom controllers, such as Red Hat OpenShift, IBM Cloud Kubernetes Service (IKS), Google Kubernetes Engine (GKE), Amazon Elastic Kubernetes Service (EKS) and Azure Kubernetes Service (AKS).
-
-
-
-- Envoy proxy (recommended v1.19 or later), to wire up Upstream services (i.e. the services to be protected with Authorino) and external authorization filter (Authorino) for integrations based on the reverse-proxy architecture - example
+-
+
Kubernetes server (recommended v1.21 or later), with permission to create Kubernetes Custom Resource Definitions (CRDs) (for bootstrapping Authorino and Authorino Operator)
+
+Alternative: K8s distros and platforms
+Alternatively to upstream Kubernetes, you should be able to use any other Kubernetes distribution or Kubernetes Management Platform (KMP) with support for Kubernetes Custom Resources Definitions (CRD) and custom controllers, such as Red Hat OpenShift, IBM Cloud Kubernetes Service (IKS), Google Kubernetes Engine (GKE), Amazon Elastic Kubernetes Service (EKS) and Azure Kubernetes Service (AKS).
+
+
+-
+
Envoy proxy (recommended v1.19 or later), to wire up Upstream services (i.e. the services to be protected with Authorino) and external authorization filter (Authorino) for integrations based on the reverse-proxy architecture - example
+
+Alternative: Non-reverse-proxy integration
+Technically, any client that implements Envoy's external authorization gRPC protocol should be compatible with Authorino. For integrations based on the reverse-proxy architecture nevertheless, we strongly recommended that you leverage Envoy alongside Authorino.
+
+
-
- Alternative: Non-reverse-proxy integration
-
- Technically, any client that implements Envoy's external authorization gRPC protocol should be compatible with Authorino. For integrations based on the reverse-proxy architecture nevertheless, we strongly recommended that you leverage Envoy along side Authorino.
-
-
Feature-specific requirements¶
A few examples are:
@@ -3696,146 +3687,127 @@ Feature-specific requirementsKeycloak which can solve both and connect to external identity sources and user federation like LDAP.
-
-
For Kubernetes authentication tokens, platform support for the TokenReview and SubjectAccessReview APIs of Kubernetes shall be required. In case you want to be able to requests access tokens for clients running outside the custer, you may also want to check out the requisites for using Kubernetes TokenRquest API (GA in v1.20).
+For Kubernetes authentication tokens, platform support for the TokenReview and SubjectAccessReview APIs of Kubernetes shall be required. In case you want to be able to requests access tokens for clients running outside the custer, you may also want to check out the requisites for using Kubernetes TokenRequest API (GA in v1.20).
-
-
For User-Managed Access (UMA) resource data, you will need a UMA-compliant server running as well. This can be an implementation of the UMA protocol by each upstream API itself or (more tipically) an external server that knows about the resources. Again, Keycloak can be a good fit here as well. Just keep in mind that, whatever resource server you choose, changing-state actions commanded in the upstream APIs or other parties will have to be reflected in the resource server. Authorino will not do that for you.
+For User-Managed Access (UMA) resource data, you will need a UMA-compliant server running as well. This can be an implementation of the UMA protocol by each upstream API itself or (more typically) an external server that knows about the resources. Again, Keycloak can be a good fit here as well. Just keep in mind that, whatever resource server you choose, changing-state actions commanded in the upstream APIs or other parties will have to be reflected in the resource server. Authorino will not do that for you.
Check out the Feature specification page for more feature-specific requirements.
Installation¶
Step: Install the Authorino Operator¶
The simplest way to install the Authorino Operator is by applying the manifest bundle:
-kubectl apply -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
+curl -sL https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/utils/install.sh | bash -s
The above will install the latest build of the Authorino Operator and latest version of the manifests (CRDs and RBAC), which by default points as well to the latest build of Authorino, both based on the main
branches of each component. To install a stable released version of the Operator and therefore also defaults to its latest compatible stable release of Authorino, replace main
with another tag of a proper release of the Operator, e.g. 'v0.2.0'.
-Alternatively, you can deploy the Authorino Operator using the Operator Lifecycle Manager bundles. For instructions, check out Installing via OLM.
+This step will also install cert-manager in the cluster (required).
+Alternatively, you can deploy the Authorino Operator using the Operator Lifecycle Manager bundles. For instructions, check out Installing via OLM.
Step: Request an Authorino instance¶
Choose either cluster-wide or namespaced deployment mode and whether you want TLS termination enabled for the Authorino endpoints (gRPC authorization, raw HTTP authorization, and OIDC Festival Wristband Discovery listeners), and follow the corresponding instructions below.
The instructions here are for centralized gateway or centralized authorization service architecture. Check out the Topologies section of the docs for alternatively running Authorino in a sidecar container.
- Cluster-wide (with TLS)
-
- Create the namespace:
+Cluster-wide (with TLS)
+Create the namespace:
-
- Deploy [cert-manager](https://github.com/jetstack/cert-manager) (skip if you already have certificates and certificate keys created and stored in Kubernetes `Secret`s in the namespace or cert-manager is installed and running in the cluster):
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml
-
-
- Create the TLS certificates (skip if you already have certificates and certificate keys created and stored in Kubernetes `Secret`s in the namespace):
- curl -sSL https://raw.githubusercontent.com/Kuadrant/authorino/main/deploy/certs.yaml | sed "s/\$(AUTHORINO_INSTANCE)/authorino/g;s/\$(NAMESPACE)/authorino/g" | kubectl -n authorino apply -f -
-
-
- Deploy Authorino:
- kubectl -n authorino apply -f -<<EOF
-apiVersion: operator.authorino.kuadrant.io/v1beta1
-kind: Authorino
-metadata:
- name: authorino
-spec:
- replicas: 1
- clusterWide: true
- listener:
- tls:
- enabled: true
- certSecretRef:
- name: authorino-server-cert
+
+Create the TLS certificates (requires cert-manager; skip if you already have certificates and certificate keys created and stored in Kubernetes Secret
s in the namespace):
+
curl -sSL https://raw.githubusercontent.com/Kuadrant/authorino/main/deploy/certs.yaml | sed "s/\$(AUTHORINO_INSTANCE)/authorino/g;s/\$(NAMESPACE)/authorino/g" | kubectl -n authorino apply -f -
+
+Deploy Authorino:
+
kubectl -n authorino apply -f -<<EOF
+apiVersion: operator.authorino.kuadrant.io/v1beta1
+kind: Authorino
+metadata:
+ name: authorino
+spec:
+ replicas: 1
+ clusterWide: true
+ listener:
+ tls:
+ enabled: true
+ certSecretRef:
+ name: authorino-server-cert
+ oidcServer:
+ tls:
+ enabled: true
+ certSecretRef:
+ name: authorino-oidc-server-cert
+EOF
+
+
+
+Cluster-wide (without TLS)
+kubectl create namespace authorino
+kubectl -n authorino apply -f -<<EOF
+apiVersion: operator.authorino.kuadrant.io/v1beta1
+kind: Authorino
+metadata:
+ name: authorino
+spec:
+ image: quay.io/kuadrant/authorino:latest
+ replicas: 1
+ clusterWide: true
+ listener:
+ tls:
+ enabled: false
oidcServer:
tls:
- enabled: true
- certSecretRef:
- name: authorino-oidc-server-cert
-EOF
+ enabled: false
+EOF
-
- Cluster-wide (without TLS)
-
- kubectl create namespace authorino
-kubectl -n authorino apply -f -<<EOF
-apiVersion: operator.authorino.kuadrant.io/v1beta1
-kind: Authorino
-metadata:
- name: authorino
-spec:
- image: quay.io/kuadrant/authorino:latest
- replicas: 1
- clusterWide: true
- listener:
- tls:
- enabled: false
- oidcServer:
- tls:
- enabled: false
-EOF
-
+Namespaced (with TLS)
+Create the namespace:
+
+Create the TLS certificates (requires cert-manager; skip if you already have certificates and certificate keys created and stored in Kubernetes Secret
s in the namespace):
+
curl -sSL https://raw.githubusercontent.com/Kuadrant/authorino/main/deploy/certs.yaml | sed "s/\$(AUTHORINO_INSTANCE)/authorino/g;s/\$(NAMESPACE)/myapp/g" | kubectl -n myapp apply -f -
+
+Deploy Authorino:
+
kubectl -n myapp apply -f -<<EOF
+apiVersion: operator.authorino.kuadrant.io/v1beta1
+kind: Authorino
+metadata:
+ name: authorino
+spec:
+ image: quay.io/kuadrant/authorino:latest
+ replicas: 1
+ clusterWide: false
+ listener:
+ tls:
+ enabled: true
+ certSecretRef:
+ name: authorino-server-cert
+ oidcServer:
+ tls:
+ enabled: true
+ certSecretRef:
+ name: authorino-oidc-server-cert
+EOF
+
-
- Namespaced (with TLS)
-
- Create the namespace:
-
-
- Deploy [cert-manager](https://github.com/jetstack/cert-manager) (skip if you already have certificates and certificate keys created and stored in Kubernetes `Secret`s in the namespace or cert-manager is installed and running in the cluster):
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml
-
-
- Create the TLS certificates (skip if you already have certificates and certificate keys created and stored in Kubernetes `Secret`s in the namespace):
- curl -sSL https://raw.githubusercontent.com/Kuadrant/authorino/main/deploy/certs.yaml | sed "s/\$(AUTHORINO_INSTANCE)/authorino/g;s/\$(NAMESPACE)/myapp/g" | kubectl -n myapp apply -f -
-
-
- Deploy Authorino:
- kubectl -n myapp apply -f -<<EOF
-apiVersion: operator.authorino.kuadrant.io/v1beta1
-kind: Authorino
-metadata:
- name: authorino
-spec:
- image: quay.io/kuadrant/authorino:latest
- replicas: 1
- clusterWide: false
- listener:
- tls:
- enabled: true
- certSecretRef:
- name: authorino-server-cert
- oidcServer:
- tls:
- enabled: true
- certSecretRef:
- name: authorino-oidc-server-cert
-EOF
-
-
-
-
- Namespaced (without TLS)
-
- kubectl create namespace myapp
-kubectl -n myapp apply -f -<<EOF
-apiVersion: operator.authorino.kuadrant.io/v1beta1
-kind: Authorino
-metadata:
- name: authorino
-spec:
- image: quay.io/kuadrant/authorino:latest
- replicas: 1
- clusterWide: false
- listener:
- tls:
- enabled: false
- oidcServer:
- tls:
- enabled: false
-EOF
+Namespaced (without TLS)
+kubectl create namespace myapp
+kubectl -n myapp apply -f -<<EOF
+apiVersion: operator.authorino.kuadrant.io/v1beta1
+kind: Authorino
+metadata:
+ name: authorino
+spec:
+ image: quay.io/kuadrant/authorino:latest
+ replicas: 1
+ clusterWide: false
+ listener:
+ tls:
+ enabled: false
+ oidcServer:
+ tls:
+ enabled: false
+EOF
-
Protect a service¶
The most typical integration to protect services with Authorino is by putting the service (upstream) behind a reverse-proxy or API gateway, enabled with an authorization filter that ensures all requests to the service are first checked with the authorization server (Authorino).
To do that, make sure you have your upstream service deployed and running, usually in the same Kubernetes server where you installed Authorino. Then, setup an Envoy proxy and create an Authorino AuthConfig
for your service.
@@ -3850,157 +3822,157 @@ Life cycleStep: Setup Envoy¶
To configure Envoy for proxying requests targeting the upstream service and authorizing with Authorino, setup an Envoy configuration that enables Envoy's external authorization HTTP filter. Store the configuration in a ConfigMap
.
These are the important bits in the Envoy configuration to activate Authorino:
-static_resources:
- listeners:
-
- - address: {…} # TCP socket address and port of the proxy
- filter_chains:
- - filters:
- - name: envoy.http_connection_manager
- typed_config:
- "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
- route_config: {…} # routing configs - virtual host domain and endpoint matching patterns and corresponding upstream services to redirect the traffic
- http_filters:
- - name: envoy.filters.http.ext_authz # the external authorization filter
- typed_config:
- "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
- transport_api_version: V3
- failure_mode_allow: false # ensures only authenticated and authorized traffic goes through
- grpc_service:
- envoy_grpc:
- cluster_name: authorino
- timeout: 1s
- clusters:
- - name: authorino
- connect_timeout: 0.25s
- type: strict_dns
- lb_policy: round_robin
- http2_protocol_options: {}
- load_assignment:
- cluster_name: authorino
- endpoints:
- - lb_endpoints:
- - endpoint:
- address:
- socket_address:
- address: authorino-authorino-authorization # name of the Authorino service deployed – it can be the fully qualified name with `.<namespace>.svc.cluster.local` suffix (e.g. `authorino-authorino-authorization.myapp.svc.cluster.local`)
- port_value: 50051
- transport_socket: # in case TLS termination is enabled in Authorino; omit it otherwise
- name: envoy.transport_sockets.tls
- typed_config:
- "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
- common_tls_context:
- validation_context:
- trusted_ca:
- filename: /etc/ssl/certs/authorino-ca-cert.crt
+static_resources:
+ listeners:
+
+ - address: {…} # TCP socket address and port of the proxy
+ filter_chains:
+ - filters:
+ - name: envoy.http_connection_manager
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ route_config: {…} # routing configs - virtual host domain and endpoint matching patterns and corresponding upstream services to redirect the traffic
+ http_filters:
+ - name: envoy.filters.http.ext_authz # the external authorization filter
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ transport_api_version: V3
+ failure_mode_allow: false # ensures only authenticated and authorized traffic goes through
+ grpc_service:
+ envoy_grpc:
+ cluster_name: authorino
+ timeout: 1s
+ clusters:
+ - name: authorino
+ connect_timeout: 0.25s
+ type: strict_dns
+ lb_policy: round_robin
+ http2_protocol_options: {}
+ load_assignment:
+ cluster_name: authorino
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: authorino-authorino-authorization # name of the Authorino service deployed – it can be the fully qualified name with `.<namespace>.svc.cluster.local` suffix (e.g. `authorino-authorino-authorization.myapp.svc.cluster.local`)
+ port_value: 50051
+ transport_socket: # in case TLS termination is enabled in Authorino; omit it otherwise
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ validation_context:
+ trusted_ca:
+ filename: /etc/ssl/certs/authorino-ca-cert.crt
-For a complete Envoy ConfigMap
containing an upstream API protected with Authorino, with TLS enabled and option for rate limiting with Limitador, plus a webapp served with under the same domain of the protected API, check out this example.
+For a complete Envoy ConfigMap
containing an upstream API protected with Authorino, with TLS enabled and option for rate limiting with Limitador, plus a webapp served with under the same domain of the protected API, check out this example.
After creating the ConfigMap
with the Envoy configuration, create an Envoy Deployment
and Service
. E.g.:
-kubectl -n myapp apply -f -<<EOF
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: envoy
- labels:
- app: envoy
-spec:
- selector:
- matchLabels:
- app: envoy
- template:
- metadata:
- labels:
- app: envoy
- spec:
- containers:
-
- - name: envoy
- image: envoyproxy/envoy:v1.19-latest
- command: ["/usr/local/bin/envoy"]
- args:
- - --config-path /usr/local/etc/envoy/envoy.yaml
- - --service-cluster front-proxy
- - --log-level info
- - --component-log-level filter:trace,http:debug,router:debug
- ports:
- - name: web
- containerPort: 8000 # matches the adddress of the listener in the envoy config
- volumeMounts:
- - name: config
- mountPath: /usr/local/etc/envoy
- readOnly: true
- - name: authorino-ca-cert # in case TLS termination is enabled in Authorino; omit it otherwise
- subPath: ca.crt
- mountPath: /etc/ssl/certs/authorino-ca-cert.crt
- readOnly: true
- volumes:
- - name: config
- configMap:
- name: envoy
- items:
- - key: envoy.yaml
- path: envoy.yaml
- - name: authorino-ca-cert # in case TLS termination is enabled in Authorino; omit it otherwise
- secret:
- defaultMode: 420
- secretName: authorino-ca-cert
- replicas: 1
-EOF
+kubectl -n myapp apply -f -<<EOF
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: envoy
+ labels:
+ app: envoy
+spec:
+ selector:
+ matchLabels:
+ app: envoy
+ template:
+ metadata:
+ labels:
+ app: envoy
+ spec:
+ containers:
+
+ - name: envoy
+ image: envoyproxy/envoy:v1.19-latest
+ command: ["/usr/local/bin/envoy"]
+ args:
+ - --config-path /usr/local/etc/envoy/envoy.yaml
+ - --service-cluster front-proxy
+ - --log-level info
+ - --component-log-level filter:trace,http:debug,router:debug
+ ports:
+ - name: web
+ containerPort: 8000 # matches the address of the listener in the envoy config
+ volumeMounts:
+ - name: config
+ mountPath: /usr/local/etc/envoy
+ readOnly: true
+ - name: authorino-ca-cert # in case TLS termination is enabled in Authorino; omit it otherwise
+ subPath: ca.crt
+ mountPath: /etc/ssl/certs/authorino-ca-cert.crt
+ readOnly: true
+ volumes:
+ - name: config
+ configMap:
+ name: envoy
+ items:
+ - key: envoy.yaml
+ path: envoy.yaml
+ - name: authorino-ca-cert # in case TLS termination is enabled in Authorino; omit it otherwise
+ secret:
+ defaultMode: 420
+ secretName: authorino-ca-cert
+ replicas: 1
+EOF
-