diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index d41401082c8c12f69182c0ef28ae6d01040e2436..2738364fee08901e63e1ef4ae2914a7b1d7b0c34 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -57,6 +57,12 @@ jobs:
       - name: Start services
         run: docker-compose -f docker-compose.test.yaml up -d
 
+      - name: Create kind cluster
+        uses: helm/kind-action@v1.0.0
+        with:
+          version: v0.10.0
+          node_image: kindest/node:v1.19.7@sha256:a70639454e97a4b733f9d9b67e12c01f6b0297449d5b9cbbef87473458e26dca
+
       - name: Test
         run: make testall
         env:
@@ -78,6 +84,7 @@ jobs:
           DEX_KEYSTONE_ADMIN_URL: http://localhost:${{ job.services.keystone.ports[35357] }}
           DEX_KEYSTONE_ADMIN_USER: demo
           DEX_KEYSTONE_ADMIN_PASS: DEMO_PASS
+          DEX_KUBERNETES_CONFIG_PATH: ~/.kube/config
 
       - name: Lint
         run: make lint
diff --git a/Makefile b/Makefile
index 81923af4566bc6425585159453df237c8b5d9881..a5f2d7c943e9535de5f3e0cd0604b1526f8f38e2 100644
--- a/Makefile
+++ b/Makefile
@@ -61,25 +61,12 @@ up: docker-compose.override.yaml ## Launch the development environment
 down: clear ## Destroy the development environment
 	docker-compose down --volumes --remove-orphans --rmi local
 
-test: bin/test/kube-apiserver bin/test/etcd
+test:
 	@go test -v ./...
 
-testrace: bin/test/kube-apiserver bin/test/etcd
+testrace:
 	@go test -v --race ./...
 
-export TEST_ASSET_KUBE_APISERVER=$(abspath bin/test/kube-apiserver)
-export TEST_ASSET_ETCD=$(abspath bin/test/etcd)
-
-bin/test/kube-apiserver:
-	@mkdir -p bin/test
-	curl -L https://storage.googleapis.com/k8s-c10s-test-binaries/kube-apiserver-$(shell uname)-x86_64 > bin/test/kube-apiserver
-	chmod +x bin/test/kube-apiserver
-
-bin/test/etcd:
-	@mkdir -p bin/test
-	curl -L https://storage.googleapis.com/k8s-c10s-test-binaries/etcd-$(shell uname)-x86_64 > bin/test/etcd
-	chmod +x bin/test/etcd
-
 bin/golangci-lint: bin/golangci-lint-${GOLANGCI_VERSION}
 	@ln -sf golangci-lint-${GOLANGCI_VERSION} bin/golangci-lint
 bin/golangci-lint-${GOLANGCI_VERSION}:
diff --git a/go.mod b/go.mod
index 62507059ecdbb403bfedca62933d756af4551da4..ed0dd182be8639d4e59a7ee0ffc7ff969c489a47 100644
--- a/go.mod
+++ b/go.mod
@@ -35,7 +35,6 @@ require (
 	google.golang.org/grpc v1.38.0
 	google.golang.org/protobuf v1.26.0
 	gopkg.in/square/go-jose.v2 v2.5.1
-	sigs.k8s.io/testing_frameworks v0.1.2
 )
 
 replace github.com/dexidp/dex/api/v2 => ./api/v2
diff --git a/storage/kubernetes/storage_test.go b/storage/kubernetes/storage_test.go
index 42ba19a4011a3133612add389a48d59442d745a6..08a25d9fc8753ce3312079bd601cc366c2a96da1 100644
--- a/storage/kubernetes/storage_test.go
+++ b/storage/kubernetes/storage_test.go
@@ -5,40 +5,26 @@ import (
 	"crypto/tls"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"os"
+	"path/filepath"
 	"strings"
 	"testing"
 
 	"github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/require"
 	"github.com/stretchr/testify/suite"
-	"sigs.k8s.io/testing_frameworks/integration"
 
 	"github.com/dexidp/dex/storage"
 	"github.com/dexidp/dex/storage/conformance"
 )
 
-const kubeconfigTemplate = `apiVersion: v1
-kind: Config
-clusters:
-- name: local
-  cluster:
-    server: SERVERURL
-users:
-- name: local
-  user:
-contexts:
-- context:
-    cluster: local
-    user: local
-`
+const kubeconfigPathVariableName = "DEX_KUBERNETES_CONFIG_PATH"
 
 func TestStorage(t *testing.T) {
-	if os.Getenv("TEST_ASSET_KUBE_APISERVER") == "" || os.Getenv("TEST_ASSET_ETCD") == "" {
-		t.Skip("control plane binaries are missing")
+	if os.Getenv(kubeconfigPathVariableName) == "" {
+		t.Skip(fmt.Sprintf("variable %q not set, skipping kubernetes storage tests\n", kubeconfigPathVariableName))
 	}
 
 	suite.Run(t, new(StorageTestSuite))
@@ -46,33 +32,24 @@ func TestStorage(t *testing.T) {
 
 type StorageTestSuite struct {
 	suite.Suite
-
-	controlPlane *integration.ControlPlane
-
 	client *client
 }
 
-func (s *StorageTestSuite) SetupSuite() {
-	s.controlPlane = &integration.ControlPlane{}
-
-	err := s.controlPlane.Start()
-	s.Require().NoError(err)
-}
+func (s *StorageTestSuite) expandDir(dir string) string {
+	if strings.HasPrefix(dir, "~/") {
+		homedir, err := os.UserHomeDir()
+		s.Require().NoError(err)
 
-func (s *StorageTestSuite) TearDownSuite() {
-	s.controlPlane.Stop()
+		dir = filepath.Join(homedir, strings.TrimPrefix(dir, "~/"))
+	}
+	return dir
 }
 
 func (s *StorageTestSuite) SetupTest() {
-	f, err := ioutil.TempFile("", "dex-kubeconfig-*")
-	s.Require().NoError(err)
-	defer f.Close()
-
-	_, err = f.WriteString(strings.ReplaceAll(kubeconfigTemplate, "SERVERURL", s.controlPlane.APIURL().String()))
-	s.Require().NoError(err)
+	kubeconfigPath := s.expandDir(os.Getenv(kubeconfigPathVariableName))
 
 	config := Config{
-		KubeConfigFile: f.Name(),
+		KubeConfigFile: kubeconfigPath,
 	}
 
 	logger := &logrus.Logger{
@@ -81,10 +58,10 @@ func (s *StorageTestSuite) SetupTest() {
 		Level:     logrus.DebugLevel,
 	}
 
-	client, err := config.open(logger, true)
+	kubeClient, err := config.open(logger, true)
 	s.Require().NoError(err)
 
-	s.client = client
+	s.client = kubeClient
 }
 
 func (s *StorageTestSuite) TestStorage() {