From 49ccfa4c1f8219ff077ebd3524586d07b872e87f Mon Sep 17 00:00:00 2001 From: Lenin Alevski Date: Tue, 5 Jan 2021 02:45:17 -0600 Subject: [PATCH] TLS certificates configuration for tenant - Update Create Tenant Wizard to support configuring multiple TLS Certificates - Enable support for both autocert and custom certs when creating a tenant --- .../Console/Tenants/ListTenants/AddTenant.tsx | 748 ++++++++++-------- .../Console/Tenants/ListTenants/utils.ts | 8 + restapi/admin_tenants_helper.go | 9 +- 3 files changed, 453 insertions(+), 312 deletions(-) diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx b/portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx index 0ea069ac18..df2bfcd9ee 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx @@ -20,7 +20,7 @@ import get from "lodash/get"; import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; import Grid from "@material-ui/core/Grid"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; -import { LinearProgress, Typography } from "@material-ui/core"; +import { Button, LinearProgress, Typography } from "@material-ui/core"; import Table from "@material-ui/core/Table"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; @@ -61,8 +61,10 @@ import { IQuotaElement, IQuotas, Opts, + KeyPair, } from "./utils"; import { IMemorySize } from "./types"; +import Divider from "@material-ui/core/Divider"; interface IAddTenantProps { open: boolean; @@ -130,6 +132,12 @@ const AddTenant = ({ const [imageName, setImageName] = useState(""); const [volumeSize, setVolumeSize] = useState("100"); const [enableTLS, setEnableTLS] = useState(true); + const [enableAutoCert, setEnableAutoCert] = useState(true); + const [enableCustomCerts, setEnableCustomCerts] = useState(false); + const [ + enableCustomCertsForKES, + setEnableCustomCertsForKES, + ] = useState(false); const [sizeFactor, setSizeFactor] = useState("Gi"); const [storageClasses, setStorageClassesList] = useState([]); const [selectedStorageClass, setSelectedStorageClass] = useState(""); @@ -148,7 +156,6 @@ const AddTenant = ({ const [ADGroupBaseDN, setADGroupBaseDN] = useState(""); const [ADGroupSearchFilter, setADGroupSearchFilter] = useState(""); const [ADNameAttribute, setADNameAttribute] = useState(""); - const [tlsType, setTLSType] = useState("autocert"); const [enableEncryption, setEnableEncryption] = useState(false); const [encryptionType, setEncryptionType] = useState("vault"); const [gemaltoEndpoint, setGemaltoEndpoint] = useState(""); @@ -222,8 +229,6 @@ const AddTenant = ({ // FilesBase64 const [filesBase64, setFilesBase64] = useState({ - tlsKey: "", - tlsCert: "", consoleKey: "", consoleCert: "", serverKey: "", @@ -237,8 +242,15 @@ const AddTenant = ({ }); // Files States - const [tlsKeyVal, setTlsKeyVal] = useState(""); - const [tlsCertVal, setTlsCertVal] = useState(""); + const [minioCertificates, setMinioCertificates] = useState([ + { + id: Date.now().toString(), + key: "", + cert: "", + encoded_key: "", + encoded_cert: "", + }, + ]); const [consoleKeyVal, setConsoleKeyVal] = useState(""); const [consoleCertVal, setConsoleCertVal] = useState(""); const [serverKeyVal, setServerKeyVal] = useState(""); @@ -250,6 +262,48 @@ const AddTenant = ({ const [vaultCAVal, setVaultCAVal] = useState(""); const [gemaltoCAVal, setGemaltoCAVal] = useState(""); + // Certificates functions + const addKeyPair = () => { + setMinioCertificates((currentCertificates) => [ + ...currentCertificates, + { + id: Date.now().toString(), + key: "", + cert: "", + encoded_key: "", + encoded_cert: "", + }, + ]); + }; + + const deleteKeyPair = (id: string) => { + if (minioCertificates.length > 1) { + setMinioCertificates( + minioCertificates.filter((item: KeyPair) => item.id !== id) + ); + } + }; + + const addFileToKeyPair = ( + id: string, + key: string, + fileName: string, + value: string + ) => { + setMinioCertificates( + minioCertificates.map((item: KeyPair) => { + if (item.id === id) { + return { + ...item, + [key]: fileName, + [`encoded_${key}`]: value, + }; + } + return item; + }) + ); + }; + /*Debounce functions*/ // Storage Quotas @@ -632,76 +686,49 @@ const AddTenant = ({ ]); useEffect(() => { - let securityValidation: IValidation[] = []; - if (!enableTLS) { setSecurityValid(true); setValidationErrors({}); return; } - - if (tlsType === "autocert") { + if (enableAutoCert) { setSecurityValid(true); setValidationErrors({}); return; } - - securityValidation = [ - ...securityValidation, - { - fieldKey: "tlsKey", - required: true, - value: filesBase64.tlsKey, - }, - { - fieldKey: "tlsCert", - required: true, - value: filesBase64.tlsCert, - }, - { - fieldKey: "consoleKey", - required: true, - value: filesBase64.consoleKey, - }, - { - fieldKey: "consoleCert", - required: true, - value: filesBase64.consoleCert, - }, - ]; - - const commonVal = commonFormValidation(securityValidation); - - setSecurityValid(Object.keys(commonVal).length === 0); - - setValidationErrors(commonVal); - }, [enableTLS, filesBase64, tlsType]); + if (enableCustomCerts) { + setSecurityValid(true); + setValidationErrors({}); + return; + } + setSecurityValid(false); + }, [enableTLS, enableAutoCert, enableCustomCerts]); useEffect(() => { let encryptionValidation: IValidation[] = []; if (enableEncryption) { - if (enableTLS && tlsType !== "autocert") { + if (enableCustomCerts) { encryptionValidation = [ ...encryptionValidation, { fieldKey: "serverKey", - required: true, + required: !enableAutoCert, value: filesBase64.serverKey, }, { fieldKey: "serverCert", - required: true, + required: !enableAutoCert, value: filesBase64.serverCert, }, { fieldKey: "clientKey", - required: true, + required: !enableAutoCert, value: filesBase64.clientKey, }, { fieldKey: "clientCert", - required: true, + required: !enableAutoCert, value: filesBase64.clientCert, }, ]; @@ -715,11 +742,6 @@ const AddTenant = ({ required: true, value: vaultEndpoint, }, - { - fieldKey: "vault_engine", - required: true, - value: vaultEngine, - }, { fieldKey: "vault_id", required: true, @@ -730,31 +752,16 @@ const AddTenant = ({ required: true, value: vaultSecret, }, - { - fieldKey: "vault_key", - required: true, - value: filesBase64.vaultKey, - }, - { - fieldKey: "vault_cert", - required: true, - value: filesBase64.vaultCert, - }, - { - fieldKey: "vault_ca", - required: true, - value: filesBase64.vaultCA, - }, { fieldKey: "vault_ping", - required: true, + required: false, value: vaultPing, customValidation: parseInt(vaultPing) < 0, customValidationMessage: "Value needs to be 0 or greater", }, { fieldKey: "vault_retry", - required: true, + required: false, value: vaultRetry, customValidation: parseInt(vaultRetry) < 0, customValidationMessage: "Value needs to be 0 or greater", @@ -808,16 +815,11 @@ const AddTenant = ({ }, { fieldKey: "gemalto_retry", - required: true, + required: false, value: gemaltoRetry, customValidation: parseInt(gemaltoRetry) < 0, customValidationMessage: "Value needs to be 0 or greater", }, - { - fieldKey: "gemalto_ca", - required: true, - value: filesBase64.gemaltoCA, - }, ]; } } @@ -893,7 +895,7 @@ const AddTenant = ({ namespace: namespace, access_key: "", secret_key: "", - enable_tls: enableTLS && tlsType === "autocert", + enable_tls: enableAutoCert, enable_console: true, enable_prometheus: true, service_name: "", @@ -935,36 +937,36 @@ const AddTenant = ({ }; } - if (tlsType === "customcert") { - let tenantCerts: any = null; - let consoleCerts: any = null; - if (filesBase64.tlsCert !== "" && filesBase64.tlsKey !== "") { - tenantCerts = { - minio: { - crt: filesBase64.tlsCert, - key: filesBase64.tlsKey, - }, - }; - } + let tenantCerts: any = null; + let consoleCerts: any = null; + if (minioCertificates.length > 0) { + tenantCerts = { + minio: minioCertificates + .map((keyPair: KeyPair) => ({ + crt: keyPair.encoded_cert, + key: keyPair.encoded_key, + })) + .filter((keyPair) => keyPair.crt && keyPair.key), + }; + } - if (filesBase64.consoleCert !== "" && filesBase64.consoleKey !== "") { - consoleCerts = { - console: { - crt: filesBase64.consoleCert, - key: filesBase64.consoleKey, - }, - }; - } + if (filesBase64.consoleCert !== "" && filesBase64.consoleKey !== "") { + consoleCerts = { + console: { + crt: filesBase64.consoleCert, + key: filesBase64.consoleKey, + }, + }; + } - if (tenantCerts || consoleCerts) { - dataSend = { - ...dataSend, - tls: { - ...tenantCerts, - ...consoleCerts, - }, - }; - } + if (tenantCerts || consoleCerts) { + dataSend = { + ...dataSend, + tls: { + ...tenantCerts, + ...consoleCerts, + }, + }; } if (enableEncryption) { @@ -972,6 +974,12 @@ const AddTenant = ({ switch (encryptionType) { case "gemalto": + let gemaltoCA = {}; + if (filesBase64.gemaltoCA !== "") { + gemaltoCA = { + ca: filesBase64.gemaltoCA, + }; + } insertEncrypt = { gemalto: { keysecure: { @@ -979,10 +987,10 @@ const AddTenant = ({ credentials: { token: gemaltoToken, domain: gemaltoDomain, - retry: gemaltoRetry, + retry: parseInt(gemaltoRetry), }, tls: { - ca: filesBase64.gemaltoCA, + ...gemaltoCA, }, }, }, @@ -1005,6 +1013,28 @@ const AddTenant = ({ }; break; case "vault": + let vaultKeyPair = null; + let vaultCA = null; + if (filesBase64.vaultKey !== "" && filesBase64.vaultCert !== "") { + vaultKeyPair = { + key: filesBase64.vaultKey, + crt: filesBase64.vaultCert, + }; + } + if (filesBase64.vaultCA !== "") { + vaultCA = { + ca: filesBase64.vaultCA, + }; + } + let vaultTLS = null; + if (vaultKeyPair || vaultCA) { + vaultTLS = { + tls: { + ...vaultKeyPair, + ...vaultCA, + }, + }; + } insertEncrypt = { vault: { endpoint: vaultEndpoint, @@ -1015,32 +1045,43 @@ const AddTenant = ({ engine: vaultAppRoleEngine, id: vaultId, secret: vaultSecret, - retry: vaultRetry, - }, - tls: { - key: filesBase64.vaultKey, - crt: filesBase64.vaultCert, - ca: filesBase64.vaultCA, + retry: parseInt(vaultRetry), }, + ...vaultTLS, status: { - ping: vaultPing, + ping: parseInt(vaultPing), }, }, }; break; } - dataSend = { - ...dataSend, - encryption: { + let encryptionServerKeyPair: any = {}; + let encryptionClientKeyPair: any = {}; + + if (filesBase64.clientKey !== "" && filesBase64.clientCert !== "") { + encryptionClientKeyPair = { client: { key: filesBase64.clientKey, crt: filesBase64.clientCert, }, + }; + } + + if (filesBase64.serverKey !== "" && filesBase64.serverCert !== "") { + encryptionServerKeyPair = { server: { key: filesBase64.serverKey, crt: filesBase64.serverCert, }, + }; + } + + dataSend = { + ...dataSend, + encryption: { + ...encryptionClientKeyPair, + ...encryptionServerKeyPair, ...insertEncrypt, }, }; @@ -1124,6 +1165,16 @@ const AddTenant = ({ (element) => element.erasureCode === ecParity ); + let encryptionAvailable = false; + if ( + enableTLS && + (enableAutoCert || + minioCertificates.filter((item) => item.encoded_key && item.encoded_cert) + .length > 0) + ) { + encryptionAvailable = true; + } + const wizardSteps: IWizardElement[] = [ { label: "Name Tenant", @@ -1609,100 +1660,156 @@ const AddTenant = ({

- Autocert: minio-operator will generate all TLS certificates + AutoCert: MinIO Operator will generate all TLS certificates automatically - Custom certificates: allow user to provide your own + Custom certificates: Allow user to provide your own certificates +
)} {enableTLS && ( - { - setTLSType(e.target.value); + const targetD = e.target; + const checked = targetD.checked; + + setEnableAutoCert(checked); }} - selectorOptions={[ - { label: "Autocert", value: "autocert" }, - { label: "Custom Certificate", value: "customcert" }, - ]} + label={"Enable AutoCert"} + /> + { + const targetD = e.target; + const checked = targetD.checked; + + setEnableCustomCerts(checked); + }} + label={"Custom Certificates"} /> - {tlsType !== "autocert" && ( + {enableCustomCerts && ( -
MinIO TLS Certs
- - { - storeCertInObject("tlsKey", encodedValue); - setTlsKeyVal(fileName); - clearValidationError("tlsKey"); - }} - accept=".key,.pem" - id="tlsKey" - name="tlsKey" - label="Key" - error={validationErrors["tlsKey"] || ""} - value={tlsKeyVal} - required - /> - - - { - storeCertInObject("tlsCert", encodedValue); - setTlsCertVal(fileName); - clearValidationError("tlsCert"); - }} - accept=".cer,.crt,.cert,.pem" - id="tlsCert" - name="tlsCert" - label="Cert" - error={validationErrors["tlsCert"] || ""} - value={tlsCertVal} - required - /> + + + + MinIO Certificates + + + {minioCertificates.map((keyPair: KeyPair) => ( + + + { + addFileToKeyPair( + keyPair.id, + "key", + fileName, + encodedValue + ); + }} + accept=".key,.pem" + id="tlsKey" + name="tlsKey" + label="Key" + value={keyPair.key} + /> + + + { + addFileToKeyPair( + keyPair.id, + "cert", + fileName, + encodedValue + ); + }} + accept=".cer,.crt,.cert,.pem" + id="tlsCert" + name="tlsCert" + label="Cert" + value={keyPair.cert} + /> + + + + + + ))} + + + -
Console TLS Certs
- - { - storeCertInObject("consoleKey", encodedValue); - setConsoleKeyVal(fileName); - clearValidationError("consoleKey"); - }} - accept=".key,.pem" - id="consoleKey" - name="consoleKey" - label="Key" - error={validationErrors["consoleKey"] || ""} - value={consoleKeyVal} - required - /> + + +
+ +
+
- - { - storeCertInObject("consoleCert", encodedValue); - setConsoleCertVal(fileName); - clearValidationError("consoleCert"); - }} - accept=".cer,.crt,.cert,.pem" - id="consoleCert" - name="consoleCert" - label="Cert" - error={validationErrors["consoleCert"] || ""} - value={consoleCertVal} - required - /> + + + + Console Certificates + + + + { + storeCertInObject("consoleKey", encodedValue); + setConsoleKeyVal(fileName); + }} + accept=".key,.pem" + id="consoleKey" + name="consoleKey" + label="Key" + value={consoleKeyVal} + /> + + + { + storeCertInObject("consoleCert", encodedValue); + setConsoleCertVal(fileName); + }} + accept=".cer,.crt,.cert,.pem" + id="consoleCert" + name="consoleCert" + label="Cert" + value={consoleCertVal} + /> +
)} @@ -1740,7 +1847,7 @@ const AddTenant = ({ setEnableEncryption(checked); }} label={"Enable Server Side Encryption"} - disabled={!enableTLS} + disabled={!encryptionAvailable} /> {enableEncryption && ( @@ -1761,80 +1868,115 @@ const AddTenant = ({ ]} /> - - {enableTLS && tlsType !== "autocert" && ( + {encryptionType === "vault" && ( -
Server
- { - storeCertInObject("serverKey", encodedValue); - setServerKeyVal(fileName); - clearValidationError("serverKey"); + { + const targetD = e.target; + const checked = targetD.checked; + + setEnableCustomCertsForKES(checked); }} - accept=".key,.pem" - id="serverKey" - name="serverKey" - label="Key" - error={validationErrors["serverKey"] || ""} - value={serverKeyVal} - required + label={"Custom Certificates"} + disabled={!enableAutoCert} /> - - { - storeCertInObject("serverCert", encodedValue); - setServerCertVal(fileName); - clearValidationError("serverCert"); - }} - accept=".cer,.crt,.cert,.pem" - id="serverCert" - name="serverCert" - label="Cert" - error={validationErrors["serverCert"] || ""} - value={serverCertVal} - required - /> - -
Client
- - { - storeCertInObject("clientKey", encodedValue); - setClientKeyVal(fileName); - clearValidationError("clientKey"); - }} - accept=".key,.pem" - id="clientKey" - name="clientKey" - label="Key" - error={validationErrors["clientKey"] || ""} - value={clientKeyVal} - required - /> - - - { - storeCertInObject("clientCert", encodedValue); - setClientCertVal(fileName); - clearValidationError("clientCert"); - }} - accept=".cer,.crt,.cert,.pem" - id="clientCert" - name="clientCert" - label="Cert" - error={validationErrors["clientCert"] || ""} - value={clientCertVal} - required - /> - -
- )} - - {encryptionType === "vault" && ( - + {(enableCustomCertsForKES || !enableAutoCert) && ( + + + + Encryption Service Certificates + + + + + { + storeCertInObject("serverKey", encodedValue); + setServerKeyVal(fileName); + clearValidationError("serverKey"); + }} + accept=".key,.pem" + id="serverKey" + name="serverKey" + label="Key" + error={validationErrors["serverKey"] || ""} + value={serverKeyVal} + required={!enableAutoCert} + /> + + + { + storeCertInObject("serverCert", encodedValue); + setServerCertVal(fileName); + clearValidationError("serverCert"); + }} + accept=".cer,.crt,.cert,.pem" + id="serverCert" + name="serverCert" + label="Cert" + error={validationErrors["serverCert"] || ""} + value={serverCertVal} + required={!enableAutoCert} + /> + + + + + + Mutual TLS authentication + + + + + { + storeCertInObject("clientKey", encodedValue); + setClientKeyVal(fileName); + clearValidationError("clientKey"); + }} + accept=".key,.pem" + id="clientKey" + name="clientKey" + label="Key" + error={validationErrors["clientKey"] || ""} + value={clientKeyVal} + required={!enableAutoCert} + /> + + + { + storeCertInObject("clientCert", encodedValue); + setClientCertVal(fileName); + clearValidationError("clientCert"); + }} + accept=".cer,.crt,.cert,.pem" + id="clientCert" + name="clientCert" + label="Cert" + error={validationErrors["clientCert"] || ""} + value={clientCertVal} + required={!enableAutoCert} + /> + + + + )} @@ -1905,7 +2045,7 @@ const AddTenant = ({ setVaultId(e.target.value); clearValidationError("vault_id"); }} - label="Id" + label="AppRole ID" value={vaultId} error={validationErrors["vault_id"] || ""} required @@ -1919,7 +2059,7 @@ const AddTenant = ({ setVaultSecret(e.target.value); clearValidationError("vault_secret"); }} - label="Secret" + label="AppRole Secret" value={vaultSecret} error={validationErrors["vault_secret"] || ""} required @@ -1935,44 +2075,41 @@ const AddTenant = ({ setVaultRetry(e.target.value); clearValidationError("vault_retry"); }} - label="Retry" + label="Retry (Seconds)" value={vaultRetry} error={validationErrors["vault_retry"] || ""} - required - /> - -
TLS
- - { - storeCertInObject("vaultKey", encodedValue); - setVaultKeyVal(fileName); - clearValidationError("vault_key"); - }} - accept=".key,.pem" - id="vault_key" - name="vault_key" - label="Key" - error={validationErrors["vault_key"] || ""} - value={vaultKeyVal} - required /> - - { - storeCertInObject("vaultCert", encodedValue); - setVaultCertVal(fileName); - clearValidationError("vault_cert"); - }} - accept=".cer,.crt,.cert,.pem" - id="vault_cert" - name="vault_cert" - label="Cert" - error={validationErrors["vault_cert"] || ""} - value={vaultCertVal} - required - /> +
Mutual TLS authentication (optional)
+ + + { + storeCertInObject("vaultKey", encodedValue); + setVaultKeyVal(fileName); + clearValidationError("vault_key"); + }} + accept=".key,.pem" + id="vault_key" + name="vault_key" + label="Key" + value={vaultKeyVal} + /> + + + { + storeCertInObject("vaultCert", encodedValue); + setVaultCertVal(fileName); + clearValidationError("vault_cert"); + }} + accept=".cer,.crt,.cert,.pem" + id="vault_cert" + name="vault_cert" + label="Cert" + value={vaultCertVal} + /> +
Status
@@ -2001,10 +2136,9 @@ const AddTenant = ({ setVaultPing(e.target.value); clearValidationError("vault_ping"); }} - label="Ping" + label="Ping (Seconds)" value={vaultPing} error={validationErrors["vault_ping"] || ""} - required />
@@ -2086,7 +2220,7 @@ const AddTenant = ({ onChange={(e: React.ChangeEvent) => { setAWSToken(e.target.value); }} - label="Secret Key" + label="Token" value={awsToken} /> @@ -2147,12 +2281,12 @@ const AddTenant = ({ setGemaltoRetry(e.target.value); clearValidationError("gemalto_retry"); }} - label="Domain" + label="Retry (seconds)" value={gemaltoRetry} error={validationErrors["gemalto_retry"] || ""} /> -
TLS
+
Custom CA Root certificate verification
{ @@ -2164,9 +2298,7 @@ const AddTenant = ({ id="gemalto_ca" name="gemalto_ca" label="CA" - error={validationErrors["gemalto_ca"] || ""} value={gemaltoCAVal} - required />
diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/utils.ts b/portal-ui/src/screens/Console/Tenants/ListTenants/utils.ts index 981e3631a1..ed1672a58e 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/utils.ts +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/utils.ts @@ -33,6 +33,14 @@ export interface IQuotas { export const minMemReq = 2147483648; +export interface KeyPair { + id: string; + encoded_cert: string; + encoded_key: string; + cert: string; + key: string; +} + export const ecListTransform = (ecList: string[]): Opts[] => { return ecList.map((value) => { return { label: value, value }; diff --git a/restapi/admin_tenants_helper.go b/restapi/admin_tenants_helper.go index e1745479a6..acd9a2ad51 100644 --- a/restapi/admin_tenants_helper.go +++ b/restapi/admin_tenants_helper.go @@ -231,12 +231,13 @@ func getKESConfiguration(ctx context.Context, clientSet K8sClientI, ns string, e // secrets to be used by the operator for TLS encryption func createOrReplaceExternalCertSecrets(ctx context.Context, clientSet K8sClientI, ns string, keyPairs []*models.KeyPairConfiguration, secretName, tenantName string) ([]*operator.LocalCertificateReference, error) { var keyPairSecrets []*operator.LocalCertificateReference - for _, keyPair := range keyPairs { + for i, keyPair := range keyPairs { + secretName := fmt.Sprintf("%s-%d", secretName, i) if keyPair == nil || keyPair.Crt == nil || keyPair.Key == nil || *keyPair.Crt == "" || *keyPair.Key == "" { return nil, errors.New("certificate files must not be empty") } // delete secret with same name if exists - err := clientSet.deleteSecret(ctx, ns, secretName, metav1.DeleteOptions{}) + err := clientSet.deleteSecret(ctx, ns, fmt.Sprintf("%s-%d", secretName, i), metav1.DeleteOptions{}) if err != nil { // log the error if any and continue log.Println(err) @@ -289,8 +290,8 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl log.Println(err) } // if autoCert is enabled then Operator will generate the client certificates, calculate the client cert identity - // and pass it to KES via the $MINIO_KES_IDENTITY variable - clientCrtIdentity := "$MINIO_KES_IDENTITY" + // and pass it to KES via the ${MINIO_KES_IDENTITY} variable + clientCrtIdentity := "${MINIO_KES_IDENTITY}" // If a client certificate is provided proceed to calculate the identity if encryptionCfg.Client != nil { // Client certificate for KES used by Minio to mTLS