CINXE.COM
Multi-Tenant Crossplane · Crossplane v1.16
<!doctype html><html lang=en class=color-toggle-hidden color-theme=light><head><meta charset=utf-8><script type="text/javascript"> ;window.NREUM||(NREUM={});NREUM.init={distributed_tracing:{enabled:true},privacy:{cookies_enabled:true},ajax:{deny_list:["bam.nr-data.net"]}}; window.NREUM||(NREUM={}),__nr_require=function(t,e,n){function r(n){if(!e[n]){var o=e[n]={exports:{}};t[n][0].call(o.exports,function(e){var o=t[n][1][e];return r(o||e)},o,o.exports)}return e[n].exports}if("function"==typeof __nr_require)return __nr_require;for(var o=0;o<n.length;o++)r(n[o]);return r}({1:[function(t,e,n){function r(t){try{s.console&&console.log(t)}catch(e){}}var o,i=t("ee"),a=t(32),s={};try{o=localStorage.getItem("__nr_flags").split(","),console&&"function"==typeof console.log&&(s.console=!0,o.indexOf("dev")!==-1&&(s.dev=!0),o.indexOf("nr_dev")!==-1&&(s.nrDev=!0))}catch(c){}s.nrDev&&i.on("internal-error",function(t){r(t.stack)}),s.dev&&i.on("fn-err",function(t,e,n){r(n.stack)}),s.dev&&(r("NR AGENT IN DEVELOPMENT MODE"),r("flags: "+a(s,function(t,e){return t}).join(", ")))},{}],2:[function(t,e,n){function r(t,e,n,r,s){try{l?l-=1:o(s||new UncaughtException(t,e,n),!0)}catch(f){try{i("ierr",[f,c.now(),!0])}catch(d){}}return"function"==typeof u&&u.apply(this,a(arguments))}function UncaughtException(t,e,n){this.message=t||"Uncaught error with no additional information",this.sourceURL=e,this.line=n}function o(t,e){var n=e?null:c.now();i("err",[t,n])}var i=t("handle"),a=t(33),s=t("ee"),c=t("loader"),f=t("gos"),u=window.onerror,d=!1,p="nr@seenError";if(!c.disabled){var l=0;c.features.err=!0,t(1),window.onerror=r;try{throw new Error}catch(h){"stack"in h&&(t(14),t(13),"addEventListener"in window&&t(7),c.xhrWrappable&&t(15),d=!0)}s.on("fn-start",function(t,e,n){d&&(l+=1)}),s.on("fn-err",function(t,e,n){d&&!n[p]&&(f(n,p,function(){return!0}),this.thrown=!0,o(n))}),s.on("fn-end",function(){d&&!this.thrown&&l>0&&(l-=1)}),s.on("internal-error",function(t){i("ierr",[t,c.now(),!0])})}},{}],3:[function(t,e,n){var r=t("loader");r.disabled||(r.features.ins=!0)},{}],4:[function(t,e,n){function r(){U++,L=g.hash,this[u]=y.now()}function o(){U--,g.hash!==L&&i(0,!0);var t=y.now();this[h]=~~this[h]+t-this[u],this[d]=t}function i(t,e){E.emit("newURL",[""+g,e])}function a(t,e){t.on(e,function(){this[e]=y.now()})}var s="-start",c="-end",f="-body",u="fn"+s,d="fn"+c,p="cb"+s,l="cb"+c,h="jsTime",m="fetch",v="addEventListener",w=window,g=w.location,y=t("loader");if(w[v]&&y.xhrWrappable&&!y.disabled){var x=t(11),b=t(12),E=t(9),R=t(7),O=t(14),T=t(8),P=t(15),S=t(10),M=t("ee"),N=M.get("tracer"),C=t(23);t(17),y.features.spa=!0;var L,U=0;M.on(u,r),b.on(p,r),S.on(p,r),M.on(d,o),b.on(l,o),S.on(l,o),M.buffer([u,d,"xhr-resolved"]),R.buffer([u]),O.buffer(["setTimeout"+c,"clearTimeout"+s,u]),P.buffer([u,"new-xhr","send-xhr"+s]),T.buffer([m+s,m+"-done",m+f+s,m+f+c]),E.buffer(["newURL"]),x.buffer([u]),b.buffer(["propagate",p,l,"executor-err","resolve"+s]),N.buffer([u,"no-"+u]),S.buffer(["new-jsonp","cb-start","jsonp-error","jsonp-end"]),a(T,m+s),a(T,m+"-done"),a(S,"new-jsonp"),a(S,"jsonp-end"),a(S,"cb-start"),E.on("pushState-end",i),E.on("replaceState-end",i),w[v]("hashchange",i,C(!0)),w[v]("load",i,C(!0)),w[v]("popstate",function(){i(0,U>1)},C(!0))}},{}],5:[function(t,e,n){function r(){var t=new PerformanceObserver(function(t,e){var n=t.getEntries();s(v,[n])});try{t.observe({entryTypes:["resource"]})}catch(e){}}function o(t){if(s(v,[window.performance.getEntriesByType(w)]),window.performance["c"+p])try{window.performance[h](m,o,!1)}catch(t){}else try{window.performance[h]("webkit"+m,o,!1)}catch(t){}}function i(t){}if(window.performance&&window.performance.timing&&window.performance.getEntriesByType){var a=t("ee"),s=t("handle"),c=t(14),f=t(13),u=t(6),d=t(23),p="learResourceTimings",l="addEventListener",h="removeEventListener",m="resourcetimingbufferfull",v="bstResource",w="resource",g="-start",y="-end",x="fn"+g,b="fn"+y,E="bstTimer",R="pushState",O=t("loader");if(!O.disabled){O.features.stn=!0,t(9),"addEventListener"in window&&t(7);var T=NREUM.o.EV;a.on(x,function(t,e){var n=t[0];n instanceof T&&(this.bstStart=O.now())}),a.on(b,function(t,e){var n=t[0];n instanceof T&&s("bst",[n,e,this.bstStart,O.now()])}),c.on(x,function(t,e,n){this.bstStart=O.now(),this.bstType=n}),c.on(b,function(t,e){s(E,[e,this.bstStart,O.now(),this.bstType])}),f.on(x,function(){this.bstStart=O.now()}),f.on(b,function(t,e){s(E,[e,this.bstStart,O.now(),"requestAnimationFrame"])}),a.on(R+g,function(t){this.time=O.now(),this.startPath=location.pathname+location.hash}),a.on(R+y,function(t){s("bstHist",[location.pathname+location.hash,this.startPath,this.time])}),u()?(s(v,[window.performance.getEntriesByType("resource")]),r()):l in window.performance&&(window.performance["c"+p]?window.performance[l](m,o,d(!1)):window.performance[l]("webkit"+m,o,d(!1))),document[l]("scroll",i,d(!1)),document[l]("keypress",i,d(!1)),document[l]("click",i,d(!1))}}},{}],6:[function(t,e,n){e.exports=function(){return"PerformanceObserver"in window&&"function"==typeof window.PerformanceObserver}},{}],7:[function(t,e,n){function r(t){for(var e=t;e&&!e.hasOwnProperty(u);)e=Object.getPrototypeOf(e);e&&o(e)}function o(t){s.inPlace(t,[u,d],"-",i)}function i(t,e){return t[1]}var a=t("ee").get("events"),s=t("wrap-function")(a,!0),c=t("gos"),f=XMLHttpRequest,u="addEventListener",d="removeEventListener";e.exports=a,"getPrototypeOf"in Object?(r(document),r(window),r(f.prototype)):f.prototype.hasOwnProperty(u)&&(o(window),o(f.prototype)),a.on(u+"-start",function(t,e){var n=t[1];if(null!==n&&("function"==typeof n||"object"==typeof n)){var r=c(n,"nr@wrapped",function(){function t(){if("function"==typeof n.handleEvent)return n.handleEvent.apply(n,arguments)}var e={object:t,"function":n}[typeof n];return e?s(e,"fn-",null,e.name||"anonymous"):n});this.wrapped=t[1]=r}}),a.on(d+"-start",function(t){t[1]=this.wrapped||t[1]})},{}],8:[function(t,e,n){function r(t,e,n){var r=t[e];"function"==typeof r&&(t[e]=function(){var t=i(arguments),e={};o.emit(n+"before-start",[t],e);var a;e[m]&&e[m].dt&&(a=e[m].dt);var s=r.apply(this,t);return o.emit(n+"start",[t,a],s),s.then(function(t){return o.emit(n+"end",[null,t],s),t},function(t){throw o.emit(n+"end",[t],s),t})})}var o=t("ee").get("fetch"),i=t(33),a=t(32);e.exports=o;var s=window,c="fetch-",f=c+"body-",u=["arrayBuffer","blob","json","text","formData"],d=s.Request,p=s.Response,l=s.fetch,h="prototype",m="nr@context";d&&p&&l&&(a(u,function(t,e){r(d[h],e,f),r(p[h],e,f)}),r(s,"fetch",c),o.on(c+"end",function(t,e){var n=this;if(e){var r=e.headers.get("content-length");null!==r&&(n.rxSize=r),o.emit(c+"done",[null,e],n)}else o.emit(c+"done",[t],n)}))},{}],9:[function(t,e,n){var r=t("ee").get("history"),o=t("wrap-function")(r);e.exports=r;var i=window.history&&window.history.constructor&&window.history.constructor.prototype,a=window.history;i&&i.pushState&&i.replaceState&&(a=i),o.inPlace(a,["pushState","replaceState"],"-")},{}],10:[function(t,e,n){function r(t){function e(){f.emit("jsonp-end",[],l),t.removeEventListener("load",e,c(!1)),t.removeEventListener("error",n,c(!1))}function n(){f.emit("jsonp-error",[],l),f.emit("jsonp-end",[],l),t.removeEventListener("load",e,c(!1)),t.removeEventListener("error",n,c(!1))}var r=t&&"string"==typeof t.nodeName&&"script"===t.nodeName.toLowerCase();if(r){var o="function"==typeof t.addEventListener;if(o){var a=i(t.src);if(a){var d=s(a),p="function"==typeof d.parent[d.key];if(p){var l={};u.inPlace(d.parent,[d.key],"cb-",l),t.addEventListener("load",e,c(!1)),t.addEventListener("error",n,c(!1)),f.emit("new-jsonp",[t.src],l)}}}}}function o(){return"addEventListener"in window}function i(t){var e=t.match(d);return e?e[1]:null}function a(t,e){var n=t.match(l),r=n[1],o=n[3];return o?a(o,e[r]):e[r]}function s(t){var e=t.match(p);return e&&e.length>=3?{key:e[2],parent:a(e[1],window)}:{key:t,parent:window}}var c=t(23),f=t("ee").get("jsonp"),u=t("wrap-function")(f);if(e.exports=f,o()){var d=/[?&](?:callback|cb)=([^&#]+)/,p=/(.*)\.([^.]+)/,l=/^(\w+)(\.|$)(.*)$/,h=["appendChild","insertBefore","replaceChild"];Node&&Node.prototype&&Node.prototype.appendChild?u.inPlace(Node.prototype,h,"dom-"):(u.inPlace(HTMLElement.prototype,h,"dom-"),u.inPlace(HTMLHeadElement.prototype,h,"dom-"),u.inPlace(HTMLBodyElement.prototype,h,"dom-")),f.on("dom-start",function(t){r(t[0])})}},{}],11:[function(t,e,n){var r=t("ee").get("mutation"),o=t("wrap-function")(r),i=NREUM.o.MO;e.exports=r,i&&(window.MutationObserver=function(t){return this instanceof i?new i(o(t,"fn-")):i.apply(this,arguments)},MutationObserver.prototype=i.prototype)},{}],12:[function(t,e,n){function r(t){var e=i.context(),n=s(t,"executor-",e,null,!1),r=new f(n);return i.context(r).getCtx=function(){return e},r}var o=t("wrap-function"),i=t("ee").get("promise"),a=t("ee").getOrSetContext,s=o(i),c=t(32),f=NREUM.o.PR;e.exports=i,f&&(window.Promise=r,["all","race"].forEach(function(t){var e=f[t];f[t]=function(n){function r(t){return function(){i.emit("propagate",[null,!o],a,!1,!1),o=o||!t}}var o=!1;c(n,function(e,n){Promise.resolve(n).then(r("all"===t),r(!1))});var a=e.apply(f,arguments),s=f.resolve(a);return s}}),["resolve","reject"].forEach(function(t){var e=f[t];f[t]=function(t){var n=e.apply(f,arguments);return t!==n&&i.emit("propagate",[t,!0],n,!1,!1),n}}),f.prototype["catch"]=function(t){return this.then(null,t)},f.prototype=Object.create(f.prototype,{constructor:{value:r}}),c(Object.getOwnPropertyNames(f),function(t,e){try{r[e]=f[e]}catch(n){}}),o.wrapInPlace(f.prototype,"then",function(t){return function(){var e=this,n=o.argsToArray.apply(this,arguments),r=a(e);r.promise=e,n[0]=s(n[0],"cb-",r,null,!1),n[1]=s(n[1],"cb-",r,null,!1);var c=t.apply(this,n);return r.nextPromise=c,i.emit("propagate",[e,!0],c,!1,!1),c}}),i.on("executor-start",function(t){t[0]=s(t[0],"resolve-",this,null,!1),t[1]=s(t[1],"resolve-",this,null,!1)}),i.on("executor-err",function(t,e,n){t[1](n)}),i.on("cb-end",function(t,e,n){i.emit("propagate",[n,!0],this.nextPromise,!1,!1)}),i.on("propagate",function(t,e,n){this.getCtx&&!e||(this.getCtx=function(){if(t instanceof Promise)var e=i.context(t);return e&&e.getCtx?e.getCtx():this})}),r.toString=function(){return""+f})},{}],13:[function(t,e,n){var r=t("ee").get("raf"),o=t("wrap-function")(r),i="equestAnimationFrame";e.exports=r,o.inPlace(window,["r"+i,"mozR"+i,"webkitR"+i,"msR"+i],"raf-"),r.on("raf-start",function(t){t[0]=o(t[0],"fn-")})},{}],14:[function(t,e,n){function r(t,e,n){t[0]=a(t[0],"fn-",null,n)}function o(t,e,n){this.method=n,this.timerDuration=isNaN(t[1])?0:+t[1],t[0]=a(t[0],"fn-",this,n)}var i=t("ee").get("timer"),a=t("wrap-function")(i),s="setTimeout",c="setInterval",f="clearTimeout",u="-start",d="-";e.exports=i,a.inPlace(window,[s,"setImmediate"],s+d),a.inPlace(window,[c],c+d),a.inPlace(window,[f,"clearImmediate"],f+d),i.on(c+u,r),i.on(s+u,o)},{}],15:[function(t,e,n){function r(t,e){d.inPlace(e,["onreadystatechange"],"fn-",s)}function o(){var t=this,e=u.context(t);t.readyState>3&&!e.resolved&&(e.resolved=!0,u.emit("xhr-resolved",[],t)),d.inPlace(t,y,"fn-",s)}function i(t){x.push(t),m&&(E?E.then(a):w?w(a):(R=-R,O.data=R))}function a(){for(var t=0;t<x.length;t++)r([],x[t]);x.length&&(x=[])}function s(t,e){return e}function c(t,e){for(var n in t)e[n]=t[n];return e}t(7);var f=t("ee"),u=f.get("xhr"),d=t("wrap-function")(u),p=t(23),l=NREUM.o,h=l.XHR,m=l.MO,v=l.PR,w=l.SI,g="readystatechange",y=["onload","onerror","onabort","onloadstart","onloadend","onprogress","ontimeout"],x=[];e.exports=u;var b=window.XMLHttpRequest=function(t){var e=new h(t);try{u.emit("new-xhr",[e],e),e.addEventListener(g,o,p(!1))}catch(n){try{u.emit("internal-error",[n])}catch(r){}}return e};if(c(h,b),b.prototype=h.prototype,d.inPlace(b.prototype,["open","send"],"-xhr-",s),u.on("send-xhr-start",function(t,e){r(t,e),i(e)}),u.on("open-xhr-start",r),m){var E=v&&v.resolve();if(!w&&!v){var R=1,O=document.createTextNode(R);new m(a).observe(O,{characterData:!0})}}else f.on("fn-end",function(t){t[0]&&t[0].type===g||a()})},{}],16:[function(t,e,n){function r(t){if(!s(t))return null;var e=window.NREUM;if(!e.loader_config)return null;var n=(e.loader_config.accountID||"").toString()||null,r=(e.loader_config.agentID||"").toString()||null,f=(e.loader_config.trustKey||"").toString()||null;if(!n||!r)return null;var h=l.generateSpanId(),m=l.generateTraceId(),v=Date.now(),w={spanId:h,traceId:m,timestamp:v};return(t.sameOrigin||c(t)&&p())&&(w.traceContextParentHeader=o(h,m),w.traceContextStateHeader=i(h,v,n,r,f)),(t.sameOrigin&&!u()||!t.sameOrigin&&c(t)&&d())&&(w.newrelicHeader=a(h,m,v,n,r,f)),w}function o(t,e){return"00-"+e+"-"+t+"-01"}function i(t,e,n,r,o){var i=0,a="",s=1,c="",f="";return o+"@nr="+i+"-"+s+"-"+n+"-"+r+"-"+t+"-"+a+"-"+c+"-"+f+"-"+e}function a(t,e,n,r,o,i){var a="btoa"in window&&"function"==typeof window.btoa;if(!a)return null;var s={v:[0,1],d:{ty:"Browser",ac:r,ap:o,id:t,tr:e,ti:n}};return i&&r!==i&&(s.d.tk=i),btoa(JSON.stringify(s))}function s(t){return f()&&c(t)}function c(t){var e=!1,n={};if("init"in NREUM&&"distributed_tracing"in NREUM.init&&(n=NREUM.init.distributed_tracing),t.sameOrigin)e=!0;else if(n.allowed_origins instanceof Array)for(var r=0;r<n.allowed_origins.length;r++){var o=h(n.allowed_origins[r]);if(t.hostname===o.hostname&&t.protocol===o.protocol&&t.port===o.port){e=!0;break}}return e}function f(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&!!NREUM.init.distributed_tracing.enabled}function u(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&!!NREUM.init.distributed_tracing.exclude_newrelic_header}function d(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&NREUM.init.distributed_tracing.cors_use_newrelic_header!==!1}function p(){return"init"in NREUM&&"distributed_tracing"in NREUM.init&&!!NREUM.init.distributed_tracing.cors_use_tracecontext_headers}var l=t(29),h=t(18);e.exports={generateTracePayload:r,shouldGenerateTrace:s}},{}],17:[function(t,e,n){function r(t){var e=this.params,n=this.metrics;if(!this.ended){this.ended=!0;for(var r=0;r<p;r++)t.removeEventListener(d[r],this.listener,!1);e.aborted||(n.duration=a.now()-this.startTime,this.loadCaptureCalled||4!==t.readyState?null==e.status&&(e.status=0):i(this,t),n.cbTime=this.cbTime,s("xhr",[e,n,this.startTime,this.endTime,"xhr"],this))}}function o(t,e){var n=c(e),r=t.params;r.hostname=n.hostname,r.port=n.port,r.protocol=n.protocol,r.host=n.hostname+":"+n.port,r.pathname=n.pathname,t.parsedOrigin=n,t.sameOrigin=n.sameOrigin}function i(t,e){t.params.status=e.status;var n=v(e,t.lastSize);if(n&&(t.metrics.rxSize=n),t.sameOrigin){var r=e.getResponseHeader("X-NewRelic-App-Data");r&&(t.params.cat=r.split(", ").pop())}t.loadCaptureCalled=!0}var a=t("loader");if(a.xhrWrappable&&!a.disabled){var s=t("handle"),c=t(18),f=t(16).generateTracePayload,u=t("ee"),d=["load","error","abort","timeout"],p=d.length,l=t("id"),h=t(24),m=t(22),v=t(19),w=t(23),g=NREUM.o.REQ,y=window.XMLHttpRequest;a.features.xhr=!0,t(15),t(8),u.on("new-xhr",function(t){var e=this;e.totalCbs=0,e.called=0,e.cbTime=0,e.end=r,e.ended=!1,e.xhrGuids={},e.lastSize=null,e.loadCaptureCalled=!1,e.params=this.params||{},e.metrics=this.metrics||{},t.addEventListener("load",function(n){i(e,t)},w(!1)),h&&(h>34||h<10)||t.addEventListener("progress",function(t){e.lastSize=t.loaded},w(!1))}),u.on("open-xhr-start",function(t){this.params={method:t[0]},o(this,t[1]),this.metrics={}}),u.on("open-xhr-end",function(t,e){"loader_config"in NREUM&&"xpid"in NREUM.loader_config&&this.sameOrigin&&e.setRequestHeader("X-NewRelic-ID",NREUM.loader_config.xpid);var n=f(this.parsedOrigin);if(n){var r=!1;n.newrelicHeader&&(e.setRequestHeader("newrelic",n.newrelicHeader),r=!0),n.traceContextParentHeader&&(e.setRequestHeader("traceparent",n.traceContextParentHeader),n.traceContextStateHeader&&e.setRequestHeader("tracestate",n.traceContextStateHeader),r=!0),r&&(this.dt=n)}}),u.on("send-xhr-start",function(t,e){var n=this.metrics,r=t[0],o=this;if(n&&r){var i=m(r);i&&(n.txSize=i)}this.startTime=a.now(),this.listener=function(t){try{"abort"!==t.type||o.loadCaptureCalled||(o.params.aborted=!0),("load"!==t.type||o.called===o.totalCbs&&(o.onloadCalled||"function"!=typeof e.onload))&&o.end(e)}catch(n){try{u.emit("internal-error",[n])}catch(r){}}};for(var s=0;s<p;s++)e.addEventListener(d[s],this.listener,w(!1))}),u.on("xhr-cb-time",function(t,e,n){this.cbTime+=t,e?this.onloadCalled=!0:this.called+=1,this.called!==this.totalCbs||!this.onloadCalled&&"function"==typeof n.onload||this.end(n)}),u.on("xhr-load-added",function(t,e){var n=""+l(t)+!!e;this.xhrGuids&&!this.xhrGuids[n]&&(this.xhrGuids[n]=!0,this.totalCbs+=1)}),u.on("xhr-load-removed",function(t,e){var n=""+l(t)+!!e;this.xhrGuids&&this.xhrGuids[n]&&(delete this.xhrGuids[n],this.totalCbs-=1)}),u.on("xhr-resolved",function(){this.endTime=a.now()}),u.on("addEventListener-end",function(t,e){e instanceof y&&"load"===t[0]&&u.emit("xhr-load-added",[t[1],t[2]],e)}),u.on("removeEventListener-end",function(t,e){e instanceof y&&"load"===t[0]&&u.emit("xhr-load-removed",[t[1],t[2]],e)}),u.on("fn-start",function(t,e,n){e instanceof y&&("onload"===n&&(this.onload=!0),("load"===(t[0]&&t[0].type)||this.onload)&&(this.xhrCbStart=a.now()))}),u.on("fn-end",function(t,e){this.xhrCbStart&&u.emit("xhr-cb-time",[a.now()-this.xhrCbStart,this.onload,e],e)}),u.on("fetch-before-start",function(t){function e(t,e){var n=!1;return e.newrelicHeader&&(t.set("newrelic",e.newrelicHeader),n=!0),e.traceContextParentHeader&&(t.set("traceparent",e.traceContextParentHeader),e.traceContextStateHeader&&t.set("tracestate",e.traceContextStateHeader),n=!0),n}var n,r=t[1]||{};"string"==typeof t[0]?n=t[0]:t[0]&&t[0].url?n=t[0].url:window.URL&&t[0]&&t[0]instanceof URL&&(n=t[0].href),n&&(this.parsedOrigin=c(n),this.sameOrigin=this.parsedOrigin.sameOrigin);var o=f(this.parsedOrigin);if(o&&(o.newrelicHeader||o.traceContextParentHeader))if("string"==typeof t[0]||window.URL&&t[0]&&t[0]instanceof URL){var i={};for(var a in r)i[a]=r[a];i.headers=new Headers(r.headers||{}),e(i.headers,o)&&(this.dt=o),t.length>1?t[1]=i:t.push(i)}else t[0]&&t[0].headers&&e(t[0].headers,o)&&(this.dt=o)}),u.on("fetch-start",function(t,e){this.params={},this.metrics={},this.startTime=a.now(),this.dt=e,t.length>=1&&(this.target=t[0]),t.length>=2&&(this.opts=t[1]);var n,r=this.opts||{},i=this.target;"string"==typeof i?n=i:"object"==typeof i&&i instanceof g?n=i.url:window.URL&&"object"==typeof i&&i instanceof URL&&(n=i.href),o(this,n);var s=(""+(i&&i instanceof g&&i.method||r.method||"GET")).toUpperCase();this.params.method=s,this.txSize=m(r.body)||0}),u.on("fetch-done",function(t,e){this.endTime=a.now(),this.params||(this.params={}),this.params.status=e?e.status:0;var n;"string"==typeof this.rxSize&&this.rxSize.length>0&&(n=+this.rxSize);var r={txSize:this.txSize,rxSize:n,duration:a.now()-this.startTime};s("xhr",[this.params,r,this.startTime,this.endTime,"fetch"],this)})}},{}],18:[function(t,e,n){var r={};e.exports=function(t){if(t in r)return r[t];var e=document.createElement("a"),n=window.location,o={};e.href=t,o.port=e.port;var i=e.href.split("://");!o.port&&i[1]&&(o.port=i[1].split("/")[0].split("@").pop().split(":")[1]),o.port&&"0"!==o.port||(o.port="https"===i[0]?"443":"80"),o.hostname=e.hostname||n.hostname,o.pathname=e.pathname,o.protocol=i[0],"/"!==o.pathname.charAt(0)&&(o.pathname="/"+o.pathname);var a=!e.protocol||":"===e.protocol||e.protocol===n.protocol,s=e.hostname===document.domain&&e.port===n.port;return o.sameOrigin=a&&(!e.hostname||s),"/"===o.pathname&&(r[t]=o),o}},{}],19:[function(t,e,n){function r(t,e){var n=t.responseType;return"json"===n&&null!==e?e:"arraybuffer"===n||"blob"===n||"json"===n?o(t.response):"text"===n||""===n||void 0===n?o(t.responseText):void 0}var o=t(22);e.exports=r},{}],20:[function(t,e,n){function r(){}function o(t,e,n,r){return function(){return u.recordSupportability("API/"+e+"/called"),i(t+e,[f.now()].concat(s(arguments)),n?null:this,r),n?void 0:this}}var i=t("handle"),a=t(32),s=t(33),c=t("ee").get("tracer"),f=t("loader"),u=t(25),d=NREUM;"undefined"==typeof window.newrelic&&(newrelic=d);var p=["setPageViewName","setCustomAttribute","setErrorHandler","finished","addToTrace","inlineHit","addRelease"],l="api-",h=l+"ixn-";a(p,function(t,e){d[e]=o(l,e,!0,"api")}),d.addPageAction=o(l,"addPageAction",!0),d.setCurrentRouteName=o(l,"routeName",!0),e.exports=newrelic,d.interaction=function(){return(new r).get()};var m=r.prototype={createTracer:function(t,e){var n={},r=this,o="function"==typeof e;return i(h+"tracer",[f.now(),t,n],r),function(){if(c.emit((o?"":"no-")+"fn-start",[f.now(),r,o],n),o)try{return e.apply(this,arguments)}catch(t){throw c.emit("fn-err",[arguments,this,t],n),t}finally{c.emit("fn-end",[f.now()],n)}}}};a("actionText,setName,setAttribute,save,ignore,onEnd,getContext,end,get".split(","),function(t,e){m[e]=o(h,e)}),newrelic.noticeError=function(t,e){"string"==typeof t&&(t=new Error(t)),u.recordSupportability("API/noticeError/called"),i("err",[t,f.now(),!1,e])}},{}],21:[function(t,e,n){function r(t){if(NREUM.init){for(var e=NREUM.init,n=t.split("."),r=0;r<n.length-1;r++)if(e=e[n[r]],"object"!=typeof e)return;return e=e[n[n.length-1]]}}e.exports={getConfiguration:r}},{}],22:[function(t,e,n){e.exports=function(t){if("string"==typeof t&&t.length)return t.length;if("object"==typeof t){if("undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer&&t.byteLength)return t.byteLength;if("undefined"!=typeof Blob&&t instanceof Blob&&t.size)return t.size;if(!("undefined"!=typeof FormData&&t instanceof FormData))try{return JSON.stringify(t).length}catch(e){return}}}},{}],23:[function(t,e,n){var r=!1;try{var o=Object.defineProperty({},"passive",{get:function(){r=!0}});window.addEventListener("testPassive",null,o),window.removeEventListener("testPassive",null,o)}catch(i){}e.exports=function(t){return r?{passive:!0,capture:!!t}:!!t}},{}],24:[function(t,e,n){var r=0,o=navigator.userAgent.match(/Firefox[\/\s](\d+\.\d+)/);o&&(r=+o[1]),e.exports=r},{}],25:[function(t,e,n){function r(t,e){var n=[a,t,{name:t},e];return i("storeMetric",n,null,"api"),n}function o(t,e){var n=[s,t,{name:t},e];return i("storeEventMetrics",n,null,"api"),n}var i=t("handle"),a="sm",s="cm";e.exports={constants:{SUPPORTABILITY_METRIC:a,CUSTOM_METRIC:s},recordSupportability:r,recordCustom:o}},{}],26:[function(t,e,n){function r(){return s.exists&&performance.now?Math.round(performance.now()):(i=Math.max((new Date).getTime(),i))-a}function o(){return i}var i=(new Date).getTime(),a=i,s=t(34);e.exports=r,e.exports.offset=a,e.exports.getLastTimestamp=o},{}],27:[function(t,e,n){function r(t){return!(!t||!t.protocol||"file:"===t.protocol)}e.exports=r},{}],28:[function(t,e,n){function r(t,e){var n=t.getEntries();n.forEach(function(t){"first-paint"===t.name?p("timing",["fp",Math.floor(t.startTime)]):"first-contentful-paint"===t.name&&p("timing",["fcp",Math.floor(t.startTime)])})}function o(t,e){var n=t.getEntries();if(n.length>0){var r=n[n.length-1];if(c&&c<r.startTime)return;p("lcp",[r])}}function i(t){t.getEntries().forEach(function(t){t.hadRecentInput||p("cls",[t])})}function a(t){if(t instanceof v&&!g){var e=Math.round(t.timeStamp),n={type:t.type};e<=l.now()?n.fid=l.now()-e:e>l.offset&&e<=Date.now()?(e-=l.offset,n.fid=l.now()-e):e=l.now(),g=!0,p("timing",["fi",e,n])}}function s(t){"hidden"===t&&(c=l.now(),p("pageHide",[c]))}if(!("init"in NREUM&&"page_view_timing"in NREUM.init&&"enabled"in NREUM.init.page_view_timing&&NREUM.init.page_view_timing.enabled===!1)){var c,f,u,d,p=t("handle"),l=t("loader"),h=t(31),m=t(23),v=NREUM.o.EV;if("PerformanceObserver"in window&&"function"==typeof window.PerformanceObserver){f=new PerformanceObserver(r);try{f.observe({entryTypes:["paint"]})}catch(w){}u=new PerformanceObserver(o);try{u.observe({entryTypes:["largest-contentful-paint"]})}catch(w){}d=new PerformanceObserver(i);try{d.observe({type:"layout-shift",buffered:!0})}catch(w){}}if("addEventListener"in document){var g=!1,y=["click","keydown","mousedown","pointerdown","touchstart"];y.forEach(function(t){document.addEventListener(t,a,m(!1))})}h(s)}},{}],29:[function(t,e,n){function r(){function t(){return e?15&e[n++]:16*Math.random()|0}var e=null,n=0,r=window.crypto||window.msCrypto;r&&r.getRandomValues&&(e=r.getRandomValues(new Uint8Array(31)));for(var o,i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",a="",s=0;s<i.length;s++)o=i[s],"x"===o?a+=t().toString(16):"y"===o?(o=3&t()|8,a+=o.toString(16)):a+=o;return a}function o(){return a(16)}function i(){return a(32)}function a(t){function e(){return n?15&n[r++]:16*Math.random()|0}var n=null,r=0,o=window.crypto||window.msCrypto;o&&o.getRandomValues&&Uint8Array&&(n=o.getRandomValues(new Uint8Array(31)));for(var i=[],a=0;a<t;a++)i.push(e().toString(16));return i.join("")}e.exports={generateUuid:r,generateSpanId:o,generateTraceId:i}},{}],30:[function(t,e,n){function r(t,e){if(!o)return!1;if(t!==o)return!1;if(!e)return!0;if(!i)return!1;for(var n=i.split("."),r=e.split("."),a=0;a<r.length;a++)if(r[a]!==n[a])return!1;return!0}var o=null,i=null,a=/Version\/(\S+)\s+Safari/;if(navigator.userAgent){var s=navigator.userAgent,c=s.match(a);c&&s.indexOf("Chrome")===-1&&s.indexOf("Chromium")===-1&&(o="Safari",i=c[1])}e.exports={agent:o,version:i,match:r}},{}],31:[function(t,e,n){function r(t){function e(){t(s&&document[s]?document[s]:document[i]?"hidden":"visible")}"addEventListener"in document&&a&&document.addEventListener(a,e,o(!1))}var o=t(23);e.exports=r;var i,a,s;"undefined"!=typeof document.hidden?(i="hidden",a="visibilitychange",s="visibilityState"):"undefined"!=typeof document.msHidden?(i="msHidden",a="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(i="webkitHidden",a="webkitvisibilitychange",s="webkitVisibilityState")},{}],32:[function(t,e,n){function r(t,e){var n=[],r="",i=0;for(r in t)o.call(t,r)&&(n[i]=e(r,t[r]),i+=1);return n}var o=Object.prototype.hasOwnProperty;e.exports=r},{}],33:[function(t,e,n){function r(t,e,n){e||(e=0),"undefined"==typeof n&&(n=t?t.length:0);for(var r=-1,o=n-e||0,i=Array(o<0?0:o);++r<o;)i[r]=t[e+r];return i}e.exports=r},{}],34:[function(t,e,n){e.exports={exists:"undefined"!=typeof window.performance&&window.performance.timing&&"undefined"!=typeof window.performance.timing.navigationStart}},{}],ee:[function(t,e,n){function r(){}function o(t){function e(t){return t&&t instanceof r?t:t?f(t,c,a):a()}function n(n,r,o,i,a){if(a!==!1&&(a=!0),!l.aborted||i){t&&a&&t(n,r,o);for(var s=e(o),c=m(n),f=c.length,u=0;u<f;u++)c[u].apply(s,r);var p=d[y[n]];return p&&p.push([x,n,r,s]),s}}function i(t,e){g[t]=m(t).concat(e)}function h(t,e){var n=g[t];if(n)for(var r=0;r<n.length;r++)n[r]===e&&n.splice(r,1)}function m(t){return g[t]||[]}function v(t){return p[t]=p[t]||o(n)}function w(t,e){l.aborted||u(t,function(t,n){e=e||"feature",y[n]=e,e in d||(d[e]=[])})}var g={},y={},x={on:i,addEventListener:i,removeEventListener:h,emit:n,get:v,listeners:m,context:e,buffer:w,abort:s,aborted:!1};return x}function i(t){return f(t,c,a)}function a(){return new r}function s(){(d.api||d.feature)&&(l.aborted=!0,d=l.backlog={})}var c="nr@context",f=t("gos"),u=t(32),d={},p={},l=e.exports=o();e.exports.getOrSetContext=i,l.backlog=d},{}],gos:[function(t,e,n){function r(t,e,n){if(o.call(t,e))return t[e];var r=n();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!1}),r}catch(i){}return t[e]=r,r}var o=Object.prototype.hasOwnProperty;e.exports=r},{}],handle:[function(t,e,n){function r(t,e,n,r){o.buffer([t],r),o.emit(t,e,n)}var o=t("ee").get("handle");e.exports=r,r.ee=o},{}],id:[function(t,e,n){function r(t){var e=typeof t;return!t||"object"!==e&&"function"!==e?-1:t===window?0:a(t,i,function(){return o++})}var o=1,i="nr@id",a=t("gos");e.exports=r},{}],loader:[function(t,e,n){function r(){if(!P++){var t=T.info=NREUM.info,e=v.getElementsByTagName("script")[0];if(setTimeout(f.abort,3e4),!(t&&t.licenseKey&&t.applicationID&&e))return f.abort();c(R,function(e,n){t[e]||(t[e]=n)});var n=a();s("mark",["onload",n+T.offset],null,"api"),s("timing",["load",n]);var r=v.createElement("script");0===t.agent.indexOf("http://")||0===t.agent.indexOf("https://")?r.src=t.agent:r.src=h+"://"+t.agent,e.parentNode.insertBefore(r,e)}}function o(){"complete"===v.readyState&&i()}function i(){s("mark",["domContent",a()+T.offset],null,"api")}var a=t(26),s=t("handle"),c=t(32),f=t("ee"),u=t(30),d=t(27),p=t(21),l=t(23),h=p.getConfiguration("ssl")===!1?"http":"https",m=window,v=m.document,w="addEventListener",g="attachEvent",y=m.XMLHttpRequest,x=y&&y.prototype,b=!d(m.location);NREUM.o={ST:setTimeout,SI:m.setImmediate,CT:clearTimeout,XHR:y,REQ:m.Request,EV:m.Event,PR:m.Promise,MO:m.MutationObserver};var E=""+location,R={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",agent:"js-agent.newrelic.com/nr-spa-1212.min.js"},O=y&&x&&x[w]&&!/CriOS/.test(navigator.userAgent),T=e.exports={offset:a.getLastTimestamp(),now:a,origin:E,features:{},xhrWrappable:O,userAgent:u,disabled:b};if(!b){t(20),t(28),v[w]?(v[w]("DOMContentLoaded",i,l(!1)),m[w]("load",r,l(!1))):(v[g]("onreadystatechange",o),m[g]("onload",r)),s("mark",["firstbyte",a.getLastTimestamp()],null,"api");var P=0}},{}],"wrap-function":[function(t,e,n){function r(t,e){function n(e,n,r,c,f){function nrWrapper(){var i,a,u,p;try{a=this,i=d(arguments),u="function"==typeof r?r(i,a):r||{}}catch(l){o([l,"",[i,a,c],u],t)}s(n+"start",[i,a,c],u,f);try{return p=e.apply(a,i)}catch(h){throw s(n+"err",[i,a,h],u,f),h}finally{s(n+"end",[i,a,p],u,f)}}return a(e)?e:(n||(n=""),nrWrapper[p]=e,i(e,nrWrapper,t),nrWrapper)}function r(t,e,r,o,i){r||(r="");var s,c,f,u="-"===r.charAt(0);for(f=0;f<e.length;f++)c=e[f],s=t[c],a(s)||(t[c]=n(s,u?c+r:r,o,c,i))}function s(n,r,i,a){if(!h||e){var s=h;h=!0;try{t.emit(n,r,i,e,a)}catch(c){o([c,n,r,i],t)}h=s}}return t||(t=u),n.inPlace=r,n.flag=p,n}function o(t,e){e||(e=u);try{e.emit("internal-error",t)}catch(n){}}function i(t,e,n){if(Object.defineProperty&&Object.keys)try{var r=Object.keys(t);return r.forEach(function(n){Object.defineProperty(e,n,{get:function(){return t[n]},set:function(e){return t[n]=e,e}})}),e}catch(i){o([i],n)}for(var a in t)l.call(t,a)&&(e[a]=t[a]);return e}function a(t){return!(t&&t instanceof Function&&t.apply&&!t[p])}function s(t,e){var n=e(t);return n[p]=t,i(t,n,u),n}function c(t,e,n){var r=t[e];t[e]=s(r,n)}function f(){for(var t=arguments.length,e=new Array(t),n=0;n<t;++n)e[n]=arguments[n];return e}var u=t("ee"),d=t(33),p="nr@original",l=Object.prototype.hasOwnProperty,h=!1;e.exports=r,e.exports.wrapFunction=s,e.exports.wrapInPlace=c,e.exports.argsToArray=f},{}]},{},["loader",2,17,5,3,4]); ;NREUM.loader_config={accountID:"3768898",trustKey:"3768898",agentID:"1134285132",licenseKey:"NRJS-2bc9f9fb1efc463f27c",applicationID:"1134285132"} ;NREUM.info={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",licenseKey:"NRJS-2bc9f9fb1efc463f27c",applicationID:"1134285132",sa:1} newrelic.addRelease("", "Remove-ControllerConfig-r-production-4dd74f6-17d951-17d94f"); </script><meta name=viewport content="width=device-width,initial-scale=1"><meta name=author content="Crossplane Community"><meta name=color-scheme content="light dark"><meta name=docsearch:language content="en"><meta name=generator content="Hugo 0.119.0"><link rel=preload href=/fonts/Avenir-Roman.woff2 as=font type=font/woff2 crossorigin><meta property="og:image" content="/img/crossplane-logo-og.webp"><meta property="twitter:card" content="/img/crossplane-logo-og.webp"><meta property="og:image:width" content="600"><meta property="og:image:height" content="199"><meta property="og:image:alt" content="Crossplane name and popsicle logo"><meta property="twitter:image:alt" content="Crossplane name and popsicle logo"><meta property="og:type" content="website"><meta name=twitter:site content="@crossplane_io"><meta property="og:site_name" content="Crossplane Documentation"><meta name=description content="Crossplane lets you build a control plane with Kubernetes-style declarative and API-driven configuration and management for anything."><meta property="og:url" content="https://docs.crossplane.io/v1.16/guides/multi-tenant/"><meta name=docsearch:modified content="September 9, 2024"><meta name=docsearch:version content="1.16"><title>Multi-Tenant Crossplane · Crossplane v1.16</title><link rel=canonical href=https://docs.crossplane.io/latest/guides/multi-tenant/><script>(()=>{var e=window.matchMedia("(prefers-color-scheme: dark)").matches,t=localStorage.getItem("darkSwitch")!==null&&localStorage.getItem("darkSwitch")==="dark",n=localStorage.getItem("darkSwitch")!==null&&localStorage.getItem("darkSwitch")==="light";n&&(e=!1),t||e?document.documentElement.setAttribute("color-theme","dark"):document.documentElement.setAttribute("color-theme","light")})()</script><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/@docsearch/css@3 media=print onload='this.media="all"'><link rel=preconnect href=https://9UXKYX61NK-dsn.algolia.net crossorigin data-proofer-ignore><link href="https://docs.crossplane.io/scss/docs.0346bfd4a8aeace526724de64ddada78a0e5122b3b0c83b1021770d6ddef1160.css" rel=stylesheet><link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=192x192 href=/android-chrome-192x192.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=manifest href=/site.webmanifest><link rel=mask-icon href=/safari-pinned-tab.svg color=#f87c44><meta name=apple-mobile-web-app-title content="Crossplane Docs"><meta name=application-name content="Crossplane Docs"><meta name=msapplication-TileColor content="#333f5b"><meta name=theme-color content="#ffffff"><meta property="og:title" content="Crossplane Docs · v1.16 · Multi-Tenant Crossplane"><meta property="og:description" content="This guide describes how to use Crossplane effectively in multi-tenant environments by utilizing Kubernetes primitives and compatible policy enforcement projects in the cloud native ecosystem. Summary …"></head><body><svg xmlns="http://www.w3.org/2000/svg" style="display:none"><symbol id="check2" viewBox="0 0 16 16"><path d="M13.854 3.646a.5.5.0 010 .708l-7 7a.5.5.0 01-.708.0l-3.5-3.5a.5.5.0 11.708-.708L6.5 10.293l6.646-6.647a.5.5.0 01.708.0z"/></symbol><symbol id="x" viewBox="0 0 16 16"><path d="M2.146 2.854a.5.5.0 11.708-.708L8 7.293l5.146-5.147a.5.5.0 01.708.708L8.707 8l5.147 5.146a.5.5.0 01-.708.708L8 8.707l-5.146 5.147a.5.5.0 01-.708-.708L7.293 8 2.146 2.854z"/></symbol><symbol id="chevron-expand" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M3.646 9.146a.5.5.0 01.708.0L8 12.793l3.646-3.647a.5.5.0 01.708.708l-4 4a.5.5.0 01-.708.0l-4-4a.5.5.0 010-.708zm0-2.292a.5.5.0 00.708.0L8 3.207l3.646 3.647a.5.5.0 00.708-.708l-4-4a.5.5.0 00-.708.0l-4 4a.5.5.0 000 .708z"/></symbol><symbol id="clipboard" viewBox="0 0 16 16"><path d="M4 1.5H3a2 2 0 00-2 2V14a2 2 0 002 2h10a2 2 0 002-2V3.5a2 2 0 00-2-2h-1v1h1a1 1 0 011 1V14a1 1 0 01-1 1H3a1 1 0 01-1-1V3.5a1 1 0 011-1h1v-1z"/><path d="M9.5 1a.5.5.0 01.5.5v1a.5.5.0 01-.5.5h-3A.5.5.0 016 2.5v-1a.5.5.0 01.5-.5h3zm-3-1A1.5 1.5.0 005 1.5v1A1.5 1.5.0 006.5 4h3A1.5 1.5.0 0011 2.5v-1A1.5 1.5.0 009.5.0h-3z"/></symbol><symbol id="plus" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 2a.5.5.0 01.5.5v5h5a.5.5.0 010 1h-5v5a.5.5.0 01-1 0v-5h-5a.5.5.0 010-1h5v-5A.5.5.0 018 2z"/></symbol><symbol id="three-dots" viewBox="0 0 16 16"><path d="M3 9.5a1.5 1.5.0 110-3 1.5 1.5.0 010 3zm5 0a1.5 1.5.0 110-3 1.5 1.5.0 010 3zm5 0a1.5 1.5.0 110-3 1.5 1.5.0 010 3z"/></symbol><symbol id="info" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545.0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275.0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 11-2 0 1 1 0 012 0z"/></symbol><symbol id="check" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="M10.97 4.97a.235.235.0 00-.02.022L7.477 9.417 5.384 7.323a.75.75.0 00-1.06 1.06L6.97 11.03a.75.75.0 001.079-.02l3.992-4.99A.75.75.0 0010.97 4.97z"/></symbol><symbol id="exclamation" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="M7.002 11a1 1 0 112 0 1 1 0 01-2 0zM7.1 4.995a.905.905.0 111.8.0l-.35 3.507a.552.552.0 01-1.1.0L7.1 4.995z"/></symbol><symbol id="x-circle" viewBox="0 0 16 16"><path d="M8 15A7 7 0 118 1a7 7 0 010 14zm0 1A8 8 0 108 0a8 8 0 000 16z"/><path d="M4.646 4.646a.5.5.0 01.708.0L8 7.293l2.646-2.647a.5.5.0 01.708.708L8.707 8l2.647 2.646a.5.5.0 01-.708.708L8 8.707l-2.646 2.647a.5.5.0 01-.708-.708L7.293 8 4.646 5.354a.5.5.0 010-.708z"/></symbol><symbol id="fire" viewBox="0 0 16 16"><path d="M8 16c3.314.0 6-2 6-5.5.0-1.5-.5-4-2.5-6 .25 1.5-1.25 2-1.25 2C11 4 9 .5 6 0c.357 2 .5 4-2 6-1.25 1-2 2.729-2 4.5C2 14 4.686 16 8 16zm0-1c-1.657.0-3-1-3-2.75.0-.75.25-2 1.25-3C6.125 10 7 10.5 7 10.5c-.375-1.25.5-3.25 2-3.5-.179 1-.25 2 1 3 .625.5 1 1.364 1 2.25C11 14 9.657 15 8 15z"/></symbol><symbol id="search" viewBox="0 0 16 16"><path d="M11.742 10.344a6.5 6.5.0 10-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 001.415-1.414l-3.85-3.85a1.007 1.007.0 00-.115-.1zM12 6.5a5.5 5.5.0 11-11 0 5.5 5.5.0 0111 0z"/></symbol><symbol id="clipboard-check" viewBox="0 0 16 16"><path d="M6.5.0A1.5 1.5.0 005 1.5v1A1.5 1.5.0 006.5 4h3A1.5 1.5.0 0011 2.5v-1A1.5 1.5.0 009.5.0h-3zm3 1a.5.5.0 01.5.5v1a.5.5.0 01-.5.5h-3A.5.5.0 016 2.5v-1a.5.5.0 01.5-.5h3z"/><path d="M4 1.5H3a2 2 0 00-2 2V14a2 2 0 002 2h10a2 2 0 002-2V3.5a2 2 0 00-2-2h-1v1A2.5 2.5.0 019.5 5h-3A2.5 2.5.0 014 2.5v-1zm6.854 7.354-3 3a.5.5.0 01-.708.0l-1.5-1.5a.5.5.0 01.708-.708L7.5 10.793l2.646-2.647a.5.5.0 01.708.708z"/></symbol><symbol id="pencil-square" viewBox="0 0 16 16"><path d="M15.502 1.94a.5.5.0 010 .706L14.459 3.69l-2-2L13.502.646a.5.5.0 01.707.0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5.0 00-.121.196l-.805 2.414a.25.25.0 00.316.316l2.414-.805a.5.5.0 00.196-.12l6.813-6.814z"/><path fill-rule="evenodd" d="M1 13.5A1.5 1.5.0 002.5 15h11a1.5 1.5.0 001.5-1.5v-6a.5.5.0 00-1 0v6a.5.5.0 01-.5.5h-11a.5.5.0 01-.5-.5v-11a.5.5.0 01.5-.5H9a.5.5.0 000-1H2.5A1.5 1.5.0 001 2.5v11z"/></symbol><symbol id="github" viewBox="0 0 16 16"><path d="M8 0C3.58.0.0 3.58.0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38.0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95.0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12.0.0.67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15.0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48.0 1.07-.01 1.93-.01 2.2.0.21.15.46.55.38A8.012 8.012.0 0016 8c0-4.42-3.58-8-8-8z"/></symbol><symbol id="box-arrow-up-right" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.636 3.5a.5.5.0 00-.5-.5H1.5A1.5 1.5.0 000 4.5v10A1.5 1.5.0 001.5 16h10a1.5 1.5.0 001.5-1.5V7.864a.5.5.0 00-1 0V14.5a.5.5.0 01-.5.5h-10a.5.5.0 01-.5-.5v-10a.5.5.0 01.5-.5h6.636a.5.5.0 00.5-.5z"/><path fill-rule="evenodd" d="M16 .5a.5.5.0 00-.5-.5h-5a.5.5.0 000 1h3.793L6.146 9.146a.5.5.0 10.708.708L15 1.707V5.5a.5.5.0 001 0v-5z"/></symbol></svg><header class="navbar docs-navbar navbar-expand-lg py-0 align-items-center"><div class=docs-left-toggle><button class=navbar-toggler type=button data-bs-toggle=offcanvas data-bs-target=#bdSidebar aria-controls=bdSidebar aria-label="Toggle docs content"><svg xmlns="http://www.w3.org/2000/svg" width="1.5rem" height="1.5rem" fill="currentcolor" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2.5 11.5A.5.5.0 013 11h10a.5.5.0 010 1H3a.5.5.0 01-.5-.5zm0-4A.5.5.0 013 7h10a.5.5.0 010 1H3a.5.5.0 01-.5-.5zm0-4A.5.5.0 013 3h10a.5.5.0 010 1H3a.5.5.0 01-.5-.5z"/></svg> <span class="d-none fs-6 pe-1">Browse</span></button></div><div class="docs-right-toggle order-3"><button class=navbar-toggler type=button data-bs-toggle=offcanvas data-bs-target=#offcanvas aria-controls=offcanvas aria-label="Toggle Crossplane navigation"><svg class="bi white" aria-hidden="true"><use xlink:href="#three-dots"/></svg></button></div><div class=navbar-brand><a href=https://www.crossplane.io aria-label=Crossplane><img src=/img/crossplane-logo.svg alt="Crossplane logo" srcset="/img/crossplane-logo.svg 1x, /img/crossplane-logo.svg 2x" width=152px decoding=async data-nimg=future loading=lazy></a></div><div class="w-100 offcanvas-lg offcanvas-end" tabindex=-1 id=offcanvas aria-labelledby=offcanvasLabel><div class="offcanvas-body p-0"><div class="offcanvas-header p-0"><div class=navbar-brand><a href=https://www.crossplane.io aria-label=Crossplane><img src=/img/crossplane-logo.svg alt="Crossplane logo" srcset="/img/crossplane-logo.svg 1x, /img/crossplane-logo.svg 2x" width=152px decoding=async data-nimg=future loading=lazy></a></div><button type=button class="btn-close btn-close-white" data-bs-dismiss=offcanvas aria-label=Close data-bs-target=#offcanvas></button></div><div class="navbar-center-links collapse navbar-collapse justify-content-evenly show"><ul class="navbar-nav align-items-center"><li class=nav-item><a class=navbar-link href=https://www.crossplane.io/why-control-planes>Why Control Planes?</a></li><li class=nav-item><a class=navbar-link aria-current=page href=https://docs.crossplane.io/>Documentation</a></li><li class=nav-item><a class=navbar-link href=https://www.crossplane.io/community>Community</a></li><li class=nav-item><a class=navbar-link href=https://blog.crossplane.io/>Blog</a></li></ul></div><div class="navbar-icons flex-shrink-1 show"><ul class=navbar-nav><li class="nav-item col-xs p-2"><a class=navbar-link href=https://github.com/crossplane title="Crossplane Github Repository" target=_blank rel=noopener><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentcolor" class="icon-github" viewBox="0 0 16 16"><path d="M8 0C3.58.0.0 3.58.0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38.0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95.0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12.0.0.67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15.0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48.0 1.07-.01 1.93-.01 2.2.0.21.15.46.55.38A8.012 8.012.0 0016 8c0-4.42-3.58-8-8-8z"/></svg><span class=icon-label>Crossplane GitHub</span></a></li><li class="nav-item col-xs p-2"><div id=slack><a class=navbar-link href=https://slack.crossplane.io title="Join the Crossplane Slack" target=_blank rel=noopener><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentcolor" class="icon-slack" viewBox="0 0 16 16"><path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036.0 10.111C0 9.186.756 8.43 1.68 8.43h1.682v1.68zm.846.0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685.0 01-1.682-1.68v-4.21zM5.89 3.362c-.926.0-1.682-.756-1.682-1.681S4.964.0 5.89.0s1.68.756 1.68 1.68v1.682H5.89zm0 .846c.924.0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57.0 6.814.0 5.89c0-.926.756-1.682 1.68-1.682h4.21zm6.749 1.682c0-.926.755-1.682 1.68-1.682.925.0 1.681.756 1.681 1.681s-.756 1.681-1.68 1.681h-1.681V5.89zm-.848.0c0 .924-.755 1.68-1.68 1.68A1.685 1.685.0 018.43 5.89V1.68C8.43.757 9.186.0 10.11.0c.926.0 1.681.756 1.681 1.68v4.21zm-1.681 6.748c.926.0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924.0-1.68-.755-1.68-1.68.0-.925.756-1.681 1.68-1.681h4.21c.924.0 1.68.756 1.68 1.68.0.926-.756 1.681-1.68 1.681h-4.21z"/></svg><span class=icon-label>Crossplane Slack</span></a></div></li><li class="nav-item col-x p-2"><div class="vr d-lg-flex mx-lg-2 text-white"></div></li><li class="nav-item col-xs p-2"><div class="form-check form-switch color-switcher"><input class="d-flex form-check-input" type=checkbox id=darkSwitch> <label class="d-flex navbar-link form-check-label" for=darkSwitch>Dark Mode</label></div></li></ul></div></div></div></header><div class="bd-layout docs-container" data-bs-spy=scroll data-bs-target=#TableOfContents data-bs-threshold=0,1 data-bs-root-margin="0% 0% -75%"><aside class=bd-sidebar><div class="offcanvas-lg offcanvas-start bd-sidebar-container" tabindex=-1 id=bdSidebar aria-labelledby=bdSidebarOffcanvasLabel><div class="offcanvas-header pb-4 border-bottom"><div class="d-flex offcanvas-title fw-bold" id=bdNavbarOffcanvasLabel>Crossplane Documentation - v1.16</div><div class=d-flex><button type=button class="btn-close bi align-self-center p-0" data-bs-dismiss=offcanvas aria-label=Close data-bs-target=#bdSidebar></button></div></div><div class=offcanvas-body><div class="container-fluid p-0"><div class="search-container d-flex row pt-3 ps-4 docsearch opacity-50" data-bs-target=#bdSidebar data-bs-dismiss=offcanvas aria-label="Docs navigation"><div class=p-0 id=docSearch></div></div><nav class="bd-links-nav w-100" aria-label="Docs navigation"><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/>Overview</a></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/getting-started/>Getting Started</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Getting Started Section"> <label for=collapse-ddb170dc class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-ddb170dc aria-expanded=false aria-label="Close or Expand Getting Started Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-ddb170dc><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/getting-started/introduction/>Crossplane Introduction</a></div></div><div class="container flex-row collapse" id=collapse-ddb170dc><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/getting-started/provider-aws/>AWS Quickstart</a></div></div><div class="container flex-row collapse" id=collapse-ddb170dc><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/getting-started/provider-azure/>Azure Quickstart</a></div></div><div class="container flex-row collapse" id=collapse-ddb170dc><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/getting-started/provider-gcp/>GCP Quickstart</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/software/>Install, Upgrade and Uninstall</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Install, Upgrade and Uninstall Section"> <label for=collapse-9f2b1e08 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-9f2b1e08 aria-expanded=false aria-label="Close or Expand Install, Upgrade and Uninstall Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-9f2b1e08><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/software/install/>Install Crossplane</a></div></div><div class="container flex-row collapse" id=collapse-9f2b1e08><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/software/upgrade/>Upgrade Crossplane</a></div></div><div class="container flex-row collapse" id=collapse-9f2b1e08><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/software/uninstall/>Uninstall Crossplane</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/concepts/>Concepts</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Concepts Section"> <label for=collapse-9e31ed45 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-9e31ed45 aria-expanded=false aria-label="Close or Expand Concepts Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/pods/>Crossplane Pods</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/providers/>Providers</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/managed-resources/>Managed Resources</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/compositions/>Compositions</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/composition-revisions/>Composition Revisions</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/composite-resource-definitions/>Composite Resource Definitions</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/composite-resources/>Composite Resources</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/claims/>Claims</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/patch-and-transform/>Patch and Transforms</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/environment-configs/>Environment Configurations</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/composition-functions/>Composition Functions</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/usages/>Usages</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/connection-details/>Connection Details</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/packages/>Configuration Packages</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/server-side-apply/>Server-Side Apply</a></div></div><div class="container flex-row collapse" id=collapse-9e31ed45><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/concepts/image-configs/>Image Configs</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100 active-parent"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/guides/>Guides</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" checked aria-label="Close or Expand Guides Section"> <label for=collapse-c8ab9da3 class=sidebar-label data-bs-toggle=collapse data-bs-target=#collapse-c8ab9da3 aria-expanded=false aria-label="Close or Expand Guides Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/disaster-recovery/>Disaster Recovery with Crossplane</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/write-a-composition-function-in-go/>Write a Composition Function in Go</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/write-a-composition-function-in-python/>Write a Composition Function in Python</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/import-existing-resources/>Import Existing Resources</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/vault-as-secret-store/>Vault as an External Secret Store</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/vault-injection/>Vault Credential Injection</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex active" href=https://docs.crossplane.io/v1.16/guides/multi-tenant/>Multi-Tenant Crossplane</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/crossplane-with-argo-cd/>Configuring Crossplane with Argo CD</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/self-signed-ca-certs/>Self-Signed CA Certs</a></div></div><div class="container flex-row collapse show" id=collapse-c8ab9da3><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/guides/troubleshoot-crossplane/>Troubleshoot Crossplane</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/cli/>CLI Reference</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand CLI Reference Section"> <label for=collapse-2f1c64f4 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-2f1c64f4 aria-expanded=false aria-label="Close or Expand CLI Reference Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-2f1c64f4><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/cli/command-reference/>Command Reference</a></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/api/>API Reference</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand API Reference Section"> <label for=collapse-569451c8 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-569451c8 aria-expanded=false aria-label="Close or Expand API Reference Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href=https://docs.crossplane.io/v1.16/learn/>Learn More</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><input type=checkbox class="d-flex sidebar-checkbox" aria-label="Close or Expand Learn More Section"> <label for=collapse-47924500 class="sidebar-label collapsed" data-bs-toggle=collapse data-bs-target=#collapse-47924500 aria-expanded=false aria-label="Close or Expand Learn More Section"><svg class="flex bi sidebar-icon plus"><use xlink:href="#plus"/></svg><svg class="flex bi sidebar-icon x"><use xlink:href="#x"/></svg></label></div></div><div class="container flex-row collapse" id=collapse-47924500><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/learn/release-cycle/>Release Cycle</a></div></div><div class="container flex-row collapse" id=collapse-47924500><div class="d-flex flex-column"><a class="bd-links d-flex" href=https://docs.crossplane.io/v1.16/learn/feature-lifecycle/>Feature Lifecycle</a></div></div></div><div class="section-container container pe-0 pt-1"><div class=nav-container><a href=https://docs.crossplane.io/contribute/ class="d-inline-flex align-items-center">Contributing Guide</a></div></div><div class="section-container container pe-0 pt-1"><div class="container nav-container pe-0 d-flex w-100"><a class="d-flex w-100 border-0" href="https://github.com/orgs/crossplane/projects/20/views/9?pane=info" target=_blank>Crossplane Roadmap</a><div class="d-flex flex-shrink-1 sidebar-control-container align-self-center"><a href="https://github.com/orgs/crossplane/projects/20/views/9?pane=info"><svg class="flex bi"><use xlink:href="#box-arrow-up-right"/></svg></a></div></div></div></nav></div></div></aside><main class="bd-main order-1"><div class="bd-intro pt-2 ps-lg-2"><div class="d-md-flex flex-md-row-reverse align-items-center justify-content-between"><div class="mb-3 mb-md-0 d-flex"><div class="dropdown float-end bd-dropdown"><a class="btn btn-outline-secondary dropdown-toggle bd-dropdown-item text-reset" href=# role=button id=dropdownMenuLink data-bs-toggle=dropdown aria-haspopup=true aria-expanded=false>v1.16</a><div class="dropdown-menu bd-border-color bd-dropdown" aria-labelledby=dropdownMenuLink><a class="dropdown-item bd-dropdown-item" href=https://docs.crossplane.io/master/guides/multi-tenant/>master</a> <a class="dropdown-item bd-dropdown-item" href=https://docs.crossplane.io/v1.18/guides/multi-tenant/>v1.18<div class="badge rounded-pill latest">Latest</div></a><a class="dropdown-item bd-dropdown-item" href=https://docs.crossplane.io/v1.17/guides/multi-tenant/>v1.17</a> <a class="dropdown-item bd-dropdown-item active" aria-current=true href=https://docs.crossplane.io/v1.16/guides/multi-tenant/>v1.16</a></div></div></div><h1 class="bd-title mb-0" id=content>Multi-Tenant Crossplane</h1></div></div><div class="bd-toc mt-3 mb-5 my-lg-0 ps-xl-3 mb-lg-5"><button class="btn btn-link p-md-0 mb-2 mb-md-0 text-decoration-none bd-toc-toggle d-md-none" type=button data-bs-toggle=collapse data-bs-target=#tocContents aria-expanded=false aria-controls=tocContents> On this page<svg class="bi d-md-none ms-2" aria-hidden="true"><use xlink:href="#chevron-expand"/></svg></button> <strong class="d-none d-md-block h6 my-2">On this page</strong><hr class="d-none d-md-block my-2"><div class="collapse bd-toc-collapse" id=tocContents><nav id=TableOfContents><ul class=nav><li class=nav-item><a class=nav-link href=#summary>Summary</a></li><li class=nav-item><a class=nav-link href=#background>Background</a><ul class=nav><li class=nav-item><a class=nav-link href=#cluster-scoped-managed-resources>Cluster-Scoped Managed Resources</a></li><li class=nav-item><a class=nav-link href=#namespace-scoped-claims>Namespace Scoped Claims</a></li></ul></li><li class=nav-item><a class=nav-link href=#single-cluster-multi-tenancy>Single Cluster Multi-Tenancy</a><ul class=nav><li class=nav-item><a class=nav-link href=#composition-as-an-isolation-mechanism>Composition as an Isolation Mechanism</a></li><li class=nav-item><a class=nav-link href=#namespaces-as-an-isolation-mechanism>Namespaces as an Isolation Mechanism</a></li><li class=nav-item><a class=nav-link href=#policy-enforcement-with-open-policy-agent>Policy Enforcement with Open Policy Agent</a></li></ul></li><li class=nav-item><a class=nav-link href=#multi-cluster-multi-tenancy>Multi-Cluster Multi-Tenancy</a><ul class=nav><li class=nav-item><a class=nav-link href=#reproducible-platforms-with-configuration-packages>Reproducible Platforms with Configuration Packages</a></li><li class=nav-item><a class=nav-link href=#control-plane-of-control-planes>Control Plane of Control Planes</a></li></ul></li></ul></li></ul></nav><nav class=pt-3><div class=pb-2><svg class="bi" width="1em" height="1em"><use xlink:href="#pencil-square"/></svg><span class=ps-1><a target=_blank href="https://github.com/crossplane/docs/issues/new?title=[Web%20Bug]%20-%20Multi-Tenant%20Crossplane&body=%3c!--%20What%27s%20the%20problem?%20--%3e%0a%0a%0aURL:%20https://docs.crossplane.io/v1.16/guides/multi-tenant/">Report a problem</a></span></div><div><svg class="bi" width="1em" height="1em"><use xlink:href="#github"/></svg><span class=ps-1><a href=https://github.com/crossplane/docs/tree/master/content/v1.16/guides/multi-tenant.md>View page source</a></span></div></div></nav></div><div class="bd-content ps-lg-2 DocSearch-content"><div class="bd-callout bd-callout-info d-flex flex-column w-100"><div class="d-flex bd-title fs-6 fw-bold border-bottom border-info"><div class="d-flex pe-3 align-self-center"><svg class="bi flex-shrink-0" role="img" aria-label="Info:"><use xlink:href="#info"/></svg></div><div class=d-flex>This document is for an older version of Crossplane.</div></div><div class=mt-3><p>This document applies to Crossplane version v1.16 and not to the latest release v1.18.</p></div></div><p>This guide describes how to use Crossplane effectively in multi-tenant environments by utilizing Kubernetes primitives and compatible policy enforcement projects in the cloud native ecosystem.</p><h2 id=summary>Summary <a class=anchor-link id=summary href=#summary aria-label="Link to this section: Summary"></a></h2><p>Infrastructure operators in multi-tenant Crossplane environments typically utilize composition and Kubernetes RBAC to define lightweight, standardized policies that dictate what level of self-service developers are given when requesting infrastructure. This is primarily achieved through exposing abstract resource types at the namespace scope, defining <code>Roles</code> for teams and individuals within that namespace, and patching the <code>spec.providerConfigRef</code> of the underlying managed resources so that they use a specific <code>ProviderConfig</code> and credentials when provisioned from each namespace. Larger organizations, or those with more complex environments, may choose to incorporate third-party policy engines, or scale to multiple Crossplane clusters. The following sections describe each of these scenarios in greater detail.</p><ul><li><a href=#summary>Summary</a></li><li><a href=#background>Background</a><ul><li><a href=#cluster-scoped-managed-resources>Cluster-Scoped Managed Resources</a></li><li><a href=#namespace-scoped-claims>Namespace Scoped Claims</a></li></ul></li><li><a href=#single-cluster-multi-tenancy>Single Cluster Multi-Tenancy</a><ul><li><a href=#composition-as-an-isolation-mechanism>Composition as an Isolation Mechanism</a></li><li><a href=#namespaces-as-an-isolation-mechanism>Namespaces as an Isolation Mechanism</a></li><li><a href=#policy-enforcement-with-open-policy-agent>Policy Enforcement with Open Policy Agent</a></li></ul></li><li><a href=#multi-cluster-multi-tenancy>Multi-Cluster Multi-Tenancy</a><ul><li><a href=#reproducible-platforms-with-configuration-packages>Reproducible Platforms with Configuration Packages</a></li><li><a href=#control-plane-of-control-planes>Control Plane of Control Planes</a></li></ul></li></ul><h2 id=background>Background <a class=anchor-link id=background href=#background aria-label="Link to this section: Background"></a></h2><p>Crossplane is designed to run in multi-tenant environments where many teams are consuming the services and abstractions provided by infrastructure operators in the cluster. This functionality is facilitated by two major design patterns in the Crossplane ecosystem.</p><h3 id=cluster-scoped-managed-resources>Cluster-Scoped Managed Resources <a class=anchor-link id=cluster-scoped-managed-resources href=#cluster-scoped-managed-resources aria-label="Link to this section: Cluster-Scoped Managed Resources"></a></h3><p>Typically, Crossplane providers, which supply granular <a href=https://docs.crossplane.io/master/concepts/managed-resources/>managed resources</a> that reflect an external API, authenticate by using a <code>ProviderConfig</code> object that points to a credentials source (such as a Kubernetes <code>Secret</code>, the <code>Pod</code> filesystem, or an environment variable). Then, every managed resource references a <code>ProviderConfig</code> that points to credentials with sufficient permissions to manage that resource type.</p><p>For example, the following <code>ProviderConfig</code> for <code>provider-aws</code> points to a Kubernetes <code>Secret</code> with AWS credentials.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-0-1><a class=lnlinks href=#hl-0-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>aws.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-2><a class=lnlinks href=#hl-0-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>ProviderConfig</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-3><a class=lnlinks href=#hl-0-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-4><a class=lnlinks href=#hl-0-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>cool-aws-creds</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-5><a class=lnlinks href=#hl-0-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-6><a class=lnlinks href=#hl-0-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>credentials</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-7><a class=lnlinks href=#hl-0-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>source</span><span class=p>:</span><span class=w> </span><span class=l>Secret</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-8><a class=lnlinks href=#hl-0-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>secretRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-9><a class=lnlinks href=#hl-0-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>namespace</span><span class=p>:</span><span class=w> </span><span class=l>crossplane-system</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-10><a class=lnlinks href=#hl-0-10>10</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>aws-creds</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-0-11><a class=lnlinks href=#hl-0-11>11</a></span><span class=cl><span class=w> </span><span class=nt>key</span><span class=p>:</span><span class=w> </span><span class=l>creds</span><span class=w> </span></span></span></code></pre></div><p>If a user desired for these credentials to be used to provision an <code>RDSInstance</code>, they would reference the <code>ProviderConfig</code> in the object manifest:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-1-1><a class=lnlinks href=#hl-1-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>database.aws.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-2><a class=lnlinks href=#hl-1-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>RDSInstance</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-3><a class=lnlinks href=#hl-1-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-4><a class=lnlinks href=#hl-1-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>rdsmysql</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-5><a class=lnlinks href=#hl-1-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-6><a class=lnlinks href=#hl-1-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-7><a class=lnlinks href=#hl-1-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>region</span><span class=p>:</span><span class=w> </span><span class=l>us-east-1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-8><a class=lnlinks href=#hl-1-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>dbInstanceClass</span><span class=p>:</span><span class=w> </span><span class=l>db.t3.medium</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-9><a class=lnlinks href=#hl-1-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>masterUsername</span><span class=p>:</span><span class=w> </span><span class=l>masteruser</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-10><a class=lnlinks href=#hl-1-10>10</a></span><span class=cl><span class=w> </span><span class=nt>allocatedStorage</span><span class=p>:</span><span class=w> </span><span class=m>20</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-11><a class=lnlinks href=#hl-1-11>11</a></span><span class=cl><span class=w> </span><span class=nt>engine</span><span class=p>:</span><span class=w> </span><span class=l>mysql</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-12><a class=lnlinks href=#hl-1-12>12</a></span><span class=cl><span class=w> </span><span class=nt>engineVersion</span><span class=p>:</span><span class=w> </span><span class=s2>"5.6.35"</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-13><a class=lnlinks href=#hl-1-13>13</a></span><span class=cl><span class=w> </span><span class=nt>skipFinalSnapshotBeforeDeletion</span><span class=p>:</span><span class=w> </span><span class=kc>true</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-14><a class=lnlinks href=#hl-1-14>14</a></span><span class=cl><span class=w> </span><span class=nt>providerConfigRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-15><a class=lnlinks href=#hl-1-15>15</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>cool-aws-creds</span><span class=w> </span><span class=c># name of ProviderConfig above</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-16><a class=lnlinks href=#hl-1-16>16</a></span><span class=cl><span class=w> </span><span class=nt>writeConnectionSecretToRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-17><a class=lnlinks href=#hl-1-17>17</a></span><span class=cl><span class=w> </span><span class=nt>namespace</span><span class=p>:</span><span class=w> </span><span class=l>crossplane-system</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-1-18><a class=lnlinks href=#hl-1-18>18</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>aws-rdsmysql-conn</span><span class=w> </span></span></span></code></pre></div><p>Since both the <code>ProviderConfig</code> and all managed resources are cluster-scoped, the RDS controller in <code>provider-aws</code> will resolve this reference by fetching the <code>ProviderConfig</code>, obtaining the credentials it points to, and using those credentials to reconcile the <code>RDSInstance</code>. This means that anyone who has been given <a href=https://kubernetes.io/docs/reference/access-authn-authz/rbac/>RBAC</a> to manage <code>RDSInstance</code> objects can use any credentials to do so. In practice, Crossplane assumes that only folks acting as infrastructure administrators or platform builders will interact directly with cluster-scoped resources.</p><h3 id=namespace-scoped-claims>Namespace Scoped Claims <a class=anchor-link id=namespace-scoped-claims href=#namespace-scoped-claims aria-label="Link to this section: Namespace Scoped Claims"></a></h3><p>While managed resources exist at the cluster scope, composite resources, which are defined using a <strong>CompositeResourceDefinition (XRD)</strong> may exist at either the cluster or namespace scope. Platform builders define XRDs and <strong>Compositions</strong> that specify what granular managed resources should be created in response to the creation of an instance of the XRD. More information about this architecture can be found in the <a href=https://docs.crossplane.io/master/concepts/compositions/>Composition</a> documentation.</p><p>Every XRD is exposed at the cluster scope, but only those with <code>spec.claimNames</code> defined will have a namespace scoped variant.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-2-1><a class=lnlinks href=#hl-2-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>apiextensions.crossplane.io/v1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-2><a class=lnlinks href=#hl-2-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>CompositeResourceDefinition</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-3><a class=lnlinks href=#hl-2-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-4><a class=lnlinks href=#hl-2-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>xmysqlinstances.example.org</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-5><a class=lnlinks href=#hl-2-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-6><a class=lnlinks href=#hl-2-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>group</span><span class=p>:</span><span class=w> </span><span class=l>example.org</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-7><a class=lnlinks href=#hl-2-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>names</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-8><a class=lnlinks href=#hl-2-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>XMySQLInstance</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-9><a class=lnlinks href=#hl-2-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>plural</span><span class=p>:</span><span class=w> </span><span class=l>xmysqlinstances</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-10><a class=lnlinks href=#hl-2-10>10</a></span><span class=cl><span class=w> </span><span class=nt>claimNames</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-11><a class=lnlinks href=#hl-2-11>11</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>MySQLInstance</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-12><a class=lnlinks href=#hl-2-12>12</a></span><span class=cl><span class=w> </span><span class=nt>plural</span><span class=p>:</span><span class=w> </span><span class=l>mysqlinstances</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-2-13><a class=lnlinks href=#hl-2-13>13</a></span><span class=cl><span class=w></span><span class=nn>...</span><span class=w> </span></span></span></code></pre></div><p>When the example above is created, Crossplane will produce two <a href=https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/>CustomResourceDefinitions</a>:</p><ol><li>A cluster-scoped type with <code>kind: XMySQLInstance</code>. This is referred to as a <strong>Composite Resource (XR)</strong>.</li><li>A namespace scoped type with <code>kind: MySQLInstance</code>. This is referred to as a <strong>Claim (XRC)</strong>.</li></ol><p>Platform builders may choose to define an arbitrary number of Compositions that map to these types, meaning that creating a <code>MySQLInstance</code> in a given namespace can result in the creations of any set of managed resources at the cluster scope. For instance, creating a <code>MySQLInstance</code> could result in the creation of the <code>RDSInstance</code> defined above.</p><h2 id=single-cluster-multi-tenancy>Single Cluster Multi-Tenancy <a class=anchor-link id=single-cluster-multi-tenancy href=#single-cluster-multi-tenancy aria-label="Link to this section: Single Cluster Multi-Tenancy"></a></h2><p>Depending on the size and scope of an organization, platform teams may choose to run one central Crossplane control plane, or many different ones for each team or business unit. This section will focus on servicing multiple teams within a single cluster, which may or may not be one of many other Crossplane clusters in the organization.</p><h3 id=composition-as-an-isolation-mechanism>Composition as an Isolation Mechanism <a class=anchor-link id=composition-as-an-isolation-mechanism href=#composition-as-an-isolation-mechanism aria-label="Link to this section: Composition as an Isolation Mechanism"></a></h3><p>While managed resources always reflect every field that the underlying provider API exposes, XRDs can have any schema that a platform builder chooses. The fields in the XRD schema can then be patched onto fields in the underlying managed resource defined in a Composition, essentially exposing those fields as configurable to the consumer of the XR or XRC.</p><p>This feature serves as a lightweight policy mechanism by only giving the consumer the ability to customize the underlying resources to the extent the platform builder desires. For instance, in the examples above, a platform builder may choose to define a <code>spec.location</code> field in the schema of the <code>XMySQLInstance</code> that’s an enum with options <code>east</code> and <code>west</code>. In the Composition, those fields could map to the <code>RDSInstance</code> <code>spec.region</code> field, making the value either <code>us-east-1</code> or <code>us-west-1</code>. If no other patches were defined for the <code>RDSInstance</code>, giving a user the ability (using RBAC) to create a <code>XMySQLInstance</code> / <code>MySQLInstance</code> would be akin to giving the ability to create a specifically configured <code>RDSInstance</code>, where they can only decide the region where it lives and they’re restricted to two options.</p><p>This model is in contrast to many infrastructure as code tools where the end user must have provider credentials to create the underlying resources that are rendered from the abstraction. Crossplane takes a different approach, defining various credentials in the cluster (using the <code>ProviderConfig</code>), then giving only the provider controllers the ability to utilize those credentials and provision infrastructure on the users behalf. This creates a consistent permission model, even when using many providers with differing IAM models, by standardizing on Kubernetes RBAC.</p><h3 id=namespaces-as-an-isolation-mechanism>Namespaces as an Isolation Mechanism <a class=anchor-link id=namespaces-as-an-isolation-mechanism href=#namespaces-as-an-isolation-mechanism aria-label="Link to this section: Namespaces as an Isolation Mechanism"></a></h3><p>While the ability to define abstract schemas and patches to concrete resource types using composition is powerful, the ability to define Claim types at the namespace scope enhances the functionality further by enabling RBAC to be applied with namespace restrictions. Most users in a cluster don’t have access to cluster-scoped resources as they’re considered only relevant to infrastructure admins by both Kubernetes and Crossplane.</p><p>Building on our <code>XMySQLInstance</code> / <code>MySQLInstance</code> example, a platform builder may choose to define permissions on <code>MySQLInstance</code> at the namespace scope using a <code>Role</code>. This allows for giving users the ability to create and manage <code>MySQLInstances</code> in their given namespace, but not the ability to see those defined in other namespaces.</p><p>Furthermore, because the <code>metadata.namespace</code> is a field on the XRC, patching can be utilized to configure managed resources based on the namespace in which the corresponding XRC was defined. This is especially useful if a platform builder wants to designate specific credentials or a set of credentials that users in a given namespace can utilize when provisioning infrastructure using an XRC. This can be accomplished today by creating one or more <code>ProviderConfig</code> objects that include the name of the namespace in the <code>ProviderConfig</code> name. For example, if any <code>MySQLInstance</code> created in the <code>team-1</code> namespace should use specific AWS credentials when the provider controller creates the underlying <code>RDSInstance</code>, the platform builder could:</p><ol><li>Define a <code>ProviderConfig</code> with name <code>team-1</code>.</li></ol><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-3-1><a class=lnlinks href=#hl-3-1> 1</a></span><span class=cl><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>aws.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-2><a class=lnlinks href=#hl-3-2> 2</a></span><span class=cl><span class=w></span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>ProviderConfig</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-3><a class=lnlinks href=#hl-3-3> 3</a></span><span class=cl><span class=w></span><span class=nt>metadata</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-4><a class=lnlinks href=#hl-3-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>team-1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-5><a class=lnlinks href=#hl-3-5> 5</a></span><span class=cl><span class=w></span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-6><a class=lnlinks href=#hl-3-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>credentials</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-7><a class=lnlinks href=#hl-3-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>source</span><span class=p>:</span><span class=w> </span><span class=l>Secret</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-8><a class=lnlinks href=#hl-3-8> 8</a></span><span class=cl><span class=w> </span><span class=nt>secretRef</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-9><a class=lnlinks href=#hl-3-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>namespace</span><span class=p>:</span><span class=w> </span><span class=l>crossplane-system</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-10><a class=lnlinks href=#hl-3-10>10</a></span><span class=cl><span class=w> </span><span class=nt>name</span><span class=p>:</span><span class=w> </span><span class=l>team-1-creds</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-3-11><a class=lnlinks href=#hl-3-11>11</a></span><span class=cl><span class=w> </span><span class=nt>key</span><span class=p>:</span><span class=w> </span><span class=l>creds</span><span class=w> </span></span></span></code></pre></div><ol start=2><li>Define a <code>Composition</code> that patches the namespace of the Claim reference in the XR to the <code>providerConfigRef</code> of the <code>RDSInstance</code>.</li></ol><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=ln id=hl-4-1><a class=lnlinks href=#hl-4-1> 1</a></span><span class=cl><span class=nn>...</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-2><a class=lnlinks href=#hl-4-2> 2</a></span><span class=cl><span class=w></span><span class=nt>resources</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-3><a class=lnlinks href=#hl-4-3> 3</a></span><span class=cl><span class=w></span>- <span class=nt>base</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-4><a class=lnlinks href=#hl-4-4> 4</a></span><span class=cl><span class=w> </span><span class=nt>apiVersion</span><span class=p>:</span><span class=w> </span><span class=l>database.aws.crossplane.io/v1beta1</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-5><a class=lnlinks href=#hl-4-5> 5</a></span><span class=cl><span class=w> </span><span class=nt>kind</span><span class=p>:</span><span class=w> </span><span class=l>RDSInstance</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-6><a class=lnlinks href=#hl-4-6> 6</a></span><span class=cl><span class=w> </span><span class=nt>spec</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-7><a class=lnlinks href=#hl-4-7> 7</a></span><span class=cl><span class=w> </span><span class=nt>forProvider</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-8><a class=lnlinks href=#hl-4-8> 8</a></span><span class=cl><span class=w> </span><span class=l>...</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-9><a class=lnlinks href=#hl-4-9> 9</a></span><span class=cl><span class=w> </span><span class=nt>patches</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-10><a class=lnlinks href=#hl-4-10>10</a></span><span class=cl><span class=w> </span>- <span class=nt>fromFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>spec.claimRef.namespace</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-11><a class=lnlinks href=#hl-4-11>11</a></span><span class=cl><span class=w> </span><span class=nt>toFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>spec.providerConfigRef.name</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-12><a class=lnlinks href=#hl-4-12>12</a></span><span class=cl><span class=w> </span><span class=nt>policy</span><span class=p>:</span><span class=w> </span></span></span><span class=line><span class=ln id=hl-4-13><a class=lnlinks href=#hl-4-13>13</a></span><span class=cl><span class=w> </span><span class=nt>fromFieldPath</span><span class=p>:</span><span class=w> </span><span class=l>Required</span><span class=w> </span></span></span></code></pre></div><p>This would result in the <code>RDSInstance</code> using the <code>ProviderConfig</code> of whatever namespace the corresponding <code>MySQLInstance</code> was created in.</p><blockquote><p>Note that this model currently only allows for a single <code>ProviderConfig</code> per namespace. However, future Crossplane releases should allow for defining a set of <code>ProviderConfig</code> that can be selected from using <a href=https://github.com/crossplane/crossplane/pull/2093>Multiple Source Field patching</a>.</p></blockquote><h3 id=policy-enforcement-with-open-policy-agent>Policy Enforcement with Open Policy Agent <a class=anchor-link id=policy-enforcement-with-open-policy-agent href=#policy-enforcement-with-open-policy-agent aria-label="Link to this section: Policy Enforcement with Open Policy Agent"></a></h3><p>In some Crossplane deployment models, only using composition and RBAC to define policy won’t be flexible enough. However, because Crossplane brings management of external infrastructure to the Kubernetes API, it’s well suited to integrate with other projects in the cloud native ecosystem. Organizations and individuals that need a more robust policy engine, or just prefer a more general language for defining policy, often turn to <a href=https://www.openpolicyagent.org/>Open Policy Agent</a> (OPA). OPA allows platform builders to write custom logic in <a href=https://www.openpolicyagent.org/docs/latest/policy-language/>Rego</a>, a domain specific language. Writing policy in this manner allows for not only incorporating the information available in the specific resource being evaluated, but also using other state represented in the cluster. Crossplane users typically install OPA <a href=https://open-policy-agent.github.io/gatekeeper/website/docs/>Gatekeeper</a> to make policy management as streamlined as possible.</p><blockquote><p>A live demo of using OPA with Crossplane can be viewed <a href=https://youtu.be/TaF0_syejXc>here</a>.</p></blockquote><h2 id=multi-cluster-multi-tenancy>Multi-Cluster Multi-Tenancy <a class=anchor-link id=multi-cluster-multi-tenancy href=#multi-cluster-multi-tenancy aria-label="Link to this section: Multi-Cluster Multi-Tenancy"></a></h2><p>Organizations that deploy Crossplane across many clusters typically take advantage of two major features that make managing multiple control planes much simpler.</p><h3 id=reproducible-platforms-with-configuration-packages>Reproducible Platforms with Configuration Packages <a class=anchor-link id=reproducible-platforms-with-configuration-packages href=#reproducible-platforms-with-configuration-packages aria-label="Link to this section: Reproducible Platforms with Configuration Packages"></a></h3><p><a href=https://docs.crossplane.io/master/concepts/packages/>Configuration packages</a> allow platform builders to package their XRDs and Compositions into <a href=https://github.com/opencontainers/image-spec>OCI images</a> that can be distributed via any OCI compliant image registry. These packages can also declare dependencies on providers, meaning that a single package can declare all of the granular managed resources, the controllers that must be deployed to reconcile them, and the abstract types that expose the underlying resources using composition.</p><p>Organizations with many Crossplane deployments utilize Configuration packages to</p><p>reproduce their platform in each cluster. This can be as simple as installing</p><p>Crossplane with the flag to automatically install a Configuration package alongside it.</p><pre tabindex=0><code>helm install crossplane --namespace crossplane-system crossplane-stable/crossplane --set configuration.packages='{"registry.upbound.io/xp/getting-started-with-aws:latest"}' </code></pre><h3 id=control-plane-of-control-planes>Control Plane of Control Planes <a class=anchor-link id=control-plane-of-control-planes href=#control-plane-of-control-planes aria-label="Link to this section: Control Plane of Control Planes"></a></h3><p>Taking the multi-cluster multi-tenancy model one step further, some organizations opt to manage their many Crossplane clusters using a single central Crossplane control plane. This requires setting up the central cluster, then using a provider to spin up new clusters (such as an <a href=https://marketplace.upbound.io/providers/crossplane-contrib/provider-aws/latest/resources/eks.aws.crossplane.io/Cluster/v1beta1>EKS Cluster</a> using <a href=https://marketplace.upbound.io/providers/crossplane-contrib/provider-aws>provider-aws</a>), then using <a href=https://marketplace.upbound.io/providers/crossplane-contrib/provider-helm/>provider-helm</a> to install Crossplane into the new remote cluster, potentially bundling a common Configuration package into each install using the method described above.</p><p>This advanced pattern allows for full management of Crossplane clusters using Crossplane itself, and when done properly, is a scalable solution to providing dedicated control planes to many tenants within a single organization.</p></div></main></div><footer class="bd-footer p-5"><div class="container text-center"><div class="row pb-5 top-row"><div class="col-lg img-col"><img src=/img/crossplane-logo.svg alt="Crossplane logo" srcset="/img/crossplane-logo.svg 1x, /img/crossplane-logo.svg 2x" width=185 height=40 decoding=async data-nimg=future loading=lazy class="d-flex crossplane-footer"></div><div class="col-lg links-col d-fill justify-content-evenly ms-5"><div class=row><div class=col-lg><a class=footer-link target=_blank href=https://twitter.com/crossplane_io>Twitter</a></div><div class=col-lg><a class=footer-link target=_blank href=https://www.youtube.com/channel/UC19FgzMBMqBro361HbE46Fw>Youtube</a></div><div class=col-lg><a class=footer-link target=_blank href="https://www.youtube.com/playlist?list=PL510POnNVaaYFuK-B_SIUrpIonCtLVOzT">Podcast</a></div><div class=col-lg><a class=footer-link target=_blank href=https://groups.google.com/g/crossplane-dev>Forum</a></div></div></div></div><div class="row pb-5"><div class="col-lg copyright-col pe-4 border-end"><p>© Crossplane Authors 2024. Documentation distributed under <a target=_blank href=https://creativecommons.org/licenses/by/4.0/>CC-BY-4.0</a>.</p><p>© 2024 The Linux Foundation. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our <a target=_blank href=https://www.linuxfoundation.org/legal/trademark-usage>Trademark Usage</a> page.</p></div><div class="col-lg cncf-col ms-5"><a class=d-flex target=_blank href=https://www.cncf.io/><img alt=cncfLogo src=/img/cncf-white.webp width=702 height=114 decoding=async data-nimg=future loading=lazy class="cncf-footer py-3"></a><p class=d-flex>We are a Cloud Native Computing Foundation incubating project.</p></div></div></div></footer><script src=https://docs.crossplane.io/js/main-727bf178.bundle.min.js data-no-instant></script><script type=text/javascript>(function(e,t,n,s,o,i,a){e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)},i=t.createElement(s),i.async=1,i.src="https://www.clarity.ms/tag/"+o,a=t.getElementsByTagName(s)[0],a.parentNode.insertBefore(i,a)})(window,document,"clarity","script","el5517lxor")</script> <script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-WFF2NQHG")</script><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WFF2NQHG" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><script type=text/javascript>adroll_adv_id="B4XQTO44VJFVDGCGM332GU",adroll_pix_id="6ROIBHUPMVCSXN7HHIKJTK",adroll_version="2.0",function(e,t,n,s,o){e.__adroll_loaded=!0,e.adroll=e.adroll||[],e.adroll.f=["setProperties","identify","track"];var i="https://s.adroll.com/j/"+adroll_adv_id+"/roundtrip.js";for(o=0;o<e.adroll.f.length;o++)e.adroll[e.adroll.f[o]]=e.adroll[e.adroll.f[o]]||function(t){return function(){e.adroll.push([t,arguments])}}(e.adroll.f[o]);n=t.createElement("script"),s=t.getElementsByTagName("script")[0],n.async=1,n.src=i,s.parentNode.insertBefore(n,s)}(window,document),adroll.track("pageView")</script><script src=https://cdn.jsdelivr.net/npm/@docsearch/js@3></script> <script>docsearch({container:"#docSearch",appId:"9UXKYX61NK",indexName:"crossplane",apiKey:"e07e181044d561f6a4cb7261931d980a",placeholder:"Search the docs"})</script></body></html>