diff --git a/ci-operator/step-registry/hypershift/dump/hypershift-dump-chain.yaml b/ci-operator/step-registry/hypershift/dump/hypershift-dump-chain.yaml
index 3c334621e614c..f68ca708d05e4 100644
--- a/ci-operator/step-registry/hypershift/dump/hypershift-dump-chain.yaml
+++ b/ci-operator/step-registry/hypershift/dump/hypershift-dump-chain.yaml
@@ -29,3 +29,4 @@ chain:
documentation: The type of managed service the HyperShift Operator is installed on.
timeout: 15m0s
- ref: hypershift-debug
+ - ref: hypershift-k8sgpt
diff --git a/ci-operator/step-registry/hypershift/k8sgpt/OWNERS b/ci-operator/step-registry/hypershift/k8sgpt/OWNERS
new file mode 100644
index 0000000000000..0e5c211132276
--- /dev/null
+++ b/ci-operator/step-registry/hypershift/k8sgpt/OWNERS
@@ -0,0 +1,17 @@
+approvers:
+- csrwng
+- enxebre
+- sjenning
+- LiangquanLi930
+- bryan-cox
+- jparrill
+- mgencur
+options: {}
+reviewers:
+- csrwng
+- enxebre
+- sjenning
+- LiangquanLi930
+- bryan-cox
+- jparrill
+- mgencur
diff --git a/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-commands.sh b/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-commands.sh
new file mode 100644
index 0000000000000..04d104ff3b7bb
--- /dev/null
+++ b/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-commands.sh
@@ -0,0 +1,143 @@
+#!/bin/bash
+
+set -euo pipefail
+
+EXPLAIN="${EXPLAIN:-false}"
+JUNIT_REPORT="${JUNIT_REPORT:-false}"
+
+OS="$(uname -s)_$(uname -m)"
+K8SGPT_VERSION=${K8SGPT_VERSION:-0.4.25}
+K8SGPT_DIR=${K8SGPT_DIR:-/tmp}
+
+download_binary(){
+ local url="https://github.com/k8sgpt-ai/k8sgpt/releases/download/v${K8SGPT_VERSION}/k8sgpt_${OS}.tar.gz"
+ curl --fail --retry 8 --retry-all-errors -sS -L "${url}" | tar -xzC "${K8SGPT_DIR}/"
+ chmod +x "${K8SGPT_DIR}/k8sgpt"
+}
+
+function set_proxy () {
+ if test -s "${SHARED_DIR}/proxy-conf.sh" ; then
+ echo "setting the proxy"
+ echo "source ${SHARED_DIR}/proxy-conf.sh"
+ # shellcheck disable=SC1091
+ source "${SHARED_DIR}/proxy-conf.sh"
+ else
+ echo "no proxy setting."
+ fi
+}
+
+if [ -f "${SHARED_DIR}/kubeconfig" ] ; then
+ export KUBECONFIG=${SHARED_DIR}/kubeconfig
+fi
+
+set_proxy
+
+download_binary
+
+export PATH="${K8SGPT_DIR}:${PATH}"
+
+k8sgpt version
+
+explain_arg=""
+if [[ "${EXPLAIN}" == "true" ]]; then
+ explain_arg="--explain"
+ openai_token=$(cat "/var/run/vault/tests-private-account/openai-token")
+ k8sgpt auth add --model gpt-3.5-turbo --backend openai --password "${openai_token}" || true
+fi
+
+all_filters=(Ingress CronJob Node MutatingWebhookConfiguration Pod Deployment ReplicaSet \
+ValidatingWebhookConfiguration ConfigMap PersistentVolumeClaim Service StatefulSet)
+# Service and ValidatingWebhookConfiguration filters cause false negatives for hosted clusters.
+# ConfigMap filters cause false positives, reporting unused configmaps.
+excluded_filters=(Service ValidatingWebhookConfiguration ConfigMap)
+active_filters=()
+for filter in "${all_filters[@]}"; do
+ if [[ ! ${excluded_filters[*]} =~ ${filter} ]]; then
+ active_filters+=("$filter")
+ fi
+done
+
+active_filters_str=$(echo "${active_filters[@]}" | tr ' ' ',')
+
+common_params=(--output json --anonymize --with-doc "$explain_arg" --filter "$active_filters_str")
+
+mkdir -p "${ARTIFACT_DIR}/namespaces" "${ARTIFACT_DIR}/hostedcluster"
+
+CLUSTER_NAME="$(echo -n $PROW_JOB_ID|sha256sum|cut -c-20)"
+HOSTED_CLUSTER_NS=$(oc get hostedcluster -A -ojsonpath='{.items[0].metadata.namespace}')
+
+mgmt_fail=false
+# Collect only hypershift-related namespaces from the management cluster.
+for namespace in hypershift "${HOSTED_CLUSTER_NS}" "${HOSTED_CLUSTER_NS}-${CLUSTER_NAME}"; do
+ mkdir -p "${ARTIFACT_DIR}/namespaces/$namespace"
+ # Run the scan on the management cluster
+ result_file="${ARTIFACT_DIR}/namespaces/$namespace/result.json"
+ k8sgpt --kubeconfig="$KUBECONFIG" analyze --namespace "$namespace" "${common_params[@]}" | \
+ tee "$result_file" || true
+ if [[ -f "$result_file" ]]; then
+ if ! grep "problems\": 0" "$result_file" &>/dev/null; then
+ mgmt_fail=true
+ fi
+ fi
+done
+
+guest_fail=false
+# Run the scan on the guest cluster
+if [[ -f "${SHARED_DIR}/nested_kubeconfig" ]]; then
+ k8sgpt --kubeconfig="${SHARED_DIR}/nested_kubeconfig" analyze "${common_params[@]}" | \
+ tee "${ARTIFACT_DIR}/hostedcluster/result.json" || true
+ if ! grep "problems\": 0" "${ARTIFACT_DIR}/hostedcluster/result.json" &>/dev/null; then
+ guest_fail=true
+ fi
+fi
+
+# Optionally generate a JUnit report.
+if [[ "${JUNIT_REPORT}" == "false" ]]; then
+ exit 0
+fi
+
+mkdir -p "${ARTIFACT_DIR}/junit"
+
+testcase_mgmt=""
+testcase_guest=""
+
+failures=0
+
+if [[ "${mgmt_fail}" == "true" ]]; then
+ failures=$((failures + 1))
+ result_mgmt=""
+ for namespace in hypershift "${HOSTED_CLUSTER_NS}" "${HOSTED_CLUSTER_NS}-${CLUSTER_NAME}"; do
+ result_mgmt+=$(cat "${ARTIFACT_DIR}/namespaces/$namespace/result.json")
+ done
+ testcase_mgmt=$(cat <
+ problems detected
+
+${result_mgmt}
+
+
+EOF
+ )
+fi
+
+if [[ "${guest_fail}" == "true" ]]; then
+ failures=$((failures + 1))
+ result_guest=$(cat "${ARTIFACT_DIR}/hostedcluster/result.json")
+ testcase_guest=$(cat <
+ problems detected
+
+${result_guest}
+
+
+EOF
+ )
+fi
+
+cat <"${ARTIFACT_DIR}/junit/k8sgpt-result.xml"
+
+ ${testcase_mgmt}
+ ${testcase_guest}
+
+EOF
+
diff --git a/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-ref.metadata.json b/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-ref.metadata.json
new file mode 100644
index 0000000000000..ec19cb4729746
--- /dev/null
+++ b/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-ref.metadata.json
@@ -0,0 +1,23 @@
+{
+ "path": "hypershift/k8sgpt/hypershift-k8sgpt-ref.yaml",
+ "owners": {
+ "approvers": [
+ "csrwng",
+ "enxebre",
+ "sjenning",
+ "LiangquanLi930",
+ "bryan-cox",
+ "jparrill",
+ "mgencur"
+ ],
+ "reviewers": [
+ "csrwng",
+ "enxebre",
+ "sjenning",
+ "LiangquanLi930",
+ "bryan-cox",
+ "jparrill",
+ "mgencur"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-ref.yaml b/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-ref.yaml
new file mode 100644
index 0000000000000..7f2ca82c75bc1
--- /dev/null
+++ b/ci-operator/step-registry/hypershift/k8sgpt/hypershift-k8sgpt-ref.yaml
@@ -0,0 +1,23 @@
+ref:
+ as: hypershift-k8sgpt
+ cli: latest
+ env:
+ - name: EXPLAIN
+ default: "false"
+ documentation: "Whether to explain the results by AI."
+ - name: JUNIT_REPORT
+ default: "false"
+ documentation: "Whether to generate a JUnit report."
+ grace_period: 10m
+ commands: hypershift-k8sgpt-commands.sh
+ from: hypershift-operator
+ resources:
+ requests:
+ cpu: 100m
+ memory: 100Mi
+ credentials:
+ - namespace: test-credentials
+ name: tests-private-account
+ mount_path: /var/run/vault/tests-private-account
+ documentation: |-
+ Scanning clusters, diagnosing, and triaging issues by calling AI.