Skip to content

Conversation

guicassolato
Copy link
Collaborator

@guicassolato guicassolato commented Mar 17, 2022

Adds support for the "host" AuthConfig lookup key to be provided in the payload to the /Check request as Envoy ext-authz per-route "context extension".

Authorino will favor the "host" lookup key whenever passed in the context extensions before the actual "host" HTTP attribute.

This is an alternative approach for enhanced AuthConfig lookups, without changing the lookup structure too much, although relying more on Envoy to set the right payload.

This should be enough to cover use cases such as of path-based AuthConfig lookup and wildcard subdomains AuthConfig lookup.

Closes #222
Closes #171


Verification steps

Path-based AuthConfig lookup use case

In this use case, 2 different APIs are behind the same base domain and differentiated by the path prefix:

  • pets.com/dogs → Dogs API
  • pets.com/cats → Cats API

Build and deploy this branch:

make local-setup

Edit the sample Envoy config to include the required 'host' context extension that will make Authorino to favour this as lookup key before the actual host of the request:

kubectl -n authorino edit configmap/envoy
[...]
routes:
- match:
    prefix: /dogs
  route:
    cluster: talker-api
  typed_per_filter_config:
    envoy.filters.http.ext_authz:
      \"@type\": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
      check_settings:
        context_extensions:
          host: dogs.pets.com
- match:
    prefix: /cats
  route:
    cluster: talker-api
  typed_per_filter_config:
    envoy.filters.http.ext_authz:
      \"@type\": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
      check_settings:
        context_extensions:
          host: cats.pets.com
[...]

In the above, we've used the same upstream API (i.e. talker-api) for both routes only for demo purposes. In a real-life scenario, "dogs" and "cats" would be 2 different upstream APIs.

Restart Envoy:

kubectl -n authorino rollout restart deployments/envoy

Forward the requests:

kubectl -n authorino port-forward deployment/envoy 8000:8000 &

Apply the AuthConfigs:

kubectl -n authorino apply -f -<<EOF
apiVersion: authorino.kuadrant.io/v1beta1
kind: AuthConfig
metadata:
  name: dogs
spec:
  hosts:
  - dogs.pets.com
  identity:
  - name: friends
    apiKey:
      labelSelectors:
        api: dogs-api
    credentials:
      in: authorization_header
      keySelector: APIKEY
EOF
kubectl -n authorino apply -f -<<EOF
apiVersion: authorino.kuadrant.io/v1beta1
kind: AuthConfig
metadata:
  name: cats
spec:
  hosts:
  - cats.pets.com
  identity:
  - name: friends
    apiKey:
      labelSelectors:
        api: cats-api
    credentials:
      in: authorization_header
      keySelector: APIKEY
EOF

Create the API keys:

kubectl -n authorino apply -f -<<EOF
apiVersion: v1
kind: Secret
metadata:
  name: api-key-1
  labels:
    authorino.kuadrant.io/managed-by: authorino
    api: dogs-api
stringData:
  api_key: ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx
type: Opaque
EOF
kubectl -n authorino apply -f -<<EOF
apiVersion: v1
kind: Secret
metadata:
  name: api-key-2
  labels:
    authorino.kuadrant.io/managed-by: authorino
    api: cats-api
stringData:
  api_key: WBGo87IR29ifJKUfxZvL8zLqBKYPRg2g
type: Opaque
EOF

Consume the APIs under same base domain:

curl -H 'Host: pets.com' -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://localhost:8000/dogs -i
# 200

curl -H 'Host: pets.com' -H 'Authorization: APIKEY WBGo87IR29ifJKUfxZvL8zLqBKYPRg2g' http://localhost:8000/dogs -i
# 401
curl -H 'Host: pets.com' -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://localhost:8000/cats -i
# 401

curl -H 'Host: pets.com' -H 'Authorization: APIKEY WBGo87IR29ifJKUfxZvL8zLqBKYPRg2g' http://localhost:8000/cats -i
# 200

Wildcard subdomain AuthConfig lookup use case

In this use case, a single Pets API serves requests for any subdomain that matches *.pets.com, e.g.:

  • dogs.pets.com → Pets API
  • cats.pets.com → Pets API

Build and deploy this branch:

make local-setup

Edit the sample Envoy config to include the required 'host' context extension that will make Authorino to favour this as lookup key before the actual host of the request:

kubectl -n authorino edit configmap/envoy
[...]
virtual_hosts:
- name: local_service
  domains: ['*.pets.com']
  typed_per_filter_config:
    envoy.filters.http.ext_authz:
      \"@type\": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
      check_settings:
        context_extensions:
          host: pets.com
[...]

The "host" context extension above is any key that matches one of the hosts listed in the targeted AuthConfig.

Restart Envoy:

kubectl -n authorino rollout restart deployments/envoy

Forward the requests:

kubectl -n authorino port-forward deployment/envoy 8000:8000 &

Apply the AuthConfig:

kubectl -n authorino apply -f -<<EOF
apiVersion: authorino.kuadrant.io/v1beta1
kind: AuthConfig
metadata:
  name: pets
spec:
  hosts:
  - pets.com
  identity:
  - name: friends
    apiKey:
      labelSelectors:
        group: friends
    credentials:
      in: authorization_header
      keySelector: APIKEY
EOF

Create an API key:

kubectl -n authorino apply -f -<<EOF
apiVersion: v1
kind: Secret
metadata:
  name: api-key-1
  labels:
    authorino.kuadrant.io/managed-by: authorino
    group: friends
stringData:
  api_key: ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx
type: Opaque
EOF

Consume the API under different subdomains:

curl -H 'Host: dogs.pets.com' -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://localhost:8000 -i
# 200
curl -H 'Host: cats.pets.com' -H 'Authorization: APIKEY ndyBzreUzF4zqDQsqSPMHkRhriEOtcRx' http://localhost:8000 -i
# 200

@guicassolato guicassolato self-assigned this Mar 17, 2022
@guicassolato guicassolato changed the title Support for lookup keys passed in context extensions Support for "host" lookup key passed as context extension Mar 17, 2022
@guicassolato guicassolato marked this pull request as ready for review March 17, 2022 17:21
@guicassolato guicassolato requested a review from a team March 17, 2022 17:21
Copy link
Collaborator

@eguzki eguzki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: In the verification steps, regarding the "path based routing", how can you tell which configuration is being applied? Maybe two api keys would make it clearer.

@guicassolato
Copy link
Collaborator Author

nit: In the verification steps, regarding the "path based routing", how can you tell which configuration is being applied?

We can only tell from the Authorino logs in the case, I'm afraid.

Maybe two api keys would make it clearer.

I'll change in the description of the PR (for whoever checks it in the future).

In the user guide for host overriding via context extensions, I made sure to abstract this detail. What matters is: 2 AuthConfigs, the right one will be used in each request based on path-prefix.

Thanks for pointing out, @eguzki!

@guicassolato
Copy link
Collaborator Author

I'll change in the description of the PR (for whoever checks it in the future).

Done.

@guicassolato guicassolato merged commit 0c82786 into main Mar 18, 2022
@guicassolato guicassolato deleted the induced-lookup branch March 18, 2022 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AuthConfig lookup based on host + path prefix AuthConfig supports wildcard (sub)domains
2 participants