diff --git a/404.html b/404.html index 23b079fd..45d0169d 100644 --- a/404.html +++ b/404.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/assets/js/87583c6c.6d8524a7.js b/assets/js/87583c6c.6d8524a7.js new file mode 100644 index 00000000..63504f90 --- /dev/null +++ b/assets/js/87583c6c.6d8524a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1836],{5680:(e,t,r)=>{r.d(t,{xA:()=>d,yg:()=>h});var a=r(6540);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=p(r),m=n,h=c["".concat(l,".").concat(m)]||c[m]||g[m]||i;return r?a.createElement(h,o(o({ref:t},d),{},{components:r})):a.createElement(h,o({ref:t},d))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:n,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var a=r(8168),n=(r(6540),r(5680));const i={sidebar_position:3,title:"Credentials operator"},o=void 0,s={unversionedId:"reference/configuration/credentials-operator/README",id:"reference/configuration/credentials-operator/README",title:"Credentials operator",description:"The credentials operator provisions just-in-time credentials for workloads running on Kubernetes. These credentials come in the form of Kubernetes Secrets (mTLS certificates, database username + passwords), or AWS IAM roles.",source:"@site/docs/reference/configuration/credentials-operator/README.mdx",sourceDirName:"reference/configuration/credentials-operator",slug:"/reference/configuration/credentials-operator/",permalink:"/reference/configuration/credentials-operator/",draft:!1,editUrl:"https://github.com/otterize/docs/edit/main/docs/reference/configuration/credentials-operator/README.mdx",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,title:"Credentials operator"},sidebar:"docSidebar",previous:{title:"Configuring Kafka brokers",permalink:"/reference/configuration/intents-operator/configuration"},next:{title:"Helm chart",permalink:"/reference/configuration/credentials-operator/helm-chart"}},l={},p=[{value:"Deploying the credentials operator",id:"deploying-the-credentials-operator",level:2},{value:"Provisioning AWS IAM roles using the credentials operator",id:"provisioning-aws-iam-roles-using-the-credentials-operator",level:2},{value:"Provisioning mTLS certificates using the credentials operator",id:"provisioning-mtls-certificates-using-the-credentials-operator",level:2},{value:"Provisioning database username + password using the credentials operator",id:"provisioning-database-username--password-using-the-credentials-operator",level:2},{value:"How does the credentials operator provision certificates?",id:"how-does-the-credentials-operator-provision-certificates",level:3},{value:"Step 1: SPIRE entry registration",id:"step-1-spire-entry-registration",level:4},{value:"Step 2: Certificate generation",id:"step-2-certificate-generation",level:4},{value:"cert-manager",id:"cert-manager",level:5},{value:"Otterize Cloud",id:"otterize-cloud",level:5},{value:"SPIRE",id:"spire",level:5},{value:"SPIRE workload registrar",id:"spire-workload-registrar",level:2},{value:"Pod annotations",id:"pod-annotations",level:2}],d={toc:p},c="wrapper";function g(e){let{components:t,...r}=e;return(0,n.yg)(c,(0,a.A)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("p",null,"The credentials operator provisions just-in-time credentials for workloads running on Kubernetes. These credentials come in the form of Kubernetes Secrets (mTLS certificates, database username + passwords), or AWS IAM roles."),(0,n.yg)("h2",{id:"deploying-the-credentials-operator"},"Deploying the credentials operator"),(0,n.yg)("p",null,"To deploy the operator, ",(0,n.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart"},"use the Helm chart"),"."),(0,n.yg)("p",null,"To deploy with Otterize Cloud as the certificate provider, we recommend you ",(0,n.yg)("a",{parentName:"p",href:"https://app.otterize.com/"},"follow the instructions in Otterize Cloud"),".\nTo deploy with cert-manager as the certificate provider, you must also ",(0,n.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart#cert-manager-parameters"},"configure the Issuer name and whether it should look for a ClusterIssuer or an Issuer (namespace-scoped)"),"."),(0,n.yg)("h2",{id:"provisioning-aws-iam-roles-using-the-credentials-operator"},"Provisioning AWS IAM roles using the credentials operator"),(0,n.yg)("p",null,"The credentials operator is controlled using annotations placed on pods. To have it provision an AWS IAM role, you must specify the pod annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/create-aws-role"),", with the value being ",(0,n.yg)("inlineCode",{parentName:"p"},"true"),". Once you do so, the credentials operator will provision an AWS IAM role, and automatically bind it with the Kubernetes ServiceAccount of the pod by setting the EKS role ARN annotation on the ServiceAccount and the appropriate Trust Relationship on the AWS IAM role."),(0,n.yg)("h2",{id:"provisioning-mtls-certificates-using-the-credentials-operator"},"Provisioning mTLS certificates using the credentials operator"),(0,n.yg)("p",null,"The credentials operator is controlled using annotations placed on pods. To have it provision certificates and place them in Secrets, you must specify the pod annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),", with the value being the name of the secret. Once you do so, the credentials operator will provision a certificate for the pod, using Otterize Cloud, cert-manager or SPIRE, depending how you've deployed it."),(0,n.yg)("h2",{id:"provisioning-database-username--password-using-the-credentials-operator"},"Provisioning database username + password using the credentials operator"),(0,n.yg)("p",null,"The credentials operator is controlled using annotations placed on pods. To have it provision database username + password and place them in Secrets, you must specify the pod annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/user-password-secret-name"),", with the value being the name of the secret. Once you do so, the credentials operator will provision a username and password for the pod."),(0,n.yg)("p",null,"Secrets are automatically rotated (defaults to every 8 hours). This value can be controlled using the ",(0,n.yg)("inlineCode",{parentName:"p"},"databaseSecretRotationInterval")," key in the credentials operator ",(0,n.yg)("inlineCode",{parentName:"p"},"values.yaml"),"."),(0,n.yg)("p",null,"If you want pods to be restarted automatically after secret rotation, set the annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/restart-on-secret-rotation")," on the pod (no matter the value)."),(0,n.yg)("h3",{id:"how-does-the-credentials-operator-provision-certificates"},"How does the credentials operator provision certificates?"),(0,n.yg)("p",null,"The credentials operator performs two steps in order to issue certificates."),(0,n.yg)("h4",{id:"step-1-spire-entry-registration"},"Step 1: SPIRE entry registration"),(0,n.yg)("p",null,"This step only happens if the operator is configured to use SPIRE for certificate generation. Once the operator ",(0,n.yg)("a",{parentName:"p",href:"#service-name-resolution-and-automatic-pod-labeling"},"resolves the service name")," for a pod, it labels the pod so that SPIRE can find it, and registers an entry with the SPIRE server for that label."),(0,n.yg)("h4",{id:"step-2-certificate-generation"},"Step 2: Certificate generation"),(0,n.yg)("p",null,"The operator consults the annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),". If that annotation exists, the operator creates a secret named after the value of the label. That secret contains X.509 credentials within, provided by cert-manager, Otterize Cloud or SPIRE, depending on how the credentials operator is configured."),(0,n.yg)("h5",{id:"cert-manager"},"cert-manager"),(0,n.yg)("p",null,"The operator creates a cert-manager ",(0,n.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/usage/certificate/"},(0,n.yg)("inlineCode",{parentName:"a"},"Certificate"))," resource, which will create a Kubernetes Secret with the name specified by the value of the annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),". The common name and DNS names in the certificate are values that represent the identity of the service, as resolved by the ",(0,n.yg)("a",{parentName:"p",href:"#3-service-name-resolution-and-automatic-pod-labeling"},"service identity resolution algorithm"),", i.e. ",(0,n.yg)("inlineCode",{parentName:"p"},"servicename.namespace"),"."),(0,n.yg)("p",null,"The operator will use a ",(0,n.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/issuer/"},(0,n.yg)("inlineCode",{parentName:"a"},"ClusterIssuer"))," or an ",(0,n.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/issuer/"},(0,n.yg)("inlineCode",{parentName:"a"},"Issuer"))," to create the Certificate resource, which it expects to find in the same namespace as the ",(0,n.yg)("inlineCode",{parentName:"p"},"Pod")," with the annotation. The ",(0,n.yg)("inlineCode",{parentName:"p"},"Issuer")," is configured at deploy time, using the ",(0,n.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart"},"Helm chart"),"."),(0,n.yg)("p",null,"In the event that the default approver controller in ",(0,n.yg)("inlineCode",{parentName:"p"},"cert-manager")," is ",(0,n.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/certificaterequest/#approver-controller"},"disabled"),", the credentials operator can auto-approve its own ",(0,n.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/certificaterequest/"},(0,n.yg)("inlineCode",{parentName:"a"},"CertificateRequests")),". Enable this capability by ",(0,n.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart#cert-manager-parameters"},"configuring the Helm chart ",(0,n.yg)("inlineCode",{parentName:"a"},"autoApprove")," flag"),"."),(0,n.yg)("h5",{id:"otterize-cloud"},"Otterize Cloud"),(0,n.yg)("p",null,"The operator requests certificates from Otterize Cloud, which internally manages them in Hashicorp Vault. The certificates are then placed within a Kubernetes Secret named with the value of the annotation ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),"."),(0,n.yg)("h5",{id:"spire"},"SPIRE"),(0,n.yg)("p",null,"Once the operator has registered the pod with SPIRE, which happens automatically for a pod that has the ",(0,n.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name")," annotation upon pod startup. The credentials operator then acquires the SVID and certificates for the CA chain and places them within a Kubernetes Secret. The SVID and DNS names in the certificate is the identity of the service, as resolved by the ",(0,n.yg)("a",{parentName:"p",href:"#3-service-name-resolution-and-automatic-pod-labeling"},"service identity resolution algorithm"),", i.e. ",(0,n.yg)("inlineCode",{parentName:"p"},"servicename.namespace"),"."),(0,n.yg)("h2",{id:"spire-workload-registrar"},"SPIRE workload registrar"),(0,n.yg)("p",null,"When deployed with a SPIRE server, the operator registers every pod with the SPIRE server (even those without annotations).\nAlongside the credentials operator, you could use SPIRE agents and the SPIRE SDK to work with the same SPIRE server.\nTo learn more, check out the documentation for ",(0,n.yg)("a",{parentName:"p",href:"https://spiffe.io/docs/latest/spire-about/spire-concepts/"},"SPIRE"),". Note that to use the credentials operator, you do not need to work directly with SPIRE or SPIRE agents, and can do everything completely using annotations and Kubernetes Secrets."),(0,n.yg)("h2",{id:"pod-annotations"},"Pod annotations"),(0,n.yg)("table",null,(0,n.yg)("thead",{parentName:"table"},(0,n.yg)("tr",{parentName:"thead"},(0,n.yg)("th",{parentName:"tr",align:null},"Annotation"),(0,n.yg)("th",{parentName:"tr",align:null},"Description"),(0,n.yg)("th",{parentName:"tr",align:null},"Default"))),(0,n.yg)("tbody",{parentName:"table"},(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/tls-secret-name")),(0,n.yg)("td",{parentName:"tr",align:null},"If set, the operator will create a secret with this name with mTLS credentials for this pod."),(0,n.yg)("td",{parentName:"tr",align:null},"N/A")),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/dns-names")),(0,n.yg)("td",{parentName:"tr",align:null},"If set, overrides the list of subject alternative names in the certificate. Should include the hostname of Kubernetes services that will be used to access this pod."),(0,n.yg)("td",{parentName:"tr",align:null},"N/A")),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/cert-ttl")),(0,n.yg)("td",{parentName:"tr",align:null},"Override for the expiration time for the certificate in seconds."),(0,n.yg)("td",{parentName:"tr",align:null},"If deployed with the bundled SPIRE server, 1 day (86400).")),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/cert-type")),(0,n.yg)("td",{parentName:"tr",align:null},"Type of the credential bundle - ",(0,n.yg)("inlineCode",{parentName:"td"},"pem")," or ",(0,n.yg)("inlineCode",{parentName:"td"},"jks"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"pem"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/cert-file-name")),(0,n.yg)("td",{parentName:"tr",align:null},"Certificate key name in the secret. When mounted, this is the filename for the certificate (when using SPIRE it's the SVID file). Only used when cert-type is ",(0,n.yg)("inlineCode",{parentName:"td"},"pem"),". Not supported when ",(0,n.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,n.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"cert.pem"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/ca-file-name")),(0,n.yg)("td",{parentName:"tr",align:null},"Bundle (certificate chain bundle) key name in the secret. When mounted, this is the filename for the certificate chain. Only used when cert-type is ",(0,n.yg)("inlineCode",{parentName:"td"},"pem"),". Not supported when ",(0,n.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,n.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"ca.pem"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/key-file-name")),(0,n.yg)("td",{parentName:"tr",align:null},"Private key key name in the secret. When mounted, this is the filename for the private key. Only used when cert-type is ",(0,n.yg)("inlineCode",{parentName:"td"},"pem"),". Not supported when ",(0,n.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,n.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"key.pem"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/keystore-file-name")),(0,n.yg)("td",{parentName:"tr",align:null},"Keystore key name in the secret. When mounted, this is the filename for the keystore. Only used when cert-type is ",(0,n.yg)("inlineCode",{parentName:"td"},"jks"),". Not supported when ",(0,n.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,n.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"keystore.jks"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/truststore-file-name")),(0,n.yg)("td",{parentName:"tr",align:null},"Truststore key name in the secret. When mounted, this is the filename for the truststore. Only used when cert-type is ",(0,n.yg)("inlineCode",{parentName:"td"},"jks"),". Not supported when ",(0,n.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,n.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"truststore.jks"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/jks-password")),(0,n.yg)("td",{parentName:"tr",align:null},"Password for the JKS truststore and keystore. Only used when cert-type is ",(0,n.yg)("inlineCode",{parentName:"td"},"jks"),"."),(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"password"))),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/restart-pod-on-certificate-renewal")),(0,n.yg)("td",{parentName:"tr",align:null},"A pod with this annotation (no matter the value) will be restarted after certificate renewal, along with any replicas. Should be ideally set through the pod owner's ",(0,n.yg)("inlineCode",{parentName:"td"},"template")," spec so it will persist between restarts."),(0,n.yg)("td",{parentName:"tr",align:null},"N/A")),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/user-password-secret-name")),(0,n.yg)("td",{parentName:"tr",align:null},"If set, the operator will create a secret with this name containing user-password credentials for this pod."),(0,n.yg)("td",{parentName:"tr",align:null},"N/A")),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/restart-on-secret-rotation")),(0,n.yg)("td",{parentName:"tr",align:null},"A pod with this annotation (no matter the value) will be restarted after user-password secret rotation, along with any replicas. Should be ideally set through the pod owner's ",(0,n.yg)("inlineCode",{parentName:"td"},"template")," spec so it will persist between restarts."),(0,n.yg)("td",{parentName:"tr",align:null})),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},(0,n.yg)("inlineCode",{parentName:"td"},"intents.otterize.com/service-name")),(0,n.yg)("td",{parentName:"tr",align:null},"Used for ",(0,n.yg)("a",{parentName:"td",href:"/reference/service-identities#kubernetes-service-identity-resolution"},"service identity resolution"),"."),(0,n.yg)("td",{parentName:"tr",align:null})))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/87583c6c.d4b5f4ad.js b/assets/js/87583c6c.d4b5f4ad.js deleted file mode 100644 index f43b1648..00000000 --- a/assets/js/87583c6c.d4b5f4ad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1836],{5680:(e,t,r)=>{r.d(t,{xA:()=>d,yg:()=>h});var n=r(6540);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},c="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=p(r),m=a,h=c["".concat(l,".").concat(m)]||c[m]||g[m]||i;return r?n.createElement(h,o(o({ref:t},d),{},{components:r})):n.createElement(h,o({ref:t},d))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:a,o[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var n=r(8168),a=(r(6540),r(5680));const i={sidebar_position:3,title:"Credentials operator"},o=void 0,s={unversionedId:"reference/configuration/credentials-operator/README",id:"reference/configuration/credentials-operator/README",title:"Credentials operator",description:"The credentials operator provisions just-in-time credentials for workloads running on Kubernetes. These credentials come in the form of Kubernetes Secrets (mTLS certificates, database username + passwords), or AWS IAM roles.",source:"@site/docs/reference/configuration/credentials-operator/README.mdx",sourceDirName:"reference/configuration/credentials-operator",slug:"/reference/configuration/credentials-operator/",permalink:"/reference/configuration/credentials-operator/",draft:!1,editUrl:"https://github.com/otterize/docs/edit/main/docs/reference/configuration/credentials-operator/README.mdx",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,title:"Credentials operator"},sidebar:"docSidebar",previous:{title:"Configuring Kafka brokers",permalink:"/reference/configuration/intents-operator/configuration"},next:{title:"Helm chart",permalink:"/reference/configuration/credentials-operator/helm-chart"}},l={},p=[{value:"Deploying the credentials operator",id:"deploying-the-credentials-operator",level:2},{value:"Provisioning AWS IAM roles using the credentials operator",id:"provisioning-aws-iam-roles-using-the-credentials-operator",level:2},{value:"Provisioning mTLS certificates using the credentials operator",id:"provisioning-mtls-certificates-using-the-credentials-operator",level:2},{value:"Provisioning database username + password using the credentials operator",id:"provisioning-database-username--password-using-the-credentials-operator",level:2},{value:"How does the credentials operator provision certificates?",id:"how-does-the-credentials-operator-provision-certificates",level:3},{value:"Step 1: SPIRE entry registration",id:"step-1-spire-entry-registration",level:4},{value:"Step 2: Certificate generation",id:"step-2-certificate-generation",level:4},{value:"cert-manager",id:"cert-manager",level:5},{value:"Otterize Cloud",id:"otterize-cloud",level:5},{value:"SPIRE",id:"spire",level:5},{value:"SPIRE workload registrar",id:"spire-workload-registrar",level:2},{value:"Pod annotations",id:"pod-annotations",level:2}],d={toc:p},c="wrapper";function g(e){let{components:t,...r}=e;return(0,a.yg)(c,(0,n.A)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"The credentials operator provisions just-in-time credentials for workloads running on Kubernetes. These credentials come in the form of Kubernetes Secrets (mTLS certificates, database username + passwords), or AWS IAM roles."),(0,a.yg)("h2",{id:"deploying-the-credentials-operator"},"Deploying the credentials operator"),(0,a.yg)("p",null,"To deploy the operator, ",(0,a.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart"},"use the Helm chart"),"."),(0,a.yg)("p",null,"To deploy with Otterize Cloud as the certificate provider, we recommend you ",(0,a.yg)("a",{parentName:"p",href:"https://app.otterize.com/"},"follow the instructions in Otterize Cloud"),".\nTo deploy with cert-manager as the certificate provider, you must also ",(0,a.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart#cert-manager-parameters"},"configure the Issuer name and whether it should look for a ClusterIssuer or an Issuer (namespace-scoped)"),"."),(0,a.yg)("h2",{id:"provisioning-aws-iam-roles-using-the-credentials-operator"},"Provisioning AWS IAM roles using the credentials operator"),(0,a.yg)("p",null,"The credentials operator is controlled using annotations placed on pods. To have it provision an AWS IAM role, you must specify the pod annotation ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/create-aws-role"),", with the value being ",(0,a.yg)("inlineCode",{parentName:"p"},"true"),". Once you do so, the credentials operator will provision an AWS IAM role, and automatically bind it with the Kubernetes ServiceAccount of the pod by setting the EKS role ARN annotation on the ServiceAccount and the appropriate Trust Relationship on the AWS IAM role."),(0,a.yg)("h2",{id:"provisioning-mtls-certificates-using-the-credentials-operator"},"Provisioning mTLS certificates using the credentials operator"),(0,a.yg)("p",null,"The credentials operator is controlled using annotations placed on pods. To have it provision certificates and place them in Secrets, you must specify the pod annotation ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),", with the value being the name of the secret. Once you do so, the credentials operator will provision a certificate for the pod, using Otterize Cloud, cert-manager or SPIRE, depending how you've deployed it."),(0,a.yg)("h2",{id:"provisioning-database-username--password-using-the-credentials-operator"},"Provisioning database username + password using the credentials operator"),(0,a.yg)("p",null,"The credentials operator is controlled using annotations placed on pods. To have it provision database username + password and place them in Secrets, you must specify the pod annotation ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/user-password-secret-name"),", with the value being the name of the secret. Once you do so, the credentials operator will provision a username and password for the pod."),(0,a.yg)("h3",{id:"how-does-the-credentials-operator-provision-certificates"},"How does the credentials operator provision certificates?"),(0,a.yg)("p",null,"The credentials operator performs two steps in order to issue certificates."),(0,a.yg)("h4",{id:"step-1-spire-entry-registration"},"Step 1: SPIRE entry registration"),(0,a.yg)("p",null,"This step only happens if the operator is configured to use SPIRE for certificate generation. Once the operator ",(0,a.yg)("a",{parentName:"p",href:"#service-name-resolution-and-automatic-pod-labeling"},"resolves the service name")," for a pod, it labels the pod so that SPIRE can find it, and registers an entry with the SPIRE server for that label."),(0,a.yg)("h4",{id:"step-2-certificate-generation"},"Step 2: Certificate generation"),(0,a.yg)("p",null,"The operator consults the annotation ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),". If that annotation exists, the operator creates a secret named after the value of the label. That secret contains X.509 credentials within, provided by cert-manager, Otterize Cloud or SPIRE, depending on how the credentials operator is configured."),(0,a.yg)("h5",{id:"cert-manager"},"cert-manager"),(0,a.yg)("p",null,"The operator creates a cert-manager ",(0,a.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/usage/certificate/"},(0,a.yg)("inlineCode",{parentName:"a"},"Certificate"))," resource, which will create a Kubernetes Secret with the name specified by the value of the annotation ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),". The common name and DNS names in the certificate are values that represent the identity of the service, as resolved by the ",(0,a.yg)("a",{parentName:"p",href:"#3-service-name-resolution-and-automatic-pod-labeling"},"service identity resolution algorithm"),", i.e. ",(0,a.yg)("inlineCode",{parentName:"p"},"servicename.namespace"),"."),(0,a.yg)("p",null,"The operator will use a ",(0,a.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/issuer/"},(0,a.yg)("inlineCode",{parentName:"a"},"ClusterIssuer"))," or an ",(0,a.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/issuer/"},(0,a.yg)("inlineCode",{parentName:"a"},"Issuer"))," to create the Certificate resource, which it expects to find in the same namespace as the ",(0,a.yg)("inlineCode",{parentName:"p"},"Pod")," with the annotation. The ",(0,a.yg)("inlineCode",{parentName:"p"},"Issuer")," is configured at deploy time, using the ",(0,a.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart"},"Helm chart"),"."),(0,a.yg)("p",null,"In the event that the default approver controller in ",(0,a.yg)("inlineCode",{parentName:"p"},"cert-manager")," is ",(0,a.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/certificaterequest/#approver-controller"},"disabled"),", the credentials operator can auto-approve its own ",(0,a.yg)("a",{parentName:"p",href:"https://cert-manager.io/docs/concepts/certificaterequest/"},(0,a.yg)("inlineCode",{parentName:"a"},"CertificateRequests")),". Enable this capability by ",(0,a.yg)("a",{parentName:"p",href:"/reference/configuration/credentials-operator/helm-chart#cert-manager-parameters"},"configuring the Helm chart ",(0,a.yg)("inlineCode",{parentName:"a"},"autoApprove")," flag"),"."),(0,a.yg)("h5",{id:"otterize-cloud"},"Otterize Cloud"),(0,a.yg)("p",null,"The operator requests certificates from Otterize Cloud, which internally manages them in Hashicorp Vault. The certificates are then placed within a Kubernetes Secret named with the value of the annotation ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name"),"."),(0,a.yg)("h5",{id:"spire"},"SPIRE"),(0,a.yg)("p",null,"Once the operator has registered the pod with SPIRE, which happens automatically for a pod that has the ",(0,a.yg)("inlineCode",{parentName:"p"},"credentials-operator.otterize.com/tls-secret-name")," annotation upon pod startup. The credentials operator then acquires the SVID and certificates for the CA chain and places them within a Kubernetes Secret. The SVID and DNS names in the certificate is the identity of the service, as resolved by the ",(0,a.yg)("a",{parentName:"p",href:"#3-service-name-resolution-and-automatic-pod-labeling"},"service identity resolution algorithm"),", i.e. ",(0,a.yg)("inlineCode",{parentName:"p"},"servicename.namespace"),"."),(0,a.yg)("h2",{id:"spire-workload-registrar"},"SPIRE workload registrar"),(0,a.yg)("p",null,"When deployed with a SPIRE server, the operator registers every pod with the SPIRE server (even those without annotations).\nAlongside the credentials operator, you could use SPIRE agents and the SPIRE SDK to work with the same SPIRE server.\nTo learn more, check out the documentation for ",(0,a.yg)("a",{parentName:"p",href:"https://spiffe.io/docs/latest/spire-about/spire-concepts/"},"SPIRE"),". Note that to use the credentials operator, you do not need to work directly with SPIRE or SPIRE agents, and can do everything completely using annotations and Kubernetes Secrets."),(0,a.yg)("h2",{id:"pod-annotations"},"Pod annotations"),(0,a.yg)("table",null,(0,a.yg)("thead",{parentName:"table"},(0,a.yg)("tr",{parentName:"thead"},(0,a.yg)("th",{parentName:"tr",align:null},"Annotation"),(0,a.yg)("th",{parentName:"tr",align:null},"Description"),(0,a.yg)("th",{parentName:"tr",align:null},"Default"))),(0,a.yg)("tbody",{parentName:"table"},(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/tls-secret-name")),(0,a.yg)("td",{parentName:"tr",align:null},"If set, the operator will create a secret with this name with mTLS credentials for this pod."),(0,a.yg)("td",{parentName:"tr",align:null},"N/A")),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/dns-names")),(0,a.yg)("td",{parentName:"tr",align:null},"If set, overrides the list of subject alternative names in the certificate. Should include the hostname of Kubernetes services that will be used to access this pod."),(0,a.yg)("td",{parentName:"tr",align:null},"N/A")),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/cert-ttl")),(0,a.yg)("td",{parentName:"tr",align:null},"Override for the expiration time for the certificate in seconds."),(0,a.yg)("td",{parentName:"tr",align:null},"If deployed with the bundled SPIRE server, 1 day (86400).")),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/cert-type")),(0,a.yg)("td",{parentName:"tr",align:null},"Type of the credential bundle - ",(0,a.yg)("inlineCode",{parentName:"td"},"pem")," or ",(0,a.yg)("inlineCode",{parentName:"td"},"jks"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"pem"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/cert-file-name")),(0,a.yg)("td",{parentName:"tr",align:null},"Certificate key name in the secret. When mounted, this is the filename for the certificate (when using SPIRE it's the SVID file). Only used when cert-type is ",(0,a.yg)("inlineCode",{parentName:"td"},"pem"),". Not supported when ",(0,a.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,a.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"cert.pem"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/ca-file-name")),(0,a.yg)("td",{parentName:"tr",align:null},"Bundle (certificate chain bundle) key name in the secret. When mounted, this is the filename for the certificate chain. Only used when cert-type is ",(0,a.yg)("inlineCode",{parentName:"td"},"pem"),". Not supported when ",(0,a.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,a.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"ca.pem"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/key-file-name")),(0,a.yg)("td",{parentName:"tr",align:null},"Private key key name in the secret. When mounted, this is the filename for the private key. Only used when cert-type is ",(0,a.yg)("inlineCode",{parentName:"td"},"pem"),". Not supported when ",(0,a.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,a.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"key.pem"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/keystore-file-name")),(0,a.yg)("td",{parentName:"tr",align:null},"Keystore key name in the secret. When mounted, this is the filename for the keystore. Only used when cert-type is ",(0,a.yg)("inlineCode",{parentName:"td"},"jks"),". Not supported when ",(0,a.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,a.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"keystore.jks"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/truststore-file-name")),(0,a.yg)("td",{parentName:"tr",align:null},"Truststore key name in the secret. When mounted, this is the filename for the truststore. Only used when cert-type is ",(0,a.yg)("inlineCode",{parentName:"td"},"jks"),". Not supported when ",(0,a.yg)("inlineCode",{parentName:"td"},"certificateProvider")," is ",(0,a.yg)("inlineCode",{parentName:"td"},"cert-manager"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"truststore.jks"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/jks-password")),(0,a.yg)("td",{parentName:"tr",align:null},"Password for the JKS truststore and keystore. Only used when cert-type is ",(0,a.yg)("inlineCode",{parentName:"td"},"jks"),"."),(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"password"))),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"credentials-operator.otterize.com/restart-pod-on-certificate-renewal")),(0,a.yg)("td",{parentName:"tr",align:null},"A pod with this annotation (no matter the value) will be restarted after certificate renewal, along with any replicas. Should be ideally set through the pod owner's ",(0,a.yg)("inlineCode",{parentName:"td"},"template")," spec so it will persist between restarts."),(0,a.yg)("td",{parentName:"tr",align:null},"N/A")),(0,a.yg)("tr",{parentName:"tbody"},(0,a.yg)("td",{parentName:"tr",align:null},(0,a.yg)("inlineCode",{parentName:"td"},"intents.otterize.com/service-name")),(0,a.yg)("td",{parentName:"tr",align:null},"Used for ",(0,a.yg)("a",{parentName:"td",href:"/reference/service-identities#kubernetes-service-identity-resolution"},"service identity resolution"),"."),(0,a.yg)("td",{parentName:"tr",align:null})))))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.a1c4a5b4.js b/assets/js/runtime~main.3f3f1c5f.js similarity index 98% rename from assets/js/runtime~main.a1c4a5b4.js rename to assets/js/runtime~main.3f3f1c5f.js index c371e2cb..9655c9b5 100644 --- a/assets/js/runtime~main.a1c4a5b4.js +++ b/assets/js/runtime~main.3f3f1c5f.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,f,b,c,d={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return d[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=d,r.c=t,e=[],r.O=(a,f,b,c)=>{if(!f){var d=1/0;for(i=0;i=c)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,c0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[f,b,c]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,b){if(1&b&&(e=this(e)),8&b)return e;if("object"==typeof e&&e){if(4&b&&e.__esModule)return e;if(16&b&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var d={};a=a||[null,f({}),f([]),f(f)];for(var t=2&b&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>d[a]=()=>e[a]));return d.default=()=>e,r.d(c,d),c},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({760:"13f991ea",765:"6f40fd2f",801:"bb52994a",805:"b6b04eda",918:"01027e3c",1040:"f1151ea7",1205:"698135b2",1295:"97c2207d",1386:"a43681c9",1538:"40ccd1ee",1601:"013a04c2",1625:"f7d1f224",1709:"e93b0177",1733:"fab3c742",1836:"87583c6c",1886:"9a9c42f7",1907:"a630a6fc",1952:"5e4199df",2138:"1a4e3797",2148:"13e8e5b0",2194:"3fbbf99b",2229:"8e233326",2242:"96faae56",2324:"93fb3e94",2343:"be46e07c",2368:"2894b329",2653:"4a90ba61",2703:"6bd33d99",2706:"7b307392",2934:"751ef2b5",3024:"fef0a614",3381:"f8b70272",4194:"2c09ee5d",4312:"89d24bb8",4496:"dcc76ebc",4713:"44e49d37",4911:"a28f5f9a",4940:"f26efbc5",5066:"dff029d6",5106:"fba06901",5290:"ed63a978",5305:"797a5a6f",5548:"247783bb",5582:"da523844",5864:"671fd195",5878:"6303d649",5894:"f1a90138",6326:"42fb6e35",6587:"2e135cc6",6589:"efaf9258",6633:"c6ec7a52",6964:"6ee27f91",7199:"51639cf9",7202:"fec8a912",7255:"64420156",7317:"4d029c8d",8102:"96b2b7a2",8263:"fb8f3a82",8397:"62ac5b94",8401:"17896441",8502:"d05b304a",8581:"935f2afb",8595:"a3ff3870",8626:"944eab8f",8639:"9a6944ab",8714:"1be78505",8750:"ceba1265",8968:"59b068d1",9060:"4388075d",9184:"3ba2fa8f",9441:"c38cf504",9514:"4291f23d",9581:"f89eda61",9715:"b1654ad1",9990:"2bd353df"}[e]||e)+"."+{416:"5a82d981",760:"ff662baa",765:"21d36fb9",801:"4d9cd4d8",805:"68a50ecd",918:"1299f9a1",1040:"b6365de7",1205:"080f42cf",1295:"329b7ba8",1386:"8469fc27",1427:"db807010",1538:"58779a6e",1601:"fc45ce5e",1625:"354ae921",1709:"7754b93d",1733:"edf0efef",1774:"9ea8a3a2",1836:"d4b5f4ad",1886:"75113969",1907:"8904fcd8",1952:"89e69ac5",2138:"b3d3408a",2148:"5fc4ed15",2194:"0285d213",2229:"d3d2c4f4",2242:"feb3beba",2324:"bc45af9d",2343:"274b90ff",2368:"dc2b31bc",2653:"ef77e495",2703:"40cc61c9",2706:"36b34522",2934:"ed338caa",3024:"d0c7bb15",3381:"b387f121",4194:"cccc630c",4312:"25e48f8c",4496:"ec21e679",4713:"1717d835",4911:"09d958b2",4940:"57e7591b",5066:"5b15b888",5106:"baef74eb",5290:"9b969f70",5305:"604c0287",5548:"54c9fe51",5582:"051940bd",5864:"31425a69",5878:"c96fb342",5894:"8b6c041c",6140:"25b4571d",6326:"cdd85e86",6587:"4dc5ca9a",6589:"60ccc42b",6633:"360a7e79",6964:"31f4b69d",7199:"b2d2a9e0",7202:"9c52c13d",7255:"45a8e519",7317:"078ac474",8102:"bce72d60",8263:"8f9da060",8397:"f6ec7d8a",8401:"57dfb6c6",8502:"cf0eda4b",8581:"09c75987",8595:"2d74a1ff",8626:"b2a2d847",8639:"9f62fd9a",8714:"de56d63e",8750:"aca67551",8913:"64e5ee35",8968:"11ea3e06",9060:"e23af36f",9184:"d2ac052b",9441:"0b454f35",9462:"a16127cd",9514:"5c71d58e",9581:"bc4eba67",9715:"116e133d",9990:"cdf9b5f7"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),b={},c="docs:",r.l=(e,a,f,d)=>{if(b[e])b[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var c=b[e];if(delete b[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(f))),a)return a(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",64420156:"7255","13f991ea":"760","6f40fd2f":"765",bb52994a:"801",b6b04eda:"805","01027e3c":"918",f1151ea7:"1040","698135b2":"1205","97c2207d":"1295",a43681c9:"1386","40ccd1ee":"1538","013a04c2":"1601",f7d1f224:"1625",e93b0177:"1709",fab3c742:"1733","87583c6c":"1836","9a9c42f7":"1886",a630a6fc:"1907","5e4199df":"1952","1a4e3797":"2138","13e8e5b0":"2148","3fbbf99b":"2194","8e233326":"2229","96faae56":"2242","93fb3e94":"2324",be46e07c:"2343","2894b329":"2368","4a90ba61":"2653","6bd33d99":"2703","7b307392":"2706","751ef2b5":"2934",fef0a614:"3024",f8b70272:"3381","2c09ee5d":"4194","89d24bb8":"4312",dcc76ebc:"4496","44e49d37":"4713",a28f5f9a:"4911",f26efbc5:"4940",dff029d6:"5066",fba06901:"5106",ed63a978:"5290","797a5a6f":"5305","247783bb":"5548",da523844:"5582","671fd195":"5864","6303d649":"5878",f1a90138:"5894","42fb6e35":"6326","2e135cc6":"6587",efaf9258:"6589",c6ec7a52:"6633","6ee27f91":"6964","51639cf9":"7199",fec8a912:"7202","4d029c8d":"7317","96b2b7a2":"8102",fb8f3a82:"8263","62ac5b94":"8397",d05b304a:"8502","935f2afb":"8581",a3ff3870:"8595","944eab8f":"8626","9a6944ab":"8639","1be78505":"8714",ceba1265:"8750","59b068d1":"8968","4388075d":"9060","3ba2fa8f":"9184",c38cf504:"9441","4291f23d":"9514",f89eda61:"9581",b1654ad1:"9715","2bd353df":"9990"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var b=r.o(e,a)?e[a]:void 0;if(0!==b)if(b)f.push(b[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var c=new Promise(((f,c)=>b=e[a]=[f,c]));f.push(b[2]=c);var d=r.p+r.u(a),t=new Error;r.l(d,(f=>{if(r.o(e,a)&&(0!==(b=e[a])&&(e[a]=void 0),b)){var c=f&&("load"===f.type?"missing":f.type),d=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+c+": "+d+")",t.name="ChunkLoadError",t.type=c,t.request=d,b[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var b,c,d=f[0],t=f[1],o=f[2],n=0;if(d.some((a=>0!==e[a]))){for(b in t)r.o(t,b)&&(r.m[b]=t[b]);if(o)var i=o(r)}for(a&&a(f);n{"use strict";var e,a,f,b,c,d={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return d[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=d,r.c=t,e=[],r.O=(a,f,b,c)=>{if(!f){var d=1/0;for(i=0;i=c)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,c0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[f,b,c]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,b){if(1&b&&(e=this(e)),8&b)return e;if("object"==typeof e&&e){if(4&b&&e.__esModule)return e;if(16&b&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var d={};a=a||[null,f({}),f([]),f(f)];for(var t=2&b&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>d[a]=()=>e[a]));return d.default=()=>e,r.d(c,d),c},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({760:"13f991ea",765:"6f40fd2f",801:"bb52994a",805:"b6b04eda",918:"01027e3c",1040:"f1151ea7",1205:"698135b2",1295:"97c2207d",1386:"a43681c9",1538:"40ccd1ee",1601:"013a04c2",1625:"f7d1f224",1709:"e93b0177",1733:"fab3c742",1836:"87583c6c",1886:"9a9c42f7",1907:"a630a6fc",1952:"5e4199df",2138:"1a4e3797",2148:"13e8e5b0",2194:"3fbbf99b",2229:"8e233326",2242:"96faae56",2324:"93fb3e94",2343:"be46e07c",2368:"2894b329",2653:"4a90ba61",2703:"6bd33d99",2706:"7b307392",2934:"751ef2b5",3024:"fef0a614",3381:"f8b70272",4194:"2c09ee5d",4312:"89d24bb8",4496:"dcc76ebc",4713:"44e49d37",4911:"a28f5f9a",4940:"f26efbc5",5066:"dff029d6",5106:"fba06901",5290:"ed63a978",5305:"797a5a6f",5548:"247783bb",5582:"da523844",5864:"671fd195",5878:"6303d649",5894:"f1a90138",6326:"42fb6e35",6587:"2e135cc6",6589:"efaf9258",6633:"c6ec7a52",6964:"6ee27f91",7199:"51639cf9",7202:"fec8a912",7255:"64420156",7317:"4d029c8d",8102:"96b2b7a2",8263:"fb8f3a82",8397:"62ac5b94",8401:"17896441",8502:"d05b304a",8581:"935f2afb",8595:"a3ff3870",8626:"944eab8f",8639:"9a6944ab",8714:"1be78505",8750:"ceba1265",8968:"59b068d1",9060:"4388075d",9184:"3ba2fa8f",9441:"c38cf504",9514:"4291f23d",9581:"f89eda61",9715:"b1654ad1",9990:"2bd353df"}[e]||e)+"."+{416:"5a82d981",760:"ff662baa",765:"21d36fb9",801:"4d9cd4d8",805:"68a50ecd",918:"1299f9a1",1040:"b6365de7",1205:"080f42cf",1295:"329b7ba8",1386:"8469fc27",1427:"db807010",1538:"58779a6e",1601:"fc45ce5e",1625:"354ae921",1709:"7754b93d",1733:"edf0efef",1774:"9ea8a3a2",1836:"6d8524a7",1886:"75113969",1907:"8904fcd8",1952:"89e69ac5",2138:"b3d3408a",2148:"5fc4ed15",2194:"0285d213",2229:"d3d2c4f4",2242:"feb3beba",2324:"bc45af9d",2343:"274b90ff",2368:"dc2b31bc",2653:"ef77e495",2703:"40cc61c9",2706:"36b34522",2934:"ed338caa",3024:"d0c7bb15",3381:"b387f121",4194:"cccc630c",4312:"25e48f8c",4496:"ec21e679",4713:"1717d835",4911:"09d958b2",4940:"57e7591b",5066:"5b15b888",5106:"baef74eb",5290:"9b969f70",5305:"604c0287",5548:"54c9fe51",5582:"051940bd",5864:"31425a69",5878:"c96fb342",5894:"8b6c041c",6140:"25b4571d",6326:"cdd85e86",6587:"4dc5ca9a",6589:"60ccc42b",6633:"360a7e79",6964:"31f4b69d",7199:"b2d2a9e0",7202:"9c52c13d",7255:"45a8e519",7317:"078ac474",8102:"bce72d60",8263:"8f9da060",8397:"f6ec7d8a",8401:"57dfb6c6",8502:"cf0eda4b",8581:"09c75987",8595:"2d74a1ff",8626:"b2a2d847",8639:"9f62fd9a",8714:"de56d63e",8750:"aca67551",8913:"64e5ee35",8968:"11ea3e06",9060:"e23af36f",9184:"d2ac052b",9441:"0b454f35",9462:"a16127cd",9514:"5c71d58e",9581:"bc4eba67",9715:"116e133d",9990:"cdf9b5f7"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),b={},c="docs:",r.l=(e,a,f,d)=>{if(b[e])b[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var c=b[e];if(delete b[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(f))),a)return a(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",64420156:"7255","13f991ea":"760","6f40fd2f":"765",bb52994a:"801",b6b04eda:"805","01027e3c":"918",f1151ea7:"1040","698135b2":"1205","97c2207d":"1295",a43681c9:"1386","40ccd1ee":"1538","013a04c2":"1601",f7d1f224:"1625",e93b0177:"1709",fab3c742:"1733","87583c6c":"1836","9a9c42f7":"1886",a630a6fc:"1907","5e4199df":"1952","1a4e3797":"2138","13e8e5b0":"2148","3fbbf99b":"2194","8e233326":"2229","96faae56":"2242","93fb3e94":"2324",be46e07c:"2343","2894b329":"2368","4a90ba61":"2653","6bd33d99":"2703","7b307392":"2706","751ef2b5":"2934",fef0a614:"3024",f8b70272:"3381","2c09ee5d":"4194","89d24bb8":"4312",dcc76ebc:"4496","44e49d37":"4713",a28f5f9a:"4911",f26efbc5:"4940",dff029d6:"5066",fba06901:"5106",ed63a978:"5290","797a5a6f":"5305","247783bb":"5548",da523844:"5582","671fd195":"5864","6303d649":"5878",f1a90138:"5894","42fb6e35":"6326","2e135cc6":"6587",efaf9258:"6589",c6ec7a52:"6633","6ee27f91":"6964","51639cf9":"7199",fec8a912:"7202","4d029c8d":"7317","96b2b7a2":"8102",fb8f3a82:"8263","62ac5b94":"8397",d05b304a:"8502","935f2afb":"8581",a3ff3870:"8595","944eab8f":"8626","9a6944ab":"8639","1be78505":"8714",ceba1265:"8750","59b068d1":"8968","4388075d":"9060","3ba2fa8f":"9184",c38cf504:"9441","4291f23d":"9514",f89eda61:"9581",b1654ad1:"9715","2bd353df":"9990"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var b=r.o(e,a)?e[a]:void 0;if(0!==b)if(b)f.push(b[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var c=new Promise(((f,c)=>b=e[a]=[f,c]));f.push(b[2]=c);var d=r.p+r.u(a),t=new Error;r.l(d,(f=>{if(r.o(e,a)&&(0!==(b=e[a])&&(e[a]=void 0),b)){var c=f&&("load"===f.type?"missing":f.type),d=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+c+": "+d+")",t.name="ChunkLoadError",t.type=c,t.request=d,b[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var b,c,d=f[0],t=f[1],o=f[2],n=0;if(d.some((a=>0!==e[a]))){for(b in t)r.o(t,b)&&(r.m[b]=t[b]);if(o)var i=o(r)}for(a&&a(f);n - + @@ -197,7 +197,7 @@ - + \ No newline at end of file diff --git a/features.html b/features.html index 9a211e65..e8e32550 100644 --- a/features.html +++ b/features.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/aws-iam.html b/features/aws-iam.html index 47e747a7..27efeaa8 100644 --- a/features/aws-iam.html +++ b/features/aws-iam.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/aws-iam/reference.html b/features/aws-iam/reference.html index 0e35fca7..cb3c4a42 100644 --- a/features/aws-iam/reference.html +++ b/features/aws-iam/reference.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/features/aws-iam/tutorials/aws-iam-eks.html b/features/aws-iam/tutorials/aws-iam-eks.html index 7061e589..e0bf6641 100644 --- a/features/aws-iam/tutorials/aws-iam-eks.html +++ b/features/aws-iam/tutorials/aws-iam-eks.html @@ -14,7 +14,7 @@ - + @@ -159,7 +159,7 @@ - + \ No newline at end of file diff --git a/features/aws-iam/tutorials/aws-visibility.html b/features/aws-iam/tutorials/aws-visibility.html index edffddd2..b9479be4 100644 --- a/features/aws-iam/tutorials/aws-visibility.html +++ b/features/aws-iam/tutorials/aws-visibility.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/azure-iam.html b/features/azure-iam.html index d53b2f0e..c0474f44 100644 --- a/features/azure-iam.html +++ b/features/azure-iam.html @@ -14,7 +14,7 @@ - + @@ -157,7 +157,7 @@ - + \ No newline at end of file diff --git a/features/azure-iam/reference.html b/features/azure-iam/reference.html index f147ef7f..d74d922f 100644 --- a/features/azure-iam/reference.html +++ b/features/azure-iam/reference.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/features/azure-iam/tutorials/azure-iam-aks.html b/features/azure-iam/tutorials/azure-iam-aks.html index 60db3396..6745fcde 100644 --- a/features/azure-iam/tutorials/azure-iam-aks.html +++ b/features/azure-iam/tutorials/azure-iam-aks.html @@ -14,7 +14,7 @@ - + @@ -163,7 +163,7 @@ - + \ No newline at end of file diff --git a/features/gcp-iam.html b/features/gcp-iam.html index 9d0f3c9f..8aaf6837 100644 --- a/features/gcp-iam.html +++ b/features/gcp-iam.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/gcp-iam/reference.html b/features/gcp-iam/reference.html index ff4ea22c..f48422cb 100644 --- a/features/gcp-iam/reference.html +++ b/features/gcp-iam/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/gcp-iam/tutorials/gcp-iam-gke.html b/features/gcp-iam/tutorials/gcp-iam-gke.html index 1f98b70b..e4e1f34f 100644 --- a/features/gcp-iam/tutorials/gcp-iam-gke.html +++ b/features/gcp-iam/tutorials/gcp-iam-gke.html @@ -14,7 +14,7 @@ - + @@ -163,7 +163,7 @@ - + \ No newline at end of file diff --git a/features/github.html b/features/github.html index 82894fa1..2bbf0695 100644 --- a/features/github.html +++ b/features/github.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/github/reference.html b/features/github/reference.html index 786c5e0d..7ff2e38e 100644 --- a/features/github/reference.html +++ b/features/github/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/github/tutorials/automated-pull-requests.html b/features/github/tutorials/automated-pull-requests.html index 0ef610b9..d3b15590 100644 --- a/features/github/tutorials/automated-pull-requests.html +++ b/features/github/tutorials/automated-pull-requests.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/gitlab.html b/features/gitlab.html index 1d1528e0..a61afa1d 100644 --- a/features/gitlab.html +++ b/features/gitlab.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/gitlab/reference.html b/features/gitlab/reference.html index 63d0fd45..f594c749 100644 --- a/features/gitlab/reference.html +++ b/features/gitlab/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/gitlab/tutorials/automated-merge-requests.html b/features/gitlab/tutorials/automated-merge-requests.html index 17dad5a8..a26de29d 100644 --- a/features/gitlab/tutorials/automated-merge-requests.html +++ b/features/gitlab/tutorials/automated-merge-requests.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/istio.html b/features/istio.html index 0c7f3ec6..d09ec6f0 100644 --- a/features/istio.html +++ b/features/istio.html @@ -14,7 +14,7 @@ - + @@ -156,7 +156,7 @@ - + \ No newline at end of file diff --git a/features/istio/reference.html b/features/istio/reference.html index e9637e77..d99568c4 100644 --- a/features/istio/reference.html +++ b/features/istio/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/istio/tutorials/k8s-istio-authorization-policies.html b/features/istio/tutorials/k8s-istio-authorization-policies.html index 9c8761f8..2008eaef 100644 --- a/features/istio/tutorials/k8s-istio-authorization-policies.html +++ b/features/istio/tutorials/k8s-istio-authorization-policies.html @@ -14,7 +14,7 @@ - + @@ -171,7 +171,7 @@ - + \ No newline at end of file diff --git a/features/istio/tutorials/k8s-istio-watcher.html b/features/istio/tutorials/k8s-istio-watcher.html index 8ca4bf88..2a46ca82 100644 --- a/features/istio/tutorials/k8s-istio-watcher.html +++ b/features/istio/tutorials/k8s-istio-watcher.html @@ -14,7 +14,7 @@ - + @@ -164,7 +164,7 @@ - + \ No newline at end of file diff --git a/features/kafka.html b/features/kafka.html index 57ffa0a3..27346d10 100644 --- a/features/kafka.html +++ b/features/kafka.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/features/kafka/reference.html b/features/kafka/reference.html index b2ad8bd6..5c2b6b07 100644 --- a/features/kafka/reference.html +++ b/features/kafka/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/kafka/tutorials/k8s-kafka-mapping.html b/features/kafka/tutorials/k8s-kafka-mapping.html index d71b5fab..edb3534f 100644 --- a/features/kafka/tutorials/k8s-kafka-mapping.html +++ b/features/kafka/tutorials/k8s-kafka-mapping.html @@ -14,7 +14,7 @@ - + @@ -160,7 +160,7 @@ - + \ No newline at end of file diff --git a/features/kafka/tutorials/k8s-kafka-mtls-cert-manager.html b/features/kafka/tutorials/k8s-kafka-mtls-cert-manager.html index 3190adf3..b5f1d0ed 100644 --- a/features/kafka/tutorials/k8s-kafka-mtls-cert-manager.html +++ b/features/kafka/tutorials/k8s-kafka-mtls-cert-manager.html @@ -14,7 +14,7 @@ - + @@ -164,7 +164,7 @@ - + \ No newline at end of file diff --git a/features/kafka/tutorials/k8s-kafka-mtls.html b/features/kafka/tutorials/k8s-kafka-mtls.html index 8f4a2bcf..f4da2651 100644 --- a/features/kafka/tutorials/k8s-kafka-mtls.html +++ b/features/kafka/tutorials/k8s-kafka-mtls.html @@ -14,7 +14,7 @@ - + @@ -163,7 +163,7 @@ - + \ No newline at end of file diff --git a/features/mysql.html b/features/mysql.html index 85295d5a..60f08e26 100644 --- a/features/mysql.html +++ b/features/mysql.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/mysql/reference.html b/features/mysql/reference.html index 93aca488..7315fdce 100644 --- a/features/mysql/reference.html +++ b/features/mysql/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/mysql/tutorials/mysql.html b/features/mysql/tutorials/mysql.html index 2bcd239c..4d55a772 100644 --- a/features/mysql/tutorials/mysql.html +++ b/features/mysql/tutorials/mysql.html @@ -14,7 +14,7 @@ - + @@ -159,7 +159,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies.html b/features/network-mapping-network-policies.html index 6f00efd6..6f557116 100644 --- a/features/network-mapping-network-policies.html +++ b/features/network-mapping-network-policies.html @@ -14,7 +14,7 @@ - + @@ -157,7 +157,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/reference.html b/features/network-mapping-network-policies/reference.html index cadf23e8..13f0a487 100644 --- a/features/network-mapping-network-policies/reference.html +++ b/features/network-mapping-network-policies/reference.html @@ -14,7 +14,7 @@ - + @@ -161,7 +161,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/reference/Network-Policies-Deep-Dive.html b/features/network-mapping-network-policies/reference/Network-Policies-Deep-Dive.html index b6fae89a..32c7a562 100644 --- a/features/network-mapping-network-policies/reference/Network-Policies-Deep-Dive.html +++ b/features/network-mapping-network-policies/reference/Network-Policies-Deep-Dive.html @@ -14,7 +14,7 @@ - + @@ -166,7 +166,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/tutorials/aws-eks-cni-mini.html b/features/network-mapping-network-policies/tutorials/aws-eks-cni-mini.html index 1bcd1a21..5ef30387 100644 --- a/features/network-mapping-network-policies/tutorials/aws-eks-cni-mini.html +++ b/features/network-mapping-network-policies/tutorials/aws-eks-cni-mini.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/tutorials/k8s-egress-access-control-tutorial.html b/features/network-mapping-network-policies/tutorials/k8s-egress-access-control-tutorial.html index 53b93f8e..65144c0f 100644 --- a/features/network-mapping-network-policies/tutorials/k8s-egress-access-control-tutorial.html +++ b/features/network-mapping-network-policies/tutorials/k8s-egress-access-control-tutorial.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/tutorials/k8s-network-mapper.html b/features/network-mapping-network-policies/tutorials/k8s-network-mapper.html index 54b7cc72..bce9a386 100644 --- a/features/network-mapping-network-policies/tutorials/k8s-network-mapper.html +++ b/features/network-mapping-network-policies/tutorials/k8s-network-mapper.html @@ -14,7 +14,7 @@ - + @@ -163,7 +163,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/tutorials/k8s-network-policies.html b/features/network-mapping-network-policies/tutorials/k8s-network-policies.html index 6314a952..23eef29f 100644 --- a/features/network-mapping-network-policies/tutorials/k8s-network-policies.html +++ b/features/network-mapping-network-policies/tutorials/k8s-network-policies.html @@ -14,7 +14,7 @@ - + @@ -173,7 +173,7 @@ - + \ No newline at end of file diff --git a/features/network-mapping-network-policies/tutorials/protect-1-service-network-policies.html b/features/network-mapping-network-policies/tutorials/protect-1-service-network-policies.html index 670279a4..0003c666 100644 --- a/features/network-mapping-network-policies/tutorials/protect-1-service-network-policies.html +++ b/features/network-mapping-network-policies/tutorials/protect-1-service-network-policies.html @@ -14,7 +14,7 @@ - + @@ -157,7 +157,7 @@ - + \ No newline at end of file diff --git a/features/postgresql.html b/features/postgresql.html index 875cc412..4624f648 100644 --- a/features/postgresql.html +++ b/features/postgresql.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/features/postgresql/reference.html b/features/postgresql/reference.html index 2e9e85c7..c9c8a68f 100644 --- a/features/postgresql/reference.html +++ b/features/postgresql/reference.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/features/postgresql/tutorials/postgres-mapping.html b/features/postgresql/tutorials/postgres-mapping.html index 276d404b..4d6496bb 100644 --- a/features/postgresql/tutorials/postgres-mapping.html +++ b/features/postgresql/tutorials/postgres-mapping.html @@ -14,7 +14,7 @@ - + @@ -175,7 +175,7 @@ - + \ No newline at end of file diff --git a/features/postgresql/tutorials/postgres.html b/features/postgresql/tutorials/postgres.html index bf4bf26c..ae3f3666 100644 --- a/features/postgresql/tutorials/postgres.html +++ b/features/postgresql/tutorials/postgres.html @@ -14,7 +14,7 @@ - + @@ -158,7 +158,7 @@ - + \ No newline at end of file diff --git a/index.html b/index.html index 7f2e0639..1e2ad357 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/overview.html b/overview.html index 359d0af3..77079376 100644 --- a/overview.html +++ b/overview.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/overview/installation.html b/overview/installation.html index 147156c5..cabd9be2 100644 --- a/overview/installation.html +++ b/overview/installation.html @@ -14,7 +14,7 @@ - + @@ -161,7 +161,7 @@ - + \ No newline at end of file diff --git a/overview/intent-based-access-control.html b/overview/intent-based-access-control.html index 4da3b673..31baa4bc 100644 --- a/overview/intent-based-access-control.html +++ b/overview/intent-based-access-control.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/overview/otterize-cloud.html b/overview/otterize-cloud.html index 98815336..959f181a 100644 --- a/overview/otterize-cloud.html +++ b/overview/otterize-cloud.html @@ -14,7 +14,7 @@ - + @@ -169,7 +169,7 @@ - + \ No newline at end of file diff --git a/overview/otterize-oss.html b/overview/otterize-oss.html index 661dceab..ac7560f9 100644 --- a/overview/otterize-oss.html +++ b/overview/otterize-oss.html @@ -14,7 +14,7 @@ - + @@ -159,7 +159,7 @@ - + \ No newline at end of file diff --git a/overview/otterize-oss/error-telemetry.html b/overview/otterize-oss/error-telemetry.html index d8fdb9aa..2347b6f8 100644 --- a/overview/otterize-oss/error-telemetry.html +++ b/overview/otterize-oss/error-telemetry.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/overview/otterize-oss/usage-telemetry.html b/overview/otterize-oss/usage-telemetry.html index 10aa7c9e..b4b799af 100644 --- a/overview/otterize-oss/usage-telemetry.html +++ b/overview/otterize-oss/usage-telemetry.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/reference/IBAC-Overview.html b/reference/IBAC-Overview.html index 35da692d..5451c9d7 100644 --- a/reference/IBAC-Overview.html +++ b/reference/IBAC-Overview.html @@ -14,7 +14,7 @@ - + @@ -182,7 +182,7 @@ - + \ No newline at end of file diff --git a/reference/api.html b/reference/api.html index 9aab93f7..56b13950 100644 --- a/reference/api.html +++ b/reference/api.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/reference/cli.html b/reference/cli.html index 76a0a845..ce0b2f21 100644 --- a/reference/cli.html +++ b/reference/cli.html @@ -14,7 +14,7 @@ - + @@ -172,7 +172,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/credentials-operator.html b/reference/configuration/credentials-operator.html index a91611ad..aede1c69 100644 --- a/reference/configuration/credentials-operator.html +++ b/reference/configuration/credentials-operator.html @@ -14,7 +14,7 @@ - + @@ -60,9 +60,9 @@

Credentials operator

The credentials operator provisions just-in-time credentials for workloads running on Kubernetes. These credentials come in the form of Kubernetes Secrets (mTLS certificates, database username + passwords), or AWS IAM roles.

Deploying the credentials operator

To deploy the operator, use the Helm chart.

To deploy with Otterize Cloud as the certificate provider, we recommend you follow the instructions in Otterize Cloud. -To deploy with cert-manager as the certificate provider, you must also configure the Issuer name and whether it should look for a ClusterIssuer or an Issuer (namespace-scoped).

Provisioning AWS IAM roles using the credentials operator

The credentials operator is controlled using annotations placed on pods. To have it provision an AWS IAM role, you must specify the pod annotation credentials-operator.otterize.com/create-aws-role, with the value being true. Once you do so, the credentials operator will provision an AWS IAM role, and automatically bind it with the Kubernetes ServiceAccount of the pod by setting the EKS role ARN annotation on the ServiceAccount and the appropriate Trust Relationship on the AWS IAM role.

Provisioning mTLS certificates using the credentials operator

The credentials operator is controlled using annotations placed on pods. To have it provision certificates and place them in Secrets, you must specify the pod annotation credentials-operator.otterize.com/tls-secret-name, with the value being the name of the secret. Once you do so, the credentials operator will provision a certificate for the pod, using Otterize Cloud, cert-manager or SPIRE, depending how you've deployed it.

Provisioning database username + password using the credentials operator

The credentials operator is controlled using annotations placed on pods. To have it provision database username + password and place them in Secrets, you must specify the pod annotation credentials-operator.otterize.com/user-password-secret-name, with the value being the name of the secret. Once you do so, the credentials operator will provision a username and password for the pod.

How does the credentials operator provision certificates?

The credentials operator performs two steps in order to issue certificates.

Step 1: SPIRE entry registration

This step only happens if the operator is configured to use SPIRE for certificate generation. Once the operator resolves the service name for a pod, it labels the pod so that SPIRE can find it, and registers an entry with the SPIRE server for that label.

Step 2: Certificate generation

The operator consults the annotation credentials-operator.otterize.com/tls-secret-name. If that annotation exists, the operator creates a secret named after the value of the label. That secret contains X.509 credentials within, provided by cert-manager, Otterize Cloud or SPIRE, depending on how the credentials operator is configured.

cert-manager

The operator creates a cert-manager Certificate resource, which will create a Kubernetes Secret with the name specified by the value of the annotation credentials-operator.otterize.com/tls-secret-name. The common name and DNS names in the certificate are values that represent the identity of the service, as resolved by the service identity resolution algorithm, i.e. servicename.namespace.

The operator will use a ClusterIssuer or an Issuer to create the Certificate resource, which it expects to find in the same namespace as the Pod with the annotation. The Issuer is configured at deploy time, using the Helm chart.

In the event that the default approver controller in cert-manager is disabled, the credentials operator can auto-approve its own CertificateRequests. Enable this capability by configuring the Helm chart autoApprove flag.

Otterize Cloud

The operator requests certificates from Otterize Cloud, which internally manages them in Hashicorp Vault. The certificates are then placed within a Kubernetes Secret named with the value of the annotation credentials-operator.otterize.com/tls-secret-name.

SPIRE

Once the operator has registered the pod with SPIRE, which happens automatically for a pod that has the credentials-operator.otterize.com/tls-secret-name annotation upon pod startup. The credentials operator then acquires the SVID and certificates for the CA chain and places them within a Kubernetes Secret. The SVID and DNS names in the certificate is the identity of the service, as resolved by the service identity resolution algorithm, i.e. servicename.namespace.

SPIRE workload registrar

When deployed with a SPIRE server, the operator registers every pod with the SPIRE server (even those without annotations). +To deploy with cert-manager as the certificate provider, you must also configure the Issuer name and whether it should look for a ClusterIssuer or an Issuer (namespace-scoped).

Provisioning AWS IAM roles using the credentials operator

The credentials operator is controlled using annotations placed on pods. To have it provision an AWS IAM role, you must specify the pod annotation credentials-operator.otterize.com/create-aws-role, with the value being true. Once you do so, the credentials operator will provision an AWS IAM role, and automatically bind it with the Kubernetes ServiceAccount of the pod by setting the EKS role ARN annotation on the ServiceAccount and the appropriate Trust Relationship on the AWS IAM role.

Provisioning mTLS certificates using the credentials operator

The credentials operator is controlled using annotations placed on pods. To have it provision certificates and place them in Secrets, you must specify the pod annotation credentials-operator.otterize.com/tls-secret-name, with the value being the name of the secret. Once you do so, the credentials operator will provision a certificate for the pod, using Otterize Cloud, cert-manager or SPIRE, depending how you've deployed it.

Provisioning database username + password using the credentials operator

The credentials operator is controlled using annotations placed on pods. To have it provision database username + password and place them in Secrets, you must specify the pod annotation credentials-operator.otterize.com/user-password-secret-name, with the value being the name of the secret. Once you do so, the credentials operator will provision a username and password for the pod.

Secrets are automatically rotated (defaults to every 8 hours). This value can be controlled using the databaseSecretRotationInterval key in the credentials operator values.yaml.

If you want pods to be restarted automatically after secret rotation, set the annotation credentials-operator.otterize.com/restart-on-secret-rotation on the pod (no matter the value).

How does the credentials operator provision certificates?

The credentials operator performs two steps in order to issue certificates.

Step 1: SPIRE entry registration

This step only happens if the operator is configured to use SPIRE for certificate generation. Once the operator resolves the service name for a pod, it labels the pod so that SPIRE can find it, and registers an entry with the SPIRE server for that label.

Step 2: Certificate generation

The operator consults the annotation credentials-operator.otterize.com/tls-secret-name. If that annotation exists, the operator creates a secret named after the value of the label. That secret contains X.509 credentials within, provided by cert-manager, Otterize Cloud or SPIRE, depending on how the credentials operator is configured.

cert-manager

The operator creates a cert-manager Certificate resource, which will create a Kubernetes Secret with the name specified by the value of the annotation credentials-operator.otterize.com/tls-secret-name. The common name and DNS names in the certificate are values that represent the identity of the service, as resolved by the service identity resolution algorithm, i.e. servicename.namespace.

The operator will use a ClusterIssuer or an Issuer to create the Certificate resource, which it expects to find in the same namespace as the Pod with the annotation. The Issuer is configured at deploy time, using the Helm chart.

In the event that the default approver controller in cert-manager is disabled, the credentials operator can auto-approve its own CertificateRequests. Enable this capability by configuring the Helm chart autoApprove flag.

Otterize Cloud

The operator requests certificates from Otterize Cloud, which internally manages them in Hashicorp Vault. The certificates are then placed within a Kubernetes Secret named with the value of the annotation credentials-operator.otterize.com/tls-secret-name.

SPIRE

Once the operator has registered the pod with SPIRE, which happens automatically for a pod that has the credentials-operator.otterize.com/tls-secret-name annotation upon pod startup. The credentials operator then acquires the SVID and certificates for the CA chain and places them within a Kubernetes Secret. The SVID and DNS names in the certificate is the identity of the service, as resolved by the service identity resolution algorithm, i.e. servicename.namespace.

SPIRE workload registrar

When deployed with a SPIRE server, the operator registers every pod with the SPIRE server (even those without annotations). Alongside the credentials operator, you could use SPIRE agents and the SPIRE SDK to work with the same SPIRE server. -To learn more, check out the documentation for SPIRE. Note that to use the credentials operator, you do not need to work directly with SPIRE or SPIRE agents, and can do everything completely using annotations and Kubernetes Secrets.

Pod annotations

AnnotationDescriptionDefault
credentials-operator.otterize.com/tls-secret-nameIf set, the operator will create a secret with this name with mTLS credentials for this pod.N/A
credentials-operator.otterize.com/dns-namesIf set, overrides the list of subject alternative names in the certificate. Should include the hostname of Kubernetes services that will be used to access this pod.N/A
credentials-operator.otterize.com/cert-ttlOverride for the expiration time for the certificate in seconds.If deployed with the bundled SPIRE server, 1 day (86400).
credentials-operator.otterize.com/cert-typeType of the credential bundle - pem or jks.pem
credentials-operator.otterize.com/cert-file-nameCertificate key name in the secret. When mounted, this is the filename for the certificate (when using SPIRE it's the SVID file). Only used when cert-type is pem. Not supported when certificateProvider is cert-manager.cert.pem
credentials-operator.otterize.com/ca-file-nameBundle (certificate chain bundle) key name in the secret. When mounted, this is the filename for the certificate chain. Only used when cert-type is pem. Not supported when certificateProvider is cert-manager.ca.pem
credentials-operator.otterize.com/key-file-namePrivate key key name in the secret. When mounted, this is the filename for the private key. Only used when cert-type is pem. Not supported when certificateProvider is cert-manager.key.pem
credentials-operator.otterize.com/keystore-file-nameKeystore key name in the secret. When mounted, this is the filename for the keystore. Only used when cert-type is jks. Not supported when certificateProvider is cert-manager.keystore.jks
credentials-operator.otterize.com/truststore-file-nameTruststore key name in the secret. When mounted, this is the filename for the truststore. Only used when cert-type is jks. Not supported when certificateProvider is cert-manager.truststore.jks
credentials-operator.otterize.com/jks-passwordPassword for the JKS truststore and keystore. Only used when cert-type is jks.password
credentials-operator.otterize.com/restart-pod-on-certificate-renewalA pod with this annotation (no matter the value) will be restarted after certificate renewal, along with any replicas. Should be ideally set through the pod owner's template spec so it will persist between restarts.N/A
intents.otterize.com/service-nameUsed for service identity resolution.
- + \ No newline at end of file diff --git a/reference/configuration/credentials-operator/helm-chart.html b/reference/configuration/credentials-operator/helm-chart.html index b0fd7505..2015537b 100644 --- a/reference/configuration/credentials-operator/helm-chart.html +++ b/reference/configuration/credentials-operator/helm-chart.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@
- + \ No newline at end of file diff --git a/reference/configuration/intents-operator.html b/reference/configuration/intents-operator.html index c4979a41..ea240126 100644 --- a/reference/configuration/intents-operator.html +++ b/reference/configuration/intents-operator.html @@ -14,7 +14,7 @@ - + @@ -172,7 +172,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/intents-operator/configuration.html b/reference/configuration/intents-operator/configuration.html index 4a39aaba..9eff9efd 100644 --- a/reference/configuration/intents-operator/configuration.html +++ b/reference/configuration/intents-operator/configuration.html @@ -14,7 +14,7 @@ - + @@ -157,7 +157,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/intents-operator/helm-chart.html b/reference/configuration/intents-operator/helm-chart.html index 272191cd..360707d3 100644 --- a/reference/configuration/intents-operator/helm-chart.html +++ b/reference/configuration/intents-operator/helm-chart.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/network-mapper.html b/reference/configuration/network-mapper.html index c589c482..003ecda1 100644 --- a/reference/configuration/network-mapper.html +++ b/reference/configuration/network-mapper.html @@ -14,7 +14,7 @@ - + @@ -157,7 +157,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/network-mapper/helm-chart.html b/reference/configuration/network-mapper/helm-chart.html index 28ed3d17..b7f50a52 100644 --- a/reference/configuration/network-mapper/helm-chart.html +++ b/reference/configuration/network-mapper/helm-chart.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/network-mapper/kafka-watcher.html b/reference/configuration/network-mapper/kafka-watcher.html index c0e5cb27..f9a41d5b 100644 --- a/reference/configuration/network-mapper/kafka-watcher.html +++ b/reference/configuration/network-mapper/kafka-watcher.html @@ -14,7 +14,7 @@ - + @@ -161,7 +161,7 @@ - + \ No newline at end of file diff --git a/reference/configuration/otterize-chart.html b/reference/configuration/otterize-chart.html index 19efc8b0..3a5bc7e6 100644 --- a/reference/configuration/otterize-chart.html +++ b/reference/configuration/otterize-chart.html @@ -14,7 +14,7 @@ - + @@ -159,7 +159,7 @@ - + \ No newline at end of file diff --git a/reference/mtls.html b/reference/mtls.html index 08409701..292b936f 100644 --- a/reference/mtls.html +++ b/reference/mtls.html @@ -14,7 +14,7 @@ - + @@ -165,7 +165,7 @@ - + \ No newline at end of file diff --git a/reference/service-identities.html b/reference/service-identities.html index 6a141868..1172f283 100644 --- a/reference/service-identities.html +++ b/reference/service-identities.html @@ -14,7 +14,7 @@ - + @@ -160,7 +160,7 @@ - + \ No newline at end of file diff --git a/reference/shadow-vs-active-enforcement.html b/reference/shadow-vs-active-enforcement.html index 05bc67cc..2ef0fdec 100644 --- a/reference/shadow-vs-active-enforcement.html +++ b/reference/shadow-vs-active-enforcement.html @@ -14,7 +14,7 @@ - + @@ -156,7 +156,7 @@ - + \ No newline at end of file diff --git a/reference/terminology.html b/reference/terminology.html index 2b6bb14c..5070d1f3 100644 --- a/reference/terminology.html +++ b/reference/terminology.html @@ -14,7 +14,7 @@ - + @@ -165,7 +165,7 @@ - + \ No newline at end of file diff --git a/reference/troubleshooting.html b/reference/troubleshooting.html index 5164dd5f..01400a5a 100644 --- a/reference/troubleshooting.html +++ b/reference/troubleshooting.html @@ -14,7 +14,7 @@ - + @@ -156,7 +156,7 @@ - + \ No newline at end of file diff --git a/reference/validating-clientintents.html b/reference/validating-clientintents.html index 10bb8d65..c1935b55 100644 --- a/reference/validating-clientintents.html +++ b/reference/validating-clientintents.html @@ -14,7 +14,7 @@ - + @@ -156,7 +156,7 @@ - + \ No newline at end of file diff --git a/search.html b/search.html index da635db3..43a7195f 100644 --- a/search.html +++ b/search.html @@ -14,7 +14,7 @@ - + @@ -154,7 +154,7 @@ - + \ No newline at end of file diff --git a/security.html b/security.html index 7e0e42bf..18f82ab3 100644 --- a/security.html +++ b/security.html @@ -14,7 +14,7 @@ - + @@ -155,7 +155,7 @@ - + \ No newline at end of file