This demo walks you through the process of setting up a local Kubernetes cluster with Kuadrant, where you will protect Gateway API endpoints by declaring Kuadrant AuthPolicy custom resources.
Clone the repo:
git clone -b authpolicy-v2 [email protected]:Kuadrant/kuadrant-operator.git && cd kuadrant-operator
Run the following command to create a local Kubernetes cluster with Kind, install & deploy Kuadrant:
make local-setup
Request an instance of Kuadrant:
kubectl -n kuadrant-system apply -f - <<EOF
apiVersion: kuadrant.io/v1beta1
kind: Kuadrant
metadata:
name: kuadrant
spec: {}
EOF
kubectl apply -f examples/toystore/toystore.yaml
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: toystore
spec:
parentRefs:
- name: istio-ingressgateway
namespace: istio-system
hostnames:
- api.toystore.com
rules:
- matches:
- method: GET
path:
type: PathPrefix
value: "/cars"
- method: GET
path:
type: PathPrefix
value: "/dolls"
backendRefs:
- name: toystore
port: 80
- matches:
- path:
type: PathPrefix
value: "/admin"
backendRefs:
- name: toystore
port: 80
EOF
Send requests to the API unprotected:
curl -H 'Host: api.toystore.com' http://localhost:9080/cars -i
# HTTP/1.1 200 OK
curl -H 'Host: api.toystore.com' http://localhost:9080/dolls -i
# HTTP/1.1 200 OK
curl -H 'Host: api.toystore.com' http://localhost:9080/admin -i
# HTTP/1.1 200 OK
Create an AuthPolicy to enforce the following auth rules:
- Authentication:
- All users must present a valid API key
- Authorization:
/admin*
routes require user mapped to theadmins
group (kuadrant.io/groups=admins
annotation added to the Kubernetes API key Secret)
kubectl apply -f - <<EOF
apiVersion: kuadrant.io/v1beta2
kind: AuthPolicy
metadata:
name: toystore
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: toystore
rules:
authentication:
"api-key-authn":
apiKey:
selector: {}
credentials:
authorizationHeader:
prefix: APIKEY
authorization:
"only-admins":
opa:
rego: |
groups := split(object.get(input.auth.identity.metadata.annotations, "kuadrant.io/groups", ""), ",")
allow { groups[_] == "admins" }
routeSelectors:
- matches:
- path:
type: PathPrefix
value: "/admin"
EOF
(Optional) Verify internal custom resources reconciled by Kuadrant
Verify the Istio AuthorizationPolicy created in association with the policy:
kubectl get authorizationpolicy/on-istio-ingressgateway-using-toystore -n istio-system -o yaml
Verify the Authorino AuthConfig created in association with the policy:
kubectl get authconfig/ap-default-toystore -o yaml
Create the API keys:
kubectl apply -f -<<EOF
apiVersion: v1
kind: Secret
metadata:
name: api-key-regular-user
labels:
authorino.kuadrant.io/managed-by: authorino
stringData:
api_key: iamaregularuser
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
name: api-key-admin-user
labels:
authorino.kuadrant.io/managed-by: authorino
annotations:
kuadrant.io/groups: admins
stringData:
api_key: iamanadmin
type: Opaque
EOF
Send requests to the API protected by Kuadrant:
curl -H 'Host: api.toystore.com' http://localhost:9080/cars -i
# HTTP/1.1 401 Unauthorized
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://localhost:9080/cars -i
# HTTP/1.1 200 OK
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://localhost:9080/admin -i
# HTTP/1.1 403 Forbidden
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamanadmin' http://localhost:9080/admin -i
# HTTP/1.1 200 OK
Create the policy:
kubectl -n istio-system apply -f - <<EOF
apiVersion: kuadrant.io/v1beta2
kind: AuthPolicy
metadata:
name: gw-auth
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: istio-ingressgateway
rules:
authorization:
deny-all:
opa:
rego: "allow = false"
response:
unauthorized:
headers:
"content-type":
value: application/json
body:
value: |
{
"error": "Forbidden",
"message": "Access denied by default by the gateway operator. If you are the administrator of the service, create a specific auth policy for the route."
}
EOF
The policy won't be effective until there is at least one accepted route not yet protected by another more specific policy attached to it.
Create a route that will inherit the default policy attached to the gateway:
kubectl apply -f -<<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: other
spec:
parentRefs:
- name: istio-ingressgateway
namespace: istio-system
hostnames:
- "*.other-apps.com"
EOF
(Optional) Verify internal custom resources reconciled by Kuadrant
Verify the Istio AuthorizationPolicy created in association with the policy:
kubectl get authorizationpolicy/on-istio-ingressgateway -n istio-system -o yaml
Verify the Authorino AuthConfig created in association with the policy:
kubectl get authconfig/ap-istio-system-gw-auth -n istio-system -o yaml
Send requests to the route protected by the default policy set at the level of the gateway:
curl -H 'Host: foo.other-apps.com' http://localhost:9080/ -i
# HTTP/1.1 403 Forbidden
make local-cleanup