Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tutorials to reference 'Getting Started' as prereq #1129

Merged
merged 5 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 89 additions & 28 deletions doc/user-guides/auth/auth-for-app-devs-and-platform-engineers.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Enforcing authentication & authorization with Kuadrant AuthPolicy

This guide walks you through the process of setting up a local Kubernetes cluster with Kuadrant where you will protect [Gateway API](https://gateway-api.sigs.k8s.io/) endpoints by declaring Kuadrant AuthPolicy custom resources.
This tutorial walks you through the process of setting up a local Kubernetes cluster with Kuadrant where you will protect [Gateway API](https://gateway-api.sigs.k8s.io/) endpoints by declaring Kuadrant AuthPolicy custom resources.

Three AuthPolicies will be declared:

Expand All @@ -14,7 +14,7 @@ Topology:
```
┌─────────────────────────┐
│ (Gateway) │ ┌───────────────┐
kuadrant-ingressgateway │◄──│ (AuthPolicy) │
external │◄──│ (AuthPolicy) │
│ │ │ gw-auth │
│ * │ └───────────────┘
└─────────────────────────┘
Expand All @@ -35,24 +35,87 @@ Topology:
└─────────────────┘
```

## Setup the environment
## Prerequisites

Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make.md) to set up your environment before continuing with this doc.
- Kubernetes cluster with Kuadrant operator installed. See our [Getting Started](/getting-started) guide for more information.
Copy link
Member

Choose a reason for hiding this comment

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

just because this will 404 on GH, maybe we include an absolute link? https://docs.kuadrant.io/latest/getting-started

Copy link
Member

Choose a reason for hiding this comment

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

(I realise this will 404 too right now until we do our next stable release)

Copy link
Member Author

Choose a reason for hiding this comment

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

@jasonmadigan summarising some options discussed offline:

  1. Your suggestion above to change link to absolute /latest
  2. Similar to above, but use a /dev link
  3. Leaving as is, knowing it will 404 on github, but be OK on docs site
  4. Move those user guides into the docs repo, so relative links work in github and on docs site

The links 404ing are a symptom of how these docs are being used for the docs site by mkdocs.
The dual target is not ideal, given this limitation around relative links if referencing a doc from another repo.
I'm not keen on having the absolute url as that gets treated as an external url by the mkdocs tooling and potentially bypasses some CI checks (like detecting 404s)

If you're in agreement, how about we go with 3 (as that's already the case potentially for other docs),
with an agreement to investigate 4 as a long term option, at least for these docs in the kuadrant operator site.
I wonder if there's a need to have these docs in this repo as well, if we have them in the docs repo and site, and link to the site from the main README.

Copy link
Member

Choose a reason for hiding this comment

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

seems like the most pragmatic option to me. can work on 4 longer term.

- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) command line tool.

### Setup environment variables

Set the following environment variables used for convenience in this tutorial:

```bash
export KUADRANT_GATEWAY_NS=api-gateway # Namespace for the example Gateway
export KUADRANT_GATEWAY_NAME=external # Name for the example Gateway
export KUADRANT_DEVELOPER_NS=toystore # Namespace for an example toystore app

```

### Create an Ingress Gateway

Create the namespace the Gateway will be deployed in:

```bash
kubectl create ns ${KUADRANT_GATEWAY_NS}
```

Create a gateway using toystore as the listener hostname:

```bash
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: ${KUADRANT_GATEWAY_NAME}
namespace: ${KUADRANT_GATEWAY_NS}
labels:
kuadrant.io/gateway: "true"
spec:
gatewayClassName: istio
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
EOF
```

Check the status of the `Gateway` ensuring the gateway is Accepted and Programmed:

```bash
kubectl get gateway ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o=jsonpath='{.status.conditions[?(@.type=="Accepted")].message}{"\n"}{.status.conditions[?(@.type=="Programmed")].message}{"\n"}'
```

### Deploy the Toy Store sample application (Persona: _App developer_)


Create the namespace for the toystore API:

```bash
kubectl create ns ${KUADRANT_DEVELOPER_NS}
```
Deploy the Toy store
```sh
kubectl apply -f examples/toystore/toystore.yaml
kubectl apply -f https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/refs/heads/main/examples/toystore/toystore.yaml -n ${KUADRANT_DEVELOPER_NS}
```

