Skip to content

Adding mTLS kuadrant installation mode #1170

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

Merged
merged 26 commits into from
Apr 9, 2025
Merged

Conversation

laurafitzgerald
Copy link
Contributor

@laurafitzgerald laurafitzgerald commented Feb 20, 2025

What

Closes #1153

Changes

  • add a boolean to Kuadrant CRD to turn on/off the config
  • add permissions on PeerAuthentication
  • new peer authentication reconciler: Add PeerAuthentication when mTLS mode is on in STRICT mode with a label selector kuadrant.io/managed: "true". Remove it when mTLS mode is off
  • new limitador istio integration reconciler. Inject sidecar.istio.io/inject label. Value depends on mTLS mode.
  • new authorino istio integration reconciler. Inject sidecar.istio.io/inject label. Value depends on mTLS mode.
  • Reconcile rate limit and auth EnvoyFilters to Configure / Unconfigure connection transport layer (envoy.transport_sockets.tls)
  • state of the world new watch and reconcile
  • Llink peer authentication to Kuadrant CR
  • is limitador installed logic -> at controller boot time the CRDs can only be checked, the limitador resource depends on kuadrant cr.
  • Deployment.spec.template.label mutator
  • LinkDeploymentToLimitador
  • LinkDeploymentToAuthorino Cannot add the deployment of Authorino to the topology without adding all the cluster deployment to the topology.
  • tests
  • Report a status to the cr when istio is not installed -> Follow up work to be done described in When mTLS is enabled and Istio is not installed in the cluster then report in the status #1263 (this PR is already too big)
  • kuadrant CRD: additional printer column mtls
  • Doc -> will be addressed as part of Update documentation to reflect the new method of configuration. #1154

Verification steps

The storyboard is:

  1. Run kuadrant with nTLS mode OFF. Then apply some rate limit and auth policies and run traffic.
  2. Switch mTLS mode to ON. Verify traffic gets handled as expected and required configuration is in place.
  3. Switch mTLS mode back to OFF. Verify traffic gets handled as expected and required mTLS configuration is no longer in the resources. The purpose of this step is to show reconciliation capabilities of the involved controllers.
  • Run the following on this branch.
make local-setup GATEWAYAPI_PROVIDER=istio
  • Apply the Kuadrant custom resource with mtls disabled
kubectl -n kuadrant-system apply -f - <<EOF
---
apiVersion: kuadrant.io/v1beta1
kind: Kuadrant
metadata:
  name: kuadrant-sample
spec: 
  mtls:
    enable: false
EOF
  • Wait for kuadrant instance to be ready
kubectl wait --timeout=300s --for=condition=Ready kuadrant kuadrant-sample -n kuadrant-system
  • Verify mTLS is disabled
kubectl get kuadrant kuadrant-sample -n kuadrant-system

Result should show false

NAME              MTLS    AGE
kuadrant-sample   false   3m42s

Skip DNS sections as not relevant for these verification steps
As there is no real DNS resolution, testing the policies should be done providing a custom IP address for a name to curl tool. As follows:

export INGRESS_HOST=$(kubectl get gtw ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o jsonpath='{.status.addresses[0].value}')
export INGRESS_PORT=$(kubectl get gtw ${KUADRANT_GATEWAY_NAME} -n ${KUADRANT_GATEWAY_NS} -o jsonpath='{.spec.listeners[?(@.name=="api")].port}')

while :; do 
  curl -k --write-out '%{http_code}\n' --silent --output /dev/null --resolve api.$KUADRANT_ZONE_ROOT_DOMAIN:$INGRESS_PORT:$INGRESS_HOST "https://api.$KUADRANT_ZONE_ROOT_DOMAIN:$INGRESS_PORT/cars" | grep -E --color "\b(429)\b|$"
  sleep 1
done

Turn mtls ON

kubectl patch kuadrant kuadrant-sample --type=merge --patch '{"spec": {"mtls": {"enable": true}}}' -n kuadrant-system
  • Verify mTLS is enabled
kubectl get kuadrant kuadrant-sample -n kuadrant-system

Result should show true

NAME              MTLS   AGE
kuadrant-sample   true   15m
  • Verify traffic still gets rate limited and auth policy being applied
while :; do 
  curl -k --write-out '%{http_code}\n' --silent --output /dev/null --resolve api.$KUADRANT_ZONE_ROOT_DOMAIN:$INGRESS_PORT:$INGRESS_HOST "https://api.$KUADRANT_ZONE_ROOT_DOMAIN:$INGRESS_PORT/cars" | grep -E --color "\b(429)\b|$"
  sleep 1
