Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/guicassolato/kas-fleet-manager-authorino

Protecting Red Hat Kafka Service Fleet Manager with Authorino
https://github.com/guicassolato/kas-fleet-manager-authorino

Last synced: 15 days ago
JSON representation

Protecting Red Hat Kafka Service Fleet Manager with Authorino

Awesome Lists containing this project

README

        

# Kafka Fleet Manager with Authorino (POC)

This is a Proof of Concept (PoC) on protecting the [Kafka Management API](https://api.openshift.com/?urls.primaryName=kafka%20service%20fleet%20manager%20service) (a.k.a. Kafka Fleet Manager service, or **kas-fleet-manager**) with [Authorino](https://github.com/kuadrant/authorino).

## Architecture

![Architecture](architecture.svg)

## Install

Meet the prerequisites

- [KAS Installer](https://github.com/bf2fc6cc711aee1a0c2a/kas-installer) tool
- A custom version of kaf-fleet-manager that includes the ext-authz metadata endpoints such as [guicassolato/kas-fleet-manager](https://github.com/guicassolato/kas-fleet-manager/tree/ext-authz)
- [OpenShift](https://www.openshift.com) (tested on OpenShift v4.11.7)
- A user with administrative privileges in the OpenShift cluster
- Red Hat user with permissions to pull the required container images
- Application and Data Services [Service Account](https://console.redhat.com/application-services/service-accounts)
- Kubernetes CLI (`kubectl`)
- [OpenShift CLI](https://docs.openshift.com/container-platform/4.11/cli_reference/openshift_cli/getting-started-cli.html) (`oc`)
- [yq](https://mikefarah.gitbook.io/yq/) (v0.4.x)

Additional prerequisites on MacOS:
- envsubst (`brew install gettext`)

① Login to the cluster

Export the cluster domain to a shell variable:

```sh
export K8S_CLUSTER_DOMAIN=
```

Login to the target OpenShift cluster where you want to run the Kafka Fleet Manager API:

```sh
oc login --token= --server=https://api.$K8S_CLUSTER_DOMAIN:6443
```

② Run the Kafka Fleet Manager service

Make sure to match the [prerequisites](https://github.com/bf2fc6cc711aee1a0c2a/kas-installer#prerequisites) to use KAS Installer and then execute the steps below.

Download KAS Installer:

```sh
git clone [email protected]:bf2fc6cc711aee1a0c2a/kas-installer.git && cd kas-installer
```

Replace the placeholders below with the corresponding values and create your custom KAS installer configuration file `kas-installer.env`:

```sh
cat <kas-installer.env
K8S_CLUSTER_DOMAIN="${K8S_CLUSTER_DOMAIN}"

USER=authorino

RH_USERNAME=""
RH_USER_ID=""
RH_ORG_ID=""

OBSERVABILITY_CONFIG_REPO="https://api.github.com/repos//observability-resources-mk/contents"
OBSERVABILITY_CONFIG_ACCESS_TOKEN=

IMAGE_REPOSITORY_USERNAME=
IMAGE_REPOSITORY_PASSWORD=

SSO_PROVIDER_TYPE=redhat_sso
REDHAT_SSO_HOSTNAME=sso.redhat.com
REDHAT_SSO_CLIENT_ID=
REDHAT_SSO_CLIENT_SECRET=

KAS_FLEET_MANAGER_IMAGE_REPOSITORY=guicassolato/kas-fleet-manager
KAS_FLEET_MANAGER_IMAGE_TAG=ext-authz
EOF
```

Install Kafka Fleet Manager:

```sh
./kas-installer.sh
```

The step above may take several minutes.

③ Install Authorino

Install the Authorino Operator:

```sh
kubectl apply -f -<

④ Enable external authorization

**Apply the AuthConfigs**

```sh
curl -sL https://raw.githubusercontent.com/guicassolato/kas-fleet-manager-authorino/main/kas-fleet-manager-authconfig.yaml | envsubst | kubectl -n kas-fleet-manager-authorino apply -f -
kubectl -n kas-fleet-manager-authorino apply -f https://raw.githubusercontent.com/guicassolato/kas-fleet-manager-authorino/main/kas-fleet-manager-pip-authconfig.yaml
```

**Patch the Envoy configuration**

Patch the Envoy config with the ext-authz filter:

```sh
kubectl -n kas-fleet-manager-authorino get configmap/kas-fleet-manager-envoy-config -o jsonpath='{.data.main\.yaml}' > /tmp/envoy-config.yaml
yq -i '
.static_resources.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.kas-fleet-manager-authorino.svc","port_value":50051}}}}]}]},"transport_socket":{"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[1].filter_chains[0].filters[0].typed_config.http_filters = [{"name":"envoy.filters.http.ext_authz","typed_config":{"@type":"type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz","transport_api_version":"V3","failure_mode_allow":true,"grpc_service":{"envoy_grpc":{"cluster_name":"authorino"},"timeout":"1s"}}}] + .static_resources.listeners[1].filter_chains[0].filters[0].typed_config.http_filters
' /tmp/envoy-config.yaml
sed -e 's/\x1B\[[0-9;]*[JKmsu]//g' -i /tmp/envoy-config.yaml

kubectl -n kas-fleet-manager-authorino delete configmap kas-fleet-manager-envoy-config
kubectl -n kas-fleet-manager-authorino create configmap kas-fleet-manager-envoy-config --from-file=main.yaml=/tmp/envoy-config.yaml
```

Mount Authorino's TLS certs into the Envoy deployment:

```sh
kubectl -n kas-fleet-manager-authorino patch deployment/kas-fleet-manager --type='json' -p='[
{"op":"add","path":"/spec/template/spec/volumes/-","value":{"name":"authorino-ca-cert","secret":{"defaultMode":420,"secretName":"authorino-authorino-authorization-tls"}}},
{"op":"add","path":"/spec/template/spec/containers/1/volumeMounts/-","value":{"mountPath":"/etc/ssl/certs/authorino-ca-cert.crt","name":"authorino-ca-cert","readOnly":true,"subPath":"tls.crt"}}]'
```

The command above will restart the Kafka Fleet Manager service.

⑤ Test the installation

Test the deployment by sending requests to the Kafka Fleet Manager service. Assert conformity of the deployment based on the expected response codes according to the permissions of your user.

List Kafka clusters:

```sh
curl -H "Authorization: Bearer $(ocm token)" \
https://kas-fleet-manager-kas-fleet-manager-authorino.apps.$K8S_CLUSTER_DOMAIN/api/kafkas_mgmt/v1/kafkas
```

Create a Kafka cluster:

```sh
curl -H "Authorization: Bearer $(ocm token)" \
-H 'Content-Type: application/json' \
-d '{"name":"my-kafka","cloud_provider":"aws","region":"us-east-1","multi_az":false}' \
"https://kas-fleet-manager-kas-fleet-manager-authorino.apps.$K8S_CLUSTER_DOMAIN/api/kafkas_mgmt/v1/kafkas?async=true"
```

List supported cloud providers:

```sh
curl -H "Authorization: Bearer $(ocm token)" \
https://kas-fleet-manager-kas-fleet-manager-authorino.apps.$K8S_CLUSTER_DOMAIN/api/kafkas_mgmt/v1/cloud_providers
```

List supported cloud provider regions (AWS):

```sh
curl -H "Authorization: Bearer $(ocm token)" \
https://kas-fleet-manager-kas-fleet-manager-authorino.apps.$K8S_CLUSTER_DOMAIN/api/kafkas_mgmt/v1/cloud_providers/aws/regions
```

List supported instance types (AWS us-east-1):

```sh
curl -H "Authorization: Bearer $(ocm token)" \
https://kas-fleet-manager-kas-fleet-manager-authorino.apps.$K8S_CLUSTER_DOMAIN/api/kafkas_mgmt/v1/instance_types/aws/us-east-1
```

List Service Accounts:

```sh
curl -H "Authorization: Bearer $(ocm token)" \
https://kas-fleet-manager-kas-fleet-manager-authorino.apps.$K8S_CLUSTER_DOMAIN/api/kafkas_mgmt/v1/service_accounts
```

Cleanup

Decommission the Kafka Fleet Manager service:

```sh
./uninstall.sh
```

Uninstall the Authorino Operator:

```sh
kubectl delete namespace authorino-operator
```

## Leverage

On an installation of kas-fleet-manager protected with Authorino as above, try the following editing of the `kas-fleet-manager` AuthConfig:

Deny access to a user altogether

Edit the `kas-fleet-manager` AuthConfig:

```sh
kubectl -n kas-fleet-manager-authorino edit authconfig/kas-fleet-manager
```

Find the authorization policy called `deny-list` and add an email to the `list` array in Rego, e.g.:

```rego
list := [
"[email protected]",
"[email protected]",
"[email protected]" # <====== forbidden user
]
denied { list[_] == input.auth.identity.email }
allow { not denied }
```

You can check your Red Hat OCM user email with the following command:

```sh
ocm token --payload | jq -r .email
```

Save and exit the editing of the AuthConfig.

Test the change by sending a request to kas-fleet-manager authenticating with the now forbidden user. Authorino should respond with a `403` status code.

Revert the steps above to reauthorize the user.

Replace the Admin API RBAC with Kubernetes RBAC

Make possible for users authenticating with Red Hat SSO External to send requests to the admin endpoints of kas-fleet-manager, provided they are bound to required roles in the Kubernetes RBAC.

Create the roles:

```sh
kubectl -n kas-fleet-manager-authorino apply -f -<

## Advanced topics

Harden the installation by setting up the following environment policies:

Limit traffic to Authorino with a NetworkPolicy

```sh
kubectl -n kas-fleet-manager-authorino apply -f -<

Limit the features of Authorino that can be used in the kas-fleet-manager AuthConfig

Kubernetes [dynamic admission webhooks](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) can be used to trigger validations of arbitrary Kubernetes resources that cluster users try to persist, including `AuthConfig` custom resources. Provided the rules to validade such resources are expressed in another AuthConfig – one that validates all AuthConfigs –, Authorino itself can be hooked to perform the validation.

The following steps configure Authorino to validate all requests to the Kubernetes API involving AuthConfig custom resources that are targeted to the dedicated instance of Authorino that serves the kas-fleet-manager authorization requests. As an example, the following validation rule is enforced:




Any AuthConfig linking the ingress host name used to access kas-fleet-manager must verify user access tokens issued by a Red Hat SSO server.


Create the AuthConfig to validate all AuthConfigs:

```sh
curl -sL https://raw.githubusercontent.com/guicassolato/kas-fleet-manager-authorino/main/validating-webhook-authconfig.yaml | envsubst | kubectl -n kas-fleet-manager-authorino apply -f -
```

Create a `ValidatingWebhookConfiguration`:

```sh
kubectl -n kas-fleet-manager-authorino apply -f -<