Annotated Gateway resource
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
FEATURE STATE: cert-manager 1.15 [beta]
đ This page focuses on automatically creating Certificate resources by annotating Kubernetes Gateway resource. If you are looking for using an ACME Issuer along with HTTP-01 challenges using the Kubernetes Gateway API, see ACME HTTP-01.
đ§ cert-manager 1.14+ is tested with v1 Kubernetes Gateway API. It should also work with v1beta1 and v1alpha2 because of resource conversion, but has not been tested with it.
cert-manager can generate TLS certificates for Gateway resources. This is configured by adding annotations to a Gateway and is similar to the process for Securing Ingress Resources.
The Gateway resource is part of the Gateway API, a set of CRDs that you install on your Kubernetes cluster and which provide various improvements over the Ingress API.
The Gateway resource holds the TLS configuration, as illustrated in the following diagram (source: https://gateway-api.sigs.k8s.io):

đ This feature requires the installation of the Gateway API bundle and passing an additional flag to the cert-manager controller.
To install v1.5.1 Gateway API bundle (Gateway CRDs and webhook), run the following command:
kubectl apply -f "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml"
Since cert-manager 1.15, the Gateway API support is no longer gated behind a feature flag, but you still need to enable the Gateway API support.
To enable the Gateway API support, use the file-based
configuration using the
following config Helm value:
config:apiVersion: controller.config.cert-manager.io/v1alpha1kind: ControllerConfigurationenableGatewayAPI: true
The corresponding Helm command is:
helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager \--set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \--set config.kind="ControllerConfiguration" \--set config.enableGatewayAPI=true
The Gateway API CRDs should either be installed before cert-manager starts or the cert-manager Deployment should be restarted after installing the Gateway API CRDs. This is important because some of the cert-manager components only perform the Gateway API check on startup. You can restart cert-manager with the following command:
kubectl rollout restart deployment cert-manager -n cert-manager
The annotations cert-manager.io/issuer or cert-manager.io/cluster-issuer
tell cert-manager to create a Certificate for a Gateway. For example, the
following Gateway will trigger the creation of a Certificate with the name
example-com-tls:
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: exampleannotations:cert-manager.io/issuer: foospec:gatewayClassName: foolisteners:- name: httphostname: example.comport: 443protocol: HTTPSallowedRoutes:namespaces:from: Alltls:mode: TerminatecertificateRefs:- name: example-com-tls
A few moments later, cert-manager will create a Certificate. The Certificate is
named after the Secret name example-com-tls. The dnsNames field is set with
the hostname field from the Gateway spec.
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-com-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- example.com # â Copied from the `hostname` field.secretName: example-com-tls
đ§ this mechanism can only be used to create Secrets in the same namespace as the Gateway, see cert-manager#5610
Use cases
Generate TLS certs for selected TLS blocks
cert-manager skips any listener block that cannot be used for generating a Certificate. For a listener block to be used for creating a Certificate, it must meet the following requirements:
| Field | Requirement |
|---|---|
hostname | Must not be empty. |
tls.mode | Must be set to Terminate. Passthrough is not supported. |
tls.certificateRef.name | Cannot be left empty. |
tls.certificateRef.kind | If specified, must be set to Secret. |
tls.certificateRef.group | If specified, must be set to core. |
tls.certificateRef.namespace | If specified, must be the same as the Gateway. |
In the following example, the first four listener blocks will not be used to generate Certificate resources:
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: my-gatewaynamespace: defaultannotations:cert-manager.io/issuer: my-issuerspec:gatewayClassName: foolisteners:# â Missing "tls" block, the following listener is skipped.- name: example-1port: 80protocol: HTTPhostname: example.com# â Missing "hostname", the following listener is skipped.- name: example-2port: 443protocol: HTTPStls:certificateRefs:- name: example-com-tlskind: Secretgroup: ""# â "mode: Passthrough" is not supported, the following listener is skipped.- name: example-3hostname: example.comport: 8443protocol: HTTPStls:mode: PassthroughcertificateRefs:- name: example-com-tlskind: Secretgroup: ""# â Cross-namespace secret references are not supported, the following listener is skipped.- name: example-4hostname: foo.example.comport: 8443protocol: HTTPSallowedRoutes:namespaces:from: Alltls:mode: TerminatecertificateRefs:- name: example-com-tlskind: Secretgroup: ""namespace: other-namespace# â The following listener is valid.- name: example-5hostname: bar.example.com # â Required.port: 8443protocol: HTTPSallowedRoutes:namespaces:from: Alltls:mode: Terminate # â Required. "Terminate" is the only supported mode.certificateRefs:- name: example-com-tls # â Required.kind: Secret # â Optional. "Secret" is the only valid value.group: "" # â Optional. "" is the only valid value.
cert-manager has skipped over the first four listener blocks and has created a
single Certificate named example-com-tls for the last listener block:
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-com-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- foo.example.comsecretName: example-com-tls
Two listeners with the same Secret name
The same Secret name can be re-used in multiple TLS blocks, regardless of the hostname. Let us imagine that you have these two listeners:
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: exampleannotations:cert-manager.io/issuer: my-issuerspec:gatewayClassName: foolisteners:# Listener 1.- name: example-1hostname: example.comport: 443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: example-com-tls# Listener 2: Same Secret name as Listener 1, with a different hostname.- name: example-2hostname: "*.example.com"port: 443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: example-com-tls# Listener 3: also same Secret name, except the hostname is also the same.- name: example-3hostname: "*.example.com"port: 8443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: example-com-tls# Listener 4: different Secret name.- name: example-4hostname: site.orgport: 443protocol: HTTPStls:mode: TerminatecertificateRefs:- name: site-org-tls
cert-manager will create two Certificates since two Secret names are used:
example-com-tls and site-org-tls. Note the Certificate's dnsNames contains
a single occurrence of *.example.com for both listener 2 and 3 (the
hostname values are de-duplicated).
The two Certificates look like this:
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-com-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- example.com # From listener 1.- *.example.com # From listener 2 and 3.secretName: example-com-tls---apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: site-org-tlsspec:issuerRef:name: my-issuerkind: Issuergroup: cert-manager.iodnsNames:- site.org # From listener 4.secretName: site-org-tls
Supported Annotations
If you are migrating to Gateway resources from Ingress resources, be aware that
there are some differences between the annotations for Ingress resources
versus the annotations for Gateway resources.
The Gateway resource supports the following annotations for generating
Certificate resources:
-
cert-manager.io/issuer: the name of the Issuer that should issue the certificate required for thisGateway. The Issuer must be in the same namespace as theGatewayresource. -
cert-manager.io/cluster-issuer: the name of acert-manager.ioClusterIssuerto acquire the certificate required for thisGateway. It does not matter in which namespace yourGatewayresides, asClusterIssuersare non-namespaced resources. -
cert-manager.io/issuer-kind: the kind of the external issuer resource, for exampleAWSPCAIssuer. This is only necessary for out-of-tree issuers. -
cert-manager.io/issuer-group: the API group of the external issuer controller, for exampleawspca.cert-manager.io. This is only necessary for out-of-tree issuers. -
cert-manager.io/common-name: (optional) this annotation allows you to configurespec.commonNamefor the Certificate to be generated. -
cert-manager.io/email-sans: (optional) this annotation allows you to configurespec.emailAddressesfield for the Certificate to be generated. Supports comma-separated values e.g. "me@example.com,you@example.com" -
cert-manager.io/subject-organizations: (optional) this annotation allows you to configurespec.subject.organizationsfield for the Certificate to be generated. Supports comma-separated values e.g. "Company 1,Company 2" -
cert-manager.io/subject-organizationalunits: (optional) this annotation allows you to configurespec.subject.organizationalUnitsfield for the Certificate to be generated. Supports comma-separated values e.g. "IT Services,Cloud Services" -
cert-manager.io/subject-countries: (optional) this annotation allows you to configurespec.subject.countriesfield for the Certificate to be generated. Supports comma-separated values e.g. "Country 1,Country 2" -
cert-manager.io/subject-provinces: (optional) this annotation allows you to configurespec.subject.provincesfield for the Certificate to be generated. Supports comma-separated values e.g. "Province 1,Province 2" -
cert-manager.io/subject-localities: (optional) this annotation allows you to configurespec.subject.localitiesfield for the Certificate to be generated. Supports comma-separated values e.g. "City 1,City 2" -
cert-manager.io/subject-postalcodes: (optional) this annotation allows you to configurespec.subject.postalCodesfield for the Certificate to be generated. Supports comma-separated values e.g. "123ABC,456DEF" -
cert-manager.io/subject-streetaddresses: (optional) this annotation allows you to configurespec.subject.streetAddressesfield for the Certificate to be generated. Supports comma-separated values e.g. "123 Example St,456 Other Blvd" -
cert-manager.io/subject-serialnumber: (optional) this annotation allows you to configurespec.subject.serialNumberfield for the Certificate to be generated. Supports comma-separated values e.g. "10978342379280287615,1111144445555522228888" -
cert-manager.io/duration: (optional) this annotation allows you to configurespec.durationfield for the Certificate to be generated. -
cert-manager.io/renew-before: (optional) this annotation allows you to configurespec.renewBeforefield for the Certificate to be generated. -
cert-manager.io/usages: (optional) this annotation allows you to configurespec.usagesfield for the Certificate to be generated. Pass a string with comma-separated values i.e "key agreement,digital signature, server auth" -
cert-manager.io/revision-history-limit: (optional) this annotation allows you to configurespec.revisionHistoryLimitfield to limit the number of CertificateRequests to be kept for a Certificate. Minimum value is 1. If unset all CertificateRequests will be kept. -
cert-manager.io/private-key-algorithm: (optional) this annotation allows you to configurespec.privateKey.algorithmfield to set the algorithm for private key generation for a Certificate. Valid values areRSA,ECDSAandEd25519. If unset an algorithmRSAwill be used. -
cert-manager.io/private-key-encoding: (optional) this annotation allows you to configurespec.privateKey.encodingfield to set the encoding for private key generation for a Certificate. Valid values arePKCS1andPKCS8. If unset an algorithmPKCS1will be used. -
cert-manager.io/private-key-size: (optional) this annotation allows you to configurespec.privateKey.sizefield to set the size of the private key for a Certificate. If algorithm is set toRSA, valid values are2048,4096or8192, and will default to2048if not specified. If algorithm is set toECDSA, valid values are256,384or521, and will default to256if not specified. If algorithm is set toEd25519, size is ignored. -
cert-manager.io/private-key-rotation-policy: (optional) this annotation allows you to configurespec.privateKey.rotationPolicyfield to set the rotation policy of the private key for a Certificate. Valid values areNeverandAlways. If unset a rotation policyAlwayswill be used.
Copy annotations to the Certificate
âšī¸ This feature was added in cert-manager
v1.18.0.
It is possible to copy any specific custom annotation into the generated Certificate objects.
For example, to copy the annotation: venafi.cert-manager.io/custom-fields from the Gateway to the Certificate,
you must first redeploy the cert-manager controller with the following extra argument:
--extra-certificate-annotations=venafi.cert-manager.io/custom-fields
Or if you use Helm, supply the following values:
# values.yamlconfig:ingressShimConfig:extraCertificateAnnotations:- venafi.cert-manager.io/custom-fields
Then you can add the annotation to the Gateway resource:
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: exampleannotations:# custom configurationvenafi.cert-manager.io/custom-fields: `[ {"name": "field-name", "value": "field value"}]`