done

It should return 403 and 429s.

  • Verify that a Peer Authentication exists
kubectl get peerauthentication default -n kuadrant-system -o yaml

which should have the following spec

spec:
  mtls:
    mode: STRICT
  selector:
    matchLabels:
      kuadrant.io/managed: "true"
  • Verify that the ratelimit cluster envoyfilter has a patch with a key "transport_socket" in spec.configPatches
kubectl get envoyfilter kuadrant-ratelimiting-external -n api-gateway -o jsonpath='{.spec.configPatches[0].patch.value.transport_socket}' | yq e -P

which should have the following spec

name: envoy.transport_sockets.tls
typed_config:
  '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
  common_tls_context:
    tls_certificate_sds_secret_configs:
      - name: default
        sds_config:
          api_config_source:
            api_type: GRPC
            grpc_services:
              - envoy_grpc:
                  cluster_name: sds-grpc
    validation_context_sds_secret_config:
      name: ROOTCA
      sds_config:
        api_config_source:
          api_type: GRPC
          grpc_services:
            - envoy_grpc:
                cluster_name: sds-grpc
  • Verify that the auth cluster envoyfilter has a patch with a key "transport_socket" in spec.configPatches
kubectl get envoyfilter kuadrant-auth-external -n api-gateway -o jsonpath='{.spec.configPatches[0].patch.value.transport_socket}' | yq e -P

which should have the following spec

name: envoy.transport_sockets.tls
typed_config:
  '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
  common_tls_context:
    tls_certificate_sds_secret_configs:
      - name: default
        sds_config:
          api_config_source:
            api_type: GRPC
            grpc_services:
              - envoy_grpc:
                  cluster_name: sds-grpc
    validation_context_sds_secret_config:
      name: ROOTCA
      sds_config:
        api_config_source:
          api_type: GRPC
          grpc_services:
            - envoy_grpc:
                cluster_name: sds-grp
  • Verify that the limitador deployment has the expected labels
kubectl get deployment limitador-limitador -n kuadrant-system -o yaml | yq e '.spec.template.metadata.labels'

Which should return

app: limitador
kuadrant.io/managed: "true"
limitador-resource: limitador
sidecar.istio.io/inject: "true"
  • Verify that the authorino deployment has the expected labels
kubectl get deployment authorino -n kuadrant-system -o yaml | yq e '.spec.template.metadata.labels'

Which should return

authorino-resource: authorino
control-plane: controller-manager
kuadrant.io/managed: "true"
sidecar.istio.io/inject: "true"

Turn mtls OFF

kubectl patch kuadrant kuadrant-sample --type=merge --patch '{"spec": {"mtls": null}}' -n kuadrant-system
  • Verify mTLS is disabled
kubectl get kuadrant kuadrant-sample -n kuadrant-system

Result should show false

NAME              MTLS    AGE
kuadrant-sample   false   62m
  • Verify traffic still gets rate limited and auth policy being applied
while :; do 
  curl -k --write-out '%{http_code}\n' --silent --output /dev/null --resolve api.$KUADRANT_ZONE_ROOT_DOMAIN:$INGRESS_PORT:$INGRESS_HOST "https://api.$KUADRANT_ZONE_ROOT_DOMAIN:$INGRESS_PORT/cars" | grep -E --color "\b(429)\b|$"
  sleep 1
done

It should return 403 (forbidden) and 429s (too many requests).

  • Verify that a Peer Authentication does not exist.
kubectl get peerauthentication default -n kuadrant-system -o yaml

which should return

Error from server (NotFound): peerauthentications.security.istio.io "default" not found
  • Verify that the ratelimit cluster envoyfilter does not have a patch with a key "transport_socket" in spec.configPatches
kubectl get envoyfilter kuadrant-ratelimiting-external -n api-gateway -o jsonpath='{.spec.configPatches[0].patch.value.transport_socket}' | yq e -P

which should return empty.

  • Verify that the auth cluster envoyfilter does not have a patch with a key "transport_socket" in spec.configPatches
kubectl get envoyfilter kuadrant-auth-external -n api-gateway -o jsonpath='{.spec.configPatches[0].patch.value.transport_socket}' | yq e -P

which should return empty.

  • Verify that the limitador deployment has the istio integration label set to false
kubectl get deployment limitador-limitador -n kuadrant-system -o yaml | yq e '.spec.template.metadata.labels."sidecar.istio.io/inject"'

Which should return false.

  • Verify that the authorino deployment has the istio integration label set to false
