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 @@
  • - + @@ -1852,7 +1852,7 @@
  • - + diff --git a/0.10.0/api-quickstart/index.html b/0.10.0/api-quickstart/index.html index 959ac94aa..4dfcaad1f 100644 --- a/0.10.0/api-quickstart/index.html +++ b/0.10.0/api-quickstart/index.html @@ -11,7 +11,7 @@ - + @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/docs/design/architectural-overview-v1/index.html b/0.10.0/architecture/docs/design/architectural-overview-v1/index.html index 01126a7ff..66c7dfac0 100644 --- a/0.10.0/architecture/docs/design/architectural-overview-v1/index.html +++ b/0.10.0/architecture/docs/design/architectural-overview-v1/index.html @@ -1757,7 +1757,7 @@
  • - + @@ -2116,7 +2116,7 @@
  • - + diff --git a/0.10.0/architecture/docs/design/architectural-overview/index.html b/0.10.0/architecture/docs/design/architectural-overview/index.html index 6a187140a..bfec8a79e 100644 --- a/0.10.0/architecture/docs/design/architectural-overview/index.html +++ b/0.10.0/architecture/docs/design/architectural-overview/index.html @@ -1500,7 +1500,7 @@
  • - + @@ -1859,7 +1859,7 @@
  • - + diff --git a/0.10.0/architecture/docs/design/modular_installation/index.html b/0.10.0/architecture/docs/design/modular_installation/index.html index 90db2c55d..43acce147 100644 --- a/0.10.0/architecture/docs/design/modular_installation/index.html +++ b/0.10.0/architecture/docs/design/modular_installation/index.html @@ -1500,7 +1500,7 @@
  • - + @@ -1859,7 +1859,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0001-rlp-v2/index.html b/0.10.0/architecture/rfcs/0001-rlp-v2/index.html index b4da95a91..31ad370e0 100644 --- a/0.10.0/architecture/rfcs/0001-rlp-v2/index.html +++ b/0.10.0/architecture/rfcs/0001-rlp-v2/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0002-well-known-attributes/index.html b/0.10.0/architecture/rfcs/0002-well-known-attributes/index.html index f19b2ead2..7cbca85cf 100644 --- a/0.10.0/architecture/rfcs/0002-well-known-attributes/index.html +++ b/0.10.0/architecture/rfcs/0002-well-known-attributes/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0003-dns-policy-assets/DNSRecordStructure/index.html b/0.10.0/architecture/rfcs/0003-dns-policy-assets/DNSRecordStructure/index.html index b983213a0..06c85870a 100644 --- a/0.10.0/architecture/rfcs/0003-dns-policy-assets/DNSRecordStructure/index.html +++ b/0.10.0/architecture/rfcs/0003-dns-policy-assets/DNSRecordStructure/index.html @@ -1500,7 +1500,7 @@
  • - + @@ -1859,7 +1859,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0003-dns-policy/index.html b/0.10.0/architecture/rfcs/0003-dns-policy/index.html index c607d7e88..2c3b57534 100644 --- a/0.10.0/architecture/rfcs/0003-dns-policy/index.html +++ b/0.10.0/architecture/rfcs/0003-dns-policy/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0004-policy-status/index.html b/0.10.0/architecture/rfcs/0004-policy-status/index.html index 8a197d675..bcfe86c70 100644 --- a/0.10.0/architecture/rfcs/0004-policy-status/index.html +++ b/0.10.0/architecture/rfcs/0004-policy-status/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0005-single-cluster-dnspolicy/index.html b/0.10.0/architecture/rfcs/0005-single-cluster-dnspolicy/index.html index e26d35aa9..7982b217c 100644 --- a/0.10.0/architecture/rfcs/0005-single-cluster-dnspolicy/index.html +++ b/0.10.0/architecture/rfcs/0005-single-cluster-dnspolicy/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0006-kuadrant_sub_components_configurations/index.html b/0.10.0/architecture/rfcs/0006-kuadrant_sub_components_configurations/index.html index 93c15c9d2..f4cf0a446 100644 --- a/0.10.0/architecture/rfcs/0006-kuadrant_sub_components_configurations/index.html +++ b/0.10.0/architecture/rfcs/0006-kuadrant_sub_components_configurations/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0007-policy-sync-v1/index.html b/0.10.0/architecture/rfcs/0007-policy-sync-v1/index.html index 3241847f2..76ebf7d56 100644 --- a/0.10.0/architecture/rfcs/0007-policy-sync-v1/index.html +++ b/0.10.0/architecture/rfcs/0007-policy-sync-v1/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0008-kuadrant-release-process/index.html b/0.10.0/architecture/rfcs/0008-kuadrant-release-process/index.html index 2e029904b..90962889a 100644 --- a/0.10.0/architecture/rfcs/0008-kuadrant-release-process/index.html +++ b/0.10.0/architecture/rfcs/0008-kuadrant-release-process/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0009-defaults-and-overrides/index.html b/0.10.0/architecture/rfcs/0009-defaults-and-overrides/index.html index 0e5fc1bbb..665ef9aa4 100644 --- a/0.10.0/architecture/rfcs/0009-defaults-and-overrides/index.html +++ b/0.10.0/architecture/rfcs/0009-defaults-and-overrides/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0010-gateway-api-metrics-exporter/index.html b/0.10.0/architecture/rfcs/0010-gateway-api-metrics-exporter/index.html index a7aef698a..d92a87c37 100644 --- a/0.10.0/architecture/rfcs/0010-gateway-api-metrics-exporter/index.html +++ b/0.10.0/architecture/rfcs/0010-gateway-api-metrics-exporter/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/0011-policy-machinery/index.html b/0.10.0/architecture/rfcs/0011-policy-machinery/index.html index fd9a1eccf..94fd83888 100644 --- a/0.10.0/architecture/rfcs/0011-policy-machinery/index.html +++ b/0.10.0/architecture/rfcs/0011-policy-machinery/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/architecture/rfcs/dns-policy-api-changes/index.html b/0.10.0/architecture/rfcs/dns-policy-api-changes/index.html index f3a4b654e..d6aee3446 100644 --- a/0.10.0/architecture/rfcs/dns-policy-api-changes/index.html +++ b/0.10.0/architecture/rfcs/dns-policy-api-changes/index.html @@ -1500,7 +1500,7 @@
  • - + @@ -1859,7 +1859,7 @@
  • - + diff --git a/0.10.0/authorino-operator/index.html b/0.10.0/authorino-operator/index.html index d3d87e209..ca7ff3947 100644 --- a/0.10.0/authorino-operator/index.html +++ b/0.10.0/authorino-operator/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + diff --git a/0.10.0/authorino/docs/architecture.gif b/0.10.0/authorino/docs/architecture.gif index 65e17342b..ee5f30fe3 100644 Binary files a/0.10.0/authorino/docs/architecture.gif and b/0.10.0/authorino/docs/architecture.gif differ diff --git a/0.10.0/authorino/docs/architecture/index.html b/0.10.0/authorino/docs/architecture/index.html index 4d41c38d5..1adca322d 100644 --- a/0.10.0/authorino/docs/architecture/index.html +++ b/0.10.0/authorino/docs/architecture/index.html @@ -1504,7 +1504,7 @@
  • - + @@ -1863,7 +1863,7 @@
  • - + @@ -2736,9 +2736,9 @@
  • - + - JSON Web Keys (JWKs) and JSON Web Ket Sets (JWKS) + JSON Web Keys (JWKs) and JSON Web Key Sets (JWKS) @@ -3709,9 +3709,9 @@
  • - + - JSON Web Keys (JWKs) and JSON Web Ket Sets (JWKS) + JSON Web Keys (JWKs) and JSON Web Key Sets (JWKS) @@ -3809,41 +3809,16 @@

    Architecture

    -

    Overview

    Architecture

    -

    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.

    AuthConfigs 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.

    Topologies

    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 @@

    TopologiesCentralized gateway

    Centralized gateway topology

    -

    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.

    Centralized authorization service

    Centralized Authorino topology

    Protected service should only listen on localhost and all traffic can be considered safe.

    @@ -3864,91 +3839,115 @@

    Sidecarsnamespaced instances of Authorino with fine-grained label selectors to avoid unnecessary caching of AuthConfigs.

    Apart from that, protected service should only listen on localhost and all traffic can be considered safe.

    Cluster-wide vs. Namespaced instances

    -

    Auhorino instances can run in either cluster-wide or namespaced mode.

    -

    Namespace-scoped instances only watch resources (AuthConfigs and Secrets) 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 (AuthConfigs and Secrets) 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.

    The Authorino 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 AuthConfigs 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 AuthConfigs 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 AuthConfigs. 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 Secrets, as part of Authorino's API key authentication feature. Secret resources that store API keys are linked to their corresponding AuthConfigs in the index. Whenever the Authorino instance detects a change in the set of API key Secrets linked to an AuthConfigs, the instance reconciles the index.

    -

    Authorino only watches events related to Secrets whose metadata.labels match the label selector SECRET_LABEL_SELECTOR of the Authorino instance. The default values of the label selector for Kubernetes Secrets 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 Secrets, as part of Authorino's API key authentication feature. Secret resources that store API keys are linked to their corresponding AuthConfigs in the index. Whenever the Authorino instance detects a change in the set of API key Secrets linked to an AuthConfigs, the instance reconciles the index.

    +

    Authorino only watches events related to Secrets whose metadata.labels match the label selector --secret-label-selector of the Authorino instance. The default values of the label selector for Kubernetes Secrets representing Authorino API keys is authorino.kuadrant.io/managed-by=authorino.

    The "Auth Pipeline" (aka: enforcing protection in request-time)

    -

    Authorino Auth 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 4-phase pipeline:

    +

    Authorino Auth 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 AuthConfigs, 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.

    Domain tree

    @@ -3962,13 +3961,14 @@

    Host lookupfoo.org404 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 AuthConfigs 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' AuthConfigs, partially or fully, by just picking the same host names or overlapping host names as others.

    +

    Authorino tries to prevent host name collision between AuthConfigs 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 AuthConfigs, 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 AuthConfigs 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:

    -

    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: Priorities
    apiVersion: 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 operatoreq (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 (metricsMETADATA_UMA -authorization.json +authorization.patternMatching AUTHORIZATION_JSON @@ -5010,21 +5163,29 @@

    Common feature: Metrics (metricsAUTHORIZATION_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:

    kubectl create namespace authorino
    -
    - - 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 Secrets 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: +

    kubectl create namespace myapp
    +

    +

    Create the TLS certificates (requires cert-manager; skip if you already have certificates and certificate keys created and stored in Kubernetes Secrets 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: -
    kubectl create namespace myapp
    -
    - - 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
     
    -
    kubectl -n myapp apply -f -<<EOF
    -apiVersion: v1
    -kind: Service
    -metadata:
    -  name: envoy
    -spec:
    -  selector:
    -    app: envoy
    -  ports:
    -
    -    - name: web
    -      port: 8000
    -      protocol: TCP
    -EOF
    +
    kubectl -n myapp apply -f -<<EOF
    +apiVersion: v1
    +kind: Service
    +metadata:
    +  name: envoy
    +spec:
    +  selector:
    +    app: envoy
    +  ports:
    +
    +    - name: web
    +      port: 8000
    +      protocol: TCP
    +EOF
     

    Step: Apply an AuthConfig

    Check out the docs for a full description of Authorino's AuthConfig Custom Resource Definition (CRD) and its features.

    For examples based on specific use-cases, check out the User guides.

    For authentication based on OpenID Connect (OIDC) JSON Web Tokens (JWT), plus one simple JWT claim authorization check, a typical AuthConfig custom resource looks like the following:

    -
    kubectl -n myapp apply -f -<<EOF
    -apiVersion: authorino.kuadrant.io/v1beta1
    -kind: AuthConfig
    -metadata:
    -  name: my-api-protection
    -spec:
    -  hosts: # any hosts that resolve to the envoy service and envoy routing config where the external authorization filter is enabled
    -
    -    - my-api.io # north-south traffic through a Kubernetes `Ingress` or OpenShift `Route`
    -    - my-api.myapp.svc.cluster.local # east-west traffic (between applications within the cluster)
    -  identity:
    -    - name: idp-users
    -      oidc:
    -        endpoint: https://my-idp.com/auth/realm
    -  authorization:
    -    - name: check-claim
    -      json:
    -        rules:
    -          - selector: auth.identity.group
    -            operator: eq
    -            value: allowed-users
    -EOF
    +
    kubectl -n myapp apply -f -<<EOF
    +apiVersion: authorino.kuadrant.io/v1beta2
    +kind: AuthConfig
    +metadata:
    +  name: my-api-protection
    +spec:
    +  hosts: # any hosts that resolve to the envoy service and envoy routing config where the external authorization filter is enabled
    +
    +  - my-api.io # north-south traffic through a Kubernetes `Ingress` or OpenShift `Route`
    +  - my-api.myapp.svc.cluster.local # east-west traffic (between applications within the cluster)
    +  authentication:
    +    "idp-users":
    +      jwt:
    +        issuerUrl: https://my-idp.com/auth/realm
    +  authorization:
    +    "check-claim":
    +      patternMatching:
    +        patterns:
    +        - selector: auth.identity.group
    +          operator: eq
    +          value: allowed-users
    +EOF
     

    After applying the AuthConfig, consumers of the protected service should be able to start sending requests.

    Clean-up

    Remove protection

    Delete the AuthConfig:

    -
    kubectl -n myapp delete authconfig/my-api-protection
    +
    kubectl -n myapp delete authconfig/my-api-protection
     

    Decommission the Authorino instance:

    -
    kubectl -n myapp delete authorino/authorino
    +
    kubectl -n myapp delete authorino/authorino
     

    Uninstall

    To completely remove Authorino CRDs, run from the Authorino Operator directory:

    -
    make uninstall
    +
    make uninstall
     

    Next steps

      diff --git a/0.10.0/authorino/docs/index.html b/0.10.0/authorino/docs/index.html index a77e801df..6962ddadf 100644 --- a/0.10.0/authorino/docs/index.html +++ b/0.10.0/authorino/docs/index.html @@ -1500,7 +1500,7 @@
    1. - + @@ -1859,7 +1859,7 @@
    2. - + diff --git a/0.10.0/authorino/docs/terminology/index.html b/0.10.0/authorino/docs/terminology/index.html index 3b3290712..65c14bbac 100644 --- a/0.10.0/authorino/docs/terminology/index.html +++ b/0.10.0/authorino/docs/terminology/index.html @@ -1500,7 +1500,7 @@
    3. - + @@ -1859,7 +1859,7 @@
    4. - + diff --git a/0.10.0/authorino/docs/user-guides/anonymous-access/index.html b/0.10.0/authorino/docs/user-guides/anonymous-access/index.html index ab2719301..16d1f7cac 100644 --- a/0.10.0/authorino/docs/user-guides/anonymous-access/index.html +++ b/0.10.0/authorino/docs/user-guides/anonymous-access/index.html @@ -1332,54 +1332,54 @@
    5. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    6. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    7. - + - 3. Deploy Authorino + ❸ Deploy the Talker API
    8. - + - 4. Setup Envoy + ❹ Setup Envoy
    9. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    10. - + - 6. Consume the API + ❻ Consume the API @@ -1620,7 +1620,7 @@
    11. - + @@ -1979,7 +1979,7 @@
    12. - + @@ -3417,54 +3417,54 @@
    13. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    14. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    15. - + - 3. Deploy Authorino + ❸ Deploy the Talker API
    16. - + - 4. Setup Envoy + ❹ Setup Envoy
    17. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    18. - + - 6. Consume the API + ❻ Consume the API @@ -3505,75 +3505,106 @@

      User guide: Anonymous access

      Bypass identity verification or fall back to anonymous access when credentials fail to validate

      - - Authorino features in this guide: + + Authorino capabilities featured in this guide: - - For further details about Authorino features in general, check the [docs](./../features.md). +

      For further details about Authorino features in general, check the docs.

      -


      Requirements

        -
      • Kubernetes server
      • +
      • Kubernetes server with permissions to install cluster-scoped resources (operator, CRDs and RBAC)
      -

      Create a containerized Kubernetes server locally using Kind:

      +

      If you do not own a Kubernetes server already and just want to try out the steps in this guide, you can create a local containerized cluster by executing the command below. In this case, the main requirement is having Kind installed, with either Docker or Podman.

      kind create cluster --name authorino-tutorial
       
      -

      1. Install the Authorino Operator

      -
      kubectl apply -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
      +


      +

      The next steps walk you through installing Authorino, deploying and configuring a sample service called Talker API to be protected by the authorization service.

      + + + + + + + + + + + +
      Using Kuadrant
      +

      If you are a user of Kuadrant and already have your workload cluster configured and sample service application deployed, as well as your Gateway API network resources applied to route traffic to your service, skip straight to step ❺.

      +

      At step ❺, instead of creating an AuthConfig custom resource, create a Kuadrant AuthPolicy one. The schema of the AuthConfig's spec matches the one of the AuthPolicy's, except spec.host, which is not available in the Kuadrant AuthPolicy. Host names in a Kuadrant AuthPolicy are inferred automatically from the Kubernetes network object referred in spec.targetRef and route selectors declared in the policy.

      +

      For more about using Kuadrant to enforce authorization, check out Kuadrant auth.

      +
      + +


      +

      ❶ Install the Authorino Operator (cluster admin required)

      +

      The following command will install the Authorino Operator in the Kubernetes cluster. The operator manages instances of the Authorino authorization service.

      +
      curl -sL https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/utils/install.sh | bash -s
       
      -

      2. Deploy the Talker API

      -

      The Talker API is just an echo API, included in the Authorino examples. We will use it in this guide as the service to be protected with Authorino.

      -
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +

      ❷ Deploy Authorino

      +

      The following command will request an instance of Authorino as a separate service1 that watches for AuthConfig resources in the default namespace2, with TLS disabled3.

      +
      kubectl apply -f -<<EOF
      +apiVersion: operator.authorino.kuadrant.io/v1beta1
      +kind: Authorino
      +metadata:
      +  name: authorino
      +spec:
      +  listener:
      +    tls:
      +      enabled: false
      +  oidcServer:
      +    tls:
      +      enabled: false
      +EOF
       
      -

      3. Deploy Authorino

      -
      kubectl apply -f -<<EOF
      -apiVersion: operator.authorino.kuadrant.io/v1beta1
      -kind: Authorino
      -metadata:
      -  name: authorino
      -spec:
      -  listener:
      -    tls:
      -      enabled: false
      -  oidcServer:
      -    tls:
      -      enabled: false
      -EOF
      +

      ❸ Deploy the Talker API

      +

      The Talker API is a simple HTTP service that echoes back in the response whatever it gets in the request. We will use it in this guide as the sample service to be protected by Authorino.

      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
       
      -

      The command above will deploy Authorino as a separate service (as oposed to a sidecar of the protected API and other architectures), in namespaced reconciliation mode, and with TLS termination disabled. For other variants and deployment options, check out the Getting Started section of the docs, the Architecture page, and the spec for the Authorino CRD in the Authorino Operator repo.

      -

      4. Setup Envoy

      -

      The following bundle from the Authorino examples (manifest referred in the command below) is to apply Envoy configuration and deploy Envoy proxy, that wire up the Talker API behind the reverse-proxy and external authorization with the Authorino instance.

      -

      For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. For a simpler and straighforward way to manage an API, without having to manually install or configure Envoy and Authorino, check out Kuadrant.

      +

      ❹ Setup Envoy

      +

      The following bundle from the Authorino examples deploys the Envoy proxy and configuration to wire up the Talker API behind the reverse-proxy, with external authorization enabled with the Authorino instance.4

      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
       
      -

      The bundle also creates an Ingress with host name talker-api-authorino.127.0.0.1.nip.io, but if you are using a local Kubernetes cluster created with Kind, you need to forward requests on port 8000 to inside the cluster in order to actually reach the Envoy service:

      -
      kubectl port-forward deployment/envoy 8000:8000 &
      +

      The command above creates an Ingress with host name talker-api.127.0.0.1.nip.io. If you are using a local Kubernetes cluster created with Kind, forward requests from your local port 8000 to the Envoy service running inside the cluster:

      +
      kubectl port-forward deployment/envoy 8000:8000 2>&1 >/dev/null &
       
      -

      5. Create the AuthConfig

      +

      ❺ Create an AuthConfig

      +

      Create an Authorino AuthConfig custom resource declaring the auth rules to be enforced:

      + + + + + + +
      + Kuadrant users – + Remember to create an AuthPolicy instead of an AuthConfig. + For more, see Kuadrant auth. +
      +
      kubectl apply -f -<<EOF
      -apiVersion: authorino.kuadrant.io/v1beta1
      +apiVersion: authorino.kuadrant.io/v1beta2
       kind: AuthConfig
       metadata:
         name: talker-api-protection
       spec:
         hosts:
       
      -  - talker-api-authorino.127.0.0.1.nip.io
      -  identity:
      -  - name: public
      -    anonymous: {}
      +  - talker-api.127.0.0.1.nip.io
      +  authentication:
      +    "public":
      +      anonymous: {}
       EOF
       

      The example above enables anonymous access (i.e. removes authentication), without adding any extra layer of protection to the API. This is virtually equivalent to setting a top-level condition to the AuthConfig that always skips the configuration, or to switching authentication/authorization off completely in the route to the API.

      For more sophisticated use cases of anonymous access with Authorino, consider combining this feature with other identity sources in the AuthConfig while playing with the priorities of each source, as well as combination with when conditions, and/or adding authorization policies that either cover authentication or address anonymous access with proper rules (e.g. enforcing read-only access).

      -

      Check out the docs for the Anonymous access feature for an example of an AuthConfig that falls back to anonymous access when a priority OIDC/JWT-based authentication fails, and enforces a read-only policy in such cases.

      -

      6. Consume the API

      -
      curl http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +

      Check out the docs for the Anonymous access feature for an example of an AuthConfig that falls back to anonymous access when a priority OIDC/JWT-based authentication fails, and enforces a read-only policy in such cases.

      +

      ❻ Consume the API

      +
      curl http://talker-api.127.0.0.1.nip.io:8000/hello
       # HTTP/1.1 200 OK
       

      Cleanup

      @@ -3582,13 +3613,30 @@

      Cleanup
      kubectl delete authconfig/talker-api-protection
      -kubectl delete authorino/authorino
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete authorino/authorino
       

      To uninstall the Authorino Operator and manifests (CRDs, RBAC, etc), run:

      kubectl delete -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
       
      +
      +
      +
        +
      1. +

        In contrast to a dedicated sidecar of the protected service and other architectures. Check out Architecture > Topologies for all options. 

        +
      2. +
      3. +

        namespaced reconciliation mode. See Cluster-wide vs. Namespaced instances

        +
      4. +
      5. +

        For other variants and deployment options, check out Getting Started, as well as the Authorino CRD specification. 

        +
      6. +
      7. +

        For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. If you are running your ingress gateway in Kubernetes and wants to avoid setting up and configuring your proxy manually, check out Kuadrant

        +
      8. +
      +
      diff --git a/0.10.0/authorino/docs/user-guides/api-key-authentication/index.html b/0.10.0/authorino/docs/user-guides/api-key-authentication/index.html index f4a22d8fe..4866acd38 100644 --- a/0.10.0/authorino/docs/user-guides/api-key-authentication/index.html +++ b/0.10.0/authorino/docs/user-guides/api-key-authentication/index.html @@ -1206,72 +1206,72 @@
    19. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    20. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    21. - + - 3. Deploy Authorino + ❸ Deploy the Talker API
    22. - + - 4. Setup Envoy + ❹ Setup Envoy
    23. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    24. - + - 6. Create an API key + ❻ Create an API key
    25. - + - 7. Consume the API + ❼ Consume the API
    26. - + - 8. Delete an API key (revoke access to the API) + ❽ Delete an API key (revoke access to the API) @@ -1638,7 +1638,7 @@
    27. - + @@ -1997,7 +1997,7 @@
    28. - + @@ -3435,72 +3435,72 @@
    29. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    30. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    31. - + - 3. Deploy Authorino + ❸ Deploy the Talker API
    32. - + - 4. Setup Envoy + ❹ Setup Envoy
    33. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    34. - + - 6. Create an API key + ❻ Create an API key
    35. - + - 7. Consume the API + ❼ Consume the API
    36. - + - 8. Delete an API key (revoke access to the API) + ❽ Delete an API key (revoke access to the API) @@ -3541,81 +3541,110 @@

      User guide: Authentication with API keys

      Issue API keys stored in Kubernetes Secrets for clients to authenticate with your protected hosts.

      - - Authorino features in this guide: + + Authorino capabilities featured in this guide:
        -
      • Identity verification & authentication → API key
      • +
      • Identity verification & authentication → API key
      - - In Authorino, API keys are stored as Kubernetes `Secret`s. Each resource must contain an `api_key` entry with the value of the API key, and labeled to match the selectors specified in `spec.identity.apiKey.selector` of the `AuthConfig`. - - API key `Secret`s must also include labels that match the `secretLabelSelector` field of the Authorino instance. See [Resource reconciliation and status update](../architecture.md#resource-reconciliation-and-status-update) for details. - - For further details about Authorino features in general, check the [docs](./../features.md). +

      In Authorino, API keys are stored as Kubernetes Secrets. Each resource must contain an api_key entry with the value of the API key, and labeled to match the selectors specified in spec.identity.apiKey.selector of the AuthConfig.

      +

      API key Secrets must also include labels that match the secretLabelSelector field of the Authorino instance. See Resource reconciliation and status update for details.

      +

      For further details about Authorino features in general, check the docs.

      -


      Requirements

        -
      • Kubernetes server
      • +
      • Kubernetes server with permissions to install cluster-scoped resources (operator, CRDs and RBAC)
      -

      Create a containerized Kubernetes server locally using Kind:

      +

      If you do not own a Kubernetes server already and just want to try out the steps in this guide, you can create a local containerized cluster by executing the command below. In this case, the main requirement is having Kind installed, with either Docker or Podman.

      kind create cluster --name authorino-tutorial
       
      -

      1. Install the Authorino Operator

      -
      kubectl apply -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
      +


      +

      The next steps walk you through installing Authorino, deploying and configuring a sample service called Talker API to be protected by the authorization service.

      + + + + + + + + + + + +
      Using Kuadrant
      +

      If you are a user of Kuadrant and already have your workload cluster configured and sample service application deployed, as well as your Gateway API network resources applied to route traffic to your service, skip straight to step ❺.

      +

      At step ❺, instead of creating an AuthConfig custom resource, create a Kuadrant AuthPolicy one. The schema of the AuthConfig's spec matches the one of the AuthPolicy's, except spec.host, which is not available in the Kuadrant AuthPolicy. Host names in a Kuadrant AuthPolicy are inferred automatically from the Kubernetes network object referred in spec.targetRef and route selectors declared in the policy.

      +

      For more about using Kuadrant to enforce authorization, check out Kuadrant auth.

      +
      + +


      +

      ❶ Install the Authorino Operator (cluster admin required)

      +

      The following command will install the Authorino Operator in the Kubernetes cluster. The operator manages instances of the Authorino authorization service.

      +
      curl -sL https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/utils/install.sh | bash -s
       
      -

      2. Deploy the Talker API

      -

      The Talker API is just an echo API, included in the Authorino examples. We will use it in this guide as the service to be protected with Authorino.

      -
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +

      ❷ Deploy Authorino

      +

      The following command will request an instance of Authorino as a separate service1 that watches for AuthConfig resources in the default namespace2, with TLS disabled3.

      +
      kubectl apply -f -<<EOF
      +apiVersion: operator.authorino.kuadrant.io/v1beta1
      +kind: Authorino
      +metadata:
      +  name: authorino
      +spec:
      +  listener:
      +    tls:
      +      enabled: false
      +  oidcServer:
      +    tls:
      +      enabled: false
      +EOF
       
      -

      3. Deploy Authorino

      -
      kubectl apply -f -<<EOF
      -apiVersion: operator.authorino.kuadrant.io/v1beta1
      -kind: Authorino
      -metadata:
      -  name: authorino
      -spec:
      -  listener:
      -    tls:
      -      enabled: false
      -  oidcServer:
      -    tls:
      -      enabled: false
      -EOF
      +

      ❸ Deploy the Talker API

      +

      The Talker API is a simple HTTP service that echoes back in the response whatever it gets in the request. We will use it in this guide as the sample service to be protected by Authorino.

      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
       
      -

      The command above will deploy Authorino as a separate service (as oposed to a sidecar of the protected API and other architectures), in namespaced reconciliation mode, and with TLS termination disabled. For other variants and deployment options, check out the Getting Started section of the docs, the Architecture page, and the spec for the Authorino CRD in the Authorino Operator repo.

      -

      4. Setup Envoy

      -

      The following bundle from the Authorino examples (manifest referred in the command below) is to apply Envoy configuration and deploy Envoy proxy, that wire up the Talker API behind the reverse-proxy and external authorization with the Authorino instance.

      -

      For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. For a simpler and straighforward way to manage an API, without having to manually install or configure Envoy and Authorino, check out Kuadrant.

      +

      ❹ Setup Envoy

      +

      The following bundle from the Authorino examples deploys the Envoy proxy and configuration to wire up the Talker API behind the reverse-proxy, with external authorization enabled with the Authorino instance.4

      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
       
      -

      The bundle also creates an Ingress with host name talker-api-authorino.127.0.0.1.nip.io, but if you are using a local Kubernetes cluster created with Kind, you need to forward requests on port 8000 to inside the cluster in order to actually reach the Envoy service:

      -
      kubectl port-forward deployment/envoy 8000:8000 &
      +

      The command above creates an Ingress with host name talker-api.127.0.0.1.nip.io. If you are using a local Kubernetes cluster created with Kind, forward requests from your local port 8000 to the Envoy service running inside the cluster:

      +
      kubectl port-forward deployment/envoy 8000:8000 2>&1 >/dev/null &
       
      -

      5. Create the AuthConfig

      +

      ❺ Create an AuthConfig

      +

      Create an Authorino AuthConfig custom resource declaring the auth rules to be enforced:

      + + + + + + +
      + Kuadrant users – + Remember to create an AuthPolicy instead of an AuthConfig. + For more, see Kuadrant auth. +
      +
      kubectl apply -f -<<EOF
      -apiVersion: authorino.kuadrant.io/v1beta1
      +apiVersion: authorino.kuadrant.io/v1beta2
       kind: AuthConfig
       metadata:
         name: talker-api-protection
       spec:
         hosts:
       
      -  - talker-api-authorino.127.0.0.1.nip.io
      -  identity:
      -  - name: friends
      -    apiKey:
      -      selector:
      -        matchLabels:
      -          group: friends
      -    credentials:
      -      in: authorization_header
      -      keySelector: APIKEY
      +  - talker-api.127.0.0.1.nip.io
      +  authentication:
      +    "friends":
      +      apiKey:
      +        selector:
      +          matchLabels:
      +            group: friends
      +      credentials:
      +        authorizationHeader:
      +          prefix: APIKEY
       EOF
       
      -

      6. Create an API key

      +

      ❻ Create an API key

      kubectl apply -f -<<EOF
       apiVersion: v1
       kind: Secret
      @@ -3629,18 +3658,18 @@ 

      6. Create an API keytype: Opaque EOF

      -

      7. Consume the API

      +

      ❼ Consume the API

      With a valid API key:

      -
      curl -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +
      curl -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://talker-api.127.0.0.1.nip.io:8000/hello
       # HTTP/1.1 200 OK
       

      With missing or invalid API key:

      -
      curl -H 'Authorization: APIKEY invalid' http://talker-api-authorino.127.0.0.1.nip.io:8000/hello -i
      +
      curl -H 'Authorization: APIKEY invalid' http://talker-api.127.0.0.1.nip.io:8000/hello -i
       # HTTP/1.1 401 Unauthorized
       # www-authenticate: APIKEY realm="friends"
       # x-ext-auth-reason: the API Key provided is invalid
       
      -

      8. Delete an API key (revoke access to the API)

      +

      ❽ Delete an API key (revoke access to the API)

      kubectl delete secret/api-key-1
       

      Cleanup

      @@ -3649,13 +3678,30 @@

      Cleanup
      kubectl delete authconfig/talker-api-protection
      -kubectl delete authorino/authorino
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete authorino/authorino
       

      To uninstall the Authorino Operator and manifests (CRDs, RBAC, etc), run:

      kubectl delete -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
       
      +
      +
      +
        +
      1. +

        In contrast to a dedicated sidecar of the protected service and other architectures. Check out Architecture > Topologies for all options. 

        +
      2. +
      3. +

        namespaced reconciliation mode. See Cluster-wide vs. Namespaced instances

        +
      4. +
      5. +

        For other variants and deployment options, check out Getting Started, as well as the Authorino CRD specification. 

        +
      6. +
      7. +

        For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. If you are running your ingress gateway in Kubernetes and wants to avoid setting up and configuring your proxy manually, check out Kuadrant

        +
      8. +
      +
      diff --git a/0.10.0/authorino/docs/user-guides/authenticated-rate-limiting-envoy-dynamic-metadata/index.html b/0.10.0/authorino/docs/user-guides/authenticated-rate-limiting-envoy-dynamic-metadata/index.html index 4c4a6b4f6..4268914d4 100644 --- a/0.10.0/authorino/docs/user-guides/authenticated-rate-limiting-envoy-dynamic-metadata/index.html +++ b/0.10.0/authorino/docs/user-guides/authenticated-rate-limiting-envoy-dynamic-metadata/index.html @@ -1508,7 +1508,7 @@
    37. - + @@ -1605,72 +1605,72 @@
    38. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    39. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    40. - + - 3. Deploy Authorino + ❸ Deploy Limitador
    41. - + - 4. Deploy Limitador + ❹ Deploy the Talker API
    42. - + - 5. Setup Envoy + ❺ Setup Envoy
    43. - + - 6. Create the AuthConfig + ❻ Create an AuthConfig
    44. - + - 7. Create a couple of API keys + ❼ Create the API keys
    45. - + - 8. Consume the API + ❽ Consume the API @@ -1997,7 +1997,7 @@
    46. - + @@ -3435,72 +3435,72 @@
    47. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    48. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    49. - + - 3. Deploy Authorino + ❸ Deploy Limitador
    50. - + - 4. Deploy Limitador + ❹ Deploy the Talker API
    51. - + - 5. Setup Envoy + ❺ Setup Envoy
    52. - + - 6. Create the AuthConfig + ❻ Create an AuthConfig
    53. - + - 7. Create a couple of API keys + ❼ Create the API keys
    54. - + - 8. Consume the API + ❽ Consume the API @@ -3541,99 +3541,128 @@

      User guide: Authenticated rate limiting (with Envoy Dynamic Metadata)

      Provide Envoy with dynamic metadata about the external authorization process to be injected into the rate limiting filter.

      - - Authorino features in this guide: + + Authorino capabilities featured in this guide: - - Dynamic JSON objects built out of static values and values fetched from the [Authorization JSON](./../architecture.md#the-authorization-json) can be wrapped to be returned to the reverse-proxy as Envoy Well Known Dynamic Metadata content. Envoy can use those to inject data returned by the external authorization service into the other filters, such as the rate limiting filter. - - Check out as well the user guides about [Injecting data in the request](./injecting-data.md) and [Authentication with API keys](./api-key-authentication.md). - - For further details about Authorino features in general, check the [docs](./../features.md). +

      Dynamic JSON objects built out of static values and values fetched from the Authorization JSON can be wrapped to be returned to the reverse-proxy as Envoy Well Known Dynamic Metadata content. Envoy can use those to inject data returned by the external authorization service into the other filters, such as the rate limiting filter.

      +

      Check out as well the user guides about Injecting data in the request and Authentication with API keys.

      +

      For further details about Authorino features in general, check the docs.

      -


      Requirements

        -
      • Kubernetes server
      • +
      • Kubernetes server with permissions to install cluster-scoped resources (operator, CRDs and RBAC)
      -

      Create a containerized Kubernetes server locally using Kind:

      +

      If you do not own a Kubernetes server already and just want to try out the steps in this guide, you can create a local containerized cluster by executing the command below. In this case, the main requirement is having Kind installed, with either Docker or Podman.

      kind create cluster --name authorino-tutorial
       
      -

      1. Install the Authorino Operator

      -
      kubectl apply -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
      -
      -

      2. Deploy the Talker API

      -

      The Talker API is just an echo API, included in the Authorino examples. We will use it in this guide as the service to be protected with Authorino.

      -
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +


      +

      The next steps walk you through installing Authorino, deploying and configuring a sample service called Talker API to be protected by the authorization service.

      + + + + + + + + + + + +
      Using Kuadrant
      +

      If you are a user of Kuadrant and already have your workload cluster configured and sample service application deployed, as well as your Gateway API network resources applied to route traffic to your service, skip straight to step ❻.

      +

      At step ❻, instead of creating an AuthConfig custom resource, create a Kuadrant AuthPolicy one. The schema of the AuthConfig's spec matches the one of the AuthPolicy's, except spec.host, which is not available in the Kuadrant AuthPolicy. Host names in a Kuadrant AuthPolicy are inferred automatically from the Kubernetes network object referred in spec.targetRef and route selectors declared in the policy.

      +

      For more about using Kuadrant to enforce authorization, check out Kuadrant auth.

      +
      + +


      +

      ❶ Install the Authorino Operator (cluster admin required)

      +

      The following command will install the Authorino Operator in the Kubernetes cluster. The operator manages instances of the Authorino authorization service.

      +
      curl -sL https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/utils/install.sh | bash -s
       
      -

      3. Deploy Authorino

      -
      kubectl apply -f -<<EOF
      -apiVersion: operator.authorino.kuadrant.io/v1beta1
      -kind: Authorino
      -metadata:
      -  name: authorino
      -spec:
      -  listener:
      -    tls:
      -      enabled: false
      -  oidcServer:
      -    tls:
      -      enabled: false
      -EOF
      +

      ❷ Deploy Authorino

      +

      The following command will request an instance of Authorino as a separate service1 that watches for AuthConfig resources in the default namespace2, with TLS disabled3.

      +
      kubectl apply -f -<<EOF
      +apiVersion: operator.authorino.kuadrant.io/v1beta1
      +kind: Authorino
      +metadata:
      +  name: authorino
      +spec:
      +  listener:
      +    tls:
      +      enabled: false
      +  oidcServer:
      +    tls:
      +      enabled: false
      +EOF
       
      -

      The command above will deploy Authorino as a separate service (as oposed to a sidecar of the protected API and other architectures), in namespaced reconciliation mode, and with TLS termination disabled. For other variants and deployment options, check out the Getting Started section of the docs, the Architecture page, and the spec for the Authorino CRD in the Authorino Operator repo.

      -

      4. Deploy Limitador

      +

      ❸ Deploy Limitador

      Limitador is a lightweight rate limiting service that can be used with Envoy.

      On this bundle, we will deploy Limitador pre-configured to limit requests to the talker-api domain up to 5 requests per interval of 60 seconds per user_id. Envoy will be configured to recognize the presence of Limitador and activate it on requests to the Talker API.

      -
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/limitador/limitador-deploy.yaml
      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/limitador/limitador-deploy.yaml
       
      -

      5. Setup Envoy

      -

      The following bundle from the Authorino examples (manifest referred in the command below) is to apply Envoy configuration and deploy Envoy proxy, that wire up the Talker API behind the reverse-proxy and external authorization with the Authorino instance.

      -

      For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. For a simpler and straighforward way to manage an API, without having to manually install or configure Envoy and Authorino, check out Kuadrant.

      +

      ❹ Deploy the Talker API

      +

      The Talker API is a simple HTTP service that echoes back in the response whatever it gets in the request. We will use it in this guide as the sample service to be protected by Authorino.

      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +
      +

      ❺ Setup Envoy

      +

      The following bundle from the Authorino examples deploys the Envoy proxy and configuration to wire up the Talker API behind the reverse-proxy, with external authorization enabled with the Authorino instance.4

      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
       
      -

      The bundle also creates an Ingress with host name talker-api-authorino.127.0.0.1.nip.io, but if you are using a local Kubernetes cluster created with Kind, you need to forward requests on port 8000 to inside the cluster in order to actually reach the Envoy service:

      -
      kubectl port-forward deployment/envoy 8000:8000 &
      +

      The command above creates an Ingress with host name talker-api.127.0.0.1.nip.io. If you are using a local Kubernetes cluster created with Kind, forward requests from your local port 8000 to the Envoy service running inside the cluster:

      +
      kubectl port-forward deployment/envoy 8000:8000 2>&1 >/dev/null &
       
      -

      6. Create the AuthConfig

      +

      ❻ Create an AuthConfig

      +

      Create an Authorino AuthConfig custom resource declaring the auth rules to be enforced.

      +

      An annotation auth-data/username will be read from the Kubernetes API Key secret and passed as dynamic metadata { "ext_auth_data": { "username": «annotations.auth-data/username» } }.

      + + + + + + +
      + Kuadrant users – + Remember to create an AuthPolicy instead of an AuthConfig. + For more, see Kuadrant auth. +
      +
      kubectl apply -f -<<EOF
      -apiVersion: authorino.kuadrant.io/v1beta1
      +apiVersion: authorino.kuadrant.io/v1beta2
       kind: AuthConfig
       metadata:
         name: talker-api-protection
       spec:
         hosts:
       
      -  - talker-api-authorino.127.0.0.1.nip.io
      -  identity:
      -  - name: friends
      -    apiKey:
      -      selector:
      -        matchLabels:
      -          group: friends
      -    credentials:
      -      in: authorization_header
      -      keySelector: APIKEY
      +  - talker-api.127.0.0.1.nip.io
      +  authentication:
      +    "friends":
      +      apiKey:
      +        selector:
      +          matchLabels:
      +            group: friends
      +      credentials:
      +        authorizationHeader:
      +          prefix: APIKEY
         response:
      -  - name: rate-limit
      -    wrapper: envoyDynamicMetadata
      -    wrapperKey: ext_auth_data # how this bit of dynamic metadata from the ext authz service is named in the Envoy config
      -    json:
      -      properties:
      -      - name: username
      -        valueFrom:
      -          authJSON: auth.identity.metadata.annotations.auth-data\/username
      +    success:
      +      dynamicMetadata:
      +        "rate-limit":
      +          json:
      +            properties:
      +              "username":
      +                selector: auth.identity.metadata.annotations.auth-data\/username
      +          key: ext_auth_data # how this bit of dynamic metadata from the ext authz service is named in the Envoy config
       EOF
       
      -

      An annotation auth-data/username will be read from the Kubernetes Secrets storing valid API keys and passed as dynamic metadata { "ext_auth_data": { "username": «annotations.auth-data/username» } }.

      -

      Check out the docs for information about the common feature JSON paths for reading from the Authorization JSON.

      -

      7. Create a couple of API keys

      +

      Check out the docs for information about the common feature JSON paths for reading from the Authorization JSON.

      +

      ❼ Create the API keys

      For user John:

      kubectl apply -f -<<EOF
       apiVersion: v1
      @@ -3666,14 +3695,14 @@ 

      7. Create a couple of API keystype: Opaque EOF

      -

      8. Consume the API

      +

      ❽ Consume the API

      As John:

      -
      curl -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +
      curl -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://talker-api.127.0.0.1.nip.io:8000/hello -i
       # HTTP/1.1 200 OK
       

      Repeat the request a few more times within the 60-second time window, until the response status is 429 Too Many Requests.

      While the API is still limited to John, send requests as Jane:

      -
      curl -H 'Authorization: APIKEY 7BNaTmYGItSzXiwQLNHu82+x52p1XHgY' http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +
      curl -H 'Authorization: APIKEY 7BNaTmYGItSzXiwQLNHu82+x52p1XHgY' http://talker-api.127.0.0.1.nip.io:8000/hello -i
       # HTTP/1.1 200 OK
       

      Cleanup

      @@ -3684,14 +3713,31 @@

      Cleanup
      kubectl delete secret/api-key-1
       kubectl delete secret/api-key-2
       kubectl delete authconfig/talker-api-protection
      -kubectl delete authorino/authorino
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/limitador/limitador-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/limitador/limitador-deploy.yaml
      +kubectl delete authorino/authorino
       

      To uninstall the Authorino Operator and manifests (CRDs, RBAC, etc), run:

      kubectl delete -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
       
      +
      +
      +
        +
      1. +

        In contrast to a dedicated sidecar of the protected service and other architectures. Check out Architecture > Topologies for all options. 

        +
      2. +
      3. +

        namespaced reconciliation mode. See Cluster-wide vs. Namespaced instances

        +
      4. +
      5. +

        For other variants and deployment options, check out Getting Started, as well as the Authorino CRD specification. 

        +
      6. +
      7. +

        For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. If you are running your ingress gateway in Kubernetes and wants to avoid setting up and configuring your proxy manually, check out Kuadrant

        +
      8. +
      +
      diff --git a/0.10.0/authorino/docs/user-guides/authzed/index.html b/0.10.0/authorino/docs/user-guides/authzed/index.html new file mode 100644 index 000000000..5f3a67f99 --- /dev/null +++ b/0.10.0/authorino/docs/user-guides/authzed/index.html @@ -0,0 +1,3930 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Integration with Authzed/SpiceDB - Kuadrant Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + +
      + + +
      + +
      + + + + + + +
      +
      + + + +
      +
      +
      + + + + + +
      +
      +
      + + + + + + + +
      +
      + + + + + + + + + + + + +

      User guide: Integration with Authzed/SpiceDB

      +

      Permission requests sent to a Google Zanzibar-based Authzed/SpiceDB instance, via gRPC.

      +
      + + Authorino capabilities featured in this guide: +
        +
      • Authorization → SpiceDB
      • +
      • Identity verification & authentication → API key
      • +
      +
      +
      +


      +

      Requirements

      +
        +
      • Kubernetes server with permissions to install cluster-scoped resources (operator, CRDs and RBAC)
      • +
      +

      If you do not own a Kubernetes server already and just want to try out the steps in this guide, you can create a local containerized cluster by executing the command below. In this case, the main requirement is having Kind installed, with either Docker or Podman.

      +
      kind create cluster --name authorino-tutorial
      +
      +


      +

      The next steps walk you through installing Authorino, deploying and configuring a sample service called Talker API to be protected by the authorization service.

      + + + + + + + + + + + +
      Using Kuadrant
      +

      If you are a user of Kuadrant and already have your workload cluster configured and sample service application deployed, as well as your Gateway API network resources applied to route traffic to your service, skip straight to step ❻.

      +

      At step ❻, instead of creating an AuthConfig custom resource, create a Kuadrant AuthPolicy one. The schema of the AuthConfig's spec matches the one of the AuthPolicy's, except spec.host, which is not available in the Kuadrant AuthPolicy. Host names in a Kuadrant AuthPolicy are inferred automatically from the Kubernetes network object referred in spec.targetRef and route selectors declared in the policy.

      +

      For more about using Kuadrant to enforce authorization, check out Kuadrant auth.

      +
      + +


      +

      ❶ Install the Authorino Operator (cluster admin required)

      +

      The following command will install the Authorino Operator in the Kubernetes cluster. The operator manages instances of the Authorino authorization service.

      +
      curl -sL https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/utils/install.sh | bash -s
      +
      +

      ❷ Deploy Authorino

      +

      The following command will request an instance of Authorino as a separate service1 that watches for AuthConfig resources in the default namespace2, with TLS disabled3.

      +
      kubectl apply -f -<<EOF
      +apiVersion: operator.authorino.kuadrant.io/v1beta1
      +kind: Authorino
      +metadata:
      +  name: authorino
      +spec:
      +  listener:
      +    tls:
      +      enabled: false
      +  oidcServer:
      +    tls:
      +      enabled: false
      +EOF
      +
      +

      ❸ Deploy the Talker API

      +

      The Talker API is a simple HTTP service that echoes back in the response whatever it gets in the request. We will use it in this guide as the sample service to be protected by Authorino.

      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +
      +

      ❹ Setup Envoy

      +

      The following bundle from the Authorino examples deploys the Envoy proxy and configuration to wire up the Talker API behind the reverse-proxy, with external authorization enabled with the Authorino instance.4

      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      +
      +

      The command above creates an Ingress with host name talker-api.127.0.0.1.nip.io. If you are using a local Kubernetes cluster created with Kind, forward requests from your local port 8000 to the Envoy service running inside the cluster:

      +
      kubectl port-forward deployment/envoy 8000:8000 2>&1 >/dev/null &
      +
      +

      ❺ Create the permission database

      +

      Create the namespace:

      +
      kubectl create namespace spicedb
      +
      +

      Create the SpiceDB instance:

      +
      kubectl -n spicedb apply -f -<<EOF
      +apiVersion: apps/v1
      +kind: Deployment
      +metadata:
      +  name: spicedb
      +  labels:
      +    app: spicedb
      +spec:
      +  selector:
      +    matchLabels:
      +      app: spicedb
      +  template:
      +    metadata:
      +      labels:
      +        app: spicedb
      +    spec:
      +      containers:
      +
      +      - name: spicedb
      +        image: authzed/spicedb
      +        args:
      +        - serve
      +        - "--grpc-preshared-key"
      +        - secret
      +        - "--http-enabled"
      +        ports:
      +        - containerPort: 50051
      +        - containerPort: 8443
      +  replicas: 1
      +---
      +apiVersion: v1
      +kind: Service
      +metadata:
      +  name: spicedb
      +spec:
      +  selector:
      +    app: spicedb
      +  ports:
      +    - name: grpc
      +      port: 50051
      +      protocol: TCP
      +    - name: http
      +      port: 8443
      +      protocol: TCP
      +EOF
      +
      +

      Forward local request to the SpiceDB service inside the cluster:

      +
      kubectl -n spicedb port-forward service/spicedb 8443:8443 2>&1 >/dev/null &
      +
      +

      Create the permission schema:

      +
      curl -X POST http://localhost:8443/v1/schema/write \
      +  -H 'Authorization: Bearer secret' \
      +  -H 'Content-Type: application/json' \
      +  -d @- << EOF
      +{
      +  "schema": "definition blog/user {}\ndefinition blog/post {\n\trelation reader: blog/user\n\trelation writer: blog/user\n\n\tpermission read = reader + writer\n\tpermission write = writer\n}"
      +}
      +EOF
      +
      +

      Create the relationships:

      +
        +
      • blog/user:emiliawriter of blog/post:1
      • +
      • blog/user:beatricereader of blog/post:1
      • +
      +
      curl -X POST http://localhost:8443/v1/relationships/write \
      +  -H 'Authorization: Bearer secret' \
      +  -H 'Content-Type: application/json' \
      +  -d @- << EOF
      +{
      +  "updates": [
      +    {
      +      "operation": "OPERATION_CREATE",
      +      "relationship": {
      +        "resource": {
      +          "objectType": "blog/post",
      +          "objectId": "1"
      +        },
      +        "relation": "writer",
      +        "subject": {
      +          "object": {
      +            "objectType": "blog/user",
      +            "objectId": "emilia"
      +          }
      +        }
      +      }
      +    },
      +    {
      +      "operation": "OPERATION_CREATE",
      +      "relationship": {
      +        "resource": {
      +          "objectType": "blog/post",
      +          "objectId": "1"
      +        },
      +        "relation": "reader",
      +        "subject": {
      +          "object": {
      +            "objectType": "blog/user",
      +            "objectId": "beatrice"
      +          }
      +        }
      +      }
      +    }
      +  ]
      +}
      +EOF
      +
      +

      ❺ Create an AuthConfig

      +

      Create an Authorino AuthConfig custom resource declaring the auth rules to be enforced.

      + + + + + + +
      + Kuadrant users – + Remember to create an AuthPolicy instead of an AuthConfig. + For more, see Kuadrant auth. +
      + +

      Store the shared token for Authorino to authenticate with the SpiceDB instance in a Service:

      +
      kubectl apply -f -<<EOF
      +apiVersion: v1
      +kind: Secret
      +metadata:
      +  name: spicedb
      +  labels:
      +    app: spicedb
      +stringData:
      +  grpc-preshared-key: secret
      +EOF
      +
      +

      Create the AuthConfig:

      +
      kubectl apply -f -<<EOF
      +apiVersion: authorino.kuadrant.io/v1beta2
      +kind: AuthConfig
      +metadata:
      +  name: talker-api-protection
      +spec:
      +  hosts:
      +
      +  - talker-api.127.0.0.1.nip.io
      +  authentication:
      +    "blog-users":
      +      apiKey:
      +        selector:
      +          matchLabels:
      +            app: talker-api
      +      credentials:
      +        authorizationHeader:
      +          prefix: APIKEY
      +  authorization:
      +    "authzed-spicedb":
      +      spicedb:
      +        endpoint: spicedb.spicedb.svc.cluster.local:50051
      +        insecure: true
      +        sharedSecretRef:
      +          name: spicedb
      +          key: grpc-preshared-key
      +        subject:
      +          kind:
      +            value: blog/user
      +          name:
      +            selector: auth.identity.metadata.annotations.username
      +        resource:
      +          kind:
      +            value: blog/post
      +          name:
      +            selector: context.request.http.path.@extract:{"sep":"/","pos":2}
      +        permission:
      +          selector: context.request.http.method.@replace:{"old":"GET","new":"read"}.@replace:{"old":"POST","new":"write"}
      +EOF
      +
      +

      ❼ Create the API keys

      +

      For Emilia (writer):

      +
      kubectl apply -f -<<EOF
      +apiVersion: v1
      +kind: Secret
      +metadata:
      +  name: api-key-writer
      +  labels:
      +    authorino.kuadrant.io/managed-by: authorino
      +    app: talker-api
      +  annotations:
      +    username: emilia
      +stringData:
      +  api_key: IAMEMILIA
      +EOF
      +
      +

      For Beatrice (reader):

      +
      kubectl apply -f -<<EOF
      +apiVersion: v1
      +kind: Secret
      +metadata:
      +  name: api-key-reader
      +  labels:
      +    authorino.kuadrant.io/managed-by: authorino
      +    app: talker-api
      +  annotations:
      +    username: beatrice
      +stringData:
      +  api_key: IAMBEATRICE
      +EOF
      +
      +

      ❽ Consume the API

      +

      As Emilia, send a GET request:

      +
      curl -H 'Authorization: APIKEY IAMEMILIA' \
      +     -X GET \
      +     http://talker-api.127.0.0.1.nip.io:8000/posts/1 -i
      +# HTTP/1.1 200 OK
      +
      +

      As Emilia, send a POST request:

      +
      curl -H 'Authorization: APIKEY IAMEMILIA' \
      +     -X POST \
      +     http://talker-api.127.0.0.1.nip.io:8000/posts/1 -i
      +# HTTP/1.1 200 OK
      +
      +

      As Beatrice, send a GET request:

      +
      curl -H 'Authorization: APIKEY IAMBEATRICE' \
      +     -X GET \
      +     http://talker-api.127.0.0.1.nip.io:8000/posts/1 -i
      +# HTTP/1.1 200 OK
      +
      +

      As Beatrice, send a POST request:

      +
      curl -H 'Authorization: APIKEY IAMBEATRICE' \
      +     -X POST \
      +     http://talker-api.127.0.0.1.nip.io:8000/posts/1 -i
      +# HTTP/1.1 403 Forbidden
      +# x-ext-auth-reason: PERMISSIONSHIP_NO_PERMISSION;token=GhUKEzE2NzU3MDE3MjAwMDAwMDAwMDA=
      +
      +

      Cleanup

      +

      If you have started a Kubernetes cluster locally with Kind to try this user guide, delete it by running:

      +
      kind delete cluster --name authorino-tutorial
      +
      +

      Otherwise, delete the resources created in each step:

      +
      kubectl delete secret/api-key-1
      +kubectl delete authconfig/talker-api-protection
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete authorino/authorino
      +kubectl delete namespace spicedb
      +
      +

      To uninstall the Authorino Operator and manifests (CRDs, RBAC, etc), run:

      +
      kubectl delete -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
      +
      +
      +
      +
        +
      1. +

        In contrast to a dedicated sidecar of the protected service and other architectures. Check out Architecture > Topologies for all options. 

        +
      2. +
      3. +

        namespaced reconciliation mode. See Cluster-wide vs. Namespaced instances

        +
      4. +
      5. +

        For other variants and deployment options, check out Getting Started, as well as the Authorino CRD specification. 

        +
      6. +
      7. +

        For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. If you are running your ingress gateway in Kubernetes and wants to avoid setting up and configuring your proxy manually, check out Kuadrant

        +
      8. +
      +
      + + + + + + + + + + + + + +
      +
      + + + +
      + +
      + +
      + + + +
      + +
      +
      +
      +
      + + + + + + + + + + \ No newline at end of file diff --git a/0.10.0/authorino/docs/user-guides/caching/index.html b/0.10.0/authorino/docs/user-guides/caching/index.html index 870c84134..ebab8bb37 100644 --- a/0.10.0/authorino/docs/user-guides/caching/index.html +++ b/0.10.0/authorino/docs/user-guides/caching/index.html @@ -1508,7 +1508,7 @@
    55. - + @@ -1689,54 +1689,54 @@
    56. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    57. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    58. - + - 3. Deploy Authorino + ❸ Deploy the Talker API
    59. - + - 4. Setup Envoy + ❹ Setup Envoy
    60. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    61. - + - 6. Consume the API + ❻ Consume the API @@ -1979,7 +1979,7 @@
    62. - + @@ -3417,54 +3417,54 @@
    63. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    64. - + - 2. Deploy the Talker API + ❷ Deploy Authorino
    65. - + - 3. Deploy Authorino + ❸ Deploy the Talker API
    66. - + - 4. Setup Envoy + ❹ Setup Envoy
    67. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    68. - + - 6. Consume the API + ❻ Consume the API @@ -3519,111 +3519,143 @@

      User guide: CachingCaching

    69. -
    70. Identity verification & authentication → Anonymous access
    71. -
    72. External auth metadata → HTTP GET/GET-by-POST
    73. -
    74. Authorization → Open Policy Agent (OPA) Rego policies
    75. -
    76. Dynamic response → JSON injection
    77. +
    78. Common feature → Caching
    79. +
    80. Identity verification & authentication → Anonymous access
    81. +
    82. External auth metadata → HTTP GET/GET-by-POST
    83. +
    84. Authorization → Open Policy Agent (OPA) Rego policies
    85. +
    86. Dynamic response → JSON injection
    87. - - For further details about Authorino features in general, check the [docs](./../features.md). +

      For further details about Authorino features in general, check the docs.

      -


      Requirements

        -
      • Kubernetes server
      • +
      • Kubernetes server with permissions to install cluster-scoped resources (operator, CRDs and RBAC)
      -

      Create a containerized Kubernetes server locally using Kind:

      +

      If you do not own a Kubernetes server already and just want to try out the steps in this guide, you can create a local containerized cluster by executing the command below. In this case, the main requirement is having Kind installed, with either Docker or Podman.

      kind create cluster --name authorino-tutorial
       
      -

      1. Install the Authorino Operator

      -
      kubectl apply -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
      +


      +

      The next steps walk you through installing Authorino, deploying and configuring a sample service called Talker API to be protected by the authorization service.

      + + + + + + + + + + + +
      Using Kuadrant
      +

      If you are a user of Kuadrant and already have your workload cluster configured and sample service application deployed, as well as your Gateway API network resources applied to route traffic to your service, skip straight to step ❺.

      +

      At step ❺, instead of creating an AuthConfig custom resource, create a Kuadrant AuthPolicy one. The schema of the AuthConfig's spec matches the one of the AuthPolicy's, except spec.host, which is not available in the Kuadrant AuthPolicy. Host names in a Kuadrant AuthPolicy are inferred automatically from the Kubernetes network object referred in spec.targetRef and route selectors declared in the policy.

      +

      For more about using Kuadrant to enforce authorization, check out Kuadrant auth.

      +
      + +


      +

      ❶ Install the Authorino Operator (cluster admin required)

      +

      The following command will install the Authorino Operator in the Kubernetes cluster. The operator manages instances of the Authorino authorization service.

      +
      curl -sL https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/utils/install.sh | bash -s
       
      -

      2. Deploy the Talker API

      -

      The Talker API is just an echo API, included in the Authorino examples. We will use it in this guide as the service to be protected with Authorino.

      -
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +

      ❷ Deploy Authorino

      +

      The following command will request an instance of Authorino as a separate service1 that watches for AuthConfig resources in the default namespace2, with TLS disabled3.

      +
      kubectl apply -f -<<EOF
      +apiVersion: operator.authorino.kuadrant.io/v1beta1
      +kind: Authorino
      +metadata:
      +  name: authorino
      +spec:
      +  listener:
      +    tls:
      +      enabled: false
      +  oidcServer:
      +    tls:
      +      enabled: false
      +EOF
       
      -

      3. Deploy Authorino

      -
      kubectl apply -f -<<EOF
      -apiVersion: operator.authorino.kuadrant.io/v1beta1
      -kind: Authorino
      -metadata:
      -  name: authorino
      -spec:
      -  listener:
      -    tls:
      -      enabled: false
      -  oidcServer:
      -    tls:
      -      enabled: false
      -EOF
      +

      ❸ Deploy the Talker API

      +

      The Talker API is a simple HTTP service that echoes back in the response whatever it gets in the request. We will use it in this guide as the sample service to be protected by Authorino.

      +
      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
       
      -

      The command above will deploy Authorino as a separate service (as oposed to a sidecar of the protected API and other architectures), in namespaced reconciliation mode, and with TLS termination disabled. For other variants and deployment options, check out the Getting Started section of the docs, the Architecture page, and the spec for the Authorino CRD in the Authorino Operator repo.

      -

      4. Setup Envoy

      -

      The following bundle from the Authorino examples (manifest referred in the command below) is to apply Envoy configuration and deploy Envoy proxy, that wire up the Talker API behind the reverse-proxy and external authorization with the Authorino instance.

      -

      For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. For a simpler and straighforward way to manage an API, without having to manually install or configure Envoy and Authorino, check out Kuadrant.

      +

      ❹ Setup Envoy

      +

      The following bundle from the Authorino examples deploys the Envoy proxy and configuration to wire up the Talker API behind the reverse-proxy, with external authorization enabled with the Authorino instance.4

      kubectl apply -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
       
      -

      The bundle also creates an Ingress with host name talker-api-authorino.127.0.0.1.nip.io, but if you are using a local Kubernetes cluster created with Kind, you need to forward requests on port 8000 to inside the cluster in order to actually reach the Envoy service:

      -
      kubectl port-forward deployment/envoy 8000:8000 &
      +

      The command above creates an Ingress with host name talker-api.127.0.0.1.nip.io. If you are using a local Kubernetes cluster created with Kind, forward requests from your local port 8000 to the Envoy service running inside the cluster:

      +
      kubectl port-forward deployment/envoy 8000:8000 2>&1 >/dev/null &
       
      -

      5. Create the AuthConfig

      +

      ❺ Create an AuthConfig

      +

      Create an Authorino AuthConfig custom resource declaring the auth rules to be enforced.

      +

      The example below enables caching for the external source of metadata, which in this case, for convenience, is the same upstream API protected by Authorino (i.e. the Talker API), though consumed directly by Authorino, without passing through the proxy. This API generates a uuid random hash that it injects in the JSON response. This value is different in every request processed by the API.

      +

      The example also enables caching of returned OPA virtual documents. cached-authz is a trivial Rego policy that always grants access, but generates a timestamp, which Authorino will cache.

      +

      In both cases, the path of the HTTP request is used as cache key. I.e., whenever the path repeats, Authorino reuse the values stored previously in each cache table (cached-metadata and cached-authz), respectively saving a request to the external source of metadata and the evaluation of the OPA policy. Cache entries will expire in both cases after 60 seconds they were stored in the cache.

      +

      The cached values will be visible in the response returned by the Talker API in x-authz-data header injected by Authorino. This way, we can tell when an existing value in the cache was used and when a new one was generated and stored.

      + + + + + + +
      + Kuadrant users – + Remember to create an AuthPolicy instead of an AuthConfig. + For more, see Kuadrant auth. +
      +
      kubectl apply -f -<<EOF
      -apiVersion: authorino.kuadrant.io/v1beta1
      +apiVersion: authorino.kuadrant.io/v1beta2
       kind: AuthConfig
       metadata:
         name: talker-api-protection
       spec:
         hosts:
       
      -  - talker-api-authorino.127.0.0.1.nip.io
      -  identity:
      -  - name: anonymous
      -    anonymous: {}
      +  - talker-api.127.0.0.1.nip.io
      +  authentication:
      +    "anonymous":
      +      anonymous: {}
         metadata:
      -  - name: cached-metadata
      -    http:
      -      endpoint: http://talker-api.default.svc.cluster.local:3000/metadata/{context.request.http.path}
      -      method: GET
      -    cache:
      -      key:
      -        valueFrom: { authJSON: context.request.http.path }
      -      ttl: 60
      -  authorization:
      -  - name: cached-authz
      -    opa:
      -      inlineRego: |
      -        now = time.now_ns()
      -        allow = true
      -      allValues: true
      -    cache:
      -      key:
      -        valueFrom: { authJSON: context.request.http.path }
      -      ttl: 60
      -  response:
      -  - name: x-authz-data
      -    json:
      -      properties:
      -      - name: cached-metadata
      -        valueFrom: { authJSON: auth.metadata.cached-metadata.uuid }
      -      - name: cached-authz
      -        valueFrom: { authJSON: auth.authorization.cached-authz.now }
      -EOF
      +    "cached-metadata":
      +      http:
      +        url: "http://talker-api.default.svc.cluster.local:3000/metadata/{context.request.http.path}"
      +      cache:
      +        key:
      +          selector: context.request.http.path
      +        ttl: 60
      +  authorization:
      +    "cached-authz":
      +      opa:
      +        rego: |
      +          now = time.now_ns()
      +          allow = true
      +        allValues: true
      +      cache:
      +        key:
      +          selector: context.request.http.path
      +        ttl: 60
      +  response:
      +    success:
      +      headers:
      +        "x-authz-data":
      +          json:
      +            properties:
      +              "cached-metadata":
      +                selector: auth.metadata.cached-metadata.uuid
      +              "cached-authz":
      +                selector: auth.authorization.cached-authz.now
      +EOF
       
      -

      The example above enables caching for the external source of metadata, which in this case, for convinience, is the same upstream API protected by Authorino (i.e. the Talker API), though consumed directly by Authorino, without passing through the proxy. This API generates a uuid random hash that it injects in the JSON response. This value is different in every request processed by ythe API.

      -

      The example also enables caching of returned OPA virtual documents. cached-authz is a trivial Rego policy that always grants access, but generates a timestamp, which Authorino will cache.

      -

      In both cases, the path of the HTTP request is used as cache key. I.e., whenever the path repeats, Authorino reuse the values stored previously in each cache table (cached-metadata and cached-authz), respectively saving a request to the external source of metadata and the evaluation of the OPA policy. Cache entries will expire in both cases after 60 seconds they were stored in the cache.

      -

      The cached values will be visible in the response returned by the Talker API in x-authz-data header injected by Authorino. Thiis way, we can tell when an existing value in the cache was used and when a new one was generated and stored.

      -

      6. Consume the API

      +

      ❻ Consume the API

      1. To /hello
      -
      curl http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +
      curl http://talker-api.127.0.0.1.nip.io:8000/hello
       # […]
       #  "X-Authz-Data": "{\"cached-authz\":\"1649343067462380300\",\"cached-metadata\":\"92c111cd-a10f-4e86-8bf0-e0cd646c6f79\"}",
       # […]
      @@ -3631,7 +3663,7 @@ 

      6. Consume the API
      curl http://talker-api-authorino.127.0.0.1.nip.io:8000/goodbye
      +
      curl http://talker-api.127.0.0.1.nip.io:8000/goodbye
       # […]
       #  "X-Authz-Data": "{\"cached-authz\":\"1649343097860450300\",\"cached-metadata\":\"37fce386-1ee8-40a7-aed1-bf8a208f283c\"}",
       # […]
      @@ -3639,7 +3671,7 @@ 

      6. Consume the API
      curl http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +
      curl http://talker-api.127.0.0.1.nip.io:8000/hello
       # […]
       #  "X-Authz-Data": "{\"cached-authz\":\"1649343067462380300\",\"cached-metadata\":\"92c111cd-a10f-4e86-8bf0-e0cd646c6f79\"}",  <=== same cache-id as before
       # […]
      @@ -3647,7 +3679,7 @@ 

      6. Consume the API
      curl http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
      +
      curl http://talker-api.127.0.0.1.nip.io:8000/hello
       # […]
       #  "X-Authz-Data": "{\"cached-authz\":\"1649343135702743800\",\"cached-metadata\":\"e708a3a6-5caf-4028-ab5c-573ad9be7188\"}",  <=== different cache-id
       # […]
      @@ -3658,13 +3690,30 @@ 

      Cleanup
      kubectl delete authconfig/talker-api-protection
      -kubectl delete authorino/authorino
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      -kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/envoy/envoy-notls-deploy.yaml
      +kubectl delete -f https://raw.githubusercontent.com/kuadrant/authorino-examples/main/talker-api/talker-api-deploy.yaml
      +kubectl delete authorino/authorino
       

      To uninstall the Authorino Operator and manifests (CRDs, RBAC, etc), run:

      kubectl delete -f https://raw.githubusercontent.com/Kuadrant/authorino-operator/main/config/deploy/manifests.yaml
       
      +
      +
      +
        +
      1. +

        In contrast to a dedicated sidecar of the protected service and other architectures. Check out Architecture > Topologies for all options. 

        +
      2. +
      3. +

        namespaced reconciliation mode. See Cluster-wide vs. Namespaced instances

        +
      4. +
      5. +

        For other variants and deployment options, check out Getting Started, as well as the Authorino CRD specification. 

        +
      6. +
      7. +

        For details and instructions to setup Envoy manually, see Protect a service > Setup Envoy in the Getting Started page. If you are running your ingress gateway in Kubernetes and wants to avoid setting up and configuring your proxy manually, check out Kuadrant

        +
      8. +
      +
      diff --git a/0.10.0/authorino/docs/user-guides/deny-with-redirect-to-login/index.html b/0.10.0/authorino/docs/user-guides/deny-with-redirect-to-login/index.html index 50ca8d471..cce2061fc 100644 --- a/0.10.0/authorino/docs/user-guides/deny-with-redirect-to-login/index.html +++ b/0.10.0/authorino/docs/user-guides/deny-with-redirect-to-login/index.html @@ -1508,7 +1508,7 @@
    88. - + @@ -1626,76 +1626,76 @@
    89. - + - 1. Install the Authorino Operator + ❶ Install the Authorino Operator (cluster admin required)
    90. - + - 2. Deploy the Matrix Quotes web application + ❷ Deploy Authorino
    91. - + - 3. Deploy Authorino + ❸ Deploy the Matrix Quotes web application
    92. - + - 4. Setup Envoy + ❹ Setup Envoy
    93. - + - 5. Create the AuthConfig + ❺ Create an AuthConfig
    94. - + - 6. Create an API key + ❻ Create an API key
    95. - + - 7. Consume the application + ❼ Consume the application
    96. - + - 8. (Optional) Modify the AuthConfig to authenticate with OIDC + ❽ (Optional) Modify the AuthConfig to authenticate with OIDC -