Skip to content

User guide: Caching

Cache auth objects resolved at runtime for any configuration bit of an AuthConfig (i.e. any evaluator), of any phase (identity, metadata, authorization and dynamic response), for easy access in subsequent requests, whenever an arbitrary (user-defined) cache key repeats, until the cache entry expires.

This is particularly useful for configuration bits whose evaluation is significantly more expensive than accessing the cache. E.g.:

  • Caching of metadata fetched from external sources in general
  • Caching of previously validated identity access tokens (e.g. for OAuth2 opaque tokens that involve consuming the token introspection endpoint of an external auth server)
  • Caching of complex Rego policies that involve sending requests to external services

Cases where one will NOT want to enable caching, due to relatively cheap compared to accessing and managing the cache: - Validation of OIDC/JWT access tokens - OPA/Rego policies that do not involve external requests - JSON pattern-matching authorization - Dynamic JSON responses - Anonymous access

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


Requirements

  • Kubernetes server

Create a containerized Kubernetes server locally using Kind:

kind create cluster --name authorino-tutorial

1. Install the Authorino Operator

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

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

The command above will deploy Authorino as a separate service (as opposed 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 straightforward way to manage an API, without having to manually install or configure Envoy and Authorino, check out Kuadrant.

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 &

5. Create the AuthConfig

kubectl apply -f -<<EOF
apiVersion: authorino.kuadrant.io/v1beta2
kind: AuthConfig
metadata:
  name: talker-api-protection
spec:
  hosts:
  - talker-api-authorino.127.0.0.1.nip.io
  authentication:
    "anonymous":
      anonymous: {}
  metadata:
    "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 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.

6. Consume the API

  1. To /hello
curl http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
# […]
#  "X-Authz-Data": "{\"cached-authz\":\"1649343067462380300\",\"cached-metadata\":\"92c111cd-a10f-4e86-8bf0-e0cd646c6f79\"}",
# […]
  1. To a different path
curl http://talker-api-authorino.127.0.0.1.nip.io:8000/goodbye
# […]
#  "X-Authz-Data": "{\"cached-authz\":\"1649343097860450300\",\"cached-metadata\":\"37fce386-1ee8-40a7-aed1-bf8a208f283c\"}",
# […]
  1. To /hello again before the cache entry expires (60 seconds from the first request sent to this path)
curl http://talker-api-authorino.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
# […]
  1. To /hello again after the cache entry expires (60 seconds from the first request sent to this path)
curl http://talker-api-authorino.127.0.0.1.nip.io:8000/hello
# […]
#  "X-Authz-Data": "{\"cached-authz\":\"1649343135702743800\",\"cached-metadata\":\"e708a3a6-5caf-4028-ab5c-573ad9be7188\"}",  <=== different cache-id
# […]

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

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