kubectl get deployment authorino -n kuadrant-system -o yaml | yq e '.spec.template.metadata.labels."sidecar.istio.io/inject"'

Which should return false.

@laurafitzgerald laurafitzgerald requested a review from a team as a code owner February 20, 2025 13:10
@laurafitzgerald laurafitzgerald marked this pull request as draft February 20, 2025 13:12
Copy link
Contributor

@Boomatang Boomatang left a comment

Choose a reason for hiding this comment

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

There is a few comments that I have. I didn't try running this locally.

I would like to point out with the state of the world and the topology any time you find your self request data from the cluster you are doing something wrong

Copy link
Contributor

@Boomatang Boomatang left a comment

Choose a reason for hiding this comment

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

I think this is now at the stage where we need to be able to compile and run the operator to do a good review. It is getting close.

@laurafitzgerald laurafitzgerald force-pushed the mtls branch 3 times, most recently from da6de62 to e64e213 Compare March 12, 2025 12:45
@laurafitzgerald laurafitzgerald marked this pull request as ready for review March 12, 2025 12:45
Copy link
Contributor

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

Very good progress.

Few questions:

  • If the gateway provider is not Istio and a user enables mtls, should we report in kuadrant status?
  • When a user deletes a gateway, the peerAuthentications objects gets deleted? (not very important now and can be tackled in follow up PR's) (I learned that one peerAuthentications is created at the kuadrant namespace)

@eguzki
Copy link
Contributor

eguzki commented Mar 17, 2025

Trying to run the verification steps: it fails with

{"level":"info","ts":"2025-03-17T14:54:07Z","logger":"kuadrant-operator","msg":"pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:243: failed to list *v1.PeerAuthentication: peerauthentications.security.istio.io is forbidden: User \"system:serviceaccount:kuadrant-system:kuadrant-operator-controller-manager\" cannot list resource \"peerauthentications\" in API group \"security.istio.io\" at the cluster scope"}

Consider granting required permissions to the operator

@laurafitzgerald
Copy link
Contributor Author

@eguzki thanks for you reviews. I've been caught up with other work but starting to address those now. Need to rebase first. 🤕 😂

@laurafitzgerald laurafitzgerald force-pushed the mtls branch 3 times, most recently from 0117f93 to 8554127 Compare March 24, 2025 13:20
@eguzki eguzki added the kind/enhancement New feature or request label Mar 25, 2025
@eguzki eguzki force-pushed the mtls branch 2 times, most recently from 5f377cc to eda5877 Compare April 7, 2025 10:04
laurafitzgerald and others added 13 commits April 8, 2025 18:41
Cannot add the deployment of Authorino to the topology without adding all the cluster deployment to the topology.

Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
@eguzki
Copy link
Contributor

eguzki commented Apr 8, 2025

@david-martin done with this. Ready for another review. I just addressed your comment and added the link from kuadrant CR to the PeerAuthentication on the topology.

tests/commons.go Outdated
@@ -691,3 +692,14 @@ func IsRLPAcceptedAndEnforced(g Gomega, ctx context.Context, cl client.Client, p
g.Expect(enforcedCond.Status).To(Equal(metav1.ConditionTrue))
g.Expect(enforcedCond.Reason).To(Equal(string(kuadrant.PolicyReasonEnforced)))
}

func AuthorionIsReady(cl client.Client, key client.ObjectKey) func(g Gomega, ctx context.Context) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func AuthorionIsReady(cl client.Client, key client.ObjectKey) func(g Gomega, ctx context.Context) {
func AuthorinoIsReady(cl client.Client, key client.ObjectKey) func(g Gomega, ctx context.Context) {

sorry :)

Copy link
Contributor

Choose a reason for hiding this comment

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

🙈

Copy link
Contributor

Choose a reason for hiding this comment

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

done

Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
@david-martin
Copy link
Member

Nice one @laurafitzgerald @eguzki getting this change over the line.
Quite the epic.

@eguzki eguzki enabled auto-merge April 9, 2025 15:08
@eguzki eguzki added this pull request to the merge queue Apr 9, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 9, 2025
@eguzki eguzki added this pull request to the merge queue Apr 9, 2025
Merged via the queue into Kuadrant:main with commit 976dfe0 Apr 9, 2025
31 checks passed
@eguzki eguzki deleted the mtls branch April 9, 2025 16:13
@eguzki eguzki mentioned this pull request Apr 29, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose mTLS config via kuadrant cr which triggers kuadrant-operater to add the expected configuration to implement the functionality
5 participants