diff --git a/PROJECT b/PROJECT
index 1b0085116b20a4e09762d51d875599ba2243ee4e..b1a8dd6d1c07467e4762fd2068bb8baad7720613 100644
--- a/PROJECT
+++ b/PROJECT
@@ -5,3 +5,7 @@ resources:
 - group: certmanager
   version: v1beta1
   kind: StepIssuer
+- group: certmanager
+  kind: StepClusterIssuer
+  version: v1beta1
+
diff --git a/api/v1beta1/stepclusterissuer_types.go b/api/v1beta1/stepclusterissuer_types.go
new file mode 100644
index 0000000000000000000000000000000000000000..5f3e56145876d964525bc28101d108ebc3c05db7
--- /dev/null
+++ b/api/v1beta1/stepclusterissuer_types.go
@@ -0,0 +1,63 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1beta1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.
+
+// StepClusterIssuerSpec defines the desired state of StepClusterIssuer
+type StepClusterIssuerSpec struct {
+	// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+	// Important: Run "make" to regenerate code after modifying this file
+
+	// Foo is an example field of StepClusterIssuer. Edit StepClusterIssuer_types.go to remove/update
+	Foo string `json:"foo,omitempty"`
+}
+
+// StepClusterIssuerStatus defines the observed state of StepClusterIssuer
+type StepClusterIssuerStatus struct {
+	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+	// Important: Run "make" to regenerate code after modifying this file
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:scope=Cluster
+
+// StepClusterIssuer is the Schema for the stepclusterissuers API
+type StepClusterIssuer struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec   StepClusterIssuerSpec   `json:"spec,omitempty"`
+	Status StepClusterIssuerStatus `json:"status,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// StepClusterIssuerList contains a list of StepClusterIssuer
+type StepClusterIssuerList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []StepClusterIssuer `json:"items"`
+}
+
+func init() {
+	SchemeBuilder.Register(&StepClusterIssuer{}, &StepClusterIssuerList{})
+}
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index 7ce23db12afcb65ba30d050dbfcf225bb12ca5cf..64ea5cd46bf7704e7375ba6e2ad5314b40f1ec7a 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -38,6 +38,95 @@ func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StepClusterIssuer) DeepCopyInto(out *StepClusterIssuer) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	out.Spec = in.Spec
+	out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepClusterIssuer.
+func (in *StepClusterIssuer) DeepCopy() *StepClusterIssuer {
+	if in == nil {
+		return nil
+	}
+	out := new(StepClusterIssuer)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *StepClusterIssuer) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StepClusterIssuerList) DeepCopyInto(out *StepClusterIssuerList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]StepClusterIssuer, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepClusterIssuerList.
+func (in *StepClusterIssuerList) DeepCopy() *StepClusterIssuerList {
+	if in == nil {
+		return nil
+	}
+	out := new(StepClusterIssuerList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *StepClusterIssuerList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StepClusterIssuerSpec) DeepCopyInto(out *StepClusterIssuerSpec) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepClusterIssuerSpec.
+func (in *StepClusterIssuerSpec) DeepCopy() *StepClusterIssuerSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(StepClusterIssuerSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StepClusterIssuerStatus) DeepCopyInto(out *StepClusterIssuerStatus) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepClusterIssuerStatus.
+func (in *StepClusterIssuerStatus) DeepCopy() *StepClusterIssuerStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(StepClusterIssuerStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *StepIssuer) DeepCopyInto(out *StepIssuer) {
 	*out = *in
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 3779e3561e7e5a037eb0d2324c81ac5ccff8260c..7ed6ea985c6c3c12ad5c994db8b1106c0db94723 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -3,17 +3,20 @@
 # It should be run by config/default
 resources:
 - bases/certmanager.step.sm_stepissuers.yaml
+- bases/certmanager.step.sm_stepclusterissuers.yaml
 # +kubebuilder:scaffold:crdkustomizeresource
 
 patchesStrategicMerge:
 # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
 # patches here are for enabling the conversion webhook for each CRD
 #- patches/webhook_in_stepissuers.yaml
+#- patches/webhook_in_stepclusterissuers.yaml
 # +kubebuilder:scaffold:crdkustomizewebhookpatch
 
 # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
 # patches here are for enabling the CA injection for each CRD
 #- patches/cainjection_in_stepissuers.yaml
+#- patches/cainjection_in_stepclusterissuers.yaml
 # +kubebuilder:scaffold:crdkustomizecainjectionpatch
 
 # the following config is for teaching kustomize how to do kustomization for CRDs.
diff --git a/config/crd/patches/cainjection_in_stepclusterissuers.yaml b/config/crd/patches/cainjection_in_stepclusterissuers.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5103c3df9e25c5fa580682a51d2e8033f20f40e8
--- /dev/null
+++ b/config/crd/patches/cainjection_in_stepclusterissuers.yaml
@@ -0,0 +1,8 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+# CRD conversion requires k8s 1.13 or later.
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+  name: stepclusterissuers.certmanager.step.sm
diff --git a/config/crd/patches/webhook_in_stepclusterissuers.yaml b/config/crd/patches/webhook_in_stepclusterissuers.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7816a8fbd0c681f2a9cc20f67528773277f281d9
--- /dev/null
+++ b/config/crd/patches/webhook_in_stepclusterissuers.yaml
@@ -0,0 +1,17 @@
+# The following patch enables conversion webhook for CRD
+# CRD conversion requires k8s 1.13 or later.
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: stepclusterissuers.certmanager.step.sm
+spec:
+  conversion:
+    strategy: Webhook
+    webhookClientConfig:
+      # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
+      # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
+      caBundle: Cg==
+      service:
+        namespace: system
+        name: webhook-service
+        path: /convert
diff --git a/config/rbac/stepclusterissuer_editor_role.yaml b/config/rbac/stepclusterissuer_editor_role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2117244eeb4e166cf3265658a2a8b97f1f975c78
--- /dev/null
+++ b/config/rbac/stepclusterissuer_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit stepclusterissuers.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: stepclusterissuer-editor-role
+rules:
+- apiGroups:
+  - certmanager.step.sm
+  resources:
+  - stepclusterissuers
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - update
+  - watch
+- apiGroups:
+  - certmanager.step.sm
+  resources:
+  - stepclusterissuers/status
+  verbs:
+  - get
diff --git a/config/rbac/stepclusterissuer_viewer_role.yaml b/config/rbac/stepclusterissuer_viewer_role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..629d62e6dc5d84951d0539440f624ffa6c973df8
--- /dev/null
+++ b/config/rbac/stepclusterissuer_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view stepclusterissuers.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: stepclusterissuer-viewer-role
+rules:
+- apiGroups:
+  - certmanager.step.sm
+  resources:
+  - stepclusterissuers
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - certmanager.step.sm
+  resources:
+  - stepclusterissuers/status
+  verbs:
+  - get
diff --git a/config/samples/certmanager_v1beta1_stepclusterissuer.yaml b/config/samples/certmanager_v1beta1_stepclusterissuer.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..228375e2d371c931297fb093562dbcd531ec8ef2
--- /dev/null
+++ b/config/samples/certmanager_v1beta1_stepclusterissuer.yaml
@@ -0,0 +1,7 @@
+apiVersion: certmanager.step.sm/v1beta1
+kind: StepClusterIssuer
+metadata:
+  name: stepclusterissuer-sample
+spec:
+  # Add fields here
+  foo: bar
diff --git a/controllers/stepclusterissuer_controller.go b/controllers/stepclusterissuer_controller.go
new file mode 100644
index 0000000000000000000000000000000000000000..9ec339f91077072c042d4a37966a479fdb0f4f87
--- /dev/null
+++ b/controllers/stepclusterissuer_controller.go
@@ -0,0 +1,52 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package controllers
+
+import (
+	"context"
+
+	"github.com/go-logr/logr"
+	"k8s.io/apimachinery/pkg/runtime"
+	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	certmanagerv1beta1 "github.com/smallstep/step-issuer/api/v1beta1"
+)
+
+// StepClusterIssuerReconciler reconciles a StepClusterIssuer object
+type StepClusterIssuerReconciler struct {
+	client.Client
+	Log    logr.Logger
+	Scheme *runtime.Scheme
+}
+
+// +kubebuilder:rbac:groups=certmanager.step.sm,resources=stepclusterissuers,verbs=get;list;watch;create;update;patch;delete
+// +kubebuilder:rbac:groups=certmanager.step.sm,resources=stepclusterissuers/status,verbs=get;update;patch
+
+func (r *StepClusterIssuerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
+	_ = context.Background()
+	_ = r.Log.WithValues("stepclusterissuer", req.NamespacedName)
+
+	// your logic here
+
+	return ctrl.Result{}, nil
+}
+
+func (r *StepClusterIssuerReconciler) SetupWithManager(mgr ctrl.Manager) error {
+	return ctrl.NewControllerManagedBy(mgr).
+		For(&certmanagerv1beta1.StepClusterIssuer{}).
+		Complete(r)
+}
diff --git a/controllers/suite_test.go b/controllers/suite_test.go
index 6fb9465713bbb4387256a5f8b591acce5b9b2dbb..d8d6b31e862a838e71c8aae8d6136c9dddd9faff 100644
--- a/controllers/suite_test.go
+++ b/controllers/suite_test.go
@@ -30,7 +30,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/envtest"
 	"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
 	logf "sigs.k8s.io/controller-runtime/pkg/log"
-	"sigs.k8s.io/controller-runtime/pkg/log/zap"
+	"sigs.k8s.io/controller-runtime/pkg/log/zap"	
 	// +kubebuilder:scaffold:imports
 )
 
diff --git a/main.go b/main.go
index 72550b0114f756ccba63a292a5002169b7bd42fe..f0fbced07e708f1d721f2450f1be5343764ebbcb 100644
--- a/main.go
+++ b/main.go
@@ -99,6 +99,14 @@ func main() {
 		os.Exit(1)
 	}
 
+	if err = (&controllers.StepClusterIssuerReconciler{
+		Client: mgr.GetClient(),
+		Log:    ctrl.Log.WithName("controllers").WithName("StepClusterIssuer"),
+		Scheme: mgr.GetScheme(),
+	}).SetupWithManager(mgr); err != nil {
+		setupLog.Error(err, "unable to create controller", "controller", "StepClusterIssuer")
+		os.Exit(1)
+	}
 	// +kubebuilder:scaffold:builder
 
 	setupLog.Info("starting manager")