Create the Toy Store HTTPRoute
```bash

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
Copy link
Member

Choose a reason for hiding this comment

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

w/ helm guide, GW API v1.1 is installed

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: toystore
  namespace: ${KUADRANT_DEVELOPER_NS}
  labels:
     app: toystore
spec:
  parentRefs:
  - name: ${KUADRANT_GATEWAY_NAME}
    namespace: ${KUADRANT_GATEWAY_NS}
  hostnames:
  - api.toystore.com
  rules:
  - name: rule-1
    matches:
    - method: GET
      path:
        type: PathPrefix
        value: "/cars"
    - method: GET
      path:
        type: PathPrefix
        value: "/dolls"
    backendRefs:
    - name: toystore
      port: 80
  - name: rule-2
    matches:
    - path:
        type: PathPrefix
        value: "/admin"
    backendRefs:                                                                           <....
Error from server (BadRequest): error when creating "STDIN": HTTPRoute in version "v1" cannot be handled as a HTTPRoute: strict decoding error: unknown field "spec.rules[0].name", unknown field "spec.rules[1].name"

Copy link
Member

Choose a reason for hiding this comment

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

will continue tomorrow

Copy link
Member

Choose a reason for hiding this comment

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

@david-martin did you install your stack with helm (via the guide on https://artifacthub.io/packages/helm/kuadrant/kuadrant-operator) + cloud-provider-kind ?

Copy link
Member

@jasonmadigan jasonmadigan Jan 27, 2025

Choose a reason for hiding this comment

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

IIRC, named rules are in 1.2[1], I guess this won't work as the helm guide currently installs the v1.1 CRDs

[1] https://kubernetes.io/blog/2024/11/21/gateway-api-v1-2/#new-additions-to-experimental-channel

went without to push forward:

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: toystore
  namespace: ${KUADRANT_DEVELOPER_NS}
  labels:
     app: toystore
spec:
  parentRefs:
  - name: ${KUADRANT_GATEWAY_NAME}
    namespace: ${KUADRANT_GATEWAY_NS}
  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

Copy link
Member Author

Choose a reason for hiding this comment

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

I haven't tried the tutorials where I made the updates to add rule names.
I added those as I thought it was an oversight in those guides, given the reference to sectionNames in the Policy examples.
We might have to back out those sectionName references if they won't work with the latest kuadrant release.

Copy link
Member

Choose a reason for hiding this comment

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

yeah, just looks bad ootb as the helm guide steers you towards 1.1

if we're not highlighting sectionNames, perhaps we don't need right now

Copy link
Member Author

Choose a reason for hiding this comment

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

Both the helm install and olm install reference 1.1.0 of the gateway api CRDs.
I've traced back the original author of the guide to look for advice on what to do here.
Turns out this wasn't an oversight and it was written as intended.
Currently in Kuadrant, there are implied rule names when referencing them from a policy

The reason for this was to support sectionNames in a policy targetRef if gateway api 1.1 is used (which is the case with OSSM support at present on OpenShift).
The plan is to remove this and leverage the experimental feature in gateway api 1.2.

https://github.com/Kuadrant/policy-machinery/blob/ca213ee94f9b9f35d59d2d8a54a70902d91c8537/machinery/gateway_api_types.go#L144

I'll back out the changes

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated

kind: HTTPRoute
metadata:
name: toystore
namespace: ${KUADRANT_DEVELOPER_NS}
labels:
app: toystore
spec:
parentRefs:
- name: kuadrant-ingressgateway
namespace: gateway-system
- name: ${KUADRANT_GATEWAY_NAME}
namespace: ${KUADRANT_GATEWAY_NS}
hostnames:
- api.toystore.com
rules:
Expand Down Expand Up @@ -81,25 +144,25 @@ EOF
Export the gateway hostname and port:

```sh
export INGRESS_HOST=$(kubectl get gtw kuadrant-ingressgateway -n gateway-system -o jsonpath='{.status.addresses[0].value}')
export INGRESS_PORT=$(kubectl get gtw kuadrant-ingressgateway -n gateway-system -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
export KUADRANT_INGRESS_HOST=$(kubectl get gtw ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o jsonpath='{.status.addresses[0].value}')
export KUADRANT_INGRESS_PORT=$(kubectl get gtw ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
export KUADRANT_GATEWAY_URL=${KUADRANT_INGRESS_HOST}:${KUADRANT_INGRESS_PORT}
```

Send requests to the application unprotected:

```sh
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/cars -i
curl -H 'Host: api.toystore.com' http://$KUADRANT_GATEWAY_URL/cars -i
# HTTP/1.1 200 OK
```

```sh
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/dolls -i
curl -H 'Host: api.toystore.com' http://$KUADRANT_GATEWAY_URL/dolls -i
# HTTP/1.1 200 OK
```

```sh
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/admin -i
curl -H 'Host: api.toystore.com' http://$KUADRANT_GATEWAY_URL/admin -i
# HTTP/1.1 200 OK
```

Expand All @@ -118,6 +181,7 @@ apiVersion: kuadrant.io/v1
kind: AuthPolicy
metadata:
name: toystore-authn
namespace: ${KUADRANT_DEVELOPER_NS}
spec:
targetRef:
group: gateway.networking.k8s.io
Expand All @@ -140,6 +204,7 @@ apiVersion: kuadrant.io/v1
kind: AuthPolicy
metadata:
name: toystore-admins
namespace: ${KUADRANT_DEVELOPER_NS}
spec:
targetRef:
group: gateway.networking.k8s.io
Expand Down Expand Up @@ -189,25 +254,25 @@ EOF
Send requests to the application protected by Kuadrant:

```sh
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/cars -i
curl -H 'Host: api.toystore.com' http://$KUADRANT_GATEWAY_URL/cars -i
# HTTP/1.1 401 Unauthorized
# www-authenticate: APIKEY realm="api-key-authn"
# x-ext-auth-reason: credential not found
```

```sh
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://$GATEWAY_URL/cars -i
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://$KUADRANT_GATEWAY_URL/cars -i
# HTTP/1.1 200 OK
```

```sh
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://$GATEWAY_URL/admin -i
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://$KUADRANT_GATEWAY_URL/admin -i
# HTTP/1.1 403 Forbidden
# x-ext-auth-reason: Unauthorized
```

```sh
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamanadmin' http://$GATEWAY_URL/admin -i
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamanadmin' http://$KUADRANT_GATEWAY_URL/admin -i
# HTTP/1.1 200 OK
```

Expand All @@ -216,16 +281,17 @@ curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamanadmin' http://$G
Create the policy:

```sh
kubectl -n gateway-system apply -f - <<EOF
kubectl apply -f - <<EOF
apiVersion: kuadrant.io/v1
kind: AuthPolicy
metadata:
name: gw-auth
namespace: ${KUADRANT_GATEWAY_NS}
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: kuadrant-ingressgateway
name: ${KUADRANT_GATEWAY_NAME}
defaults:
strategy: atomic
rules:
Expand Down Expand Up @@ -257,10 +323,11 @@ apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: other
namespace: ${KUADRANT_DEVELOPER_NS}
spec:
parentRefs:
- name: kuadrant-ingressgateway
namespace: gateway-system
- name: ${KUADRANT_GATEWAY_NAME}
namespace: ${KUADRANT_GATEWAY_NS}
hostnames:
- "*.other-apps.com"
EOF
Expand All @@ -269,7 +336,7 @@ EOF
Send requests to the route protected by the default policy set at the level of the gateway:

```sh
curl -H 'Host: foo.other-apps.com' http://$GATEWAY_URL/ -i
curl -H 'Host: foo.other-apps.com' http://$KUADRANT_GATEWAY_URL/ -i
# HTTP/1.1 403 Forbidden
# content-type: application/json
# x-ext-auth-reason: Unauthorized
Expand All @@ -280,9 +347,3 @@ curl -H 'Host: foo.other-apps.com' http://$GATEWAY_URL/ -i
# "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."
# }
```
jasonmadigan marked this conversation as resolved.
Show resolved Hide resolved

## Cleanup

```sh
make local-cleanup
```
Loading
Loading