diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..ccdd4b9e --- /dev/null +++ b/404.html @@ -0,0 +1,677 @@ + + + + + + + + + + + + + + + + + + + + + + Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/architecture/index.html b/architecture/index.html new file mode 100644 index 00000000..debe6dbb --- /dev/null +++ b/architecture/index.html @@ -0,0 +1,759 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Architecture - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Architecture

+
flowchart TB
+
+  ci_cd_code[CI/CD as code]
+  git_repo[Git Repository]
+  inputs[Other inputs]
+  project[Project]
+
+  subgraph human[Interested Parties]
+    consumer[Consumer]
+    developer[Developer]
+  end
+
+  subgraph build[Hermetic and Reproducible Builds]
+    nix[Nix Package Manager]
+    nix_derivation[Nix Derivation SBOM]
+    nix_store_path[Nix Store Path - Built artifact]
+    nixpkgs_collection[Nixpkgs Collection]
+    nixpkgs_module_system[Module System]
+  end
+
+  subgraph makes[Makes]
+    makes_cli[Makes CLI]
+    makes_framework[Makes Framework]
+  end
+
+  subgraph slsa[Supply Chain Security]
+    slsa_provenance[SLSA Provenance Attestation]
+  end
+
+  consumer -- uses --> makes_cli
+  ci_cd_code -- uses --> makes_framework
+  ci_cd_code -- uses --> nixpkgs_collection
+  ci_cd_code -- uses --> inputs
+  developer -- uses --> makes_cli
+  developer -- maintains --> project
+  git_repo -- is fetched by --> makes_cli
+  git_repo -- contains --> ci_cd_code
+  makes_cli -- produces --> slsa_provenance
+  makes_cli -- uses --> nix
+  makes_framework -- uses --> nixpkgs_module_system
+  inputs -- is fetched by --> nix
+  nixpkgs_collection -- is fetched by --> nix
+  nixpkgs_module_system -- is fetched by --> nix
+  nix -- produces --> nix_derivation
+  nix -- produces --> nix_store_path
+  project -- has --> git_repo
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 00000000..1cf13b9f Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.b78d2936.min.js b/assets/javascripts/bundle.b78d2936.min.js new file mode 100644 index 00000000..520d0e51 --- /dev/null +++ b/assets/javascripts/bundle.b78d2936.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Ri=Object.create;var gr=Object.defineProperty;var ki=Object.getOwnPropertyDescriptor;var Hi=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,Pi=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,on=Object.prototype.propertyIsEnumerable;var nn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&nn(e,r,t[r]);if(kt)for(var r of kt(t))on.call(t,r)&&nn(e,r,t[r]);return e};var an=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&on.call(e,n)&&(r[n]=e[n]);return r};var Ht=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var $i=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Hi(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=ki(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Ri(Pi(e)):{},$i(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var cn=Ht((xr,sn)=>{(function(e,t){typeof xr=="object"&&typeof sn!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(T){return!!(T&&T!==document&&T.nodeName!=="HTML"&&T.nodeName!=="BODY"&&"classList"in T&&"contains"in T.classList)}function c(T){var Qe=T.type,De=T.tagName;return!!(De==="INPUT"&&s[Qe]&&!T.readOnly||De==="TEXTAREA"&&!T.readOnly||T.isContentEditable)}function f(T){T.classList.contains("focus-visible")||(T.classList.add("focus-visible"),T.setAttribute("data-focus-visible-added",""))}function u(T){T.hasAttribute("data-focus-visible-added")&&(T.classList.remove("focus-visible"),T.removeAttribute("data-focus-visible-added"))}function p(T){T.metaKey||T.altKey||T.ctrlKey||(a(r.activeElement)&&f(r.activeElement),n=!0)}function m(T){n=!1}function d(T){a(T.target)&&(n||c(T.target))&&f(T.target)}function h(T){a(T.target)&&(T.target.classList.contains("focus-visible")||T.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(T.target))}function v(T){document.visibilityState==="hidden"&&(o&&(n=!0),G())}function G(){document.addEventListener("mousemove",N),document.addEventListener("mousedown",N),document.addEventListener("mouseup",N),document.addEventListener("pointermove",N),document.addEventListener("pointerdown",N),document.addEventListener("pointerup",N),document.addEventListener("touchmove",N),document.addEventListener("touchstart",N),document.addEventListener("touchend",N)}function oe(){document.removeEventListener("mousemove",N),document.removeEventListener("mousedown",N),document.removeEventListener("mouseup",N),document.removeEventListener("pointermove",N),document.removeEventListener("pointerdown",N),document.removeEventListener("pointerup",N),document.removeEventListener("touchmove",N),document.removeEventListener("touchstart",N),document.removeEventListener("touchend",N)}function N(T){T.target.nodeName&&T.target.nodeName.toLowerCase()==="html"||(n=!1,oe())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),G(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var fn=Ht(Er=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(f){return!1}},r=t(),n=function(f){var u={next:function(){var p=f.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(f){return encodeURIComponent(f).replace(/%20/g,"+")},i=function(f){return decodeURIComponent(String(f).replace(/\+/g," "))},s=function(){var f=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof f){var d=this;p.forEach(function(oe,N){d.append(N,oe)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),f._entries&&(f._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(c,f){typeof c!="string"&&(c=String(c)),f&&typeof f!="string"&&(f=String(f));var u=document,p;if(f&&(e.location===void 0||f!==e.location.href)){f=f.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=f,u.head.appendChild(p);try{if(p.href.indexOf(f)!==0)throw new Error(p.href)}catch(T){throw new Error("URL unable to set base "+f+" due to "+T)}}var m=u.createElement("a");m.href=c,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=c,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!f)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,G=!0,oe=this;["append","delete","set"].forEach(function(T){var Qe=h[T];h[T]=function(){Qe.apply(h,arguments),v&&(G=!1,oe.search=h.toString(),G=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var N=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==N&&(N=this.search,G&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},s=i.prototype,a=function(c){Object.defineProperty(s,c,{get:function(){return this._anchorElement[c]},set:function(f){this._anchorElement[c]=f},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(c){a(c)}),Object.defineProperty(s,"search",{get:function(){return this._anchorElement.search},set:function(c){this._anchorElement.search=c,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(s,{toString:{get:function(){var c=this;return function(){return c.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(c){this._anchorElement.href=c,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(c){this._anchorElement.pathname=c},enumerable:!0},origin:{get:function(){var c={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],f=this._anchorElement.port!=c&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(f?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(c){},enumerable:!0},username:{get:function(){return""},set:function(c){},enumerable:!0}}),i.createObjectURL=function(c){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(c){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er)});var Kr=Ht((Mt,qr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Mt=="object"&&typeof qr=="object"?qr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Mt=="object"?Mt.ClipboardJS=r():t.ClipboardJS=r()})(Mt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Ci}});var s=i(279),a=i.n(s),c=i(370),f=i.n(c),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(O){return!1}}var d=function(O){var E=p()(O);return m("cut"),E},h=d;function v(j){var O=document.documentElement.getAttribute("dir")==="rtl",E=document.createElement("textarea");E.style.fontSize="12pt",E.style.border="0",E.style.padding="0",E.style.margin="0",E.style.position="absolute",E.style[O?"right":"left"]="-9999px";var H=window.pageYOffset||document.documentElement.scrollTop;return E.style.top="".concat(H,"px"),E.setAttribute("readonly",""),E.value=j,E}var G=function(O,E){var H=v(O);E.container.appendChild(H);var I=p()(H);return m("copy"),H.remove(),I},oe=function(O){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},H="";return typeof O=="string"?H=G(O,E):O instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(O==null?void 0:O.type)?H=G(O.value,E):(H=p()(O),m("copy")),H},N=oe;function T(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?T=function(E){return typeof E}:T=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},T(j)}var Qe=function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},E=O.action,H=E===void 0?"copy":E,I=O.container,q=O.target,Me=O.text;if(H!=="copy"&&H!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&T(q)==="object"&&q.nodeType===1){if(H==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(H==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Me)return N(Me,{container:I});if(q)return H==="cut"?h(q):N(q,{container:I})},De=Qe;function $e(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$e=function(E){return typeof E}:$e=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},$e(j)}function wi(j,O){if(!(j instanceof O))throw new TypeError("Cannot call a class as a function")}function rn(j,O){for(var E=0;E0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof I.action=="function"?I.action:this.defaultAction,this.target=typeof I.target=="function"?I.target:this.defaultTarget,this.text=typeof I.text=="function"?I.text:this.defaultText,this.container=$e(I.container)==="object"?I.container:document.body}},{key:"listenClick",value:function(I){var q=this;this.listener=f()(I,"click",function(Me){return q.onClick(Me)})}},{key:"onClick",value:function(I){var q=I.delegateTarget||I.currentTarget,Me=this.action(q)||"copy",Rt=De({action:Me,container:this.container,target:this.target(q),text:this.text(q)});this.emit(Rt?"success":"error",{action:Me,text:Rt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(I){return vr("action",I)}},{key:"defaultTarget",value:function(I){var q=vr("target",I);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(I){return vr("text",I)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(I){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return N(I,q)}},{key:"cut",value:function(I){return h(I)}},{key:"isSupported",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof I=="string"?[I]:I,Me=!!document.queryCommandSupported;return q.forEach(function(Rt){Me=Me&&!!document.queryCommandSupported(Rt)}),Me}}]),E}(a()),Ci=Ai},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==o;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}n.exports=s},438:function(n,o,i){var s=i(828);function a(u,p,m,d,h){var v=f.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function c(u,p,m,d,h){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof m=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return a(v,p,m,d,h)}))}function f(u,p,m,d){return function(h){h.delegateTarget=s(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=c},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(n,o,i){var s=i(879),a=i(438);function c(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(h))throw new TypeError("Third argument must be a Function");if(s.node(m))return f(m,d,h);if(s.nodeList(m))return u(m,d,h);if(s.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function f(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return a(document.body,m,d,h)}n.exports=c},817:function(n){function o(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),f=document.createRange();f.selectNodeContents(i),c.removeAllRanges(),c.addRange(f),s=c.toString()}return s}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function f(){c.off(i,f),s.apply(a,arguments)}return f._=s,this.on(i,f,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,f=a.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ns=/["'&<>]/;Go.exports=os;function os(e){var t=""+e,r=ns.exec(t);if(!r)return t;var n,o="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(f[0]===6||f[0]===2)){r=0;continue}if(f[0]===3&&(!i||f[1]>i[0]&&f[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],s;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(a){s={error:a}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(s)throw s.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||a(m,d)})})}function a(m,d){try{c(n[m](d))}catch(h){p(i[0][3],h)}}function c(m){m.value instanceof et?Promise.resolve(m.value.v).then(f,u):p(i[0][2],m)}function f(m){a("next",m)}function u(m){a("throw",m)}function p(m,d){m(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function ln(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Ee=="function"?Ee(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),o(a,c,s.done,s.value)})}}function o(i,s,a,c){Promise.resolve(c).then(function(f){i({value:f,done:a})},s)}}function A(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var $t=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Ee(s),c=a.next();!c.done;c=a.next()){var f=c.value;f.remove(this)}}catch(v){t={error:v}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var u=this.initialTeardown;if(A(u))try{u()}catch(v){i=v instanceof $t?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=Ee(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{mn(h)}catch(v){i=i!=null?i:[],v instanceof $t?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new $t(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)mn(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Sr=Ie.EMPTY;function It(e){return e instanceof Ie||e&&"closed"in e&&A(e.remove)&&A(e.add)&&A(e.unsubscribe)}function mn(e){A(e)?e():e.unsubscribe()}var Le={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,s=o.isStopped,a=o.observers;return i||s?Sr:(this.currentObservers=null,a.push(r),new Ie(function(){n.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,s=n.isStopped;o?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new En(r,n)},t}(F);var En=function(e){ie(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Sr},t}(x);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ie(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,s=n._infiniteTimeWindow,a=n._timestampProvider,c=n._windowTime;o||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,s=o._buffer,a=s.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var s=r.actions;n!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Ut);var Tn=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Wt);var Te=new Tn(Sn);var _=new F(function(e){return e.complete()});function Dt(e){return e&&A(e.schedule)}function Cr(e){return e[e.length-1]}function Ye(e){return A(Cr(e))?e.pop():void 0}function Oe(e){return Dt(Cr(e))?e.pop():void 0}function Vt(e,t){return typeof Cr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return A(e==null?void 0:e.then)}function Nt(e){return A(e[ft])}function qt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ni(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Qt=Ni();function Yt(e){return A(e==null?void 0:e[Qt])}function Gt(e){return pn(this,arguments,function(){var r,n,o,i;return Pt(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,et(r.read())];case 3:return n=s.sent(),o=n.value,i=n.done,i?[4,et(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,et(o)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Bt(e){return A(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(Nt(e))return qi(e);if(pt(e))return Ki(e);if(zt(e))return Qi(e);if(qt(e))return On(e);if(Yt(e))return Yi(e);if(Bt(e))return Gi(e)}throw Kt(e)}function qi(e){return new F(function(t){var r=e[ft]();if(A(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Ki(e){return new F(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?L(function(o,i){return e(o,i,n)}):de,ge(1),r?He(t):Vn(function(){return new Xt}))}}function zn(){for(var e=[],t=0;t=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new x}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(f){var u,p,m,d=0,h=!1,v=!1,G=function(){p==null||p.unsubscribe(),p=void 0},oe=function(){G(),u=m=void 0,h=v=!1},N=function(){var T=u;oe(),T==null||T.unsubscribe()};return y(function(T,Qe){d++,!v&&!h&&G();var De=m=m!=null?m:r();Qe.add(function(){d--,d===0&&!v&&!h&&(p=$r(N,c))}),De.subscribe(Qe),!u&&d>0&&(u=new rt({next:function($e){return De.next($e)},error:function($e){v=!0,G(),p=$r(oe,o,$e),De.error($e)},complete:function(){h=!0,G(),p=$r(oe,s),De.complete()}}),U(T).subscribe(u))})(f)}}function $r(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function z(e,t=document){let r=ce(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ce(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function er(e){return C(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),V(e===_e()),B())}function Xe(e){return{x:e.offsetLeft,y:e.offsetTop}}function Qn(e){return C(b(window,"load"),b(window,"resize")).pipe(Ce(0,Te),l(()=>Xe(e)),V(Xe(e)))}function tr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return C(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,Te),l(()=>tr(e)),V(tr(e)))}var Gn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Dr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),ga?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Dr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=va.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Bn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Xn=typeof WeakMap!="undefined"?new WeakMap:new Gn,Zn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=ya.getInstance(),n=new Aa(t,r,this);Xn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Zn.prototype[e]=function(){var t;return(t=Xn.get(this))[e].apply(t,arguments)}});var Ca=function(){return typeof rr.ResizeObserver!="undefined"?rr.ResizeObserver:Zn}(),eo=Ca;var to=new x,Ra=$(()=>k(new eo(e=>{for(let t of e)to.next(t)}))).pipe(g(e=>C(ze,k(e)).pipe(R(()=>e.disconnect()))),J(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ye(e){return Ra.pipe(S(t=>t.observe(e)),g(t=>to.pipe(L(({target:r})=>r===e),R(()=>t.unobserve(e)),l(()=>he(e)))),V(he(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ir(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var ro=new x,ka=$(()=>k(new IntersectionObserver(e=>{for(let t of e)ro.next(t)},{threshold:0}))).pipe(g(e=>C(ze,k(e)).pipe(R(()=>e.disconnect()))),J(1));function ar(e){return ka.pipe(S(t=>t.observe(e)),g(t=>ro.pipe(L(({target:r})=>r===e),R(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function no(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=he(e),o=bt(e);return r>=o.height-n.height-t}),B())}var sr={drawer:z("[data-md-toggle=drawer]"),search:z("[data-md-toggle=search]")};function oo(e){return sr[e].checked}function Ke(e,t){sr[e].checked!==t&&sr[e].click()}function Ue(e){let t=sr[e];return b(t,"change").pipe(l(()=>t.checked),V(t.checked))}function Ha(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Pa(){return C(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(V(!1))}function io(){let e=b(window,"keydown").pipe(L(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:oo("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),L(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!Ha(n,r)}return!0}),pe());return Pa().pipe(g(t=>t?_:e))}function le(){return new URL(location.href)}function ot(e){location.href=e.href}function ao(){return new x}function so(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)so(e,r)}function M(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)so(n,o);return n}function cr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function co(){return location.hash.substring(1)}function Vr(e){let t=M("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function $a(){return b(window,"hashchange").pipe(l(co),V(co()),L(e=>e.length>0),J(1))}function fo(){return $a().pipe(l(e=>ce(`[id="${e}"]`)),L(e=>typeof e!="undefined"))}function zr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(V(t.matches))}function uo(){let e=matchMedia("print");return C(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(V(e.matches))}function Nr(e,t){return e.pipe(g(r=>r?t():_))}function fr(e,t={credentials:"same-origin"}){return ue(fetch(`${e}`,t)).pipe(fe(()=>_),g(r=>r.status!==200?Tt(()=>new Error(r.statusText)):k(r)))}function We(e,t){return fr(e,t).pipe(g(r=>r.json()),J(1))}function po(e,t){let r=new DOMParser;return fr(e,t).pipe(g(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),J(1))}function ur(e){let t=M("script",{src:e});return $(()=>(document.head.appendChild(t),C(b(t,"load"),b(t,"error").pipe(g(()=>Tt(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),R(()=>document.head.removeChild(t)),ge(1))))}function lo(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function mo(){return C(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(lo),V(lo()))}function ho(){return{width:innerWidth,height:innerHeight}}function bo(){return b(window,"resize",{passive:!0}).pipe(l(ho),V(ho()))}function vo(){return Q([mo(),bo()]).pipe(l(([e,t])=>({offset:e,size:t})),J(1))}function pr(e,{viewport$:t,header$:r}){let n=t.pipe(Z("size")),o=Q([n,r]).pipe(l(()=>Xe(e)));return Q([r,t,o]).pipe(l(([{height:i},{offset:s,size:a},{x:c,y:f}])=>({offset:{x:s.x-c,y:s.y-f+i},size:a})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(s=>{let a=document.createElement("script");a.src=i,a.onload=s,document.body.appendChild(a)})),Promise.resolve())}var r=class extends EventTarget{constructor(n){super(),this.url=n,this.m=i=>{i.source===this.w&&(this.dispatchEvent(new MessageEvent("message",{data:i.data})),this.onmessage&&this.onmessage(i))},this.e=(i,s,a,c,f)=>{if(s===`${this.url}`){let u=new ErrorEvent("error",{message:i,filename:s,lineno:a,colno:c,error:f});this.dispatchEvent(u),this.onerror&&this.onerror(u)}};let o=document.createElement("iframe");o.hidden=!0,document.body.appendChild(this.iframe=o),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Contributing to Makes

+
    +
  • Bug reports: here
  • +
  • Feature requests: here
  • +
  • Give us a star: here
  • +
  • Feedback: here
  • +
+

Code contributions

+

We accept anything that benefits the community, +thanks for sharing your work with the world. +We can discuss implementation details here.

+
    +
  1. Write your idea: here
  2. +
  3. Fork Makes on GitHub
  4. +
  5. Git-clone your fork
  6. +
  7. Hack as much as you like!
  8. +
  9. Git-commit your changes.
  10. +
  11. Git-push changes to your fork
  12. +
  13. Create a Pull Request from your fork to Makes
  14. +
+

Guidelines:

+
    +
  • Keep it simple
  • +
  • Remember we write code for humans, not machines
  • +
  • Write an argument: /src/args
  • +
  • Write a module (if applies): /src/evaluator/modules
  • +
  • Write docs: /README.md or /docs
  • +
  • Write a test: /makes.nix or /makes/**/main.nix
  • +
  • Write a test GitHub workflow: /.github/workflows/dev.yml
  • +
+

Examples:

+ + +

All of the code +that you submit to our code repository +will be licensed under the MIT license.

+

Please add a Signed-off-by: Full Name <email> to your commits as explained here +to signal that you agree +to the terms of the following +Developer Certificate of Origin.

+

Thank you!

+

Review process

+

Once a pull request is opened in the repository, +a maintainer must follow the following steps +to review it:

+
    +
  1. Check that the proposed change has an associated issue, + enough discussion has happened on it, + and there is consensus in the implementation details, + and if we agree that implement it is a good idea.
  2. +
  3. Check if the change modifies the Architecture + in any way, and that it has been updated.
  4. +
  5. Check if the implementation follows the + Secure Design Principles, + and documents there + any new interactions, + or updates the documentation accordingly.
  6. +
  7. Check if the implementation introduces new threats, + or changes/removes an existing threat, + and if the Threat Model + documentation has been updated to reflect it.
  8. +
  9. Check if the change adds or modifies + an existing security property of the system, + and if the Software Assurance + documentation has been updated to reflect it.
  10. +
  11. Check if the CI/CD succeeded. + No job should fail + unless something unrelated to the pull request happened.
  12. +
  13. The Developer Certificate of Origin was accepted, + normally through checking + that the job in the CI/CD that verifies it succeeded.
  14. +
  15. The steps mentioned in the sections above were followed, + particularly check if the code is readable, + maintainable, + proper tests were added or updated, + the corresponding docs were added or updated, + and the architecture and design seems to be of good quality.
  16. +
+ + + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/governance/index.html b/governance/index.html new file mode 100644 index 00000000..bc674a4b --- /dev/null +++ b/governance/index.html @@ -0,0 +1,721 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Governance - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Governance

+

Decisions, approvals, code reviews, etc, +are made by the project maintainers:

+ +

Discussions usually happen within the issues section.

+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..c0900004 --- /dev/null +++ b/index.html @@ -0,0 +1,710 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

🦄 Makes

+

A software supply chain framework powered by Nix.

+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000..c52ec6ed --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udd84 Makes","text":"

A software supply chain framework powered by Nix.

"},{"location":"architecture/","title":"Architecture","text":"
flowchart TB\n\n  ci_cd_code[CI/CD as code]\n  git_repo[Git Repository]\n  inputs[Other inputs]\n  project[Project]\n\n  subgraph human[Interested Parties]\n    consumer[Consumer]\n    developer[Developer]\n  end\n\n  subgraph build[Hermetic and Reproducible Builds]\n    nix[Nix Package Manager]\n    nix_derivation[Nix Derivation SBOM]\n    nix_store_path[Nix Store Path - Built artifact]\n    nixpkgs_collection[Nixpkgs Collection]\n    nixpkgs_module_system[Module System]\n  end\n\n  subgraph makes[Makes]\n    makes_cli[Makes CLI]\n    makes_framework[Makes Framework]\n  end\n\n  subgraph slsa[Supply Chain Security]\n    slsa_provenance[SLSA Provenance Attestation]\n  end\n\n  consumer -- uses --> makes_cli\n  ci_cd_code -- uses --> makes_framework\n  ci_cd_code -- uses --> nixpkgs_collection\n  ci_cd_code -- uses --> inputs\n  developer -- uses --> makes_cli\n  developer -- maintains --> project\n  git_repo -- is fetched by --> makes_cli\n  git_repo -- contains --> ci_cd_code\n  makes_cli -- produces --> slsa_provenance\n  makes_cli -- uses --> nix\n  makes_framework -- uses --> nixpkgs_module_system\n  inputs -- is fetched by --> nix\n  nixpkgs_collection -- is fetched by --> nix\n  nixpkgs_module_system -- is fetched by --> nix\n  nix -- produces --> nix_derivation\n  nix -- produces --> nix_store_path\n  project -- has --> git_repo
"},{"location":"contributing/","title":"Contributing to Makes","text":"
  • Bug reports: here
  • Feature requests: here
  • Give us a star: here
  • Feedback: here
"},{"location":"contributing/#code-contributions","title":"Code contributions","text":"

We accept anything that benefits the community, thanks for sharing your work with the world. We can discuss implementation details here.

  1. Write your idea: here
  2. Fork Makes on GitHub
  3. Git-clone your fork
  4. Hack as much as you like!
  5. Git-commit your changes.
  6. Git-push changes to your fork
  7. Create a Pull Request from your fork to Makes

Guidelines:

  • Keep it simple
  • Remember we write code for humans, not machines
  • Write an argument: /src/args
  • Write a module (if applies): /src/evaluator/modules
  • Write docs: /README.md or /docs
  • Write a test: /makes.nix or /makes/**/main.nix
  • Write a test GitHub workflow: /.github/workflows/dev.yml

Examples:

  • feat(build): #262 lint git mailmap
  • feat(build): #232 lint terraform
  • feat(build): #232 test terraform
  • feat(build): #232 deploy terraform
  • feat(build): #252 aws secrets from env
  • feat(build): #232 make parallel utils
"},{"location":"contributing/#the-legal-side-of-contributions","title":"The legal side of contributions","text":"

All of the code that you submit to our code repository will be licensed under the MIT license.

Please add a Signed-off-by: Full Name <email> to your commits as explained here to signal that you agree to the terms of the following Developer Certificate of Origin.

Thank you!

"},{"location":"contributing/#review-process","title":"Review process","text":"

Once a pull request is opened in the repository, a maintainer must follow the following steps to review it:

  1. Check that the proposed change has an associated issue, enough discussion has happened on it, and there is consensus in the implementation details, and if we agree that implement it is a good idea.
  2. Check if the change modifies the Architecture in any way, and that it has been updated.
  3. Check if the implementation follows the Secure Design Principles, and documents there any new interactions, or updates the documentation accordingly.
  4. Check if the implementation introduces new threats, or changes/removes an existing threat, and if the Threat Model documentation has been updated to reflect it.
  5. Check if the change adds or modifies an existing security property of the system, and if the Software Assurance documentation has been updated to reflect it.
  6. Check if the CI/CD succeeded. No job should fail unless something unrelated to the pull request happened.
  7. The Developer Certificate of Origin was accepted, normally through checking that the job in the CI/CD that verifies it succeeded.
  8. The steps mentioned in the sections above were followed, particularly check if the code is readable, maintainable, proper tests were added or updated, the corresponding docs were added or updated, and the architecture and design seems to be of good quality.
"},{"location":"governance/","title":"Governance","text":"

Decisions, approvals, code reviews, etc, are made by the project maintainers:

  • Kevin Amado - @kamadorueda
  • Daniel Salazar - @dsalaza4
  • Jhon Perez - @jpverde

Discussions usually happen within the issues section.

"},{"location":"security/","title":"Security","text":"

This section evaluates Makes using various standards and tries to address the security of Makes as an ecosystem using the three following categories:

  • Security of using the Makes CLI.
  • Security of the software built using Makes.
  • Security of Makes as a software project.
"},{"location":"security/assurance/","title":"Software Assurance","text":"

This is what user can expect from Makes in terms of security, the notation is that of a Structured Assurance Case Model[^1].

  • The Makes CLI application is free of known security vulnerabilities.

  • The Python code of the Makes CLI application is free of known security vulnerabilities.

    • SonarCloud reviews every pull request.

    Proof:

    • You can check the SonarCloud pull requests list for Makes

    • You can check the pull requests history and see if the latest pull requests have a comment from SonarCloud. For example: PR 925, Comment 1256837172

    • Vulnerabilities count on SonarCloud is zero.

    Proof:

    • Visit the SonarCloud dashboard. The vulnerabilities count should be zero.
  • The dependencies of the Makes CLI application are free of known security vulnerabilities.

    • Dependabot alerts are enabled for the repository.

    Proof:

    • As a project maintainer, you can see if Dependabot is enabled here.
    • As an external user, there is no way to verify if Dependabot is enabled because the configuration page for this is only available to repository maintainers. However, it is possible to see the pull requests created by the bot, for example: PR 927. Additionally, an external user could check if there has been Dependabot pull requests recently by checking the pull requests history. It is important to note that if no recent pull requests exist it may mean that no known security vulnerabilities have been found, and not necessarily that this claim is false.
"},{"location":"security/assurance/#references","title":"References","text":"

[^1]:

Rhodes, T. , Boland Jr., F. , Fong, E. and Kass, M. (2009), Software Assurance Using Structured Assurance Case Models, NIST Interagency/Internal Report (NISTIR), National Institute of Standards and Technology, Gaithersburg, MD, [online], https://tsapps.nist.gov/publication/get_pdf.cfm?pub_id=902688 (Accessed September 23, 2022)

"},{"location":"security/design-principles/","title":"Design Principles","text":""},{"location":"security/design-principles/#principle-of-least-privilege","title":"Principle of Least Privilege","text":"
  • The Makes CLI is a python application that runs in user-space. The privileges required are:

  • Write access to the ${HOME}, which is normally owned by the user, so no extra privileges other than what the user already has are required.

  • Creating temporary files/directories, which respects the ${TMPDIR} environment variable, which is a functionality normally available to a user, so no extra privileges are required.
  • A system with Nix installed.
  • (optional) privileges to create Kernel namespaces.

  • The Makes framework is simply a library that aids the developer in creating build scripts, so no privileges are required, the Makes framework is just source code that the user can opt-in to use.

  • When containers are built, they are build by assembling an OCI-compliant image (TAR files per each layer plus a JSON manifest), without resorting to privileged daemons like that of Docker. They are generated as any other build (hermetic, pure, etc) using information from the Nix Store.

"},{"location":"security/design-principles/#principle-of-fail-safe-defaults","title":"Principle of Fail-Safe Defaults","text":"
  • By default, builds are run in a sandbox that uses kernel namespaces to prevent the build from accessing the network and the external file system.

The user is given the option to opt-out from this behavior, but this is enabled by default.

  • Generated files are created inside user-owned folders by default, which inherit the security that the user has previously defined for the directory.

An user may opt-out from this behavior by setting environment variables, but user-owned folders are selected by default.

  • In the most common configuration, the contents of the /nix/store are never published to the internet.

A user may want to share artifacts with other users in order to improve performance by writing artifacts to a binary cache, so that other users can download the artifacts if they have already been built by other user, but this behavior requires configuring a read+write binary cache and setting the corresponding access secret.

A read-only binary cache (https://cache.nixos.org) and no write binary cache is the default configuration,

"},{"location":"security/design-principles/#principle-of-economy-of-mechanism","title":"Principle of Economy of Mechanism","text":"
  • The Makes CLI is essentially a wrapper over Nix, so the surface is as small as possible (~1000 loc).
  • The Makes Framework defines a common set of utilities a user can opt-in to use, saving the user the work of writing that functionality themselves which would require the same amount of code anyway.
"},{"location":"security/design-principles/#principle-of-complete-mediation","title":"Principle of Complete Mediation","text":""},{"location":"security/design-principles/#principle-of-open-design","title":"Principle of Open Design","text":"
  • Makes is Free and Open Source Software, anyone can read its internals: https://github.com/fluidattacks/makes
"},{"location":"security/design-principles/#principle-of-separation-of-privilege","title":"Principle of Separation of Privilege","text":""},{"location":"security/design-principles/#principle-of-least-common-mechanism","title":"Principle of Least Common Mechanism","text":"
  • In the most common case each user of Makes has a personal /nix/store and a personal installation of Nix. The /nix/store contents are not shared between users by default, unless the user configures a read+write binary cache and sets the corresponding binary cache secret.
"},{"location":"security/design-principles/#principle-of-psychological-acceptability","title":"Principle of Psychological Acceptability","text":"
  • The Makes CLI is easy to use. Performing an installation using the default values yields a sufficiently secure version of the system. Users familiar with other build tools would feel at home.
"},{"location":"security/slsa/","title":"Supply Chain Levels for Software Artifacts","text":"

The SLSA framework helps organizations measure the level of assurance that the Software Artifacts they produce actually contain and use what they intended (integrity), by ensuring that the whole build and release process, and all of the involved sources and dependencies cannot be tampered with.

In this document, we use the version 0.1 of the specification.

Our current SLSA level is 2. The following is a detail of the levels achieved on each of the requirements:

Requirement Level Source - Version Controlled 4 Source - Verified History 4 Source - Retained Indefinitely 4 Source - Two Person Reviewed 3 Build - Scripted Build 4 Build - Build Service 4 Build - Build As Code 4 Build - Ephemeral Environment 4 Build - Isolated 2 Build - Parameter-less 4 Build - Hermetic 4 Build - Reproducible 4 Provenance - Available 4 Provenance - Authenticated 4 Provenance - Service Generated 4 Provenance - Non-Falsifiable 4 Provenance - Dependencies Complete 4 Common - Security 4 Common - Access 4 Common - Superusers 3

For clarity, this is how SLSA definitions map into our infrastructure:

  • Source: Git repository at: github.com/fluidattacks/makes.
  • Platform: GitHub Actions, Makes, and the Nix package manager.
  • Build service: GitHub Actions, using GitHub hosted runners.
  • Build: A Nix derivation.
  • Environment: A sandbox that Chroots into an empty temporary directory, provides private versions of /proc, /dev, /dev/shm, and /dev/pts, and uses a private PID, mount, network, IPC, and UTS namespace to isolate itself from other processes in the system.
  • Steps: Instructions declared in the corresponding Makes configuration files written using the Nix programming language and shell scripting, versioned as-code in the source.
"},{"location":"security/slsa/#source-requirements","title":"Source Requirements","text":""},{"location":"security/slsa/#version-controlled","title":"Version controlled","text":"

Every change to the source is tracked on GitHub, using the Git version control system.

  • Change history: There exists a record of the history of changes that went into the revision. Each change contains: the identities of the uploader and reviewers (if any), timestamps of the reviews (if any) and submission, the change description/justification, the content of the change, and the parent revisions.

For example: PR 649.

  • Immutable reference: There exists a way to indefinitely reference a particular, immutable revision. For example: c61feb1be11abc4d7ffed52c660a45c57f06599c.
"},{"location":"security/slsa/#verified-history","title":"Verified history","text":"

Every change in the revision\u2019s history need to pass through a Pull Request.

In order to approve a Pull Request the reviewer need to be strongly authenticated into GitHub. The authentication process requires 2FA, and the dates of the change are recorded in the Pull Request.

Only users who were previously granted access by a platform Admin can review Pull Requests. External contributors can create a Pull Request without any special privileges, but it won't be merged until reviewers submit their approval.

For example: PR 649.

"},{"location":"security/slsa/#retained-indefinitely","title":"Retained indefinitely","text":"

The revision and its change history are preserved indefinitely and cannot be deleted or modified (not even with multi-party approval). Additionally, the main branch is protected against accidental history overwrite using GitHub's branch protection rules.

At the moment, no legal requirement impedes us to preserve indefinitely our change history, and no obliteration policy is in effect. In fact, our source code is Free and Open Source Software: Anyone can download or fork the repository.

"},{"location":"security/slsa/#two-person-reviewed","title":"Two Person Reviewed","text":"

Every change in the revision\u2019s history is agreed to by at least one trusted person prior to submission and each of these trusted persons are authenticated into the platform (using 2FA) first. Only project maintainers can merge Pull Requests and therefore append a change into the revision's history.

"},{"location":"security/slsa/#build-requirements","title":"Build Requirements","text":""},{"location":"security/slsa/#scripted-build","title":"Scripted Build","text":"

All build steps were fully defined using GitHub Actions, Makes and Nix.

Manual commands are not necessary to invoke the build script. A new build is triggered automatically each time new changes are pushed to the repository.

For example:

  • .github/workflows/prod.yml
  • makes/cli/pypi/main.nix
"},{"location":"security/slsa/#build-service","title":"Build Service","text":"

All build steps run on GitHub Actions using GitHub hosted runners.

For example:

  • Actions tab
"},{"location":"security/slsa/#build-as-code","title":"Build As Code","text":"

All build steps have been stored and versioned in the Git Repository.

For example:

  • .github/workflows
"},{"location":"security/slsa/#ephemeral-environment","title":"Ephemeral Environment","text":"

According to the GitHub Actions documentation,

  • \"Each GitHub-hosted runner is a new virtual machine (VM) hosted by GitHub with the runner application and other tools preinstalled.\"
  • \"When the job begins, GitHub automatically provisions a new VM for that job. All steps in the job execute on the VM, allowing the steps in that job to share information using the runner's filesystem. You can run workflows directly on the VM or in a Docker container. When the job has finished, the VM is automatically decommissioned.\"

Additionally, the Nix package manager provides an ephemeral environment to each of the derivations. On Linux, the environment is a sandbox that Chroots into an empty temporary directory, provides private versions of /proc, /dev, /dev/shm, and /dev/pts, and uses a private PID, mount, network, IPC, and UTS namespace to isolate itself from other processes in the system.

"},{"location":"security/slsa/#isolated","title":"Isolated","text":"

Our build service ensures that the build steps run in an isolated environment free of influence from other build instances, whether prior or concurrent, by using containerization technologies.

Builds are executed using the Nix package manager, which prevents builds from accessing any external environment variables, network resources, sockets, or paths in the file system. and provides private versions of /proc, /dev, /dev/shm, and /dev/pts, and uses a private PID, mount, network, IPC, and UTS namespace to isolate the build from other builds happening concurrently in the system.

Input-addressed build caches are used to speed-up the pipeline.

"},{"location":"security/slsa/#parameter-less","title":"Parameter-less","text":"

The build output cannot be affected by user parameters other than the build entry point and the top-level source location.

In order to modify the build output, a change to the source code must happen first.

"},{"location":"security/slsa/#hermetic","title":"Hermetic","text":"

Builds are executed using the Nix package manager, which prevents builds from accessing any external environment variables, network resources, sockets, or paths in the file system.

All transitive build steps, sources, and dependencies are fully declared up front with immutable references.

For example:

  • makes/cli/pypi/pypi-sources.yaml.

The Nix package manager:

  • Fetches all of the declared artifacts into a trusted control plane (the /nix/store).
  • Mounts into the build sandbox the specific /nix/store paths required by it.
  • Allows a build to fetch artifacts over the network if and only if the expected artifact integrity is specified.
  • Validates the integrity of each artifact before allowing a build to use it, and fails the build if the verification fails.
  • Denies network connectivity if no expected hash is specified.
"},{"location":"security/slsa/#reproducible","title":"Reproducible","text":"

All of our build scripts are intended to be reproducible.

The reproducibility guarantees of our build scripts are that of the Nix package manager.

"},{"location":"security/slsa/#provenance-requirements","title":"Provenance Requirements","text":""},{"location":"security/slsa/#available","title":"Available","text":"

Provenance is produced by Makes, and exposed by the build service as a JSON document together with the artifacts produced by the build.

Only builds that produce artifacts generate provenance, because if a build does not produce artifacts, then there wouldn't be something to verify the provenance of.

"},{"location":"security/slsa/#authenticated","title":"Authenticated","text":"

The authenticity of the provenance comes from the fact that it can be downloaded from the build service itself, and therefore the authenticity claim is as strong as the Build and Source Requirements are secure.

The integrity of the provenance is displayed in the logs and generated by Makes.

"},{"location":"security/slsa/#service-generated","title":"Service Generated","text":"

The data in the provenance is exposed by the build service, and is generated by Makes.

Regular users of the service are not able to inject or alter the contents because a build is fully determined and automated by its configuration, and the configuration comes directly from the source.

"},{"location":"security/slsa/#non-falsifiable","title":"Non-Falsifiable","text":"

The provenance cannot be falsified by the build service's users:

  • There is no secret material to demonstrate the non-falsifiable nature of the provenance (see Provenance - Authenticated).
  • Even if such secret material existed, builds are run in an hermetic environment, and therefore they wouldn't be available to the build steps (see Build - Hermetic).
  • Every field in the provenance is generated by the build service in a trusted control plane, which is fully defined by the build configuration, which comes directly from the Source, and therefore is as secure as the Source is (see Source - Verified History).
"},{"location":"security/slsa/#dependencies-complete","title":"Dependencies Complete","text":"

The provenance contains all of dependencies that were available while running the build steps.

This is guaranteed by the fact that builds are hermetic (see Build - Hermetic). So for a build to succeed, all of its dependencies must be declared, and therefore the build tool (Makes and Nix) who fetched them at build time, have strong knowledge of their existence.

"},{"location":"security/slsa/#common-requirements","title":"Common Requirements","text":""},{"location":"security/slsa/#security","title":"Security","text":"

Please read the Security page.

"},{"location":"security/slsa/#access","title":"Access","text":"

Our build service (GitHub Actions) is SaaS, and we use GitHub hosted runners. Only some GitHub employees may have access to the runners. We cannot access the build service infrastructure physically nor remotely.

"},{"location":"security/slsa/#superusers","title":"Superusers","text":"

Only a small number of platform admins may override the guarantees provided by SLSA. Particularly through disabling security options in the repository configuration page. Doing so does not currently require approval of a second platform admin.

"},{"location":"security/threat-model/","title":"Threat Model","text":""},{"location":"security/threat-model/#spoofing","title":"Spoofing","text":"
  • A user can mistype the Makes installation command and wrongly install a different (potentially malicious) tool.

Mitigation:

  • The installation command is given in plain-text, users can copy-paste it to avoid typos.

  • A user can mistype the target project to be built with Makes, and end-up building (and potentially running) a different (potentially malicious) project.

Mitigation:

  • The most common use case (running makes on the project in the current working directory) has a very convenient syntax: $ m ., which is very unlikely to be mistyped.
  • When referencing a project over the internet, the user is forced to use a git provider (github/gitlab), the owner account (which should be trusted by the user), the target repository, and a branch, commit or tag.

    By using a commit, the user can force the integrity of the downloaded data to match what they expect.

"},{"location":"security/threat-model/#tampering","title":"Tampering","text":"
  • The Nix Store can be tampered with if no good installation measures are taken by the user.

Mitigation:

  • The Nix installation is responsibility of the user, but in general, a user could bind mount /nix as a read-only file system, and make the /nix/store only accessible by root and the nixbld group users, reducing an attack vector to the physical or local layer, which can be further protected by the use of frameworks like SLSA, and full disk encryption using LUKS.
"},{"location":"security/threat-model/#repudiation","title":"Repudiation","text":"
  • In single tenant setups, for instance when developers run Makes in their laptops, there is nothing to repudiate, there is only one user performing builds (the developer). However, in multi-tenant setups, for instance when Makes is run in a shared CI/CD system, a user could deny running a build.

Mitigation:

  • Makes produces SLSA Provenance Attestations, which identify the builder and the built artifact.
  • Most CI/CD systems (and particularly the ones supported by Makes) offer logs collection, so it would be easy to associate a build with the identity that triggered it. It is responsibility of the users to configure such CI/CD systems in a secure way and to protect (and backup) the logs.
"},{"location":"security/threat-model/#information-disclosure","title":"Information Disclosure","text":"
  • Although the /nix/store is individual per user, a user may write secrets to it, and then those secrets can be published to a binary cache that is publicly accessible.

Examples of this include Nix idioms like:

[\n  // Nix would load the secrets in plain-text to the `/nix/store`\n  ./file-with-secrets-in-plain-text.txt\n\n  // Nix would load the git repository to the `/nix/store`\n  // This also applies to other builtins.fetch* that could\n  // fetch private information\n  (builtins.fetchGit {\n    // Private repository (with potential intellectual property)\n    url = \"git@github.com:company/secrets.git\";\n  })\n]\n

Mitigation:

  • Nothing from the /nix/store is pushed to a binary cache by default. A user would need to configure the cache explicitly, and expose the corresponding secret in an environment variable.
  • Makes has support for binary caches that require a secret for reading and writting, so a user may chose to use this instead as an extra layer of prevention if loading secrets to the /nix/store is mandatory. Please see https://cachix.org/ for more information.
  • Makes has utilities for working with secrets in a way that they are only copied to the /nix/store in encrypted form, and then decrypted at runtime, where there are safe from disclosure.

    For example: secretsForAwsFromEnv, secretsForAwsFromGitlab, secretsForEnvFromSops, secretsForGpgFromEnv, secretsForKubernetesConfigFromAws, and secretsForTerraformFromEnv.

    However, we don't currently have a way to protect the user from using builtins.fetch*. If your workflow needs this, please avoid pushing artifacts to a public binary cache, or use a private binary cache instead.

  • Makes copies the contents of the git repository into a trusted control plane, and excludes all of the files that are not tracked by Git from this checkout. This means that if the file with secrets is inside the repository, but included in the .gitignore such that a git fetch of the given remote and revision would ignore it, Makes would not copy it into the trusted control plane, and therefore Nix wouldn't load it into the /nix/store.

"},{"location":"security/threat-model/#denial-of-service","title":"Denial of Service","text":""},{"location":"security/threat-model/#elevation-of-privileges","title":"Elevation of Privileges","text":""}]} \ No newline at end of file diff --git a/security/assurance/index.html b/security/assurance/index.html new file mode 100644 index 00000000..008208ad --- /dev/null +++ b/security/assurance/index.html @@ -0,0 +1,844 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Software Assurance - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Software Assurance

+

This is what user can expect from Makes in terms of security, +the notation is that of a Structured Assurance Case Model[^1].

+
    +
  • +

    The Makes CLI application is free of known security vulnerabilities.

    +
  • +
  • +

    The Python code of the Makes CLI application + is free of known security vulnerabilities.

    + +

    Proof:

    + +

    Proof:

    + +
  • +
  • +

    The dependencies of the Makes CLI application + are free of known security vulnerabilities.

    + +

    Proof:

    +
      +
    • As a project maintainer, + you can see if Dependabot is enabled + here.
    • +
    • As an external user, + there is no way to verify + if Dependabot is enabled + because the configuration page for this + is only available to repository maintainers. + However, + it is possible to see the pull requests created by the bot, + for example: + PR 927. + Additionally, + an external user could check + if there has been Dependabot pull requests recently + by checking the + pull requests history. + It is important to note + that if no recent pull requests exist + it may mean + that no known security vulnerabilities have been found, + and not necessarily that this claim is false.
    • +
    +
  • +
+ + +

References

+

[^1]:

+

Rhodes, T. , Boland Jr., F. , Fong, E. and Kass, M. (2009), +Software Assurance Using Structured Assurance Case Models, +NIST Interagency/Internal Report (NISTIR), +National Institute of Standards and Technology, +Gaithersburg, MD, [online], +https://tsapps.nist.gov/publication/get_pdf.cfm?pub_id=902688 +(Accessed September 23, 2022)

+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/security/design-principles/index.html b/security/design-principles/index.html new file mode 100644 index 00000000..8354d1bf --- /dev/null +++ b/security/design-principles/index.html @@ -0,0 +1,960 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Design Principles - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Design Principles

+

Principle of Least Privilege

+
    +
  • +

    The Makes CLI is a python application that runs in user-space. + The privileges required are:

    +
  • +
  • +

    Write access to the ${HOME}, + which is normally owned by the user, + so no extra privileges + other than what the user already has are required.

    +
  • +
  • Creating temporary files/directories, + which respects the ${TMPDIR} environment variable, + which is a functionality normally available to a user, + so no extra privileges are required.
  • +
  • A system with Nix installed.
  • +
  • +

    (optional) privileges to create Kernel namespaces.

    +
  • +
  • +

    The Makes framework is simply a library + that aids the developer in creating build scripts, + so no privileges are required, + the Makes framework is just source code + that the user can opt-in to use.

    +
  • +
  • +

    When containers are built, + they are build by assembling an OCI-compliant image + (TAR files per each layer plus a JSON manifest), + without resorting to privileged daemons like that of Docker. + They are generated as any other build (hermetic, pure, etc) + using information from the Nix Store.

    +
  • +
+

Principle of Fail-Safe Defaults

+
    +
  • By default, builds are run in a sandbox + that uses kernel namespaces + to prevent the build from accessing the network + and the external file system.
  • +
+

The user is given the option to opt-out from this behavior, + but this is enabled by default.

+
    +
  • Generated files are created inside user-owned folders by default, + which inherit the security + that the user has previously defined for the directory.
  • +
+

An user may opt-out from this behavior by setting environment variables, + but user-owned folders are selected by default.

+
    +
  • In the most common configuration, + the contents of the /nix/store + are never published to the internet.
  • +
+

A user may want to share artifacts with other users + in order to improve performance + by writing artifacts to a binary cache, + so that other users can download the artifacts + if they have already been built by other user, + but this behavior + requires configuring a read+write binary cache + and setting the corresponding access secret.

+

A read-only binary cache (https://cache.nixos.org) + and no write binary cache + is the default configuration,

+

Principle of Economy of Mechanism

+
    +
  • The Makes CLI is essentially a wrapper over Nix, + so the surface is as small as possible (~1000 loc).
  • +
  • The Makes Framework defines a common set of utilities + a user can opt-in to use, + saving the user the work of writing that functionality themselves + which would require the same amount of code anyway.
  • +
+

Principle of Complete Mediation

+

Principle of Open Design

+
    +
  • Makes is Free and Open Source Software, + anyone can read its internals: + https://github.com/fluidattacks/makes
  • +
+

Principle of Separation of Privilege

+

Principle of Least Common Mechanism

+
    +
  • In the most common case + each user of Makes has a personal /nix/store + and a personal installation of Nix. + The /nix/store contents are not shared between users by default, + unless the user configures a read+write binary cache + and sets the corresponding binary cache secret.
  • +
+

Principle of Psychological Acceptability

+
    +
  • The Makes CLI is easy to use. + Performing an installation using the default values + yields a sufficiently secure version of the system. + Users familiar with other build tools would feel at home.
  • +
+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/security/index.html b/security/index.html new file mode 100644 index 00000000..a8b4d1a1 --- /dev/null +++ b/security/index.html @@ -0,0 +1,721 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Security - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Security

+

This section evaluates Makes using various standards +and tries to address the security of Makes as an ecosystem +using the three following categories:

+
    +
  • Security of using the Makes CLI.
  • +
  • Security of the software built using Makes.
  • +
  • Security of Makes as a software project.
  • +
+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/security/slsa/index.html b/security/slsa/index.html new file mode 100644 index 00000000..ed1498dd --- /dev/null +++ b/security/slsa/index.html @@ -0,0 +1,1503 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Supply Chain Levels for Software Artifacts - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Supply Chain Levels for Software Artifacts

+

The SLSA framework +helps organizations measure +the level of assurance +that the Software Artifacts they produce +actually contain and use what they intended (integrity), +by ensuring that the whole build and release process, +and all of the involved sources and dependencies +cannot be tampered with.

+

In this document, +we use the +version 0.1 of the specification.

+

Our current SLSA level is 2. +The following is a detail of the levels achieved +on each of the requirements:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RequirementLevel
Source - Version Controlled4
Source - Verified History4
Source - Retained Indefinitely4
Source - Two Person Reviewed3
Build - Scripted Build4
Build - Build Service4
Build - Build As Code4
Build - Ephemeral Environment4
Build - Isolated2
Build - Parameter-less4
Build - Hermetic4
Build - Reproducible4
Provenance - Available4
Provenance - Authenticated4
Provenance - Service Generated4
Provenance - Non-Falsifiable4
Provenance - Dependencies Complete4
Common - Security4
Common - Access4
Common - Superusers3
+

For clarity, +this is how SLSA definitions map into our infrastructure:

+
    +
  • Source: Git repository at: + github.com/fluidattacks/makes.
  • +
  • Platform: GitHub Actions, + Makes, + and the Nix package manager.
  • +
  • Build service: + GitHub Actions, + using GitHub hosted runners.
  • +
  • Build: A Nix derivation.
  • +
  • Environment: A sandbox + that Chroots + into an empty temporary directory, + provides private versions + of /proc, /dev, /dev/shm, and /dev/pts, + and uses a private PID, mount, network, IPC, and UTS namespace + to isolate itself from other processes in the system.
  • +
  • Steps: Instructions declared + in the corresponding Makes configuration files + written using the Nix programming language + and shell scripting, versioned as-code in the source.
  • +
+

Source Requirements

+

Version controlled

+

Every change to the source is tracked on GitHub, +using the Git version control system.

+
    +
  • Change history: There exists a record + of the history of changes + that went into the revision. + Each change contains: + the identities of the uploader and reviewers (if any), + timestamps of the reviews (if any) and submission, + the change description/justification, + the content of the change, + and the parent revisions.
  • +
+

For example: PR 649.

+ +

Verified history

+

Every change in the revision’s history +need to pass through a Pull Request.

+

In order to approve a Pull Request +the reviewer need to be strongly authenticated into GitHub. +The authentication process requires 2FA, +and the dates of the change +are recorded in the Pull Request.

+

Only users who were previously granted access +by a platform Admin can review Pull Requests. +External contributors can create a Pull Request +without any special privileges, +but it won't be merged +until reviewers submit their approval.

+

For example: +PR 649.

+

Retained indefinitely

+

The revision and its change history +are preserved indefinitely +and cannot be deleted +or modified (not even with multi-party approval). +Additionally, +the main branch is protected +against accidental history overwrite +using GitHub's branch protection rules.

+

At the moment, +no legal requirement +impedes us to preserve indefinitely our change history, +and no obliteration policy is in effect. +In fact, our source code is Free and Open Source Software: +Anyone can download or fork the repository.

+

Two Person Reviewed

+

Every change in the revision’s history +is agreed to by at least one trusted person +prior to submission +and each of these trusted persons +are authenticated into the platform (using 2FA) first. +Only project maintainers can merge Pull Requests +and therefore append a change into the revision's history.

+

Build Requirements

+

Scripted Build

+

All build steps were fully defined +using GitHub Actions, Makes and Nix.

+

Manual commands are not necessary to invoke the build script. +A new build is triggered automatically +each time new changes are pushed to the repository.

+

For example:

+ +

Build Service

+

All build steps run on GitHub Actions +using GitHub hosted runners.

+

For example:

+ +

Build As Code

+

All build steps have been stored and versioned +in the Git Repository.

+

For example:

+ +

Ephemeral Environment

+

According to the GitHub Actions documentation,

+
    +
  • "Each GitHub-hosted runner + is a new virtual machine (VM) + hosted by GitHub with the runner application + and other tools preinstalled."
  • +
  • "When the job begins, + GitHub automatically provisions a new VM for that job. + All steps in the job execute on the VM, + allowing the steps in that job to share information + using the runner's filesystem. + You can run workflows directly on the VM + or in a Docker container. + When the job has finished, + the VM is automatically decommissioned."
  • +
+

Additionally, +the Nix package manager +provides an ephemeral environment to each of the derivations. +On Linux, +the environment is a sandbox +that Chroots +into an empty temporary directory, +provides private versions +of /proc, /dev, /dev/shm, and /dev/pts, +and uses a private PID, mount, network, IPC, and UTS namespace +to isolate itself from other processes in the system.

+

Isolated

+

Our build service +ensures that the build steps +run in an isolated environment +free of influence from other build instances, +whether prior or concurrent, +by using containerization technologies.

+

Builds are executed using the Nix package manager, +which prevents builds +from accessing any external environment variables, +network resources, sockets, +or paths in the file system. +and provides private versions +of /proc, /dev, /dev/shm, and /dev/pts, +and uses a private PID, mount, network, IPC, and UTS namespace +to isolate the build from other builds +happening concurrently in the system.

+

Input-addressed build caches are used to speed-up the pipeline.

+

Parameter-less

+

The build output cannot be affected by user parameters +other than the build entry point +and the top-level source location.

+

In order to modify the build output, +a change to the source code must happen first.

+

Hermetic

+

Builds are executed using the Nix package manager, +which prevents builds +from accessing any external environment variables, +network resources, sockets, +or paths in the file system.

+

All transitive build steps, sources, and dependencies +are fully declared up front with immutable references.

+

For example:

+ +

The Nix package manager:

+
    +
  • Fetches all of the declared artifacts + into a trusted control plane (the /nix/store).
  • +
  • Mounts into the build sandbox + the specific /nix/store paths required by it.
  • +
  • Allows a build to fetch artifacts over the network + if and only if the expected artifact integrity is specified.
  • +
  • Validates the integrity of each artifact + before allowing a build to use it, + and fails the build if the verification fails.
  • +
  • Denies network connectivity if no expected hash is specified.
  • +
+

Reproducible

+

All of our build scripts are intended to be reproducible.

+

The reproducibility guarantees of our build scripts +are that of the Nix package manager.

+

Provenance Requirements

+

Available

+

Provenance is produced by Makes, +and exposed by the build service +as a JSON document +together with the artifacts produced by the build.

+

Only builds that produce artifacts generate provenance, +because if a build does not produce artifacts, +then there wouldn't be something to verify the provenance of.

+

Authenticated

+

The authenticity of the provenance +comes from the fact +that it can be downloaded +from the build service itself, +and therefore the authenticity claim +is as strong as the Build and Source Requirements are secure.

+

The integrity of the provenance +is displayed in the logs +and generated by Makes.

+

Service Generated

+

The data in the provenance +is exposed by the build service, +and is generated by Makes.

+

Regular users of the service +are not able to inject +or alter the contents +because a build is fully determined +and automated by its configuration, +and the configuration comes directly from the source.

+

Non-Falsifiable

+

The provenance +cannot be falsified by the build service's users:

+
    +
  • There is no secret material + to demonstrate the non-falsifiable nature of the provenance + (see Provenance - Authenticated).
  • +
  • Even if such secret material existed, + builds are run in an hermetic environment, + and therefore they wouldn't be available to the build steps + (see Build - Hermetic).
  • +
  • Every field in the provenance is generated + by the build service in a trusted control plane, + which is fully defined by the build configuration, + which comes directly from the Source, + and therefore is as secure as the Source is + (see Source - Verified History).
  • +
+

Dependencies Complete

+

The provenance contains all of dependencies +that were available while running the build steps.

+

This is guaranteed by the fact +that builds are hermetic +(see Build - Hermetic). +So for a build to succeed, +all of its dependencies must be declared, +and therefore the build tool (Makes and Nix) +who fetched them at build time, +have strong knowledge of their existence.

+

Common Requirements

+

Security

+

Please read the Security page.

+

Access

+

Our build service (GitHub Actions) is SaaS, +and we use GitHub hosted runners. +Only some GitHub employees +may have access to the runners. +We cannot access the build service infrastructure +physically nor remotely.

+

Superusers

+

Only a small number of platform admins may override the guarantees provided by SLSA. +Particularly through disabling security options +in the repository configuration page. +Doing so does not currently require approval +of a second platform admin.

+ + + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/security/threat-model/index.html b/security/threat-model/index.html new file mode 100644 index 00000000..7177c940 --- /dev/null +++ b/security/threat-model/index.html @@ -0,0 +1,974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Threat Model - Makes Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Threat Model

+

Spoofing

+
    +
  • A user can mistype the Makes installation command + and wrongly install a different (potentially malicious) tool.
  • +
+

Mitigation:

+
    +
  • +

    The installation command is given in plain-text, + users can copy-paste it to avoid typos.

    +
  • +
  • +

    A user can mistype the target project to be built with Makes, + and end-up building (and potentially running) + a different (potentially malicious) project.

    +
  • +
+

Mitigation:

+
    +
  • The most common use case + (running makes on the project in the current working directory) + has a very convenient syntax: $ m ., + which is very unlikely to be mistyped.
  • +
  • +

    When referencing a project over the internet, + the user is forced to use a git provider (github/gitlab), + the owner account (which should be trusted by the user), + the target repository, + and a branch, commit or tag.

    +

    By using a commit, +the user can force the integrity of the downloaded data +to match what they expect.

    +
  • +
+

Tampering

+
    +
  • The Nix Store can be tampered with + if no good installation measures are taken by the user.
  • +
+

Mitigation:

+
    +
  • The Nix installation is responsibility of the user, + but in general, + a user could bind mount /nix as a read-only file system, + and make the /nix/store only accessible by root + and the nixbld group users, + reducing an attack vector to the physical or local layer, + which can be further protected + by the use of frameworks like SLSA, + and full disk encryption using LUKS.
  • +
+

Repudiation

+
    +
  • In single tenant setups, + for instance when developers run Makes in their laptops, + there is nothing to repudiate, + there is only one user performing builds (the developer). + However, + in multi-tenant setups, + for instance when Makes is run in a shared CI/CD system, + a user could deny running a build.
  • +
+

Mitigation:

+
    +
  • Makes produces + SLSA Provenance Attestations, + which identify the builder and the built artifact.
  • +
  • Most CI/CD systems + (and particularly the ones supported by Makes) + offer logs collection, + so it would be easy to associate a build + with the identity that triggered it. + It is responsibility of the users + to configure such CI/CD systems + in a secure way and to protect (and backup) the logs.
  • +
+

Information Disclosure

+
    +
  • Although the /nix/store is individual per user, + a user may write secrets to it, + and then those secrets can be published to a binary cache + that is publicly accessible.
  • +
+

Examples of this include Nix idioms like:

+
[
+  // Nix would load the secrets in plain-text to the `/nix/store`
+  ./file-with-secrets-in-plain-text.txt
+
+  // Nix would load the git repository to the `/nix/store`
+  // This also applies to other builtins.fetch* that could
+  // fetch private information
+  (builtins.fetchGit {
+    // Private repository (with potential intellectual property)
+    url = "git@github.com:company/secrets.git";
+  })
+]
+
+

Mitigation:

+
    +
  • Nothing from the /nix/store + is pushed to a binary cache by default. + A user would need to configure the cache explicitly, + and expose the corresponding secret + in an environment variable.
  • +
  • Makes has support for binary caches + that require a secret for reading and writting, + so a user may chose to use this instead + as an extra layer of prevention + if loading secrets to the /nix/store is mandatory. + Please see https://cachix.org/ for more information.
  • +
  • +

    Makes has utilities for working with secrets in a way + that they are only copied to the /nix/store + in encrypted form, + and then decrypted at runtime, + where there are safe from disclosure.

    +

    For example: +secretsForAwsFromEnv, +secretsForAwsFromGitlab, +secretsForEnvFromSops, +secretsForGpgFromEnv, +secretsForKubernetesConfigFromAws, and +secretsForTerraformFromEnv.

    +

    However, we don't currently have a way to protect the user +from using builtins.fetch*. +If your workflow needs this, +please avoid pushing artifacts to a public binary cache, +or use a private binary cache instead.

    +
  • +
  • +

    Makes copies the contents of the git repository + into a trusted control plane, + and excludes all of the files + that are not tracked by Git + from this checkout. + This means that if the file with secrets is inside the repository, + but included in the .gitignore + such that a git fetch of the given remote and revision + would ignore it, + Makes would not copy it into the trusted control plane, + and therefore Nix wouldn't load it into the /nix/store.

    +
  • +
+

Denial of Service

+

Elevation of Privileges

+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..67dc211a --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,48 @@ + + + + https://fluidattacks.github.io/makes/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/architecture/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/contributing/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/governance/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/security/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/security/assurance/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/security/design-principles/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/security/slsa/ + 2023-03-08 + daily + + + https://fluidattacks.github.io/makes/security/threat-model/ + 2023-03-08 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 00000000..5d47f6fc Binary files /dev/null and b/sitemap.xml.gz differ