diff --git a/test/404.html b/test/404.html deleted file mode 100644 index f5dd8e417935..000000000000 --- a/test/404.html +++ /dev/null @@ -1,2944 +0,0 @@ - - - - - - - - - - - - - - - - - - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- -
- - - - - - - - -
- - - - - - - -
- -
- - - - -
-
- - - -
-
-
- - - - - - -
-
-
- - - -
-
-
- - - -
-
-
- - -
-
- -

404 - Not found

- -
-
-
- -
- - - -
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/test/assets/images/favicon.png b/test/assets/images/favicon.png deleted file mode 100644 index 1cf13b9f9d97..000000000000 Binary files a/test/assets/images/favicon.png and /dev/null differ diff --git a/test/assets/javascripts/bundle.ed9748b7.min.js b/test/assets/javascripts/bundle.ed9748b7.min.js deleted file mode 100644 index 7404ed828d11..000000000000 --- a/test/assets/javascripts/bundle.ed9748b7.min.js +++ /dev/null @@ -1,29 +0,0 @@ -(()=>{var ea=Object.create;var gr=Object.defineProperty;var ta=Object.getOwnPropertyDescriptor;var ra=Object.getOwnPropertyNames,At=Object.getOwnPropertySymbols,na=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,I=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&rn(e,r,t[r]);if(At)for(var r of At(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&At)for(var n of At(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var bt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var oa=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ra(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=ta(t,o))||n.enumerable});return e};var Qe=(e,t,r)=>(r=e!=null?ea(na(e)):{},oa(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var sn=bt((xr,an)=>{(function(e,t){typeof xr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={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 s(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function c(O){var je=O.type,de=O.tagName;return!!(de==="INPUT"&&a[je]&&!O.readOnly||de==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function u(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function f(O){!O.hasAttribute("data-focus-visible-added")||(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(s(r.activeElement)&&u(r.activeElement),n=!0)}function l(O){n=!1}function d(O){!s(O.target)||(n||c(O.target))&&u(O.target)}function h(O){!s(O.target)||(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),f(O.target))}function b(O){document.visibilityState==="hidden"&&(o&&(n=!0),F())}function F(){document.addEventListener("mousemove",U),document.addEventListener("mousedown",U),document.addEventListener("mouseup",U),document.addEventListener("pointermove",U),document.addEventListener("pointerdown",U),document.addEventListener("pointerup",U),document.addEventListener("touchmove",U),document.addEventListener("touchstart",U),document.addEventListener("touchend",U)}function K(){document.removeEventListener("mousemove",U),document.removeEventListener("mousedown",U),document.removeEventListener("mouseup",U),document.removeEventListener("pointermove",U),document.removeEventListener("pointerdown",U),document.removeEventListener("pointerup",U),document.removeEventListener("touchmove",U),document.removeEventListener("touchstart",U),document.removeEventListener("touchend",U)}function U(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,K())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",l,!0),document.addEventListener("pointerdown",l,!0),document.addEventListener("touchstart",l,!0),document.addEventListener("visibilitychange",b,!0),F(),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 cn=bt(Sr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(u){return!1}},r=t(),n=function(u){var f={next:function(){var p=u.shift();return{done:p===void 0,value:p}}};return r&&(f[Symbol.iterator]=function(){return f}),f},o=function(u){return encodeURIComponent(u).replace(/%20/g,"+")},i=function(u){return decodeURIComponent(String(u).replace(/\+/g," "))},a=function(){var u=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var l=typeof p;if(l!=="undefined")if(l==="string")p!==""&&this._fromString(p);else if(p instanceof u){var d=this;p.forEach(function(K,U){d.append(U,K)})}else if(p!==null&&l==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),u._entries&&(u._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr);(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,u){typeof c!="string"&&(c=String(c)),u&&typeof u!="string"&&(u=String(u));var f=document,p;if(u&&(e.location===void 0||u!==e.location.href)){u=u.toLowerCase(),f=document.implementation.createHTMLDocument(""),p=f.createElement("base"),p.href=u,f.head.appendChild(p);try{if(p.href.indexOf(u)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+u+" due to "+O)}}var l=f.createElement("a");l.href=c,p&&(f.body.appendChild(l),l.href=l.href);var d=f.createElement("input");if(d.type="url",d.value=c,l.protocol===":"||!/:/.test(l.href)||!d.checkValidity()&&!u)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:l});var h=new e.URLSearchParams(this.search),b=!0,F=!0,K=this;["append","delete","set"].forEach(function(O){var je=h[O];h[O]=function(){je.apply(h,arguments),b&&(F=!1,K.search=h.toString(),F=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var U=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==U&&(U=this.search,F&&(b=!1,this.searchParams._fromString(this.search),b=!0))}})},a=i.prototype,s=function(c){Object.defineProperty(a,c,{get:function(){return this._anchorElement[c]},set:function(u){this._anchorElement[c]=u},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(c){s(c)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(c){this._anchorElement.search=c,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{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],u=this._anchorElement.port!=c&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(u?":"+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:Sr)});var An=bt((Fs,kt)=>{/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */var un,fn,pn,ln,mn,dn,hn,bn,vn,Ct,wr,gn,yn,xn,tt,Sn,wn,En,On,_n,Tn,Mn,Ln,Rt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(n){e(r(t,r(n)))}):typeof kt=="object"&&typeof kt.exports=="object"?e(r(t,r(kt.exports))):e(r(t));function r(n,o){return n!==t&&(typeof Object.create=="function"?Object.defineProperty(n,"__esModule",{value:!0}):n.__esModule=!0),function(i,a){return n[i]=o?o(i,a):a}}})(function(e){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])};un=function(n,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(n,o);function i(){this.constructor=n}n.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},fn=Object.assign||function(n){for(var o,i=1,a=arguments.length;i=0;f--)(u=n[f])&&(c=(s<3?u(c):s>3?u(o,i,c):u(o,i))||c);return s>3&&c&&Object.defineProperty(o,i,c),c},mn=function(n,o){return function(i,a){o(i,a,n)}},dn=function(n,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(n,o)},hn=function(n,o,i,a){function s(c){return c instanceof i?c:new i(function(u){u(c)})}return new(i||(i=Promise))(function(c,u){function f(d){try{l(a.next(d))}catch(h){u(h)}}function p(d){try{l(a.throw(d))}catch(h){u(h)}}function l(d){d.done?c(d.value):s(d.value).then(f,p)}l((a=a.apply(n,o||[])).next())})},bn=function(n,o){var i={label:0,sent:function(){if(c[0]&1)throw c[1];return c[1]},trys:[],ops:[]},a,s,c,u;return u={next:f(0),throw:f(1),return:f(2)},typeof Symbol=="function"&&(u[Symbol.iterator]=function(){return this}),u;function f(l){return function(d){return p([l,d])}}function p(l){if(a)throw new TypeError("Generator is already executing.");for(;i;)try{if(a=1,s&&(c=l[0]&2?s.return:l[0]?s.throw||((c=s.return)&&c.call(s),0):s.next)&&!(c=c.call(s,l[1])).done)return c;switch(s=0,c&&(l=[l[0]&2,c.value]),l[0]){case 0:case 1:c=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,s=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(c=i.trys,!(c=c.length>0&&c[c.length-1])&&(l[0]===6||l[0]===2)){i=0;continue}if(l[0]===3&&(!c||l[1]>c[0]&&l[1]=n.length&&(n=void 0),{value:n&&n[a++],done:!n}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},wr=function(n,o){var i=typeof Symbol=="function"&&n[Symbol.iterator];if(!i)return n;var a=i.call(n),s,c=[],u;try{for(;(o===void 0||o-- >0)&&!(s=a.next()).done;)c.push(s.value)}catch(f){u={error:f}}finally{try{s&&!s.done&&(i=a.return)&&i.call(a)}finally{if(u)throw u.error}}return c},gn=function(){for(var n=[],o=0;o1||f(b,F)})})}function f(b,F){try{p(a[b](F))}catch(K){h(c[0][3],K)}}function p(b){b.value instanceof tt?Promise.resolve(b.value.v).then(l,d):h(c[0][2],b)}function l(b){f("next",b)}function d(b){f("throw",b)}function h(b,F){b(F),c.shift(),c.length&&f(c[0][0],c[0][1])}},wn=function(n){var o,i;return o={},a("next"),a("throw",function(s){throw s}),a("return"),o[Symbol.iterator]=function(){return this},o;function a(s,c){o[s]=n[s]?function(u){return(i=!i)?{value:tt(n[s](u)),done:s==="return"}:c?c(u):u}:c}},En=function(n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=n[Symbol.asyncIterator],i;return o?o.call(n):(n=typeof Ct=="function"?Ct(n):n[Symbol.iterator](),i={},a("next"),a("throw"),a("return"),i[Symbol.asyncIterator]=function(){return this},i);function a(c){i[c]=n[c]&&function(u){return new Promise(function(f,p){u=n[c](u),s(f,p,u.done,u.value)})}}function s(c,u,f,p){Promise.resolve(p).then(function(l){c({value:l,done:f})},u)}},On=function(n,o){return Object.defineProperty?Object.defineProperty(n,"raw",{value:o}):n.raw=o,n};var r=Object.create?function(n,o){Object.defineProperty(n,"default",{enumerable:!0,value:o})}:function(n,o){n.default=o};_n=function(n){if(n&&n.__esModule)return n;var o={};if(n!=null)for(var i in n)i!=="default"&&Object.prototype.hasOwnProperty.call(n,i)&&Rt(o,n,i);return r(o,n),o},Tn=function(n){return n&&n.__esModule?n:{default:n}},Mn=function(n,o,i,a){if(i==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?n!==o||!a:!o.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?a:i==="a"?a.call(n):a?a.value:o.get(n)},Ln=function(n,o,i,a,s){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?n!==o||!s:!o.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?s.call(n,i):s?s.value=i:o.set(n,i),i},e("__extends",un),e("__assign",fn),e("__rest",pn),e("__decorate",ln),e("__param",mn),e("__metadata",dn),e("__awaiter",hn),e("__generator",bn),e("__exportStar",vn),e("__createBinding",Rt),e("__values",Ct),e("__read",wr),e("__spread",gn),e("__spreadArrays",yn),e("__spreadArray",xn),e("__await",tt),e("__asyncGenerator",Sn),e("__asyncDelegator",wn),e("__asyncValues",En),e("__makeTemplateObject",On),e("__importStar",_n),e("__importDefault",Tn),e("__classPrivateFieldGet",Mn),e("__classPrivateFieldSet",Ln)})});var Qr=bt((_t,qr)=>{/*! - * clipboard.js v2.0.10 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */(function(t,r){typeof _t=="object"&&typeof qr=="object"?qr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof _t=="object"?_t.ClipboardJS=r():t.ClipboardJS=r()})(_t,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Zi}});var a=i(279),s=i.n(a),c=i(370),u=i.n(c),f=i(817),p=i.n(f);function l(P){try{return document.execCommand(P)}catch(M){return!1}}var d=function(M){var w=p()(M);return l("cut"),w},h=d;function b(P){var M=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[M?"right":"left"]="-9999px";var D=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(D,"px"),w.setAttribute("readonly",""),w.value=P,w}var F=function(M){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},D="";if(typeof M=="string"){var R=b(M);w.container.appendChild(R),D=p()(R),l("copy"),R.remove()}else D=p()(M),l("copy");return D},K=F;function U(P){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?U=function(w){return typeof w}:U=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},U(P)}var O=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=M.action,D=w===void 0?"copy":w,R=M.container,N=M.target,Ee=M.text;if(D!=="copy"&&D!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(N!==void 0)if(N&&U(N)==="object"&&N.nodeType===1){if(D==="copy"&&N.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(D==="cut"&&(N.hasAttribute("readonly")||N.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(Ee)return K(Ee,{container:R});if(N)return D==="cut"?h(N):K(N,{container:R})},je=O;function de(P){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?de=function(w){return typeof w}:de=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},de(P)}function et(P,M){if(!(P instanceof M))throw new TypeError("Cannot call a class as a function")}function tn(P,M){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof R.action=="function"?R.action:this.defaultAction,this.target=typeof R.target=="function"?R.target:this.defaultTarget,this.text=typeof R.text=="function"?R.text:this.defaultText,this.container=de(R.container)==="object"?R.container:document.body}},{key:"listenClick",value:function(R){var N=this;this.listener=u()(R,"click",function(Ee){return N.onClick(Ee)})}},{key:"onClick",value:function(R){var N=R.delegateTarget||R.currentTarget,Ee=this.action(N)||"copy",Lt=je({action:Ee,container:this.container,target:this.target(N),text:this.text(N)});this.emit(Lt?"success":"error",{action:Ee,text:Lt,trigger:N,clearSelection:function(){N&&N.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(R){return vr("action",R)}},{key:"defaultTarget",value:function(R){var N=vr("target",R);if(N)return document.querySelector(N)}},{key:"defaultText",value:function(R){return vr("text",R)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(R){var N=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return K(R,N)}},{key:"cut",value:function(R){return h(R)}},{key:"isSupported",value:function(){var R=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],N=typeof R=="string"?[R]:R,Ee=!!document.queryCommandSupported;return N.forEach(function(Lt){Ee=Ee&&!!document.queryCommandSupported(Lt)}),Ee}}]),w}(s()),Zi=Xi},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 a(s,c){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(f,p,l,d,h){var b=u.apply(this,arguments);return f.addEventListener(l,b,h),{destroy:function(){f.removeEventListener(l,b,h)}}}function c(f,p,l,d,h){return typeof f.addEventListener=="function"?s.apply(null,arguments):typeof l=="function"?s.bind(null,document).apply(null,arguments):(typeof f=="string"&&(f=document.querySelectorAll(f)),Array.prototype.map.call(f,function(b){return s(b,p,l,d,h)}))}function u(f,p,l,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(f,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 a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[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 a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function c(l,d,h){if(!l&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(l))return u(l,d,h);if(a.nodeList(l))return f(l,d,h);if(a.string(l))return p(l,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function u(l,d,h){return l.addEventListener(d,h),{destroy:function(){l.removeEventListener(d,h)}}}function f(l,d,h){return Array.prototype.forEach.call(l,function(b){b.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(l,function(b){b.removeEventListener(d,h)})}}}function p(l,d,h){return s(document.body,l,d,h)}n.exports=c},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),u=document.createRange();u.selectNodeContents(i),c.removeAllRanges(),c.addRange(u),a=c.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function u(){c.off(i,u),a.apply(s,arguments)}return u._=a,this.on(i,u,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,u=s.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 ys=/["'&<>]/;gi.exports=xs;function xs(e){var t=""+e,r=ys.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0},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,a=o.isStopped,s=o.observers;return i||a?Er:(this.currentObservers=null,s.push(r),new Le(function(){n.currentObservers=null,Re(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new k;return r.source=this,r},t.create=function(r,n){return new Vn(r,n)},t}(k);var Vn=function(e){ee(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:Er},t}(E);var gt={now:function(){return(gt.delegate||Date).now()},delegate:void 0};var yt=function(e){ee(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=gt);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,a=n._infiniteTimeWindow,s=n._timestampProvider,c=n._windowTime;o||(i.push(r),!a&&i.push(s.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,a=o._buffer,s=a.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=at.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){if(o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);r.actions.some(function(i){return i.id===n})||(at.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Dt);var qn=function(e){ee(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 _e=new qn(zn);var z=new k(function(e){return e.complete()});function Vt(e){return e&&T(e.schedule)}function Cr(e){return e[e.length-1]}function Fe(e){return T(Cr(e))?e.pop():void 0}function ge(e){return Vt(Cr(e))?e.pop():void 0}function Nt(e,t){return typeof Cr(e)=="number"?e.pop():t}var st=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return T(e==null?void 0:e.then)}function qt(e){return T(e[it])}function Qt(e){return Symbol.asyncIterator&&T(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 ma(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Yt=ma();function Bt(e){return T(e==null?void 0:e[Yt])}function Gt(e){return kn(this,arguments,function(){var r,n,o,i;return Ht(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,Pt(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,Pt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,Pt(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Jt(e){return T(e==null?void 0:e.getReader)}function V(e){if(e instanceof k)return e;if(e!=null){if(qt(e))return da(e);if(st(e))return ha(e);if(zt(e))return ba(e);if(Qt(e))return Qn(e);if(Bt(e))return va(e);if(Jt(e))return ga(e)}throw Kt(e)}function da(e){return new k(function(t){var r=e[it]();if(T(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function ha(e){return new k(function(t){for(var r=0;r=2,!0))}function ie(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(u){var f=null,p=null,l=null,d=0,h=!1,b=!1,F=function(){p==null||p.unsubscribe(),p=null},K=function(){F(),f=l=null,h=b=!1},U=function(){var O=f;K(),O==null||O.unsubscribe()};return v(function(O,je){d++,!b&&!h&&F();var de=l=l!=null?l:r();je.add(function(){d--,d===0&&!b&&!h&&(p=jr(U,c))}),de.subscribe(je),f||(f=new ot({next:function(et){return de.next(et)},error:function(et){b=!0,F(),p=jr(K,o,et),de.error(et)},complete:function(){h=!0,F(),p=jr(K,a),de.complete()}}),re(O).subscribe(f))})(u)}}function jr(e,t){for(var r=[],n=2;ne.next(document)),e}function G(e,t=document){return Array.from(t.querySelectorAll(e))}function Q(e,t=document){let r=ue(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ue(e,t=document){return t.querySelector(e)||void 0}function Ve(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return C(y(document.body,"focusin"),y(document.body,"focusout")).pipe(Je(1),m(()=>{let t=Ve();return typeof t!="undefined"?e.contains(t):!1}),q(e===Ve()),B())}function Ne(e){return{x:e.offsetLeft,y:e.offsetTop}}function mo(e){return C(y(window,"load"),y(window,"resize")).pipe(He(0,_e),m(()=>Ne(e)),q(Ne(e)))}function ho(e){return{x:e.scrollLeft,y:e.scrollTop}}function rr(e){return C(y(e,"scroll"),y(window,"resize")).pipe(He(0,_e),m(()=>ho(e)),q(ho(e)))}var vo=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(){!Vr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Da?(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(){!Vr||!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=Ua.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}(),go=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),xo=typeof WeakMap!="undefined"?new WeakMap:new vo,So=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=Wa.getInstance(),n=new Ja(t,r,this);xo.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){So.prototype[e]=function(){var t;return(t=xo.get(this))[e].apply(t,arguments)}});var Xa=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:So}(),wo=Xa;var Eo=new E,Za=H(()=>j(new wo(e=>{for(let t of e)Eo.next(t)}))).pipe(x(e=>C(ye,j(e)).pipe(L(()=>e.disconnect()))),X(1));function Ae(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ve(e){return Za.pipe(S(t=>t.observe(e)),x(t=>Eo.pipe(_(({target:r})=>r===e),L(()=>t.unobserve(e)),m(()=>Ae(e)))),q(Ae(e)))}function ar(e){return{width:e.scrollWidth,height:e.scrollHeight}}var Oo=new E,es=H(()=>j(new IntersectionObserver(e=>{for(let t of e)Oo.next(t)},{threshold:0}))).pipe(x(e=>C(ye,j(e)).pipe(L(()=>e.disconnect()))),X(1));function _o(e){return es.pipe(S(t=>t.observe(e)),x(t=>Oo.pipe(_(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function To(e,t=16){return rr(e).pipe(m(({y:r})=>{let n=Ae(e),o=ar(e);return r>=o.height-n.height-t}),B())}var sr={drawer:Q("[data-md-toggle=drawer]"),search:Q("[data-md-toggle=search]")};function Mo(e){return sr[e].checked}function ze(e,t){sr[e].checked!==t&&sr[e].click()}function lt(e){let t=sr[e];return y(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ts(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 Lo(){return y(window,"keydown").pipe(_(e=>!(e.metaKey||e.ctrlKey)),m(e=>({mode:Mo("search")?"search":"global",type:e.key,claim(){e.preventDefault(),e.stopPropagation()}})),_(({mode:e,type:t})=>{if(e==="global"){let r=Ve();if(typeof r!="undefined")return!ts(r,t)}return!0}),ie())}function xe(){return new URL(location.href)}function cr(e){location.href=e.href}function Ao(){return new E}function Co(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)Co(e,r)}function A(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="boolean"?n.setAttribute(o,t[o]):t[o]&&n.setAttribute(o,"");for(let o of r)Co(n,o);return n}function Ro(e,t){let r=t;if(e.length>r){for(;e[r]!==" "&&--r>0;);return`${e.substring(0,r)}...`}return e}function ur(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function ko(){return location.hash.substring(1)}function Ho(e){let t=A("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function rs(){return y(window,"hashchange").pipe(m(ko),q(ko()),_(e=>e.length>0),X(1))}function Po(){return rs().pipe(m(e=>ue(`[id="${e}"]`)),_(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function Io(){let e=matchMedia("print");return C(y(window,"beforeprint").pipe(m(()=>!0)),y(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function zr(e,t){return e.pipe(x(r=>r?t():z))}function fr(e,t={credentials:"same-origin"}){return re(fetch(`${e}`,t)).pipe(_(r=>r.status===200),We(()=>z))}function Ce(e,t){return fr(e,t).pipe(x(r=>r.json()),X(1))}function $o(e,t){let r=new DOMParser;return fr(e,t).pipe(x(n=>n.text()),m(n=>r.parseFromString(n,"text/xml")),X(1))}function jo(e){let t=A("script",{src:e});return H(()=>(document.head.appendChild(t),C(y(t,"load"),y(t,"error").pipe(x(()=>Rr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),te(1))))}function Fo(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Uo(){return C(y(window,"scroll",{passive:!0}),y(window,"resize",{passive:!0})).pipe(m(Fo),q(Fo()))}function Do(){return{width:innerWidth,height:innerHeight}}function Wo(){return y(window,"resize",{passive:!0}).pipe(m(Do),q(Do()))}function Vo(){return Y([Uo(),Wo()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function pr(e,{viewport$:t,header$:r}){let n=t.pipe(J("size")),o=Y([n,r]).pipe(m(()=>Ne(e)));return Y([r,t,o]).pipe(m(([{height:i},{offset:a,size:s},{x:c,y:u}])=>({offset:{x:a.x-c,y:a.y-u+i},size:s})))}function No(e,{tx$:t}){let r=y(e,"message").pipe(m(({data:n})=>n));return t.pipe(Ot(()=>r,{leading:!0,trailing:!0}),S(n=>e.postMessage(n)),x(()=>r),ie())}var ns=Q("#__config"),mt=JSON.parse(ns.textContent);mt.base=`${new URL(mt.base,xe())}`;function me(){return mt}function se(e){return mt.features.includes(e)}function Z(e,t){return typeof t!="undefined"?mt.translations[e].replace("#",t.toString()):mt.translations[e]}function Se(e,t=document){return Q(`[data-md-component=${e}]`,t)}function ne(e,t=document){return G(`[data-md-component=${e}]`,t)}var ei=Qe(Qr());function zo(e){return A("aside",{class:"md-annotation",tabIndex:0},A("div",{class:"md-annotation__inner md-tooltip"},A("div",{class:"md-tooltip__inner md-typeset"})),A("span",{class:"md-annotation__index"},A("span",{"data-md-annotation-id":e})))}function qo(e){return A("button",{class:"md-clipboard md-icon",title:Z("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Kr(e,t){let r=t&2,n=t&1,o=Object.keys(e.terms).filter(a=>!e.terms[a]).reduce((a,s)=>[...a,A("del",null,s)," "],[]).slice(0,-1),i=new URL(e.location);return se("search.highlight")&&i.searchParams.set("h",Object.entries(e.terms).filter(([,a])=>a).reduce((a,[s])=>`${a} ${s}`.trim(),"")),A("a",{href:`${i}`,class:"md-search-result__link",tabIndex:-1},A("article",{class:["md-search-result__article",...r?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},r>0&&A("div",{class:"md-search-result__icon md-icon"}),A("h1",{class:"md-search-result__title"},e.title),n>0&&e.text.length>0&&A("p",{class:"md-search-result__teaser"},Ro(e.text,320)),e.tags&&e.tags.map(a=>A("span",{class:"md-tag"},a)),n>0&&o.length>0&&A("p",{class:"md-search-result__terms"},Z("search.result.term.missing"),": ",o)))}function Qo(e){let t=e[0].score,r=[...e],n=r.findIndex(u=>!u.location.includes("#")),[o]=r.splice(n,1),i=r.findIndex(u=>u.scoreKr(u,1)),...s.length?[A("details",{class:"md-search-result__more"},A("summary",{tabIndex:-1},s.length>0&&s.length===1?Z("search.result.more.one"):Z("search.result.more.other",s.length)),s.map(u=>Kr(u,1)))]:[]];return A("li",{class:"md-search-result__item"},c)}function Ko(e){return A("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>A("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ur(r):r)))}function Yo(e){return A("div",{class:"md-typeset__scrollwrap"},A("div",{class:"md-typeset__table"},e))}function os(e){let t=me(),r=new URL(`../${e.version}/`,t.base);return A("li",{class:"md-version__item"},A("a",{href:r.toString(),class:"md-version__link"},e.title))}function Bo(e,t){return A("div",{class:"md-version"},A("button",{class:"md-version__current","aria-label":Z("select.version.title")},t.title),A("ul",{class:"md-version__list"},e.map(os)))}function is(e,t){let r=H(()=>Y([mo(e),rr(t)])).pipe(m(([{x:n,y:o},i])=>{let{width:a}=Ae(e);return{x:n-i.x+a/2,y:o-i.y}}));return tr(e).pipe(x(n=>r.pipe(m(o=>({active:n,offset:o})),te(+!n||1/0))))}function Go(e,t){return H(()=>{let r=new E;r.subscribe({next({offset:i}){e.style.setProperty("--md-tooltip-x",`${i.x}px`),e.style.setProperty("--md-tooltip-y",`${i.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),r.pipe(Dr(500,_e),m(()=>t.getBoundingClientRect()),m(({x:i})=>i)).subscribe({next(i){i?e.style.setProperty("--md-tooltip-0",`${-i}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}});let n=Q(":scope > :last-child",e),o=y(n,"mousedown",{once:!0});return r.pipe(x(({active:i})=>i?o:z),S(i=>i.preventDefault())).subscribe(()=>e.blur()),is(e,t).pipe(S(i=>r.next(i)),L(()=>r.complete()),m(i=>I({ref:e},i)))})}function as(e){let t=[];for(let r of G(".c, .c1, .cm",e)){let n,o=r.firstChild;if(o instanceof Text)for(;n=/\((\d+)\)/.exec(o.textContent);){let i=o.splitText(n.index);o=i.splitText(n[0].length),t.push(i)}}return t}function Jo(e,t){t.append(...Array.from(e.childNodes))}function Xo(e,t,{print$:r}){let n=new Map;for(let o of as(t)){let[,i]=o.textContent.match(/\((\d+)\)/);ue(`li:nth-child(${i})`,e)&&(n.set(+i,zo(+i)),o.replaceWith(n.get(+i)))}return n.size===0?z:H(()=>{let o=new E;return r.pipe(ae(o.pipe(pe(1)))).subscribe(i=>{e.hidden=!i;for(let[a,s]of n){let c=Q(".md-typeset",s),u=Q(`li:nth-child(${a})`,e);i?Jo(c,u):Jo(u,c)}}),C(...[...n].map(([,i])=>Go(i,t))).pipe(L(()=>o.complete()),ie())})}var ss=0;function ti(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return ti(t)}}function Zo(e){return ve(e).pipe(m(({width:t})=>({scrollable:ar(e).width>t})),J("scrollable"))}function ri(e,t){let{matches:r}=matchMedia("(hover)"),n=H(()=>{let o=new E;if(o.subscribe(({scrollable:a})=>{a&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")}),ei.default.isSupported()){let a=e.closest("pre");a.id=`__code_${++ss}`,a.insertBefore(qo(a.id),e)}let i=e.closest(".highlight");if(i instanceof HTMLElement){let a=ti(i);if(typeof a!="undefined"&&(i.classList.contains("annotate")||se("content.code.annotate"))){let s=Xo(a,e,t);return Zo(e).pipe(S(c=>o.next(c)),L(()=>o.complete()),m(c=>I({ref:e},c)),Xe(ve(i).pipe(ae(o.pipe(pe(1))),m(({width:c,height:u})=>c&&u),B(),x(c=>c?s:z))))}}return Zo(e).pipe(S(a=>o.next(a)),L(()=>o.complete()),m(a=>I({ref:e},a)))});return _o(e).pipe(_(o=>o),te(1),x(()=>n))}var ni=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:transparent}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}defs #flowchart-circleEnd,defs #flowchart-circleStart,defs #flowchart-crossEnd,defs #flowchart-crossStart,defs #flowchart-pointEnd,defs #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}.actor,defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{stroke:var(--md-mermaid-node-fg-color)}text.actor>tspan{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-default-fg-color--lighter)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-edge-color)}.loopText>tspan,.messageText{font-family:var(--md-mermaid-font-family)!important}#arrowhead path,.loopText>tspan,.messageText{fill:var(--md-mermaid-edge-color);stroke:none}.loopLine{stroke:var(--md-mermaid-node-fg-color)}.labelBox,.loopLine{fill:var(--md-mermaid-node-bg-color)}.labelBox{stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-node-fg-color);font-family:var(--md-mermaid-font-family)}";var Yr,us=0;function fs(){return typeof mermaid=="undefined"||mermaid instanceof Element?jo("https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js"):j(void 0)}function oi(e){return e.classList.remove("mermaid"),Yr||(Yr=fs().pipe(S(()=>mermaid.initialize({startOnLoad:!1,themeCSS:ni})),m(()=>{}),X(1))),Yr.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${us++}`,r=A("div",{class:"mermaid"});mermaid.mermaidAPI.render(t,e.textContent,n=>{let o=r.attachShadow({mode:"closed"});o.innerHTML=n,e.replaceWith(r)})}),Yr.pipe(m(()=>({ref:e})))}function ps(e,{target$:t,print$:r}){let n=!0;return C(t.pipe(m(o=>o.closest("details:not([open])")),_(o=>e===o),m(()=>({action:"open",reveal:!0}))),r.pipe(_(o=>o||!n),S(()=>n=e.open),m(o=>({action:o?"open":"close"}))))}function ii(e,t){return H(()=>{let r=new E;return r.subscribe(({action:n,reveal:o})=>{n==="open"?e.setAttribute("open",""):e.removeAttribute("open"),o&&e.scrollIntoView()}),ps(e,t).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))})}var ai=A("table");function si(e){return e.replaceWith(ai),ai.replaceWith(Yo(e)),j({ref:e})}function ls(e){let t=G(":scope > input",e),r=t.find(n=>n.checked)||t[0];return C(...t.map(n=>y(n,"change").pipe(m(()=>({active:Q(`label[for=${n.id}]`)}))))).pipe(q({active:Q(`label[for=${r.id}]`)}))}function ci(e){let t=Q(".tabbed-labels",e);return H(()=>{let r=new E;return Y([r,ve(e)]).pipe(He(1,_e),ae(r.pipe(pe(1)))).subscribe({next([{active:n}]){let o=Ne(n),{width:i}=Ae(n);e.style.setProperty("--md-indicator-x",`${o.x}px`),e.style.setProperty("--md-indicator-width",`${i}px`),t.scrollTo({behavior:"smooth",left:o.x})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),ls(e).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))}).pipe(Ye(ce))}function ui(e,{target$:t,print$:r}){return C(...G("pre:not(.mermaid) > code",e).map(n=>ri(n,{print$:r})),...G("pre.mermaid",e).map(n=>oi(n)),...G("table:not([class])",e).map(n=>si(n)),...G("details",e).map(n=>ii(n,{target$:t,print$:r})),...G("[data-tabs]",e).map(n=>ci(n)))}function ms(e,{alert$:t}){return t.pipe(x(r=>C(j(!0),j(!1).pipe(Ie(2e3))).pipe(m(n=>({message:r,active:n})))))}function fi(e,t){let r=Q(".md-typeset",e);return H(()=>{let n=new E;return n.subscribe(({message:o,active:i})=>{r.textContent=o,i?e.setAttribute("data-md-state","open"):e.removeAttribute("data-md-state")}),ms(e,t).pipe(S(o=>n.next(o)),L(()=>n.complete()),m(o=>I({ref:e},o)))})}function ds({viewport$:e}){if(!se("header.autohide"))return j(!1);let t=e.pipe(m(({offset:{y:o}})=>o),Te(2,1),m(([o,i])=>[oMath.abs(i-o.y)>100),m(([,[o]])=>o),B()),n=lt("search");return Y([e,n]).pipe(m(([{offset:o},i])=>o.y>400&&!i),B(),x(o=>o?r:j(!1)),q(!1))}function pi(e,t){return H(()=>Y([ve(e),ds(t)])).pipe(m(([{height:r},n])=>({height:r,hidden:n})),B((r,n)=>r.height===n.height&&r.hidden===n.hidden),X(1))}function li(e,{header$:t,main$:r}){return H(()=>{let n=new E;return n.pipe(J("active"),Ge(t)).subscribe(([{active:o},{hidden:i}])=>{o?e.setAttribute("data-md-state",i?"hidden":"shadow"):e.removeAttribute("data-md-state")}),r.subscribe(n),t.pipe(ae(n.pipe(pe(1))),m(o=>I({ref:e},o)))})}function hs(e,{viewport$:t,header$:r}){return pr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:n}})=>{let{height:o}=Ae(e);return{active:n>=o}}),J("active"))}function mi(e,t){return H(()=>{let r=new E;r.subscribe(({active:o})=>{o?e.setAttribute("data-md-state","active"):e.removeAttribute("data-md-state")});let n=ue("article h1");return typeof n=="undefined"?z:hs(n,t).pipe(S(o=>r.next(o)),L(()=>r.complete()),m(o=>I({ref:e},o)))})}function di(e,{viewport$:t,header$:r}){let n=r.pipe(m(({height:i})=>i),B()),o=n.pipe(x(()=>ve(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),J("bottom"))));return Y([n,o,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:c},size:{height:u}}])=>(u=Math.max(0,u-Math.max(0,a-c,i)-Math.max(0,u+c-s)),{offset:a-i,height:u,active:a-i<=c})),B((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function bs(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return j(...e).pipe(oe(r=>y(r,"change").pipe(m(()=>r))),q(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),X(1))}function hi(e){return H(()=>{let t=new E;t.subscribe(n=>{document.body.setAttribute("data-md-color-switching","");for(let[o,i]of Object.entries(n.color))document.body.setAttribute(`data-md-color-${o}`,i);for(let o=0;o{document.body.removeAttribute("data-md-color-switching")});let r=G("input",e);return bs(r).pipe(S(n=>t.next(n)),L(()=>t.complete()),m(n=>I({ref:e},n)))})}var Br=Qe(Qr());function vs(e){e.setAttribute("data-md-copying","");let t=e.innerText;return e.removeAttribute("data-md-copying"),t}function bi({alert$:e}){Br.default.isSupported()&&new k(t=>{new Br.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||vs(Q(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(S(t=>{t.trigger.focus()}),m(()=>Z("clipboard.copied"))).subscribe(e)}function gs(e){if(e.length<2)return[""];let[t,r]=[...e].sort((o,i)=>o.length-i.length).map(o=>o.replace(/[^/]+$/,"")),n=0;if(t===r)n=t.length;else for(;t.charCodeAt(n)===r.charCodeAt(n);)n++;return e.map(o=>o.replace(t.slice(0,n),""))}function lr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return j(t);{let r=me();return $o(new URL("sitemap.xml",e||r.base)).pipe(m(n=>gs(G("loc",n).map(o=>o.textContent))),Pe([]),S(n=>__md_set("__sitemap",n,sessionStorage,e)))}}function vi({document$:e,location$:t,viewport$:r}){let n=me();if(location.protocol==="file:")return;"scrollRestoration"in history&&(history.scrollRestoration="manual",y(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));let o=ue("link[rel=icon]");typeof o!="undefined"&&(o.href=o.href);let i=lr().pipe(m(u=>u.map(f=>`${new URL(f,n.base)}`)),x(u=>y(document.body,"click").pipe(_(f=>!f.metaKey&&!f.ctrlKey),x(f=>{if(f.target instanceof Element){let p=f.target.closest("a");if(p&&!p.target){let l=new URL(p.href);if(l.search="",l.hash="",l.pathname!==location.pathname&&u.includes(l.toString()))return f.preventDefault(),j({url:new URL(p.href)})}}return ye}))),ie()),a=y(window,"popstate").pipe(_(u=>u.state!==null),m(u=>({url:new URL(location.href),offset:u.state})),ie());C(i,a).pipe(B((u,f)=>u.url.href===f.url.href),m(({url:u})=>u)).subscribe(t);let s=t.pipe(J("pathname"),x(u=>fr(u.href).pipe(We(()=>(cr(u),ye)))),ie());i.pipe(ft(s)).subscribe(({url:u})=>{history.pushState({},"",`${u}`)});let c=new DOMParser;s.pipe(x(u=>u.text()),m(u=>c.parseFromString(u,"text/html"))).subscribe(e),e.pipe($e(1)).subscribe(u=>{for(let f of["title","link[rel=canonical]","meta[name=author]","meta[name=description]","[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...se("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let p=ue(f),l=ue(f,u);typeof p!="undefined"&&typeof l!="undefined"&&p.replaceWith(l)}}),e.pipe($e(1),m(()=>Se("container")),x(u=>G("script",u)),Pr(u=>{let f=A("script");if(u.src){for(let p of u.getAttributeNames())f.setAttribute(p,u.getAttribute(p));return u.replaceWith(f),new k(p=>{f.onload=()=>p.complete()})}else return f.textContent=u.textContent,u.replaceWith(f),z})).subscribe(),C(i,a).pipe(ft(e)).subscribe(({url:u,offset:f})=>{u.hash&&!f?Ho(u.hash):window.scrollTo(0,(f==null?void 0:f.y)||0)}),r.pipe(Et(i),Je(250),J("offset")).subscribe(({offset:u})=>{history.replaceState(u,"")}),C(i,a).pipe(Te(2,1),_(([u,f])=>u.url.pathname===f.url.pathname),m(([,u])=>u)).subscribe(({offset:u})=>{window.scrollTo(0,(u==null?void 0:u.y)||0)})}var Ss=Qe(Gr());var yi=Qe(Gr());function Jr(e,t){let r=new RegExp(e.separator,"img"),n=(o,i,a)=>`${i}${a}`;return o=>{o=o.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator})(${o.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(t?(0,yi.default)(a):a).replace(i,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function xi(e){return e.split(/"([^"]+)"/g).map((t,r)=>r&1?t.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):t).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function dt(e){return e.type===1}function Si(e){return e.type===2}function ht(e){return e.type===3}function Es({config:e,docs:t}){e.lang.length===1&&e.lang[0]==="en"&&(e.lang=[Z("search.config.lang")]),e.separator==="[\\s\\-]+"&&(e.separator=Z("search.config.separator"));let n={pipeline:Z("search.config.pipeline").split(/\s*,\s*/).filter(Boolean),suggestions:se("search.suggest")};return{config:e,docs:t,options:n}}function wi(e,t){let r=me(),n=new Worker(e),o=new E,i=No(n,{tx$:o}).pipe(m(a=>{if(ht(a))for(let s of a.data.items)for(let c of s)c.location=`${new URL(c.location,r.base)}`;return a}),ie());return re(t).pipe(m(a=>({type:0,data:Es(a)}))).subscribe(o.next.bind(o)),{tx$:o,rx$:i}}function Ei({document$:e}){let t=me(),r=Ce(new URL("../versions.json",t.base)),n=r.pipe(m(o=>{let[,i]=t.base.match(/([^/]+)\/?$/);return o.find(({version:a,aliases:s})=>a===i||s.includes(i))||o[0]}));Y([r,n]).pipe(m(([o,i])=>new Map(o.filter(a=>a!==i).map(a=>[`${new URL(`../${a.version}/`,t.base)}`,a]))),x(o=>y(document.body,"click").pipe(_(i=>!i.metaKey&&!i.ctrlKey),x(i=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&o.has(a.href))return i.preventDefault(),j(a.href)}return z}),x(i=>{let{version:a}=o.get(i);return lr(new URL(i)).pipe(m(s=>{let u=xe().href.replace(t.base,"");return s.includes(u)?new URL(`../${a}/${u}`,t.base):new URL(i)}))})))).subscribe(o=>cr(o)),Y([r,n]).subscribe(([o,i])=>{Q(".md-header__topic").appendChild(Bo(o,i))}),e.pipe(x(()=>n)).subscribe(o=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){let s=((a=t.version)==null?void 0:a.default)||"latest";i=!o.aliases.includes(s),__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ne("outdated"))s.hidden=!1})}function Os(e,{rx$:t}){let r=(__search==null?void 0:__search.transform)||xi,{searchParams:n}=xe();n.has("q")&&ze("search",!0);let o=t.pipe(_(dt),te(1),m(()=>n.get("q")||""));lt("search").pipe(_(s=>!s),te(1)).subscribe(()=>{let s=new URL(location.href);s.searchParams.delete("q"),history.replaceState({},"",`${s}`)}),o.subscribe(s=>{s&&(e.value=s,e.focus())});let i=tr(e),a=C(y(e,"keyup"),y(e,"focus").pipe(Ie(1)),o).pipe(m(()=>r(e.value)),q(""),B());return Y([a,i]).pipe(m(([s,c])=>({value:s,focus:c})),X(1))}function Oi(e,{tx$:t,rx$:r}){let n=new E;return n.pipe(J("value"),m(({value:o})=>({type:2,data:o}))).subscribe(t.next.bind(t)),n.pipe(J("focus")).subscribe(({focus:o})=>{o?(ze("search",o),e.placeholder=""):e.placeholder=Z("search.placeholder")}),y(e.form,"reset").pipe(ae(n.pipe(pe(1)))).subscribe(()=>e.focus()),Os(e,{tx$:t,rx$:r}).pipe(S(o=>n.next(o)),L(()=>n.complete()),m(o=>I({ref:e},o)))}function _i(e,{rx$:t},{query$:r}){let n=new E,o=To(e.parentElement).pipe(_(Boolean)),i=Q(":scope > :first-child",e),a=Q(":scope > :last-child",e),s=t.pipe(_(dt),te(1));return n.pipe(Me(r),Et(s)).subscribe(([{items:u},{value:f}])=>{if(f)switch(u.length){case 0:i.textContent=Z("search.result.none");break;case 1:i.textContent=Z("search.result.one");break;default:i.textContent=Z("search.result.other",ur(u.length))}else i.textContent=Z("search.result.placeholder")}),n.pipe(S(()=>a.innerHTML=""),x(({items:u})=>C(j(...u.slice(0,10)),j(...u.slice(10)).pipe(Te(4),Wr(o),x(([f])=>f))))).subscribe(u=>a.appendChild(Qo(u))),t.pipe(_(ht),m(({data:u})=>u)).pipe(S(u=>n.next(u)),L(()=>n.complete()),m(u=>I({ref:e},u)))}function _s(e,{query$:t}){return t.pipe(m(({value:r})=>{let n=xe();return n.hash="",n.searchParams.delete("h"),n.searchParams.set("q",r),{url:n}}))}function Ti(e,t){let r=new E;return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),y(e,"click").subscribe(n=>n.preventDefault()),_s(e,t).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))}function Mi(e,{rx$:t},{keyboard$:r}){let n=new E,o=Se("search-query"),i=C(y(o,"keydown"),y(o,"focus")).pipe(ke(ce),m(()=>o.value),B());return n.pipe(Ge(i),m(([{suggestions:s},c])=>{let u=c.split(/([\s-]+)/);if((s==null?void 0:s.length)&&u[u.length-1]){let f=s[s.length-1];f.startsWith(u[u.length-1])&&(u[u.length-1]=f)}else u.length=0;return u})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(_(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&o.selectionStart===o.value.length&&(o.value=e.innerText);break}}),t.pipe(_(ht),m(({data:s})=>s)).pipe(S(s=>n.next(s)),L(()=>n.complete()),m(()=>({ref:e})))}function Li(e,{index$:t,keyboard$:r}){let n=me();try{let o=(__search==null?void 0:__search.worker)||n.search,i=wi(o,t),a=Se("search-query",e),s=Se("search-result",e),{tx$:c,rx$:u}=i;c.pipe(_(Si),ft(u.pipe(_(dt))),te(1)).subscribe(c.next.bind(c)),r.pipe(_(({mode:l})=>l==="search")).subscribe(l=>{let d=Ve();switch(l.type){case"Enter":if(d===a){let h=new Map;for(let b of G(":first-child [href]",s)){let F=b.firstElementChild;h.set(b,parseFloat(F.getAttribute("data-md-score")))}if(h.size){let[[b]]=[...h].sort(([,F],[,K])=>K-F);b.click()}l.claim()}break;case"Escape":case"Tab":ze("search",!1),a.blur();break;case"ArrowUp":case"ArrowDown":if(typeof d=="undefined")a.focus();else{let h=[a,...G(":not(details) > [href], summary, details[open] [href]",s)],b=Math.max(0,(Math.max(0,h.indexOf(d))+h.length+(l.type==="ArrowUp"?-1:1))%h.length);h[b].focus()}l.claim();break;default:a!==Ve()&&a.focus()}}),r.pipe(_(({mode:l})=>l==="global")).subscribe(l=>{switch(l.type){case"f":case"s":case"/":a.focus(),a.select(),l.claim();break}});let f=Oi(a,i),p=_i(s,i,{query$:f});return C(f,p).pipe(Xe(...ne("search-share",e).map(l=>Ti(l,{query$:f})),...ne("search-suggest",e).map(l=>Mi(l,i,{keyboard$:r}))))}catch(o){return e.hidden=!0,ye}}function Ai(e,{index$:t,location$:r}){return Y([t,r.pipe(q(xe()),_(n=>!!n.searchParams.get("h")))]).pipe(m(([n,o])=>Jr(n.config,!0)(o.searchParams.get("h"))),m(n=>{var a;let o=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,u=n(c);u.length>c.length&&o.set(s,u)}for(let[s,c]of o){let{childNodes:u}=A("span",null,c);s.replaceWith(...Array.from(u))}return{ref:e,nodes:o}}))}function Ts(e,{viewport$:t,main$:r}){let n=e.parentElement,o=n.offsetTop-n.parentElement.offsetTop;return Y([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(o,Math.max(0,s-i))-o,{height:a,locked:s>=i+o})),B((i,a)=>i.height===a.height&&i.locked===a.locked))}function Xr(e,n){var o=n,{header$:t}=o,r=on(o,["header$"]);let i=Q(".md-sidebar__scrollwrap",e),{y:a}=Ne(i);return H(()=>{let s=new E;return s.pipe(He(0,_e),Me(t)).subscribe({next([{height:c},{height:u}]){i.style.height=`${c-2*a}px`,e.style.top=`${u}px`},complete(){i.style.height="",e.style.top=""}}),Ts(e,r).pipe(S(c=>s.next(c)),L(()=>s.complete()),m(c=>I({ref:e},c)))})}function Ci(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return St(Ce(`${r}/releases/latest`).pipe(m(n=>({version:n.tag_name})),Pe({})),Ce(r).pipe(m(n=>({stars:n.stargazers_count,forks:n.forks_count})),Pe({}))).pipe(m(([n,o])=>I(I({},n),o)))}else{let r=`https://api.github.com/users/${e}`;return Ce(r).pipe(m(n=>({repositories:n.public_repos})),Pe({}))}}function Ri(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ce(r).pipe(m(({star_count:n,forks_count:o})=>({stars:n,forks:o})),Pe({}))}function ki(e){let[t]=e.match(/(git(?:hub|lab))/i)||[];switch(t.toLowerCase()){case"github":let[,r,n]=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);return Ci(r,n);case"gitlab":let[,o,i]=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i);return Ri(o,i);default:return z}}var Ms;function Ls(e){return Ms||(Ms=H(()=>{let t=__md_get("__source",sessionStorage);return t?j(t):ki(e.href).pipe(S(r=>__md_set("__source",r,sessionStorage)))}).pipe(We(()=>z),_(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function Hi(e){let t=Q(":scope > :last-child",e);return H(()=>{let r=new E;return r.subscribe(({facts:n})=>{t.appendChild(Ko(n)),t.setAttribute("data-md-state","done")}),Ls(e).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))})}function As(e,{viewport$:t,header$:r}){return ve(document.body).pipe(x(()=>pr(e,{header$:r,viewport$:t})),m(({offset:{y:n}})=>({hidden:n>=10})),J("hidden"))}function Pi(e,t){return H(()=>{let r=new E;return r.subscribe({next({hidden:n}){n?e.setAttribute("data-md-state","hidden"):e.removeAttribute("data-md-state")},complete(){e.removeAttribute("data-md-state")}}),(se("navigation.tabs.sticky")?j({hidden:!1}):As(e,t)).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))})}function Cs(e,{viewport$:t,header$:r}){let n=new Map,o=G("[href^=\\#]",e);for(let s of o){let c=decodeURIComponent(s.hash.substring(1)),u=ue(`[id="${c}"]`);typeof u!="undefined"&&n.set(s,u)}let i=r.pipe(J("height"),m(({height:s})=>{let c=Se("main"),u=Q(":scope > :first-child",c);return s+.8*(u.offsetTop-c.offsetTop)}),ie());return ve(document.body).pipe(J("height"),x(s=>H(()=>{let c=[];return j([...n].reduce((u,[f,p])=>{for(;c.length&&n.get(c[c.length-1]).tagName>=p.tagName;)c.pop();let l=p.offsetTop;for(;!l&&p.parentElement;)p=p.parentElement,l=p.offsetTop;return u.set([...c=[...c,f]].reverse(),l)},new Map))}).pipe(m(c=>new Map([...c].sort(([,u],[,f])=>u-f))),Ge(i),x(([c,u])=>t.pipe($r(([f,p],{offset:{y:l},size:d})=>{let h=l+d.height>=Math.floor(s.height);for(;p.length;){let[,b]=p[0];if(b-u=l&&!h)p=[f.pop(),...p];else break}return[f,p]},[[],[...c]]),B((f,p)=>f[0]===p[0]&&f[1]===p[1])))))).pipe(m(([s,c])=>({prev:s.map(([u])=>u),next:c.map(([u])=>u)})),q({prev:[],next:[]}),Te(2,1),m(([s,c])=>s.prev.length{let o=new E;return o.subscribe(({prev:i,next:a})=>{for(let[s]of a)s.removeAttribute("data-md-state"),s.classList.remove("md-nav__link--active");for(let[s,[c]]of i.entries())c.setAttribute("data-md-state","blur"),c.classList.toggle("md-nav__link--active",s===i.length-1)}),se("navigation.tracking")&&t.pipe(ae(o.pipe(pe(1))),J("offset"),Je(250),$e(1),ae(n.pipe($e(1))),wt({delay:250}),Me(o)).subscribe(([,{prev:i}])=>{let a=xe(),s=i[i.length-1];if(s&&s.length){let[c]=s,{hash:u}=new URL(c.href);a.hash!==u&&(a.hash=u,history.replaceState({},"",`${a}`))}else a.hash="",history.replaceState({},"",`${a}`)}),Cs(e,{viewport$:t,header$:r}).pipe(S(i=>o.next(i)),L(()=>o.complete()),m(i=>I({ref:e},i)))})}function Rs(e,{viewport$:t,main$:r,target$:n}){let o=t.pipe(m(({offset:{y:a}})=>a),Te(2,1),m(([a,s])=>a>s&&s>0),B()),i=r.pipe(m(({active:a})=>a));return Y([i,o]).pipe(m(([a,s])=>!(a&&s)),B(),ae(n.pipe($e(1))),er(!0),wt({delay:250}),m(a=>({hidden:a})))}function $i(e,{viewport$:t,header$:r,main$:n,target$:o}){let i=new E;return i.subscribe({next({hidden:a}){a?(e.setAttribute("data-md-state","hidden"),e.setAttribute("tabindex","-1"),e.blur()):(e.removeAttribute("data-md-state"),e.removeAttribute("tabindex"))},complete(){e.style.top="",e.setAttribute("data-md-state","hidden"),e.removeAttribute("tabindex")}}),r.pipe(ae(i.pipe(er(0),pe(1))),J("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),Rs(e,{viewport$:t,main$:n,target$:o}).pipe(S(a=>i.next(a)),L(()=>i.complete()),m(a=>I({ref:e},a)))}function ji({document$:e,tablet$:t}){e.pipe(x(()=>G("[data-md-state=indeterminate]")),S(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>y(r,"change").pipe(Fr(()=>r.hasAttribute("data-md-state")),m(()=>r))),Me(t)).subscribe(([r,n])=>{r.removeAttribute("data-md-state"),n&&(r.checked=!1)})}function ks(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Fi({document$:e}){e.pipe(x(()=>G("[data-md-scrollfix]")),S(t=>t.removeAttribute("data-md-scrollfix")),_(ks),oe(t=>y(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ui({viewport$:e,tablet$:t}){Y([lt("search"),t]).pipe(m(([r,n])=>r&&!n),x(r=>j(r).pipe(Ie(r?400:100))),Me(e)).subscribe(([r,{offset:{y:n}}])=>{if(r)document.body.setAttribute("data-md-state","lock"),document.body.style.top=`-${n}px`;else{let o=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-state"),document.body.style.top="",o&&window.scrollTo(0,o)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let n=e[r];typeof n!="object"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?t.insertBefore(this.previousSibling,n):t.replaceChild(n,this)}}}));document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var Ze=lo(),dr=Ao(),Tt=Po(),Zr=Lo(),we=Vo(),hr=Nr("(min-width: 960px)"),Wi=Nr("(min-width: 1220px)"),Vi=Io(),Ni=me(),zi=document.forms.namedItem("search")?(__search==null?void 0:__search.index)||Ce(new URL("search/search_index.json",Ni.base)):ye,en=new E;bi({alert$:en});se("navigation.instant")&&vi({document$:Ze,location$:dr,viewport$:we});var Di;((Di=Ni.version)==null?void 0:Di.provider)==="mike"&&Ei({document$:Ze});C(dr,Tt).pipe(Ie(125)).subscribe(()=>{ze("drawer",!1),ze("search",!1)});Zr.pipe(_(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ue("[href][rel=prev]");typeof t!="undefined"&&t.click();break;case"n":case".":let r=ue("[href][rel=next]");typeof r!="undefined"&&r.click();break}});ji({document$:Ze,tablet$:hr});Fi({document$:Ze});Ui({viewport$:we,tablet$:hr});var qe=pi(Se("header"),{viewport$:we}),mr=Ze.pipe(m(()=>Se("main")),x(e=>di(e,{viewport$:we,header$:qe})),X(1)),Hs=C(...ne("dialog").map(e=>fi(e,{alert$:en})),...ne("header").map(e=>li(e,{viewport$:we,header$:qe,main$:mr})),...ne("palette").map(e=>hi(e)),...ne("search").map(e=>Li(e,{index$:zi,keyboard$:Zr})),...ne("source").map(e=>Hi(e))),Ps=H(()=>C(...ne("content").map(e=>ui(e,{target$:Tt,print$:Vi})),...ne("content").map(e=>se("search.highlight")?Ai(e,{index$:zi,location$:dr}):z),...ne("header-title").map(e=>mi(e,{viewport$:we,header$:qe})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?zr(Wi,()=>Xr(e,{viewport$:we,header$:qe,main$:mr})):zr(hr,()=>Xr(e,{viewport$:we,header$:qe,main$:mr}))),...ne("tabs").map(e=>Pi(e,{viewport$:we,header$:qe})),...ne("toc").map(e=>Ii(e,{viewport$:we,header$:qe,target$:Tt})),...ne("top").map(e=>$i(e,{viewport$:we,header$:qe,main$:mr,target$:Tt})))),qi=Ze.pipe(x(()=>Ps),Xe(Hs),X(1));qi.subscribe();window.document$=Ze;window.location$=dr;window.target$=Tt;window.keyboard$=Zr;window.viewport$=we;window.tablet$=hr;window.screen$=Wi;window.print$=Vi;window.alert$=en;window.component$=qi;})(); -//# sourceMappingURL=bundle.ed9748b7.min.js.map - diff --git a/test/assets/javascripts/bundle.ed9748b7.min.js.map b/test/assets/javascripts/bundle.ed9748b7.min.js.map deleted file mode 100644 index 43c5c4e0e2bb..000000000000 --- a/test/assets/javascripts/bundle.ed9748b7.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ - "version": 3, - "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/url-polyfill/url-polyfill.js", "node_modules/rxjs/node_modules/tslib/tslib.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "node_modules/array-flat-polyfill/index.mjs", "src/assets/javascripts/bundle.ts", "node_modules/unfetch/polyfill/index.js", "node_modules/rxjs/node_modules/tslib/modules/index.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/concatMap.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/sample.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/assets/javascripts/browser/document/index.ts", "src/assets/javascripts/browser/element/_/index.ts", "src/assets/javascripts/browser/element/focus/index.ts", "src/assets/javascripts/browser/element/offset/_/index.ts", "src/assets/javascripts/browser/element/offset/content/index.ts", "node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js", "src/assets/javascripts/browser/element/size/_/index.ts", "src/assets/javascripts/browser/element/size/content/index.ts", "src/assets/javascripts/browser/element/visibility/index.ts", "src/assets/javascripts/browser/toggle/index.ts", "src/assets/javascripts/browser/keyboard/index.ts", "src/assets/javascripts/browser/location/_/index.ts", "src/assets/javascripts/utilities/h/index.ts", "src/assets/javascripts/utilities/string/index.ts", "src/assets/javascripts/browser/location/hash/index.ts", "src/assets/javascripts/browser/media/index.ts", "src/assets/javascripts/browser/request/index.ts", "src/assets/javascripts/browser/script/index.ts", "src/assets/javascripts/browser/viewport/offset/index.ts", "src/assets/javascripts/browser/viewport/size/index.ts", "src/assets/javascripts/browser/viewport/_/index.ts", "src/assets/javascripts/browser/viewport/at/index.ts", "src/assets/javascripts/browser/worker/index.ts", "src/assets/javascripts/_/index.ts", "src/assets/javascripts/components/_/index.ts", "src/assets/javascripts/components/content/code/_/index.ts", "src/assets/javascripts/templates/annotation/index.tsx", "src/assets/javascripts/templates/clipboard/index.tsx", "src/assets/javascripts/templates/search/index.tsx", "src/assets/javascripts/templates/source/index.tsx", "src/assets/javascripts/templates/table/index.tsx", "src/assets/javascripts/templates/version/index.tsx", "src/assets/javascripts/components/content/annotation/_/index.ts", "src/assets/javascripts/components/content/annotation/list/index.ts", "src/assets/javascripts/components/content/code/mermaid/index.ts", "src/assets/javascripts/components/content/details/index.ts", "src/assets/javascripts/components/content/table/index.ts", "src/assets/javascripts/components/content/tabs/index.ts", "src/assets/javascripts/components/content/_/index.ts", "src/assets/javascripts/components/dialog/index.ts", "src/assets/javascripts/components/header/_/index.ts", "src/assets/javascripts/components/header/title/index.ts", "src/assets/javascripts/components/main/index.ts", "src/assets/javascripts/components/palette/index.ts", "src/assets/javascripts/integrations/clipboard/index.ts", "src/assets/javascripts/integrations/sitemap/index.ts", "src/assets/javascripts/integrations/instant/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/transform/index.ts", "src/assets/javascripts/integrations/search/worker/message/index.ts", "src/assets/javascripts/integrations/search/worker/_/index.ts", "src/assets/javascripts/integrations/version/index.ts", "src/assets/javascripts/components/search/query/index.ts", "src/assets/javascripts/components/search/result/index.ts", "src/assets/javascripts/components/search/share/index.ts", "src/assets/javascripts/components/search/suggest/index.ts", "src/assets/javascripts/components/search/_/index.ts", "src/assets/javascripts/components/search/highlight/index.ts", "src/assets/javascripts/components/sidebar/index.ts", "src/assets/javascripts/components/source/facts/github/index.ts", "src/assets/javascripts/components/source/facts/gitlab/index.ts", "src/assets/javascripts/components/source/facts/_/index.ts", "src/assets/javascripts/components/source/_/index.ts", "src/assets/javascripts/components/tabs/index.ts", "src/assets/javascripts/components/toc/index.ts", "src/assets/javascripts/components/top/index.ts", "src/assets/javascripts/patches/indeterminate/index.ts", "src/assets/javascripts/patches/scrollfix/index.ts", "src/assets/javascripts/patches/scrolllock/index.ts", "src/assets/javascripts/polyfills/index.ts"], - "sourceRoot": "../../../..", - "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "(function(global) {\r\n /**\r\n * Polyfill URLSearchParams\r\n *\r\n * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js\r\n */\r\n\r\n var checkIfIteratorIsSupported = function() {\r\n try {\r\n return !!Symbol.iterator;\r\n } catch (error) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var iteratorSupported = checkIfIteratorIsSupported();\r\n\r\n var createIterator = function(items) {\r\n var iterator = {\r\n next: function() {\r\n var value = items.shift();\r\n return { done: value === void 0, value: value };\r\n }\r\n };\r\n\r\n if (iteratorSupported) {\r\n iterator[Symbol.iterator] = function() {\r\n return iterator;\r\n };\r\n }\r\n\r\n return iterator;\r\n };\r\n\r\n /**\r\n * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing\r\n * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.\r\n */\r\n var serializeParam = function(value) {\r\n return encodeURIComponent(value).replace(/%20/g, '+');\r\n };\r\n\r\n var deserializeParam = function(value) {\r\n return decodeURIComponent(String(value).replace(/\\+/g, ' '));\r\n };\r\n\r\n var polyfillURLSearchParams = function() {\r\n\r\n var URLSearchParams = function(searchString) {\r\n Object.defineProperty(this, '_entries', { writable: true, value: {} });\r\n var typeofSearchString = typeof searchString;\r\n\r\n if (typeofSearchString === 'undefined') {\r\n // do nothing\r\n } else if (typeofSearchString === 'string') {\r\n if (searchString !== '') {\r\n this._fromString(searchString);\r\n }\r\n } else if (searchString instanceof URLSearchParams) {\r\n var _this = this;\r\n searchString.forEach(function(value, name) {\r\n _this.append(name, value);\r\n });\r\n } else if ((searchString !== null) && (typeofSearchString === 'object')) {\r\n if (Object.prototype.toString.call(searchString) === '[object Array]') {\r\n for (var i = 0; i < searchString.length; i++) {\r\n var entry = searchString[i];\r\n if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {\r\n this.append(entry[0], entry[1]);\r\n } else {\r\n throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\\'s input');\r\n }\r\n }\r\n } else {\r\n for (var key in searchString) {\r\n if (searchString.hasOwnProperty(key)) {\r\n this.append(key, searchString[key]);\r\n }\r\n }\r\n }\r\n } else {\r\n throw new TypeError('Unsupported input\\'s type for URLSearchParams');\r\n }\r\n };\r\n\r\n var proto = URLSearchParams.prototype;\r\n\r\n proto.append = function(name, value) {\r\n if (name in this._entries) {\r\n this._entries[name].push(String(value));\r\n } else {\r\n this._entries[name] = [String(value)];\r\n }\r\n };\r\n\r\n proto.delete = function(name) {\r\n delete this._entries[name];\r\n };\r\n\r\n proto.get = function(name) {\r\n return (name in this._entries) ? this._entries[name][0] : null;\r\n };\r\n\r\n proto.getAll = function(name) {\r\n return (name in this._entries) ? this._entries[name].slice(0) : [];\r\n };\r\n\r\n proto.has = function(name) {\r\n return (name in this._entries);\r\n };\r\n\r\n proto.set = function(name, value) {\r\n this._entries[name] = [String(value)];\r\n };\r\n\r\n proto.forEach = function(callback, thisArg) {\r\n var entries;\r\n for (var name in this._entries) {\r\n if (this._entries.hasOwnProperty(name)) {\r\n entries = this._entries[name];\r\n for (var i = 0; i < entries.length; i++) {\r\n callback.call(thisArg, entries[i], name, this);\r\n }\r\n }\r\n }\r\n };\r\n\r\n proto.keys = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push(name);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.values = function() {\r\n var items = [];\r\n this.forEach(function(value) {\r\n items.push(value);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.entries = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n if (iteratorSupported) {\r\n proto[Symbol.iterator] = proto.entries;\r\n }\r\n\r\n proto.toString = function() {\r\n var searchArray = [];\r\n this.forEach(function(value, name) {\r\n searchArray.push(serializeParam(name) + '=' + serializeParam(value));\r\n });\r\n return searchArray.join('&');\r\n };\r\n\r\n\r\n global.URLSearchParams = URLSearchParams;\r\n };\r\n\r\n var checkIfURLSearchParamsSupported = function() {\r\n try {\r\n var URLSearchParams = global.URLSearchParams;\r\n\r\n return (\r\n (new URLSearchParams('?a=1').toString() === 'a=1') &&\r\n (typeof URLSearchParams.prototype.set === 'function') &&\r\n (typeof URLSearchParams.prototype.entries === 'function')\r\n );\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n if (!checkIfURLSearchParamsSupported()) {\r\n polyfillURLSearchParams();\r\n }\r\n\r\n var proto = global.URLSearchParams.prototype;\r\n\r\n if (typeof proto.sort !== 'function') {\r\n proto.sort = function() {\r\n var _this = this;\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n if (!_this._entries) {\r\n _this.delete(name);\r\n }\r\n });\r\n items.sort(function(a, b) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else if (a[0] > b[0]) {\r\n return +1;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n if (_this._entries) { // force reset because IE keeps keys index\r\n _this._entries = {};\r\n }\r\n for (var i = 0; i < items.length; i++) {\r\n this.append(items[i][0], items[i][1]);\r\n }\r\n };\r\n }\r\n\r\n if (typeof proto._fromString !== 'function') {\r\n Object.defineProperty(proto, '_fromString', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function(searchString) {\r\n if (this._entries) {\r\n this._entries = {};\r\n } else {\r\n var keys = [];\r\n this.forEach(function(value, name) {\r\n keys.push(name);\r\n });\r\n for (var i = 0; i < keys.length; i++) {\r\n this.delete(keys[i]);\r\n }\r\n }\r\n\r\n searchString = searchString.replace(/^\\?/, '');\r\n var attributes = searchString.split('&');\r\n var attribute;\r\n for (var i = 0; i < attributes.length; i++) {\r\n attribute = attributes[i].split('=');\r\n this.append(\r\n deserializeParam(attribute[0]),\r\n (attribute.length > 1) ? deserializeParam(attribute[1]) : ''\r\n );\r\n }\r\n }\r\n });\r\n }\r\n\r\n // HTMLAnchorElement\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n\r\n(function(global) {\r\n /**\r\n * Polyfill URL\r\n *\r\n * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js\r\n */\r\n\r\n var checkIfURLIsSupported = function() {\r\n try {\r\n var u = new global.URL('b', 'http://a');\r\n u.pathname = 'c d';\r\n return (u.href === 'http://a/c%20d') && u.searchParams;\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var polyfillURL = function() {\r\n var _URL = global.URL;\r\n\r\n var URL = function(url, base) {\r\n if (typeof url !== 'string') url = String(url);\r\n if (base && typeof base !== 'string') base = String(base);\r\n\r\n // Only create another document if the base is different from current location.\r\n var doc = document, baseElement;\r\n if (base && (global.location === void 0 || base !== global.location.href)) {\r\n base = base.toLowerCase();\r\n doc = document.implementation.createHTMLDocument('');\r\n baseElement = doc.createElement('base');\r\n baseElement.href = base;\r\n doc.head.appendChild(baseElement);\r\n try {\r\n if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);\r\n } catch (err) {\r\n throw new Error('URL unable to set base ' + base + ' due to ' + err);\r\n }\r\n }\r\n\r\n var anchorElement = doc.createElement('a');\r\n anchorElement.href = url;\r\n if (baseElement) {\r\n doc.body.appendChild(anchorElement);\r\n anchorElement.href = anchorElement.href; // force href to refresh\r\n }\r\n\r\n var inputElement = doc.createElement('input');\r\n inputElement.type = 'url';\r\n inputElement.value = url;\r\n\r\n if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {\r\n throw new TypeError('Invalid URL');\r\n }\r\n\r\n Object.defineProperty(this, '_anchorElement', {\r\n value: anchorElement\r\n });\r\n\r\n\r\n // create a linked searchParams which reflect its changes on URL\r\n var searchParams = new global.URLSearchParams(this.search);\r\n var enableSearchUpdate = true;\r\n var enableSearchParamsUpdate = true;\r\n var _this = this;\r\n ['append', 'delete', 'set'].forEach(function(methodName) {\r\n var method = searchParams[methodName];\r\n searchParams[methodName] = function() {\r\n method.apply(searchParams, arguments);\r\n if (enableSearchUpdate) {\r\n enableSearchParamsUpdate = false;\r\n _this.search = searchParams.toString();\r\n enableSearchParamsUpdate = true;\r\n }\r\n };\r\n });\r\n\r\n Object.defineProperty(this, 'searchParams', {\r\n value: searchParams,\r\n enumerable: true\r\n });\r\n\r\n var search = void 0;\r\n Object.defineProperty(this, '_updateSearchParams', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function() {\r\n if (this.search !== search) {\r\n search = this.search;\r\n if (enableSearchParamsUpdate) {\r\n enableSearchUpdate = false;\r\n this.searchParams._fromString(this.search);\r\n enableSearchUpdate = true;\r\n }\r\n }\r\n }\r\n });\r\n };\r\n\r\n var proto = URL.prototype;\r\n\r\n var linkURLWithAnchorAttribute = function(attributeName) {\r\n Object.defineProperty(proto, attributeName, {\r\n get: function() {\r\n return this._anchorElement[attributeName];\r\n },\r\n set: function(value) {\r\n this._anchorElement[attributeName] = value;\r\n },\r\n enumerable: true\r\n });\r\n };\r\n\r\n ['hash', 'host', 'hostname', 'port', 'protocol']\r\n .forEach(function(attributeName) {\r\n linkURLWithAnchorAttribute(attributeName);\r\n });\r\n\r\n Object.defineProperty(proto, 'search', {\r\n get: function() {\r\n return this._anchorElement['search'];\r\n },\r\n set: function(value) {\r\n this._anchorElement['search'] = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n });\r\n\r\n Object.defineProperties(proto, {\r\n\r\n 'toString': {\r\n get: function() {\r\n var _this = this;\r\n return function() {\r\n return _this.href;\r\n };\r\n }\r\n },\r\n\r\n 'href': {\r\n get: function() {\r\n return this._anchorElement.href.replace(/\\?$/, '');\r\n },\r\n set: function(value) {\r\n this._anchorElement.href = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'pathname': {\r\n get: function() {\r\n return this._anchorElement.pathname.replace(/(^\\/?)/, '/');\r\n },\r\n set: function(value) {\r\n this._anchorElement.pathname = value;\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'origin': {\r\n get: function() {\r\n // get expected port from protocol\r\n var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];\r\n // add port to origin if, expected port is different than actual port\r\n // and it is not empty f.e http://foo:8080\r\n // 8080 != 80 && 8080 != ''\r\n var addPortToOrigin = this._anchorElement.port != expectedPort &&\r\n this._anchorElement.port !== '';\r\n\r\n return this._anchorElement.protocol +\r\n '//' +\r\n this._anchorElement.hostname +\r\n (addPortToOrigin ? (':' + this._anchorElement.port) : '');\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'password': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'username': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n });\r\n\r\n URL.createObjectURL = function(blob) {\r\n return _URL.createObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n URL.revokeObjectURL = function(url) {\r\n return _URL.revokeObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n global.URL = URL;\r\n\r\n };\r\n\r\n if (!checkIfURLIsSupported()) {\r\n polyfillURL();\r\n }\r\n\r\n if ((global.location !== void 0) && !('origin' in global.location)) {\r\n var getOrigin = function() {\r\n return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');\r\n };\r\n\r\n try {\r\n Object.defineProperty(global.location, 'origin', {\r\n get: getOrigin,\r\n enumerable: true\r\n });\r\n } catch (e) {\r\n setInterval(function() {\r\n global.location.origin = getOrigin();\r\n }, 100);\r\n }\r\n }\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __createBinding;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n});\r\n", "/*!\n * clipboard.js v2.0.10\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n var fakeElement = createFakeElement(target);\n options.container.appendChild(fakeElement);\n selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n document.activeElement.blur();\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"array-flat-polyfill\"\nimport \"focus-visible\"\nimport \"unfetch/polyfill\"\nimport \"url-polyfill\"\n\nimport {\n EMPTY,\n NEVER,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getOptionalElement,\n requestJSON,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountBackToTop,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantLoading,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget()\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? __search?.index || requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up instant loading, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantLoading({ document$, location$, viewport$ })\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"[href][rel=prev]\")\n if (typeof prev !== \"undefined\")\n prev.click()\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$, target$ })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.component$ = component$ /* Component observable */\n", "self.fetch||(self.fetch=function(e,n){return n=n||{},new Promise(function(t,s){var r=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(r.status/100|0),statusText:r.statusText,status:r.status,url:r.responseURL,text:function(){return Promise.resolve(r.responseText)},json:function(){return Promise.resolve(r.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([r.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var c in r.open(n.method||\"get\",e,!0),r.onload=function(){r.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},r.onerror=s,r.withCredentials=\"include\"==n.credentials,n.headers)r.setRequestHeader(c,n.headers[c]);r.send(n.body||null)})});\n", "import tslib from '../tslib.js';\r\nconst {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n} = tslib;\r\nexport {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n};\r\n", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ReplaySubject,\n Subject,\n fromEvent\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents are implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject(1)\n fromEvent(document, \"DOMContentLoaded\", { once: true })\n .subscribe(() => document$.next(document))\n\n /* Return document */\n return document$\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getElements(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T][]\n\nexport function getElements(\n selector: string, node?: ParentNode\n): T[]\n\nexport function getElements(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll(selector))\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * Note that this function assumes that the element is present. If unsure if an\n * element is existent, use the `getOptionalElement` function instead.\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T {\n const el = getOptionalElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n\n /* Return element */\n return el\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an optional element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element or nothing\n */\nexport function getOptionalElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T] | undefined\n\nexport function getOptionalElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getOptionalElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve the currently active element\n *\n * @returns Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement || undefined\n : undefined\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n debounceTime,\n distinctUntilChanged,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * Previously, this function used `focus` and `blur` events to determine whether\n * an element is focused, but this doesn't work if there are focusable elements\n * within the elements itself. A better solutions are `focusin` and `focusout`\n * events, which bubble up the tree and allow for more fine-grained control.\n *\n * `debounceTime` is necessary, because when a focus change happens inside an\n * element, the observable would first emit `false` and then `true` again.\n *\n * @param el - Element\n *\n * @returns Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(document.body, \"focusin\"),\n fromEvent(document.body, \"focusout\")\n )\n .pipe(\n debounceTime(1),\n map(() => {\n const active = getActiveElement()\n return typeof active !== \"undefined\"\n ? el.contains(active)\n : false\n }),\n startWith(el === getActiveElement()),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @returns Element offset\n */\nexport function getElementOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.offsetLeft,\n y: el.offsetTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @returns Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(window, \"load\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { ElementOffset } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content offset (= scroll offset)\n *\n * @param el - Element\n *\n * @returns Element content offset\n */\nexport function getElementContentOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element content offset\n *\n * @param el - Element\n *\n * @returns Element content offset observable\n */\nexport function watchElementContentOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementContentOffset(el)),\n startWith(getElementContentOffset(el))\n )\n}\n", "/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that subscribes to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * Sadly, we can't use the `DOMRect` objects returned by the observer, because\n * we need the emitted values to be consistent with `getElementSize`, which will\n * return the used values (rounded) and not actual values (unrounded). Thus, we\n * use the `offset*` properties. See the linked GitHub issue.\n *\n * @see https://bit.ly/3m0k3he - GitHub issue\n *\n * @param el - Element\n *\n * @returns Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(() => getElementSize(el))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ElementSize } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content size (= scroll width and height)\n *\n * @param el - Element\n *\n * @returns Element content size\n */\nexport function getElementContentSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport {\n getElementContentSize,\n getElementSize,\n watchElementContentOffset\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Intersection observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Intersection observer observable\n *\n * This observable will create an `IntersectionObserver` on first subscription\n * and will automatically terminate it when there are no more subscribers.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new IntersectionObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n }, {\n threshold: 0\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element visibility\n *\n * @param el - Element\n *\n * @returns Element visibility observable\n */\nexport function watchElementVisibility(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ isIntersecting }) => isIntersecting)\n )\n )\n )\n}\n\n/**\n * Watch element boundary\n *\n * This function returns an observable which emits whether the bottom content\n * boundary (= scroll offset) of an element is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element boundary observable\n */\nexport function watchElementBoundary(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementContentOffset(el)\n .pipe(\n map(({ y }) => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return y >= (\n content.height - visible.height - threshold\n )\n }),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getElement } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record = {\n drawer: getElement(\"[data-md-toggle=drawer]\"),\n search: getElement(\"[data-md-toggle=search]\")\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n share\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../element\"\nimport { getToggle } from \"../toggle\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Keyboard mode\n */\nexport type KeyboardMode =\n | \"global\" /* Global */\n | \"search\" /* Search is open */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Keyboard\n */\nexport interface Keyboard {\n mode: KeyboardMode /* Keyboard mode */\n type: string /* Key type */\n claim(): void /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n * @param type - Key type\n *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(\n el: HTMLElement, type: string\n): boolean {\n switch (el.constructor) {\n\n /* Input elements */\n case HTMLInputElement:\n /* @ts-expect-error - omit unnecessary type cast */\n if (el.type === \"radio\")\n return /^Arrow/.test(type)\n else\n return true\n\n /* Select element and textarea */\n case HTMLSelectElement:\n case HTMLTextAreaElement:\n return true\n\n /* Everything else */\n default:\n return el.isContentEditable\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch keyboard\n *\n * @returns Keyboard observable\n */\nexport function watchKeyboard(): Observable {\n return fromEvent(window, \"keydown\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n map(ev => ({\n mode: getToggle(\"search\") ? \"search\" : \"global\",\n type: ev.key,\n claim() {\n ev.preventDefault()\n ev.stopPropagation()\n }\n } as Keyboard)),\n filter(({ mode, type }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active, type)\n }\n return true\n }),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function returns a `URL` object (and not `Location`) to normalize the\n * typings across the application. Furthermore, locations need to be tracked\n * without setting them and `Location` is a singleton which represents the\n * current location.\n *\n * @returns URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @returns Location subject\n */\nexport function watchLocation(): Subject {\n return new Subject()\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { JSX as JSXInternal } from \"preact\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(el: HTMLElement, child: Child | Child[]): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @template T - Element type\n *\n * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: T, attributes?: Attributes | null, ...children: Child[]\n): HTMLElementTagNameMap[T]\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T {\n const el = document.createElement(tag)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of Object.keys(attributes))\n if (typeof attributes[attr] !== \"boolean\")\n el.setAttribute(attr, attributes[attr])\n else if (attributes[attr])\n el.setAttribute(attr, \"\")\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el as T\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @returns Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0) { /* keep eating */ }\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with repository facts\n *\n * This is a reverse-engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @returns Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n shareReplay,\n startWith\n} from \"rxjs\"\n\nimport { getOptionalElement } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @returns Location hash\n */\nexport function getLocationHash(): string {\n return location.hash.substring(1)\n}\n\n/**\n * Set location hash\n *\n * Setting a new fragment identifier via `location.hash` will have no effect\n * if the value doesn't change. When a new fragment identifier is set, we want\n * the browser to target the respective element at all times, which is why we\n * use this dirty little trick.\n *\n * @param hash - Location hash\n */\nexport function setLocationHash(hash: string): void {\n const el = h(\"a\", { href: hash })\n el.addEventListener(\"click\", ev => ev.stopPropagation())\n el.click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location hash\n *\n * @returns Location hash observable\n */\nexport function watchLocationHash(): Observable {\n return fromEvent(window, \"hashchange\")\n .pipe(\n map(getLocationHash),\n startWith(getLocationHash()),\n filter(hash => hash.length > 0),\n shareReplay(1)\n )\n}\n\n/**\n * Watch location target\n *\n * @returns Location target observable\n */\nexport function watchLocationTarget(): Observable {\n return watchLocationHash()\n .pipe(\n map(id => getOptionalElement(`[id=\"${id}\"]`)!),\n filter(el => typeof el !== \"undefined\")\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n fromEvent,\n fromEventPattern,\n map,\n merge,\n startWith,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * Note that although `MediaQueryList.addListener` is deprecated we have to\n * use it, because it's the only way to ensure proper downward compatibility.\n *\n * @see https://bit.ly/3dUBH2m - GitHub issue\n *\n * @param query - Media query\n *\n * @returns Media observable\n */\nexport function watchMedia(query: string): Observable {\n const media = matchMedia(query)\n return fromEventPattern(next => (\n media.addListener(() => next(media.matches))\n ))\n .pipe(\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n const media = matchMedia(\"print\")\n return merge(\n fromEvent(window, \"beforeprint\").pipe(map(() => true)),\n fromEvent(window, \"afterprint\").pipe(map(() => false))\n )\n .pipe(\n startWith(media.matches)\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Toggle an observable with a media observable\n *\n * @template T - Data type\n *\n * @param query$ - Media observable\n * @param factory - Observable factory\n *\n * @returns Toggled observable\n */\nexport function at(\n query$: Observable, factory: () => Observable\n): Observable {\n return query$\n .pipe(\n switchMap(active => active ? factory() : EMPTY)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n filter,\n from,\n map,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * If the request fails (e.g. when dispatched from `file://` locations), the\n * observable will complete without emitting a value.\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Response observable\n */\nexport function request(\n url: URL | string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(`${url}`, options))\n .pipe(\n filter(res => res.status === 200),\n catchError(() => EMPTY)\n )\n}\n\n/**\n * Fetch JSON from the given URL\n *\n * @template T - Data type\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n url: URL | string, options?: RequestInit\n): Observable {\n return request(url, options)\n .pipe(\n switchMap(res => res.json()),\n shareReplay(1)\n )\n}\n\n/**\n * Fetch XML from the given URL\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestXML(\n url: URL | string, options?: RequestInit\n): Observable {\n const dom = new DOMParser()\n return request(url, options)\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/xml\")),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n switchMap,\n take,\n throwError\n} from \"rxjs\"\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create and load a `script` element\n *\n * This function returns an observable that will emit when the script was\n * successfully loaded, or throw an error if it didn't.\n *\n * @param src - Script URL\n *\n * @returns Script observable\n */\nexport function watchScript(src: string): Observable {\n const script = h(\"script\", { src })\n return defer(() => {\n document.head.appendChild(script)\n return merge(\n fromEvent(script, \"load\"),\n fromEvent(script, \"error\")\n .pipe(\n switchMap(() => (\n throwError(() => new ReferenceError(`Invalid script: ${src}`))\n ))\n )\n )\n .pipe(\n map(() => undefined),\n finalize(() => document.head.removeChild(script)),\n take(1)\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport offset\n */\nexport interface ViewportOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport offset\n *\n * On iOS Safari, viewport offset can be negative due to overflow scrolling.\n * As this may induce strange behaviors downstream, we'll just limit it to 0.\n *\n * @returns Viewport offset\n */\nexport function getViewportOffset(): ViewportOffset {\n return {\n x: Math.max(0, scrollX),\n y: Math.max(0, scrollY)\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @returns Viewport offset observable\n */\nexport function watchViewportOffset(): Observable {\n return merge(\n fromEvent(window, \"scroll\", { passive: true }),\n fromEvent(window, \"resize\", { passive: true })\n )\n .pipe(\n map(getViewportOffset),\n startWith(getViewportOffset())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport size\n */\nexport interface ViewportSize {\n width: number /* Viewport width */\n height: number /* Viewport height */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport size\n *\n * @returns Viewport size\n */\nexport function getViewportSize(): ViewportSize {\n return {\n width: innerWidth,\n height: innerHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport size\n *\n * @returns Viewport size observable\n */\nexport function watchViewportSize(): Observable {\n return fromEvent(window, \"resize\", { passive: true })\n .pipe(\n map(getViewportSize),\n startWith(getViewportSize())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n map,\n shareReplay\n} from \"rxjs\"\n\nimport {\n ViewportOffset,\n watchViewportOffset\n} from \"../offset\"\nimport {\n ViewportSize,\n watchViewportSize\n} from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport\n */\nexport interface Viewport {\n offset: ViewportOffset /* Viewport offset */\n size: ViewportSize /* Viewport size */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @returns Viewport observable\n */\nexport function watchViewport(): Observable {\n return combineLatest([\n watchViewportOffset(),\n watchViewportSize()\n ])\n .pipe(\n map(([offset, size]) => ({ offset, size })),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilKeyChanged,\n map\n} from \"rxjs\"\n\nimport { Header } from \"~/components\"\n\nimport { getElementOffset } from \"../../element\"\nimport { Viewport } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
/* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @returns Viewport observable\n */\nexport function watchViewportAt(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Compute element offset */\n const offset$ = combineLatest([size$, header$])\n .pipe(\n map(() => getElementOffset(el))\n )\n\n /* Compute relative viewport, return hot observable */\n return combineLatest([header$, viewport$, offset$])\n .pipe(\n map(([{ height }, { offset, size }, { x, y }]) => ({\n offset: {\n x: offset.x - x,\n y: offset.y - y + height\n },\n size\n }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n fromEvent,\n map,\n share,\n switchMap,\n tap,\n throttle\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Worker message\n */\nexport interface WorkerMessage {\n type: unknown /* Message type */\n data?: unknown /* Message data */\n}\n\n/**\n * Worker handler\n *\n * @template T - Message type\n */\nexport interface WorkerHandler<\n T extends WorkerMessage\n> {\n tx$: Subject /* Message transmission subject */\n rx$: Observable /* Message receive observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n *\n * @template T - Worker message type\n */\ninterface WatchOptions {\n tx$: Observable /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that sends all values emitted by the\n * message observable to the web worker. Web worker communication is expected\n * to be bidirectional (request-response) and synchronous. Messages that are\n * emitted during a pending request are throttled, the last one is emitted.\n *\n * @param worker - Web worker\n * @param options - Options\n *\n * @returns Worker message observable\n */\nexport function watchWorker(\n worker: Worker, { tx$ }: WatchOptions\n): Observable {\n\n /* Intercept messages from worker-like objects */\n const rx$ = fromEvent(worker, \"message\")\n .pipe(\n map(({ data }) => data as T)\n )\n\n /* Send and receive messages, return hot observable */\n return tx$\n .pipe(\n throttle(() => rx$, { leading: true, trailing: true }),\n tap(message => worker.postMessage(message)),\n switchMap(() => rx$),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"content.code.annotate\" /* Code annotations */\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.indexes\" /* Section pages */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Section navigation */\n | \"navigation.tabs\" /* Tabs navigation */\n | \"navigation.tabs.sticky\" /* Tabs navigation (sticky) */\n | \"navigation.top\" /* Back-to-top button */\n | \"navigation.tracking\" /* Anchor tracking */\n | \"search.highlight\" /* Search highlighting */\n | \"search.share\" /* Search sharing */\n | \"search.suggest\" /* Search suggestions */\n | \"toc.integrate\" /* Integrated table of contents */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Translation\n */\nexport type Translation =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.placeholder\" /* Search */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n | \"select.version.title\" /* Version selector */\n\n/**\n * Translations\n */\nexport type Translations = Record\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Versioning\n */\nexport interface Versioning {\n provider: \"mike\" /* Version provider */\n default?: string /* Default version */\n}\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Flag[] /* Feature flags */\n translations: Translations /* Translations */\n search: string /* Search worker URL */\n version?: Versioning /* Versioning */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElement(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = `${new URL(config.base, getLocation())}`\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration\n *\n * @returns Global configuration\n */\nexport function configuration(): Config {\n return config\n}\n\n/**\n * Check whether a feature flag is enabled\n *\n * @param flag - Feature flag\n *\n * @returns Test result\n */\nexport function feature(flag: Flag): boolean {\n return config.features.includes(flag)\n}\n\n/**\n * Retrieve the translation for the given key\n *\n * @param key - Key to be translated\n * @param value - Positional value, if any\n *\n * @returns Translation\n */\nexport function translation(\n key: Translation, value?: string | number\n): string {\n return typeof value !== \"undefined\"\n ? config.translations[key].replace(\"#\", value.toString())\n : config.translations[key]\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type\n */\nexport type ComponentType =\n | \"announce\" /* Announcement bar */\n | \"container\" /* Container */\n | \"content\" /* Content */\n | \"dialog\" /* Dialog */\n | \"header\" /* Header */\n | \"header-title\" /* Header title */\n | \"header-topic\" /* Header topic */\n | \"main\" /* Main area */\n | \"outdated\" /* Version warning */\n | \"palette\" /* Color palette */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"search-share\" /* Search sharing */\n | \"search-suggest\" /* Search suggestions */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n | \"top\" /* Back-to-top button */\n\n/**\n * Component\n *\n * @template T - Component type\n * @template U - Reference type\n */\nexport type Component<\n T extends {} = {},\n U extends HTMLElement = HTMLElement\n> =\n T & {\n ref: U /* Component reference */\n }\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type map\n */\ninterface ComponentTypeMap {\n \"announce\": HTMLElement /* Announcement bar */\n \"container\": HTMLElement /* Container */\n \"content\": HTMLElement /* Content */\n \"dialog\": HTMLElement /* Dialog */\n \"header\": HTMLElement /* Header */\n \"header-title\": HTMLElement /* Header title */\n \"header-topic\": HTMLElement /* Header topic */\n \"main\": HTMLElement /* Main area */\n \"outdated\": HTMLElement /* Version warning */\n \"palette\": HTMLElement /* Color palette */\n \"search\": HTMLElement /* Search */\n \"search-query\": HTMLInputElement /* Search input */\n \"search-result\": HTMLElement /* Search results */\n \"search-share\": HTMLAnchorElement /* Search sharing */\n \"search-suggest\": HTMLElement /* Search suggestions */\n \"sidebar\": HTMLElement /* Sidebar */\n \"skip\": HTMLAnchorElement /* Skip link */\n \"source\": HTMLAnchorElement /* Repository information */\n \"tabs\": HTMLElement /* Navigation tabs */\n \"toc\": HTMLElement /* Table of contents */\n \"top\": HTMLAnchorElement /* Back-to-top button */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T] {\n return getElement(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T][] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n mergeWith,\n switchMap,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n getElementContentSize,\n watchElementSize,\n watchElementVisibility\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotationList\n} from \"../../annotation\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scrollable: boolean /* Code block overflows */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global sequence number for Clipboard.js integration\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find candidate list element directly following a code block\n *\n * @param el - Code block element\n *\n * @returns List element or nothing\n */\nfunction findCandidateList(el: HTMLElement): HTMLElement | undefined {\n if (el.nextElementSibling) {\n const sibling = el.nextElementSibling as HTMLElement\n if (sibling.tagName === \"OL\")\n return sibling\n\n /* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */\n else if (sibling.tagName === \"P\" && !sibling.children.length)\n return findCandidateList(sibling)\n }\n\n /* Everything else */\n return undefined\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * This function monitors size changes of the viewport, as well as switches of\n * content tabs with embedded code blocks, as both may trigger overflow.\n *\n * @param el - Code block element\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement\n): Observable {\n return watchElementSize(el)\n .pipe(\n map(({ width }) => {\n const content = getElementContentSize(el)\n return {\n scrollable: content.width > width\n }\n }),\n distinctUntilKeyChanged(\"scrollable\")\n )\n}\n\n/**\n * Mount code block\n *\n * This function ensures that an overflowing code block is focusable through\n * keyboard, so it can be scrolled without a mouse to improve on accessibility.\n * Furthermore, if code annotations are enabled, they are mounted if and only\n * if the code block is currently visible, e.g., not in a hidden content tab.\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block and annotation component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const { matches: hover } = matchMedia(\"(hover)\")\n\n /* Defer mounting of code block - see https://bit.ly/3vHVoVD */\n const factory$ = defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ scrollable }) => {\n if (scrollable && hover)\n el.setAttribute(\"tabindex\", \"0\")\n else\n el.removeAttribute(\"tabindex\")\n })\n\n /* Render button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${++sequence}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Handle code annotations */\n const container = el.closest(\".highlight\")\n if (container instanceof HTMLElement) {\n const list = findCandidateList(container)\n\n /* Mount code annotations, if enabled */\n if (typeof list !== \"undefined\" && (\n container.classList.contains(\"annotate\") ||\n feature(\"content.code.annotate\")\n )) {\n const annotations$ = mountAnnotationList(list, el, options)\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n mergeWith(\n watchElementSize(container)\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(({ width, height }) => width && height),\n distinctUntilChanged(),\n switchMap(active => active ? annotations$ : EMPTY)\n )\n )\n )\n }\n }\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n\n /* Mount code block on first sight */\n return watchElementVisibility(el)\n .pipe(\n filter(visible => visible),\n take(1),\n switchMap(() => factory$)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an empty annotation\n *\n * @param id - Annotation identifier\n *\n * @returns Element\n */\nexport function renderAnnotation(id: number): HTMLElement {\n return (\n \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @returns Element\n */\nexport function renderClipboardButton(id: string): HTMLElement {\n return (\n code`}\n >\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ComponentChild } from \"preact\"\n\nimport { feature, translation } from \"~/_\"\nimport {\n SearchDocument,\n SearchMetadata,\n SearchResultItem\n} from \"~/integrations/search\"\nimport { h, truncate } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Render flag\n */\nconst enum Flag {\n TEASER = 1, /* Render teaser */\n PARENT = 2 /* Render as parent */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper function\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search document\n *\n * @param document - Search document\n * @param flag - Render flags\n *\n * @returns Element\n */\nfunction renderSearchDocument(\n document: SearchDocument & SearchMetadata, flag: Flag\n): HTMLElement {\n const parent = flag & Flag.PARENT\n const teaser = flag & Flag.TEASER\n\n /* Render missing query terms */\n const missing = Object.keys(document.terms)\n .filter(key => !document.terms[key])\n .reduce((list, key) => [\n ...list, {key}, \" \"\n ], [])\n .slice(0, -1)\n\n /* Assemble query string for highlighting */\n const url = new URL(document.location)\n if (feature(\"search.highlight\"))\n url.searchParams.set(\"h\", Object.entries(document.terms)\n .filter(([, match]) => match)\n .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), \"\")\n )\n\n /* Render article or section, depending on flags */\n return (\n \n \n {parent > 0 &&
}\n

{document.title}

\n {teaser > 0 && document.text.length > 0 &&\n

\n {truncate(document.text, 320)}\n

\n }\n {document.tags && document.tags.map(tag => (\n {tag}\n ))}\n {teaser > 0 && missing.length > 0 &&\n

\n {translation(\"search.result.term.missing\")}: {...missing}\n

\n }\n \n
\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @returns Element\n */\nexport function renderSearchResultItem(\n result: SearchResultItem\n): HTMLElement {\n const threshold = result[0].score\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)),\n ...best.map(section => renderSearchDocument(section, Flag.TEASER)),\n ...more.length ? [\n
\n \n {more.length > 0 && more.length === 1\n ? translation(\"search.result.more.one\")\n : translation(\"search.result.more.other\", more.length)\n }\n \n {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n
\n ] : []\n ]\n\n /* Render search result */\n return (\n
  • \n {children}\n
  • \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"~/components\"\nimport { h, round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render repository facts\n *\n * @param facts - Repository facts\n *\n * @returns Element\n */\nexport function renderSourceFacts(facts: SourceFacts): HTMLElement {\n return (\n
      \n {Object.entries(facts).map(([key, value]) => (\n
    • \n {typeof value === \"number\" ? round(value) : value}\n
    • \n ))}\n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @returns Element\n */\nexport function renderTable(table: HTMLElement): HTMLElement {\n return (\n
    \n
    \n {table}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { configuration, translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Version\n */\nexport interface Version {\n version: string /* Version identifier */\n title: string /* Version title */\n aliases: string[] /* Version aliases */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version\n *\n * @param version - Version\n *\n * @returns Element\n */\nfunction renderVersion(version: Version): HTMLElement {\n const config = configuration()\n\n /* Ensure trailing slash, see https://bit.ly/3rL5u3f */\n const url = new URL(`../${version.version}/`, config.base)\n return (\n
  • \n \n {version.title}\n \n
  • \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version selector\n *\n * @param versions - Versions\n * @param active - Active version\n *\n * @returns Element\n */\nexport function renderVersionSelector(\n versions: Version[], active: Version\n): HTMLElement {\n return (\n
    \n \n {active.title}\n \n
      \n {versions.map(renderVersion)}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n animationFrameScheduler,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n switchMap,\n take,\n tap,\n throttleTime\n} from \"rxjs\"\n\nimport {\n ElementOffset,\n getElement,\n getElementSize,\n watchElementContentOffset,\n watchElementFocus,\n watchElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Annotation\n */\nexport interface Annotation {\n active: boolean /* Annotation is active */\n offset: ElementOffset /* Annotation offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation observable\n */\nexport function watchAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable {\n const offset$ = defer(() => combineLatest([\n watchElementOffset(el),\n watchElementContentOffset(container)\n ]))\n .pipe(\n map(([{ x, y }, scroll]) => {\n const { width } = getElementSize(el)\n return ({\n x: x - scroll.x + width / 2,\n y: y - scroll.y\n })\n })\n )\n\n /* Actively watch annotation on focus */\n return watchElementFocus(el)\n .pipe(\n switchMap(active => offset$\n .pipe(\n map(offset => ({ active, offset })),\n take(+!active || Infinity)\n )\n )\n )\n}\n\n/**\n * Mount annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ offset }) {\n el.style.setProperty(\"--md-tooltip-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-tooltip-y\", `${offset.y}px`)\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-x\")\n el.style.removeProperty(\"--md-tooltip-y\")\n }\n })\n\n /* Track relative origin of tooltip */\n push$\n .pipe(\n throttleTime(500, animationFrameScheduler),\n map(() => container.getBoundingClientRect()),\n map(({ x }) => x)\n )\n .subscribe({\n\n /* Handle emission */\n next(origin) {\n if (origin)\n el.style.setProperty(\"--md-tooltip-0\", `${-origin}px`)\n else\n el.style.removeProperty(\"--md-tooltip-0\")\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-0\")\n }\n })\n\n /* Close open annotation on click */\n const index = getElement(\":scope > :last-child\", el)\n const blur$ = fromEvent(index, \"mousedown\", { once: true })\n push$\n .pipe(\n switchMap(({ active }) => active ? blur$ : EMPTY),\n tap(ev => ev.preventDefault())\n )\n .subscribe(() => el.blur())\n\n /* Create and return component */\n return watchAnnotation(el, container)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n merge,\n share,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport {\n getElement,\n getElements,\n getOptionalElement\n} from \"~/browser\"\nimport { renderAnnotation } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotation\n} from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find all annotation markers in the given code block\n *\n * @param container - Containing element\n *\n * @returns Annotation markers\n */\nfunction findAnnotationMarkers(container: HTMLElement): Text[] {\n const markers: Text[] = []\n for (const comment of getElements(\".c, .c1, .cm\", container)) {\n let match: RegExpExecArray | null\n\n /* Split text at marker and add to list */\n let text = comment.firstChild as Text\n if (text instanceof Text)\n while ((match = /\\((\\d+)\\)/.exec(text.textContent!))) {\n const marker = text.splitText(match.index)\n text = marker.splitText(match[0].length)\n markers.push(marker)\n }\n }\n return markers\n}\n\n/**\n * Swap the child nodes of two elements\n *\n * @param source - Source element\n * @param target - Target element\n */\nfunction swap(source: HTMLElement, target: HTMLElement): void {\n target.append(...Array.from(source.childNodes))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount annotation list\n *\n * This function analyzes the containing code block and checks for markers\n * referring to elements in the given annotation list. If no markers are found,\n * the list is left untouched. Otherwise, list elements are rendered as\n * annotations inside the code block.\n *\n * @param el - Annotation list element\n * @param container - Containing element\n * @param options - Options\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotationList(\n el: HTMLElement, container: HTMLElement, { print$ }: MountOptions\n): Observable> {\n\n /* Find and replace all markers with empty annotations */\n const annotations = new Map()\n for (const marker of findAnnotationMarkers(container)) {\n const [, id] = marker.textContent!.match(/\\((\\d+)\\)/)!\n if (getOptionalElement(`li:nth-child(${id})`, el)) {\n annotations.set(+id, renderAnnotation(+id))\n marker.replaceWith(annotations.get(+id)!)\n }\n }\n\n /* Keep list if there are no annotations to render */\n if (annotations.size === 0)\n return EMPTY\n\n /* Create and return component */\n return defer(() => {\n const done$ = new Subject()\n\n /* Handle print mode - see https://bit.ly/3rgPdpt */\n print$\n .pipe(\n takeUntil(done$.pipe(takeLast(1)))\n )\n .subscribe(active => {\n el.hidden = !active\n\n /* Show annotations in code block or list (print) */\n for (const [id, annotation] of annotations) {\n const inner = getElement(\".md-typeset\", annotation)\n const child = getElement(`li:nth-child(${id})`, el)\n if (!active)\n swap(child, inner)\n else\n swap(inner, child)\n }\n })\n\n /* Create and return component */\n return merge(...[...annotations]\n .map(([, annotation]) => (\n mountAnnotation(annotation, container)\n ))\n )\n .pipe(\n finalize(() => done$.complete()),\n share()\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { watchScript } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../../_\"\n\nimport themeCSS from \"./index.css\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid diagram\n */\nexport interface Mermaid {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid instance observable\n */\nlet mermaid$: Observable\n\n/**\n * Global index for Mermaid integration\n */\nlet index = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch Mermaid script\n *\n * @returns Mermaid scripts observable\n */\nfunction fetchScripts(): Observable {\n return typeof mermaid === \"undefined\" || mermaid instanceof Element\n ? watchScript(\"https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js\")\n : of(undefined)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount Mermaid diagram\n *\n * @param el - Code block element\n *\n * @returns Mermaid diagram component observable\n */\nexport function mountMermaid(\n el: HTMLElement\n): Observable> {\n el.classList.remove(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n mermaid$ ||= fetchScripts()\n .pipe(\n tap(() => mermaid.initialize({\n startOnLoad: false,\n themeCSS\n })),\n map(() => undefined),\n shareReplay(1)\n )\n\n /* Render diagram */\n mermaid$.subscribe(() => {\n el.classList.add(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n const id = `__mermaid_${index++}`\n const host = h(\"div\", { class: \"mermaid\" })\n mermaid.mermaidAPI.render(id, el.textContent, (svg: string) => {\n\n /* Create a shadow root and inject diagram */\n const shadow = host.attachShadow({ mode: \"closed\" })\n shadow.innerHTML = svg\n\n /* Replace code block with diagram */\n el.replaceWith(host)\n })\n })\n\n /* Create and return component */\n return mermaid$\n .pipe(\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {\n action: \"open\" | \"close\" /* Details state */\n reveal?: boolean /* Details is revealed */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch details\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details observable\n */\nexport function watchDetails(\n el: HTMLDetailsElement, { target$, print$ }: WatchOptions\n): Observable
    {\n let open = true\n return merge(\n\n /* Open and focus details on location target */\n target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n map(() => ({\n action: \"open\", reveal: true\n }) as Details)\n ),\n\n /* Open details on print and close afterwards */\n print$\n .pipe(\n filter(active => active || !open),\n tap(() => open = el.open),\n map(active => ({\n action: active ? \"open\" : \"close\"\n }) as Details)\n )\n )\n}\n\n/**\n * Mount details\n *\n * This function ensures that `details` tags are opened on anchor jumps and\n * prior to printing, so the whole content of the page is visible.\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details component observable\n */\nexport function mountDetails(\n el: HTMLDetailsElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$.subscribe(({ action, reveal }) => {\n if (action === \"open\")\n el.setAttribute(\"open\", \"\")\n else\n el.removeAttribute(\"open\")\n if (reveal)\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, of } from \"rxjs\"\n\nimport { renderTable } from \"~/templates\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Data table\n */\nexport interface DataTable {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Sentinel for replacement\n */\nconst sentinel = h(\"table\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount data table\n *\n * This function wraps a data table in another scrollable container, so it can\n * be smoothly scrolled on smaller screen sizes and won't break the layout.\n *\n * @param el - Data table element\n *\n * @returns Data table component observable\n */\nexport function mountDataTable(\n el: HTMLElement\n): Observable> {\n el.replaceWith(sentinel)\n sentinel.replaceWith(renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n asyncScheduler,\n auditTime,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n startWith,\n subscribeOn,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport {\n getElement,\n getElementOffset,\n getElementSize,\n getElements,\n watchElementSize\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content tabs\n */\nexport interface ContentTabs {\n active: HTMLLabelElement /* Active tab label */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch content tabs\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs observable\n */\nexport function watchContentTabs(\n el: HTMLElement\n): Observable {\n const inputs = getElements(\":scope > input\", el)\n const active = inputs.find(input => input.checked) || inputs[0]\n return merge(...inputs.map(input => fromEvent(input, \"change\")\n .pipe(\n map(() => ({\n active: getElement(`label[for=${input.id}]`)\n }) as ContentTabs)\n )\n ))\n .pipe(\n startWith({\n active: getElement(`label[for=${active.id}]`)\n } as ContentTabs)\n )\n}\n\n/**\n * Mount content tabs\n *\n * This function scrolls the active tab into view. While this functionality is\n * provided by browsers as part of `scrollInfoView`, browsers will always also\n * scroll the vertical axis, which we do not want. Thus, we decided to provide\n * this functionality ourselves.\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs component observable\n */\nexport function mountContentTabs(\n el: HTMLElement\n): Observable> {\n const container = getElement(\".tabbed-labels\", el)\n return defer(() => {\n const push$ = new Subject()\n combineLatest([push$, watchElementSize(el)])\n .pipe(\n auditTime(1, animationFrameScheduler),\n takeUntil(push$.pipe(takeLast(1)))\n )\n .subscribe({\n\n /* Handle emission */\n next([{ active }]) {\n const offset = getElementOffset(active)\n const { width } = getElementSize(active)\n\n /* Set tab indicator offset and width */\n el.style.setProperty(\"--md-indicator-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-indicator-width\", `${width}px`)\n\n /* Smoothly scroll container */\n container.scrollTo({\n behavior: \"smooth\",\n left: offset.x\n })\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-indicator-x\")\n el.style.removeProperty(\"--md-indicator-width\")\n }\n })\n\n /* Create and return component */\n return watchContentTabs(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n .pipe(\n subscribeOn(asyncScheduler)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Annotation } from \"../annotation\"\nimport {\n CodeBlock,\n Mermaid,\n mountCodeBlock,\n mountMermaid\n} from \"../code\"\nimport {\n Details,\n mountDetails\n} from \"../details\"\nimport {\n DataTable,\n mountDataTable\n} from \"../table\"\nimport {\n ContentTabs,\n mountContentTabs\n} from \"../tabs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | Annotation\n | ContentTabs\n | CodeBlock\n | Mermaid\n | DataTable\n | Details\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount content\n *\n * This function mounts all components that are found in the content of the\n * actual article, including code blocks, data tables and details.\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Content component observable\n */\nexport function mountContent(\n el: HTMLElement, { target$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre:not(.mermaid) > code\", el)\n .map(child => mountCodeBlock(child, { print$ })),\n\n /* Mermaid diagrams */\n ...getElements(\"pre.mermaid\", el)\n .map(child => mountMermaid(child)),\n\n /* Data tables */\n ...getElements(\"table:not([class])\", el)\n .map(child => mountDataTable(child)),\n\n /* Details */\n ...getElements(\"details\", el)\n .map(child => mountDetails(child, { target$, print$ })),\n\n /* Content tabs */\n ...getElements(\"[data-tabs]\", el)\n .map(child => mountContentTabs(child))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n delay,\n finalize,\n map,\n merge,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n active: boolean /* Dialog is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n alert$: Subject /* Alert subject */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch dialog\n *\n * @param _el - Dialog element\n * @param options - Options\n *\n * @returns Dialog observable\n */\nexport function watchDialog(\n _el: HTMLElement, { alert$ }: WatchOptions\n): Observable {\n return alert$\n .pipe(\n switchMap(message => merge(\n of(true),\n of(false).pipe(delay(2000))\n )\n .pipe(\n map(active => ({ message, active }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function reveals the dialog in the right corner when a new alert is\n * emitted through the subject that is passed as part of the options.\n *\n * @param el - Dialog element\n * @param options - Options\n *\n * @returns Dialog component observable\n */\nexport function mountDialog(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const inner = getElement(\".md-typeset\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ message, active }) => {\n inner.textContent = message\n if (active)\n el.setAttribute(\"data-md-state\", \"open\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n combineLatestWith,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n of,\n shareReplay,\n startWith,\n switchMap,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchToggle\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Main } from \"../../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n height: number /* Header visible height */\n hidden: boolean /* Header is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute whether the header is hidden\n *\n * If the user scrolls past a certain threshold, the header can be hidden when\n * scrolling down, and shown when scrolling up.\n *\n * @param options - Options\n *\n * @returns Toggle observable\n */\nfunction isHidden({ viewport$ }: WatchOptions): Observable {\n if (!feature(\"header.autohide\"))\n return of(false)\n\n /* Compute direction and turning point */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => [a < b, b] as const),\n distinctUntilKeyChanged(0)\n )\n\n /* Compute whether header should be hidden */\n const hidden$ = combineLatest([viewport$, direction$])\n .pipe(\n filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100),\n map(([, [direction]]) => direction),\n distinctUntilChanged()\n )\n\n /* Compute threshold for hiding */\n const search$ = watchToggle(\"search\")\n return combineLatest([viewport$, search$])\n .pipe(\n map(([{ offset }, search]) => offset.y > 400 && !search),\n distinctUntilChanged(),\n switchMap(active => active ? hidden$ : of(false)),\n startWith(false)\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header observable\n */\nexport function watchHeader(\n el: HTMLElement, options: WatchOptions\n): Observable
    {\n return defer(() => combineLatest([\n watchElementSize(el),\n isHidden(options)\n ]))\n .pipe(\n map(([{ height }, hidden]) => ({\n height,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.hidden === b.hidden\n )),\n shareReplay(1)\n )\n}\n\n/**\n * Mount header\n *\n * This function manages the different states of the header, i.e. whether it's\n * hidden or rendered with a shadow. This depends heavily on the main area.\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header component observable\n */\nexport function mountHeader(\n el: HTMLElement, { header$, main$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$)\n )\n .subscribe(([{ active }, { hidden }]) => {\n if (active)\n el.setAttribute(\"data-md-state\", hidden ? \"hidden\" : \"shadow\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Link to main area */\n main$.subscribe(push$)\n\n /* Create and return component */\n return header$\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElementSize,\n getOptionalElement,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Header } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface HeaderTitle {\n active: boolean /* Header title is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header title\n *\n * @param el - Heading element\n * @param options - Options\n *\n * @returns Header title observable\n */\nexport function watchHeaderTitle(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { viewport$, header$ })\n .pipe(\n map(({ offset: { y } }) => {\n const { height } = getElementSize(el)\n return {\n active: y >= height\n }\n }),\n distinctUntilKeyChanged(\"active\")\n )\n}\n\n/**\n * Mount header title\n *\n * This function swaps the header title from the site title to the title of the\n * current page when the user scrolls past the first headline.\n *\n * @param el - Header title element\n * @param options - Options\n *\n * @returns Header title component observable\n */\nexport function mountHeaderTitle(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ active }) => {\n if (active)\n el.setAttribute(\"data-md-state\", \"active\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Obtain headline, if any */\n const heading = getOptionalElement(\"article h1\")\n if (typeof heading === \"undefined\")\n return EMPTY\n\n /* Create and return component */\n return watchHeaderTitle(heading, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchElementSize\n} from \"~/browser\"\n\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Main area\n */\nexport interface Main {\n offset: number /* Main area top offset */\n height: number /* Main area visible height */\n active: boolean /* Main area is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch main area\n *\n * This function returns an observable that computes the visual parameters of\n * the main area which depends on the viewport vertical offset and height, as\n * well as the height of the header element, if the header is fixed.\n *\n * @param el - Main area element\n * @param options - Options\n *\n * @returns Main area observable\n */\nexport function watchMain(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable
    {\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n map(({ height }) => height),\n distinctUntilChanged()\n )\n\n /* Compute the main area's top and bottom borders */\n const border$ = adjust$\n .pipe(\n switchMap(() => watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n top: el.offsetTop,\n bottom: el.offsetTop + height\n })),\n distinctUntilKeyChanged(\"bottom\")\n )\n )\n )\n\n /* Compute the main area's offset, visible height and if we scrolled past */\n return combineLatest([adjust$, border$, viewport$])\n .pipe(\n map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {\n height = Math.max(0, height\n - Math.max(0, top - y, header)\n - Math.max(0, height + y - bottom)\n )\n return {\n offset: top - header,\n height,\n active: top - header <= y\n }\n }),\n distinctUntilChanged((a, b) => (\n a.offset === b.offset &&\n a.height === b.height &&\n a.active === b.active\n ))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n defer,\n finalize,\n fromEvent,\n map,\n mergeMap,\n observeOn,\n of,\n shareReplay,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Palette colors\n */\nexport interface PaletteColor {\n scheme?: string /* Color scheme */\n primary?: string /* Primary color */\n accent?: string /* Accent color */\n}\n\n/**\n * Palette\n */\nexport interface Palette {\n index: number /* Palette index */\n color: PaletteColor /* Palette colors */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch color palette\n *\n * @param inputs - Color palette element\n *\n * @returns Color palette observable\n */\nexport function watchPalette(\n inputs: HTMLInputElement[]\n): Observable {\n const current = __md_get(\"__palette\") || {\n index: inputs.findIndex(input => matchMedia(\n input.getAttribute(\"data-md-color-media\")!\n ).matches)\n }\n\n /* Emit changes in color palette */\n return of(...inputs)\n .pipe(\n mergeMap(input => fromEvent(input, \"change\")\n .pipe(\n map(() => input)\n )\n ),\n startWith(inputs[Math.max(0, current.index)]),\n map(input => ({\n index: inputs.indexOf(input),\n color: {\n scheme: input.getAttribute(\"data-md-color-scheme\"),\n primary: input.getAttribute(\"data-md-color-primary\"),\n accent: input.getAttribute(\"data-md-color-accent\")\n }\n } as Palette)),\n shareReplay(1)\n )\n}\n\n/**\n * Mount color palette\n *\n * @param el - Color palette element\n *\n * @returns Color palette component observable\n */\nexport function mountPalette(\n el: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(palette => {\n document.body.setAttribute(\"data-md-color-switching\", \"\")\n\n /* Set color palette */\n for (const [key, value] of Object.entries(palette.color))\n document.body.setAttribute(`data-md-color-${key}`, value)\n\n /* Toggle visibility */\n for (let index = 0; index < inputs.length; index++) {\n const label = inputs[index].nextElementSibling\n if (label instanceof HTMLElement)\n label.hidden = palette.index !== index\n }\n\n /* Persist preference in local storage */\n __md_set(\"__palette\", palette)\n })\n\n /* Revert transition durations after color switch */\n push$.pipe(observeOn(asyncScheduler))\n .subscribe(() => {\n document.body.removeAttribute(\"data-md-color-switching\")\n })\n\n /* Create and return component */\n const inputs = getElements(\"input\", el)\n return watchPalette(inputs)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n Observable,\n Subject,\n map,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Extract text to copy\n *\n * @param el - HTML element\n *\n * @returns Extracted text\n */\nfunction extract(el: HTMLElement): string {\n el.setAttribute(\"data-md-copying\", \"\")\n const text = el.innerText\n el.removeAttribute(\"data-md-copying\")\n return text\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up Clipboard.js integration\n *\n * @param options - Options\n */\nexport function setupClipboardJS(\n { alert$ }: SetupOptions\n): void {\n if (ClipboardJS.isSupported()) {\n new Observable(subscriber => {\n new ClipboardJS(\"[data-clipboard-target], [data-clipboard-text]\", {\n text: el => (\n el.getAttribute(\"data-clipboard-text\")! ||\n extract(getElement(\n el.getAttribute(\"data-clipboard-target\")!\n ))\n )\n })\n .on(\"success\", ev => subscriber.next(ev))\n })\n .pipe(\n tap(ev => {\n const trigger = ev.trigger as HTMLElement\n trigger.focus()\n }),\n map(() => translation(\"clipboard.copied\"))\n )\n .subscribe(alert$)\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defaultIfEmpty,\n map,\n of,\n tap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport { getElements, requestXML } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sitemap, i.e. a list of URLs\n */\nexport type Sitemap = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Preprocess a list of URLs\n *\n * This function replaces the `site_url` in the sitemap with the actual base\n * URL, to allow instant loading to work in occasions like Netlify previews.\n *\n * @param urls - URLs\n *\n * @returns URL path parts\n */\nfunction preprocess(urls: Sitemap): Sitemap {\n if (urls.length < 2)\n return [\"\"]\n\n /* Take the first two URLs and remove everything after the last slash */\n const [root, next] = [...urls]\n .sort((a, b) => a.length - b.length)\n .map(url => url.replace(/[^/]+$/, \"\"))\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === next.charCodeAt(index))\n index++\n\n /* Remove common prefix and return in original order */\n return urls.map(url => url.replace(root.slice(0, index), \"\"))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the sitemap for the given base URL\n *\n * @param base - Base URL\n *\n * @returns Sitemap observable\n */\nexport function fetchSitemap(base?: URL): Observable {\n const cached = __md_get(\"__sitemap\", sessionStorage, base)\n if (cached) {\n return of(cached)\n } else {\n const config = configuration()\n return requestXML(new URL(\"sitemap.xml\", base || config.base))\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\n )),\n defaultIfEmpty([]),\n tap(sitemap => __md_set(\"__sitemap\", sitemap, sessionStorage, base))\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n fromEvent,\n map,\n merge,\n of,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n getElements,\n getOptionalElement,\n request,\n setLocation,\n setLocationHash\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\nimport { h } from \"~/utilities\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\nexport interface HistoryState {\n url: URL /* State URL */\n offset?: ViewportOffset /* State viewport offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n location$: Subject /* Location subject */\n viewport$: Observable /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n { document$, location$, viewport$ }: SetupOptions\n): void {\n const config = configuration()\n if (location.protocol === \"file:\")\n return\n\n /* Disable automatic scroll restoration */\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\"\n\n /* Hack: ensure that reloads restore viewport offset */\n fromEvent(window, \"beforeunload\")\n .subscribe(() => {\n history.scrollRestoration = \"auto\"\n })\n }\n\n /* Hack: ensure absolute favicon link to omit 404s when switching */\n const favicon = getOptionalElement(\"link[rel=icon]\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = fetchSitemap()\n .pipe(\n map(paths => paths.map(path => `${new URL(path, config.base)}`)),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target) {\n const url = new URL(el.href)\n\n /* Canonicalize URL */\n url.search = \"\"\n url.hash = \"\"\n\n /* Check if URL should be intercepted */\n if (\n url.pathname !== location.pathname &&\n urls.includes(url.toString())\n ) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\n })\n }\n }\n }\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Intercept history back and forward */\n const pop$ = fromEvent(window, \"popstate\")\n .pipe(\n filter(ev => ev.state !== null),\n map(ev => ({\n url: new URL(location.href),\n offset: ev.state\n })),\n share()\n )\n\n /* Emit location change */\n merge(push$, pop$)\n .pipe(\n distinctUntilChanged((a, b) => a.url.href === b.url.href),\n map(({ url }) => url)\n )\n .subscribe(location$)\n\n /* Fetch document via `XMLHTTPRequest` */\n const response$ = location$\n .pipe(\n distinctUntilKeyChanged(\"pathname\"),\n switchMap(url => request(url.href)\n .pipe(\n catchError(() => {\n setLocation(url)\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Set new location via `history.pushState` */\n push$\n .pipe(\n sample(response$)\n )\n .subscribe(({ url }) => {\n history.pushState({}, \"\", `${url}`)\n })\n\n /* Parse and emit fetched document */\n const dom = new DOMParser()\n response$\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/html\"))\n )\n .subscribe(document$)\n\n /* Replace meta tags and components */\n document$\n .pipe(\n skip(1)\n )\n .subscribe(replacement => {\n for (const selector of [\n\n /* Meta tags */\n \"title\",\n \"link[rel=canonical]\",\n \"meta[name=author]\",\n \"meta[name=description]\",\n\n /* Components */\n \"[data-md-component=announce]\",\n \"[data-md-component=container]\",\n \"[data-md-component=header-topic]\",\n \"[data-md-component=outdated]\",\n \"[data-md-component=logo]\",\n \"[data-md-component=skip]\",\n ...feature(\"navigation.tabs.sticky\")\n ? [\"[data-md-component=tabs]\"]\n : []\n ]) {\n const source = getOptionalElement(selector)\n const target = getOptionalElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n source.replaceWith(target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => getElements(\"script\", el)),\n concatMap(el => {\n const script = h(\"script\")\n if (el.src) {\n for (const name of el.getAttributeNames())\n script.setAttribute(name, el.getAttribute(name)!)\n el.replaceWith(script)\n\n /* Complete when script is loaded */\n return new Observable(observer => {\n script.onload = () => observer.complete()\n })\n\n /* Complete immediately */\n } else {\n script.textContent = el.textContent\n el.replaceWith(script)\n return EMPTY\n }\n })\n )\n .subscribe()\n\n /* Emit history state change */\n merge(push$, pop$)\n .pipe(\n sample(document$)\n )\n .subscribe(({ url, offset }) => {\n if (url.hash && !offset) {\n setLocationHash(url.hash)\n } else {\n window.scrollTo(0, offset?.y || 0)\n }\n })\n\n /* Debounce update of viewport offset */\n viewport$\n .pipe(\n skipUntil(push$),\n debounceTime(250),\n distinctUntilKeyChanged(\"offset\")\n )\n .subscribe(({ offset }) => {\n history.replaceState(offset, \"\")\n })\n\n /* Set viewport offset from history */\n merge(push$, pop$)\n .pipe(\n bufferCount(2, 1),\n filter(([a, b]) => a.url.pathname === b.url.pathname),\n map(([, state]) => state)\n )\n .subscribe(({ offset }) => {\n window.scrollTo(0, offset?.y || 0)\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search transformation function\n *\n * @param value - Query value\n *\n * @returns Transformed query value\n */\nexport type SearchTransformFn = (value: string) => string\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Default transformation function\n *\n * 1. Search for terms in quotation marks and prepend a `+` modifier to denote\n * that the resulting document must contain all terms, converting the query\n * to an `AND` query (as opposed to the default `OR` behavior). While users\n * may expect terms enclosed in quotation marks to map to span queries, i.e.\n * for which order is important, Lunr.js doesn't support them, so the best\n * we can do is to convert the terms to an `AND` query.\n *\n * 2. Replace control characters which are not located at the beginning of the\n * query or preceded by white space, or are not followed by a non-whitespace\n * character or are at the end of the query string. Furthermore, filter\n * unmatched quotation marks.\n *\n * 3. Trim excess whitespace from left and right.\n *\n * @param query - Query value\n *\n * @returns Transformed query value\n */\nexport function defaultTransform(query: string): string {\n return query\n .split(/\"([^\"]+)\"/g) /* => 1 */\n .map((terms, index) => index & 1\n ? terms.replace(/^\\b|^(?![^\\x00-\\x7F]|$)|\\s+/g, \" +\")\n : terms\n )\n .join(\"\")\n .replace(/\"|(?:^|\\s+)[*+\\-:^~]+(?=\\s+|$)/g, \"\") /* => 2 */\n .trim() /* => 3 */\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchResult } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search message type\n */\nexport const enum SearchMessageType {\n SETUP, /* Search index setup */\n READY, /* Search index ready */\n QUERY, /* Search query */\n RESULT /* Search results */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message containing the data necessary to setup the search index\n */\nexport interface SearchSetupMessage {\n type: SearchMessageType.SETUP /* Message type */\n data: SearchIndex /* Message data */\n}\n\n/**\n * Message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * Message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * Message containing results for a search query\n */\nexport interface SearchResultMessage {\n type: SearchMessageType.RESULT /* Message type */\n data: SearchResult /* Message data */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message exchanged with the search worker\n */\nexport type SearchMessage =\n | SearchSetupMessage\n | SearchReadyMessage\n | SearchQueryMessage\n | SearchResultMessage\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Type guard for search setup messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchSetupMessage(\n message: SearchMessage\n): message is SearchSetupMessage {\n return message.type === SearchMessageType.SETUP\n}\n\n/**\n * Type guard for search ready messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchReadyMessage(\n message: SearchMessage\n): message is SearchReadyMessage {\n return message.type === SearchMessageType.READY\n}\n\n/**\n * Type guard for search query messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchQueryMessage(\n message: SearchMessage\n): message is SearchQueryMessage {\n return message.type === SearchMessageType.QUERY\n}\n\n/**\n * Type guard for search result messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchResultMessage(\n message: SearchMessage\n): message is SearchResultMessage {\n return message.type === SearchMessageType.RESULT\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ObservableInput,\n Subject,\n from,\n map,\n share\n} from \"rxjs\"\n\nimport { configuration, feature, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex } from \"../../_\"\nimport {\n SearchOptions,\n SearchPipeline\n} from \"../../options\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchSetupMessage,\n isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search worker\n */\nexport type SearchWorker = WorkerHandler\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @returns Search index\n */\nfunction setupSearchIndex({ config, docs }: SearchIndex): SearchIndex {\n\n /* Override default language with value from translation */\n if (config.lang.length === 1 && config.lang[0] === \"en\")\n config.lang = [\n translation(\"search.config.lang\")\n ]\n\n /* Override default separator with value from translation */\n if (config.separator === \"[\\\\s\\\\-]+\")\n config.separator = translation(\"search.config.separator\")\n\n /* Set pipeline from translation */\n const pipeline = translation(\"search.config.pipeline\")\n .split(/\\s*,\\s*/)\n .filter(Boolean) as SearchPipeline\n\n /* Determine search options */\n const options: SearchOptions = {\n pipeline,\n suggestions: feature(\"search.suggest\")\n }\n\n /* Return search index after defaulting */\n return { config, docs, options }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function creates a web worker to set up and query the search index,\n * which is done using Lunr.js. The index must be passed as an observable to\n * enable hacks like _localsearch_ via search index embedding as JSON.\n *\n * @param url - Worker URL\n * @param index - Search index observable input\n *\n * @returns Search worker\n */\nexport function setupSearchWorker(\n url: string, index: ObservableInput\n): SearchWorker {\n const config = configuration()\n const worker = new Worker(url)\n\n /* Create communication channels and resolve relative links */\n const tx$ = new Subject()\n const rx$ = watchWorker(worker, { tx$ })\n .pipe(\n map(message => {\n if (isSearchResultMessage(message)) {\n for (const result of message.data.items)\n for (const document of result)\n document.location = `${new URL(document.location, config.base)}`\n }\n return message\n }),\n share()\n )\n\n /* Set up search index */\n from(index)\n .pipe(\n map(data => ({\n type: SearchMessageType.SETUP,\n data: setupSearchIndex(data)\n } as SearchSetupMessage))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Subject,\n combineLatest,\n filter,\n fromEvent,\n map,\n of,\n switchMap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n getElement,\n getLocation,\n requestJSON,\n setLocation\n} from \"~/browser\"\nimport { getComponentElements } from \"~/components\"\nimport {\n Version,\n renderVersionSelector\n} from \"~/templates\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up version selector\n *\n * @param options - Options\n */\nexport function setupVersionSelector(\n { document$ }: SetupOptions\n): void {\n const config = configuration()\n const versions$ = requestJSON(\n new URL(\"../versions.json\", config.base)\n )\n\n /* Determine current version */\n const current$ = versions$\n .pipe(\n map(versions => {\n const [, current] = config.base.match(/([^/]+)\\/?$/)!\n return versions.find(({ version, aliases }) => (\n version === current || aliases.includes(current)\n )) || versions[0]\n })\n )\n\n /* Intercept inter-version navigation */\n combineLatest([versions$, current$])\n .pipe(\n map(([versions, current]) => new Map(versions\n .filter(version => version !== current)\n .map(version => [\n `${new URL(`../${version.version}/`, config.base)}`,\n version\n ])\n )),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.has(el.href)) {\n ev.preventDefault()\n return of(el.href)\n }\n }\n return EMPTY\n }),\n switchMap(url => {\n const { version } = urls.get(url)!\n return fetchSitemap(new URL(url))\n .pipe(\n map(sitemap => {\n const location = getLocation()\n const path = location.href.replace(config.base, \"\")\n return sitemap.includes(path)\n ? new URL(`../${version}/${path}`, config.base)\n : new URL(url)\n })\n )\n })\n )\n )\n )\n .subscribe(url => setLocation(url))\n\n /* Render version selector and warning */\n combineLatest([versions$, current$])\n .subscribe(([versions, current]) => {\n const topic = getElement(\".md-header__topic\")\n topic.appendChild(renderVersionSelector(versions, current))\n })\n\n /* Integrate outdated version banner with instant loading */\n document$.pipe(switchMap(() => current$))\n .subscribe(current => {\n\n /* Check if version state was already determined */\n let outdated = __md_get(\"__outdated\", sessionStorage)\n if (outdated === null) {\n const latest = config.version?.default || \"latest\"\n outdated = !current.aliases.includes(latest)\n\n /* Persist version state in session storage */\n __md_set(\"__outdated\", outdated, sessionStorage)\n }\n\n /* Unhide outdated version banner */\n if (outdated)\n for (const warning of getComponentElements(\"outdated\"))\n warning.hidden = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n combineLatest,\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n shareReplay,\n startWith,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getLocation,\n setToggle,\n watchElementFocus,\n watchToggle\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform,\n isSearchReadyMessage\n} from \"~/integrations\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query\n */\nexport interface SearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement, { rx$ }: SearchWorker\n): Observable {\n const fn = __search?.transform || defaultTransform\n\n /* Immediately show search dialog */\n const { searchParams } = getLocation()\n if (searchParams.has(\"q\"))\n setToggle(\"search\", true)\n\n /* Intercept query parameter (deep link) */\n const param$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1),\n map(() => searchParams.get(\"q\") || \"\")\n )\n\n /* Remove query parameter when search is closed */\n watchToggle(\"search\")\n .pipe(\n filter(active => !active),\n take(1)\n )\n .subscribe(() => {\n const url = new URL(location.href)\n url.searchParams.delete(\"q\")\n history.replaceState({}, \"\", `${url}`)\n })\n\n /* Set query from parameter */\n param$.subscribe(value => { // TODO: not ideal - find a better way\n if (value) {\n el.value = value\n el.focus()\n }\n })\n\n /* Intercept focus and input events */\n const focus$ = watchElementFocus(el)\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1)),\n param$\n )\n .pipe(\n map(() => fn(el.value)),\n startWith(\"\"),\n distinctUntilChanged(),\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount search query\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query component observable\n */\nexport function mountSearchQuery(\n el: HTMLInputElement, { tx$, rx$ }: SearchWorker\n): Observable> {\n const push$ = new Subject()\n\n /* Handle value changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"value\"),\n map(({ value }): SearchQueryMessage => ({\n type: SearchMessageType.QUERY,\n data: value\n }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Handle focus changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n el.placeholder = \"\"\n } else {\n el.placeholder = translation(\"search.placeholder\")\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(push$.pipe(takeLast(1)))\n )\n .subscribe(() => el.focus())\n\n /* Create and return component */\n return watchSearchQuery(el, { tx$, rx$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n filter,\n finalize,\n map,\n merge,\n of,\n skipUntil,\n switchMap,\n take,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getElement,\n watchElementBoundary\n} from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchReadyMessage,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResultItem } from \"~/templates\"\nimport { round } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result list\n *\n * This function performs a lazy rendering of the search results, depending on\n * the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const boundary$ = watchElementBoundary(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Retrieve nested components */\n const meta = getElement(\":scope > :first-child\", el)\n const list = getElement(\":scope > :last-child\", el)\n\n /* Wait until search is ready */\n const ready$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1)\n )\n\n /* Update search result metadata */\n push$\n .pipe(\n withLatestFrom(query$),\n skipUntil(ready$)\n )\n .subscribe(([{ items }, { value }]) => {\n if (value) {\n switch (items.length) {\n\n /* No results */\n case 0:\n meta.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n meta.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n meta.textContent = translation(\n \"search.result.other\",\n round(items.length)\n )\n }\n } else {\n meta.textContent = translation(\"search.result.placeholder\")\n }\n })\n\n /* Update search result list */\n push$\n .pipe(\n tap(() => list.innerHTML = \"\"),\n switchMap(({ items }) => merge(\n of(...items.slice(0, 10)),\n of(...items.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => chunk)\n )\n ))\n )\n .subscribe(result => list.appendChild(\n renderSearchResultItem(result)\n ))\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n fromEvent,\n map,\n tap\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search sharing\n */\nexport interface SearchShare {\n url: URL /* Deep link for sharing */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n query$: Observable /* Search query observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search sharing\n *\n * @param _el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing observable\n */\nexport function watchSearchShare(\n _el: HTMLElement, { query$ }: WatchOptions\n): Observable {\n return query$\n .pipe(\n map(({ value }) => {\n const url = getLocation()\n url.hash = \"\"\n url.searchParams.delete(\"h\")\n url.searchParams.set(\"q\", value)\n return { url }\n })\n )\n}\n\n/**\n * Mount search sharing\n *\n * @param el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing component observable\n */\nexport function mountSearchShare(\n el: HTMLAnchorElement, options: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe(({ url }) => {\n el.setAttribute(\"data-clipboard-text\", el.href)\n el.href = `${url}`\n })\n\n /* Prevent following of link */\n fromEvent(el, \"click\")\n .subscribe(ev => ev.preventDefault())\n\n /* Create and return component */\n return watchSearchShare(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n observeOn,\n tap\n} from \"rxjs\"\n\nimport { Keyboard } from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search suggestions\n */\nexport interface SearchSuggest {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search suggestions\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchSuggest(\n el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n\n /* Retrieve query component and track all changes */\n const query = getComponentElement(\"search-query\")\n const query$ = merge(\n fromEvent(query, \"keydown\"),\n fromEvent(query, \"focus\")\n )\n .pipe(\n observeOn(asyncScheduler),\n map(() => query.value),\n distinctUntilChanged(),\n )\n\n /* Update search suggestions */\n push$\n .pipe(\n combineLatestWith(query$),\n map(([{ suggestions }, value]) => {\n const words = value.split(/([\\s-]+)/)\n if (suggestions?.length && words[words.length - 1]) {\n const last = suggestions[suggestions.length - 1]\n if (last.startsWith(words[words.length - 1]))\n words[words.length - 1] = last\n } else {\n words.length = 0\n }\n return words\n })\n )\n .subscribe(words => el.innerHTML = words\n .join(\"\")\n .replace(/\\s/g, \" \")\n )\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Right arrow: accept current suggestion */\n case \"ArrowRight\":\n if (\n el.innerText.length &&\n query.selectionStart === query.value.length\n )\n query.value = el.innerText\n break\n }\n })\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n ObservableInput,\n filter,\n merge,\n mergeWith,\n sample,\n take\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n SearchResult,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport {\n Component,\n getComponentElement,\n getComponentElements\n} from \"../../_\"\nimport {\n SearchQuery,\n mountSearchQuery\n} from \"../query\"\nimport { mountSearchResult } from \"../result\"\nimport {\n SearchShare,\n mountSearchShare\n} from \"../share\"\nimport {\n SearchSuggest,\n mountSearchSuggest\n} from \"../suggest\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n | SearchShare\n | SearchSuggest\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search\n *\n * This function sets up the search functionality, including the underlying\n * web worker and all keyboard bindings.\n *\n * @param el - Search element\n * @param options - Options\n *\n * @returns Search component observable\n */\nexport function mountSearch(\n el: HTMLElement, { index$, keyboard$ }: MountOptions\n): Observable> {\n const config = configuration()\n try {\n const url = __search?.worker || config.search\n const worker = setupSearchWorker(url, index$)\n\n /* Retrieve query and result components */\n const query = getComponentElement(\"search-query\", el)\n const result = getComponentElement(\"search-result\", el)\n\n /* Re-emit query when search is ready */\n const { tx$, rx$ } = worker\n tx$\n .pipe(\n filter(isSearchQueryMessage),\n sample(rx$.pipe(filter(isSearchReadyMessage))),\n take(1)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n const active = getActiveElement()\n switch (key.type) {\n\n /* Enter: go to first (best) result */\n case \"Enter\":\n if (active === query) {\n const anchors = new Map()\n for (const anchor of getElements(\n \":first-child [href]\", result\n )) {\n const article = anchor.firstElementChild!\n anchors.set(anchor, parseFloat(\n article.getAttribute(\"data-md-score\")!\n ))\n }\n\n /* Go to result with highest score, if any */\n if (anchors.size) {\n const [[best]] = [...anchors].sort(([, a], [, b]) => b - a)\n best.click()\n }\n\n /* Otherwise omit form submission */\n key.claim()\n }\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n query.blur()\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n query.focus()\n } else {\n const els = [query, ...getElements(\n \":not(details) > [href], summary, details[open] [href]\",\n result\n )]\n const i = Math.max(0, (\n Math.max(0, els.indexOf(active)) + els.length + (\n key.type === \"ArrowUp\" ? -1 : +1\n )\n ) % els.length)\n els[i].focus()\n }\n\n /* Prevent scrolling of page */\n key.claim()\n break\n\n /* All other keys: hand to search query */\n default:\n if (query !== getActiveElement())\n query.focus()\n }\n })\n\n /* Set up global keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\"),\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Open search and select query */\n case \"f\":\n case \"s\":\n case \"/\":\n query.focus()\n query.select()\n\n /* Prevent scrolling of page */\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query, worker)\n const result$ = mountSearchResult(result, worker, { query$ })\n return merge(query$, result$)\n .pipe(\n mergeWith(\n\n /* Search sharing */\n ...getComponentElements(\"search-share\", el)\n .map(child => mountSearchShare(child, { query$ })),\n\n /* Search suggestions */\n ...getComponentElements(\"search-suggest\", el)\n .map(child => mountSearchSuggest(child, worker, { keyboard$ }))\n )\n )\n\n /* Gracefully handle broken search */\n } catch (err) {\n el.hidden = true\n return NEVER\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n ObservableInput,\n combineLatest,\n filter,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\nimport {\n SearchIndex,\n setupSearchHighlighter\n} from \"~/integrations\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlighting\n */\nexport interface SearchHighlight {\n nodes: Map /* Map of replacements */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n location$: Observable /* Location observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search highlighting\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Search highlighting component observable\n */\nexport function mountSearchHiglight(\n el: HTMLElement, { index$, location$ }: MountOptions\n): Observable> {\n return combineLatest([\n index$,\n location$\n .pipe(\n startWith(getLocation()),\n filter(url => !!url.searchParams.get(\"h\"))\n )\n ])\n .pipe(\n map(([index, url]) => setupSearchHighlighter(index.config, true)(\n url.searchParams.get(\"h\")!\n )),\n map(fn => {\n const nodes = new Map()\n\n /* Traverse text nodes and collect matches */\n const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT)\n for (let node = it.nextNode(); node; node = it.nextNode()) {\n if (node.parentElement?.offsetHeight) {\n const original = node.textContent!\n const replaced = fn(original)\n if (replaced.length > original.length)\n nodes.set(node as ChildNode, replaced)\n }\n }\n\n /* Replace original nodes with matches */\n for (const [node, text] of nodes) {\n const { childNodes } = h(\"span\", null, text)\n node.replaceWith(...Array.from(childNodes))\n }\n\n /* Return component */\n return { ref: el, nodes }\n })\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n auditTime,\n combineLatest,\n defer,\n distinctUntilChanged,\n finalize,\n map,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElement,\n getElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sidebar\n */\nexport interface Sidebar {\n height: number /* Sidebar height */\n locked: boolean /* Sidebar is locked */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch sidebar\n *\n * This function returns an observable that computes the visual parameters of\n * the sidebar which depends on the vertical viewport offset, as well as the\n * height of the main area. When the page is scrolled beyond the header, the\n * sidebar is locked and fills the remaining space.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar observable\n */\nexport function watchSidebar(\n el: HTMLElement, { viewport$, main$ }: WatchOptions\n): Observable {\n const parent = el.parentElement!\n const adjust =\n parent.offsetTop -\n parent.parentElement!.offsetTop\n\n /* Compute the sidebar's available height and if it should be locked */\n return combineLatest([main$, viewport$])\n .pipe(\n map(([{ offset, height }, { offset: { y } }]) => {\n height = height\n + Math.min(adjust, Math.max(0, y - offset))\n - adjust\n return {\n height,\n locked: y >= offset + adjust\n }\n }),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.locked === b.locked\n ))\n )\n}\n\n/**\n * Mount sidebar\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child \u2013 the `.md-sidebar__scrollwrap` element in order to mitigiate jittery\n * sidebars when the footer is scrolled into view. At some point we switched\n * from `absolute` / `fixed` positioning to `sticky` positioning, significantly\n * reducing jitter in some browsers (respectively Firefox and Safari) when\n * scrolling from the top. However, top-aligned sticky positioning means that\n * the sidebar snaps to the bottom when the end of the container is reached.\n * This is what leads to the mentioned jitter, as the sidebar's height may be\n * updated too slowly.\n *\n * This behaviour can be mitigiated by setting the height of the sidebar to `0`\n * while preserving the padding, and the height on its first element.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar component observable\n */\nexport function mountSidebar(\n el: HTMLElement, { header$, ...options }: MountOptions\n): Observable> {\n const inner = getElement(\".md-sidebar__scrollwrap\", el)\n const { y } = getElementOffset(inner)\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n auditTime(0, animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ height }, { height: offset }]) {\n inner.style.height = `${height - 2 * y}px`\n el.style.top = `${offset}px`\n },\n\n /* Handle complete */\n complete() {\n inner.style.height = \"\"\n el.style.top = \"\"\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Repo, User } from \"github-types\"\nimport {\n Observable,\n defaultIfEmpty,\n map,\n zip\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * GitHub release (partial)\n */\ninterface Release {\n tag_name: string /* Tag name */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user or organization\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n if (typeof repo !== \"undefined\") {\n const url = `https://api.github.com/repos/${user}/${repo}`\n return zip(\n\n /* Fetch version */\n requestJSON(`${url}/releases/latest`)\n .pipe(\n map(release => ({\n version: release.tag_name\n })),\n defaultIfEmpty({})\n ),\n\n /* Fetch stars and forks */\n requestJSON(url)\n .pipe(\n map(info => ({\n stars: info.stargazers_count,\n forks: info.forks_count\n })),\n defaultIfEmpty({})\n )\n )\n .pipe(\n map(([release, info]) => ({ ...release, ...info }))\n )\n\n /* User or organization */\n } else {\n const url = `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(info => ({\n repositories: info.public_repos\n })),\n defaultIfEmpty({})\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ProjectSchema } from \"gitlab\"\nimport {\n Observable,\n defaultIfEmpty,\n map\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab repository facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n base: string, project: string\n): Observable {\n const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`\n return requestJSON(url)\n .pipe(\n map(({ star_count, forks_count }) => ({\n stars: star_count,\n forks: forks_count\n })),\n defaultIfEmpty({})\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts for repositories\n */\nexport interface RepositoryFacts {\n stars?: number /* Number of stars */\n forks?: number /* Number of forks */\n version?: string /* Latest version */\n}\n\n/**\n * Repository facts for organizations\n */\nexport interface OrganizationFacts {\n repositories?: number /* Number of repositories */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts =\n | RepositoryFacts\n | OrganizationFacts\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch repository facts\n *\n * @param url - Repository URL\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFacts(\n url: string\n): Observable {\n const [type] = url.match(/(git(?:hub|lab))/i) || []\n switch (type.toLowerCase()) {\n\n /* GitHub repository */\n case \"github\":\n const [, user, repo] = url.match(/^.+github\\.com\\/([^/]+)\\/?([^/]+)?/i)!\n return fetchSourceFactsFromGitHub(user, repo)\n\n /* GitLab repository */\n case \"gitlab\":\n const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\\/(.+?)\\/?$/i)!\n return fetchSourceFactsFromGitLab(base, slug)\n\n /* Everything else */\n default:\n return EMPTY\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n catchError,\n defer,\n filter,\n finalize,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\nimport { renderSourceFacts } from \"~/templates\"\n\nimport { Component } from \"../../_\"\nimport {\n SourceFacts,\n fetchSourceFacts\n} from \"../facts\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information\n */\nexport interface Source {\n facts: SourceFacts /* Repository facts */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function tries to read the repository facts from session storage, and\n * if unsuccessful, fetches them from the underlying provider.\n *\n * @param el - Repository information element\n *\n * @returns Repository information observable\n */\nexport function watchSource(\n el: HTMLAnchorElement\n): Observable {\n return fetch$ ||= defer(() => {\n const cached = __md_get(\"__source\", sessionStorage)\n if (cached)\n return of(cached)\n else\n return fetchSourceFacts(el.href)\n .pipe(\n tap(facts => __md_set(\"__source\", facts, sessionStorage))\n )\n })\n .pipe(\n catchError(() => EMPTY),\n filter(facts => Object.keys(facts).length > 0),\n map(facts => ({ facts })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount repository information\n *\n * @param el - Repository information element\n *\n * @returns Repository information component observable\n */\nexport function mountSource(\n el: HTMLAnchorElement\n): Observable> {\n const inner = getElement(\":scope > :last-child\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ facts }) => {\n inner.appendChild(renderSourceFacts(facts))\n inner.setAttribute(\"data-md-state\", \"done\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation tabs\n */\nexport interface Tabs {\n hidden: boolean /* Navigation tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch navigation tabs\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs observable\n */\nexport function watchTabs(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchElementSize(document.body)\n .pipe(\n switchMap(() => watchViewportAt(el, { header$, viewport$ })),\n map(({ offset: { y } }) => {\n return {\n hidden: y >= 10\n }\n }),\n distinctUntilKeyChanged(\"hidden\")\n )\n}\n\n/**\n * Mount navigation tabs\n *\n * This function hides the navigation tabs when scrolling past the threshold\n * and makes them reappear in a nice CSS animation when scrolling back up.\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs component observable\n */\nexport function mountTabs(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n if (hidden)\n el.setAttribute(\"data-md-state\", \"hidden\")\n else\n el.removeAttribute(\"data-md-state\")\n },\n\n /* Handle complete */\n complete() {\n el.removeAttribute(\"data-md-state\")\n }\n })\n\n /* Create and return component */\n return (\n feature(\"navigation.tabs.sticky\")\n ? of({ hidden: false })\n : watchTabs(el, options)\n )\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatestWith,\n debounceTime,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n repeat,\n scan,\n share,\n skip,\n startWith,\n switchMap,\n takeLast,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n getElement,\n getElements,\n getLocation,\n getOptionalElement,\n watchElementSize\n} from \"~/browser\"\n\nimport {\n Component,\n getComponentElement\n} from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport interface TableOfContents {\n prev: HTMLAnchorElement[][] /* Anchors (previous) */\n next: HTMLAnchorElement[][] /* Anchors (next) */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch table of contents\n *\n * This is effectively a scroll spy implementation which will account for the\n * fixed header and automatically re-calculate anchor offsets when the viewport\n * is resized. The returned observable will only emit if the table of contents\n * needs to be repainted.\n *\n * This implementation tracks an anchor element's entire path starting from its\n * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the\n * Material theme currently doesn't make use of this information, it enables\n * the styling of the entire hierarchy through customization.\n *\n * Note that the current anchor is the last item of the `prev` anchor list.\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n\n /* Compute anchor-to-target mapping */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getOptionalElement(`[id=\"${id}\"]`)\n if (typeof target !== \"undefined\")\n table.set(anchor, target)\n }\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n map(({ height }) => {\n const main = getComponentElement(\"main\")\n const grid = getElement(\":scope > :first-child\", main)\n return height + 0.8 * (\n grid.offsetTop -\n main.offsetTop\n )\n }),\n share()\n )\n\n /* Compute partition of previous and next anchors */\n const partition$ = watchElementSize(document.body)\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n\n /* Build index to map anchor paths to vertical offsets */\n switchMap(body => defer(() => {\n let path: HTMLAnchorElement[] = []\n return of([...table].reduce((index, [anchor, target]) => {\n while (path.length) {\n const last = table.get(path[path.length - 1])!\n if (last.tagName >= target.tagName) {\n path.pop()\n } else {\n break\n }\n }\n\n /* If the current anchor is hidden, continue with its parent */\n let offset = target.offsetTop\n while (!offset && target.parentElement) {\n target = target.parentElement\n offset = target.offsetTop\n }\n\n /* Map reversed anchor path to vertical offset */\n return index.set(\n [...path = [...path, anchor]].reverse(),\n offset\n )\n }, new Map()))\n })\n .pipe(\n\n /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */\n map(index => new Map([...index].sort(([, a], [, b]) => a - b))),\n combineLatestWith(adjust$),\n\n /* Re-compute partition when viewport offset changes */\n switchMap(([index, adjust]) => viewport$\n .pipe(\n scan(([prev, next], { offset: { y }, size }) => {\n const last = y + size.height >= Math.floor(body.height)\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y || last) {\n prev = [...prev, next.shift()!]\n } else {\n break\n }\n }\n\n /* Look backward */\n while (prev.length) {\n const [, offset] = prev[prev.length - 1]\n if (offset - adjust >= y && !last) {\n next = [prev.pop()!, ...next]\n } else {\n break\n }\n }\n\n /* Return partition */\n return [prev, next]\n }, [[], [...index]]),\n distinctUntilChanged((a, b) => (\n a[0] === b[0] &&\n a[1] === b[1]\n ))\n )\n )\n )\n )\n )\n\n /* Compute and return anchor list migrations */\n return partition$\n .pipe(\n map(([prev, next]) => ({\n prev: prev.map(([path]) => path),\n next: next.map(([path]) => path)\n })),\n\n /* Extract anchor list migrations */\n startWith({ prev: [], next: [] }),\n bufferCount(2, 1),\n map(([a, b]) => {\n\n /* Moving down */\n if (a.prev.length < b.prev.length) {\n return {\n prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length),\n next: []\n }\n\n /* Moving up */\n } else {\n return {\n prev: b.prev.slice(-1),\n next: b.next.slice(0, b.next.length - a.next.length)\n }\n }\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, { viewport$, header$, target$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n anchor.removeAttribute(\"data-md-state\")\n anchor.classList.remove(\n \"md-nav__link--active\"\n )\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n anchor.setAttribute(\"data-md-state\", \"blur\")\n anchor.classList.toggle(\n \"md-nav__link--active\",\n index === prev.length - 1\n )\n }\n })\n\n /* Set up anchor tracking, if enabled */\n if (feature(\"navigation.tracking\"))\n viewport$\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n distinctUntilKeyChanged(\"offset\"),\n debounceTime(250),\n skip(1),\n takeUntil(target$.pipe(skip(1))),\n repeat({ delay: 250 }),\n withLatestFrom(push$)\n )\n .subscribe(([, { prev }]) => {\n const url = getLocation()\n\n /* Set hash fragment to active anchor */\n const anchor = prev[prev.length - 1]\n if (anchor && anchor.length) {\n const [active] = anchor\n const { hash } = new URL(active.href)\n if (url.hash !== hash) {\n url.hash = hash\n history.replaceState({}, \"\", `${url}`)\n }\n\n /* Reset anchor when at the top */\n } else {\n url.hash = \"\"\n history.replaceState({}, \"\", `${url}`)\n }\n })\n\n /* Create and return component */\n return watchTableOfContents(el, { viewport$, header$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n endWith,\n finalize,\n map,\n repeat,\n skip,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { Viewport } from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Back-to-top button\n */\nexport interface BackToTop {\n hidden: boolean /* Back-to-top button is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch back-to-top\n *\n * @param _el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top observable\n */\nexport function watchBackToTop(\n _el: HTMLElement, { viewport$, main$, target$ }: WatchOptions\n): Observable {\n\n /* Compute direction */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => a > b && b > 0),\n distinctUntilChanged()\n )\n\n /* Compute whether main area is active */\n const active$ = main$\n .pipe(\n map(({ active }) => active)\n )\n\n /* Compute threshold for hiding */\n return combineLatest([active$, direction$])\n .pipe(\n map(([active, direction]) => !(active && direction)),\n distinctUntilChanged(),\n takeUntil(target$.pipe(skip(1))),\n endWith(true),\n repeat({ delay: 250 }),\n map(hidden => ({ hidden }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount back-to-top\n *\n * @param el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top component observable\n */\nexport function mountBackToTop(\n el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n if (hidden) {\n el.setAttribute(\"data-md-state\", \"hidden\")\n el.setAttribute(\"tabindex\", \"-1\")\n el.blur()\n } else {\n el.removeAttribute(\"data-md-state\")\n el.removeAttribute(\"tabindex\")\n }\n },\n\n /* Handle complete */\n complete() {\n el.style.top = \"\"\n el.setAttribute(\"data-md-state\", \"hidden\")\n el.removeAttribute(\"tabindex\")\n }\n })\n\n /* Watch header height */\n header$\n .pipe(\n takeUntil(push$.pipe(endWith(0), takeLast(1))),\n distinctUntilKeyChanged(\"height\")\n )\n .subscribe(({ height }) => {\n el.style.top = `${height + 16}px`\n })\n\n /* Create and return component */\n return watchBackToTop(el, { viewport$, main$, target$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n takeWhile,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function replaces the indeterminate \"pseudo state\" with the actual\n * indeterminate state, which is used to keep navigation always expanded.\n *\n * @param options - Options\n */\nexport function patchIndeterminate(\n { document$, tablet$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\n \"[data-md-state=indeterminate]\"\n )),\n tap(el => {\n el.indeterminate = true\n el.checked = false\n }),\n mergeMap(el => fromEvent(el, \"change\")\n .pipe(\n takeWhile(() => el.hasAttribute(\"data-md-state\")),\n map(() => el)\n )\n ),\n withLatestFrom(tablet$)\n )\n .subscribe(([el, tablet]) => {\n el.removeAttribute(\"data-md-state\")\n if (tablet)\n el.checked = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @returns Test result\n */\nfunction isAppleDevice(): boolean {\n return /(iPad|iPhone|iPod)/.test(navigator.userAgent)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all elements with `data-md-scrollfix` attributes\n *\n * This is a year-old patch which ensures that overflow scrolling works at the\n * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon\n * the start of a touch event.\n *\n * @see https://bit.ly/2SCtAOO - Original source\n *\n * @param options - Options\n */\nexport function patchScrollfix(\n { document$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\"[data-md-scrollfix]\")),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n map(() => el)\n )\n )\n )\n .subscribe(el => {\n const top = el.scrollTop\n\n /* We're at the top of the container */\n if (top === 0) {\n el.scrollTop = 1\n\n /* We're at the bottom of the container */\n } else if (top + el.offsetHeight === el.scrollHeight) {\n el.scrollTop = top - 1\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n delay,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchToggle\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n viewport$: Observable /* Viewport observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch the document body to lock when search is open\n *\n * For mobile and tablet viewports, the search is rendered full screen, which\n * leads to scroll leaking when at the top or bottom of the search result. This\n * function locks the body when the search is in full screen mode, and restores\n * the scroll position when leaving.\n *\n * @param options - Options\n */\nexport function patchScrolllock(\n { viewport$, tablet$ }: PatchOptions\n): void {\n combineLatest([watchToggle(\"search\"), tablet$])\n .pipe(\n map(([active, tablet]) => active && !tablet),\n switchMap(active => of(active)\n .pipe(\n delay(active ? 400 : 100)\n )\n ),\n withLatestFrom(viewport$)\n )\n .subscribe(([active, { offset: { y }}]) => {\n if (active) {\n document.body.setAttribute(\"data-md-state\", \"lock\")\n document.body.style.top = `-${y}px`\n } else {\n const value = -1 * parseInt(document.body.style.top, 10)\n document.body.removeAttribute(\"data-md-state\")\n document.body.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node !== \"object\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n"], - "mappings": "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", - "names": [] -} diff --git a/test/assets/javascripts/lunr/min/lunr.ar.min.js b/test/assets/javascripts/lunr/min/lunr.ar.min.js deleted file mode 100644 index 248ddc5d14da..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.ar.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.de.min.js b/test/assets/javascripts/lunr/min/lunr.de.min.js deleted file mode 100644 index f3b5c108c9ee..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.de.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `German` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.du.min.js b/test/assets/javascripts/lunr/min/lunr.du.min.js deleted file mode 100644 index 49a0f3f0ac17..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.du.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Dutch` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.es.min.js b/test/assets/javascripts/lunr/min/lunr.es.min.js deleted file mode 100644 index 2989d34265c9..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.es.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Spanish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=function(){var s=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(){if(A.out_grouping(x,97,252)){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.fi.min.js b/test/assets/javascripts/lunr/min/lunr.fi.min.js deleted file mode 100644 index 29f5dfcea8f3..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.fi.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Finnish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.fr.min.js b/test/assets/javascripts/lunr/min/lunr.fr.min.js deleted file mode 100644 index 68cd0094ae03..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.fr.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `French` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.hi.min.js b/test/assets/javascripts/lunr/min/lunr.hi.min.js deleted file mode 100644 index 7dbc41402cf3..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.hi.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.hu.min.js b/test/assets/javascripts/lunr/min/lunr.hu.min.js deleted file mode 100644 index ed9d909f7344..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.hu.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Hungarian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.it.min.js b/test/assets/javascripts/lunr/min/lunr.it.min.js deleted file mode 100644 index 344b6a3c0cf8..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.it.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Italian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.ja.min.js b/test/assets/javascripts/lunr/min/lunr.ja.min.js deleted file mode 100644 index 5f254ebe91fa..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.ja.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.no.min.js b/test/assets/javascripts/lunr/min/lunr.no.min.js deleted file mode 100644 index 92bc7e4e8944..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.no.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Norwegian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.pt.min.js b/test/assets/javascripts/lunr/min/lunr.pt.min.js deleted file mode 100644 index 6c16996d6509..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.pt.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Portuguese` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.ro.min.js b/test/assets/javascripts/lunr/min/lunr.ro.min.js deleted file mode 100644 index 727714018182..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.ro.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Romanian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.ru.min.js b/test/assets/javascripts/lunr/min/lunr.ru.min.js deleted file mode 100644 index 186cc485c238..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.ru.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Russian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.sv.min.js b/test/assets/javascripts/lunr/min/lunr.sv.min.js deleted file mode 100644 index 3e5eb6400026..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.sv.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Swedish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.th.min.js b/test/assets/javascripts/lunr/min/lunr.th.min.js deleted file mode 100644 index dee3aac6e5cb..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.th.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.tr.min.js b/test/assets/javascripts/lunr/min/lunr.tr.min.js deleted file mode 100644 index 563f6ec1f525..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.tr.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Turkish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.vi.min.js b/test/assets/javascripts/lunr/min/lunr.vi.min.js deleted file mode 100644 index 22aed28c49b8..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.vi.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/min/lunr.zh.min.js b/test/assets/javascripts/lunr/min/lunr.zh.min.js deleted file mode 100644 index 7727bbe24d71..000000000000 --- a/test/assets/javascripts/lunr/min/lunr.zh.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("nodejieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/tinyseg.js b/test/assets/javascripts/lunr/tinyseg.js deleted file mode 100644 index 167fa6dd69e0..000000000000 --- a/test/assets/javascripts/lunr/tinyseg.js +++ /dev/null @@ -1,206 +0,0 @@ -/** - * export the module via AMD, CommonJS or as a browser global - * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js - */ -;(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(factory) - } else if (typeof exports === 'object') { - /** - * Node. Does not work with strict CommonJS, but - * only CommonJS-like environments that support module.exports, - * like Node. - */ - module.exports = factory() - } else { - // Browser globals (root is window) - factory()(root.lunr); - } -}(this, function () { - /** - * Just return a value to define the module export. - * This example returns an object, but the module - * can return a function as the exported value. - */ - - return function(lunr) { - // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript - // (c) 2008 Taku Kudo - // TinySegmenter is freely distributable under the terms of a new BSD licence. - // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt - - function TinySegmenter() { - var patterns = { - "[一二三四五六七八九十百千万億兆]":"M", - "[一-龠々〆ヵヶ]":"H", - "[ぁ-ん]":"I", - "[ァ-ヴーア-ン゙ー]":"K", - "[a-zA-Za-zA-Z]":"A", - "[0-90-9]":"N" - } - this.chartype_ = []; - for (var i in patterns) { - var regexp = new RegExp(i); - this.chartype_.push([regexp, patterns[i]]); - } - - this.BIAS__ = -332 - this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; - this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; - this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; - this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; - this.BP2__ = {"BO":60,"OO":-1762}; - this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; - this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; - this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; - this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; - this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; - this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; - this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; - this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; - this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; - this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; - this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; - this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; - this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; - this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; - this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; - this.TW1__ = {"につい":-4681,"東京都":2026}; - this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; - this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; - this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; - this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; - this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; - this.UC3__ = {"A":-1370,"I":2311}; - this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; - this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; - this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; - this.UP1__ = {"O":-214}; - this.UP2__ = {"B":69,"O":935}; - this.UP3__ = {"B":189}; - this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; - this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; - this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; - this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; - this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; - this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; - this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; - this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; - this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; - - return this; - } - TinySegmenter.prototype.ctype_ = function(str) { - for (var i in this.chartype_) { - if (str.match(this.chartype_[i][0])) { - return this.chartype_[i][1]; - } - } - return "O"; - } - - TinySegmenter.prototype.ts_ = function(v) { - if (v) { return v; } - return 0; - } - - TinySegmenter.prototype.segment = function(input) { - if (input == null || input == undefined || input == "") { - return []; - } - var result = []; - var seg = ["B3","B2","B1"]; - var ctype = ["O","O","O"]; - var o = input.split(""); - for (i = 0; i < o.length; ++i) { - seg.push(o[i]); - ctype.push(this.ctype_(o[i])) - } - seg.push("E1"); - seg.push("E2"); - seg.push("E3"); - ctype.push("O"); - ctype.push("O"); - ctype.push("O"); - var word = seg[3]; - var p1 = "U"; - var p2 = "U"; - var p3 = "U"; - for (var i = 4; i < seg.length - 3; ++i) { - var score = this.BIAS__; - var w1 = seg[i-3]; - var w2 = seg[i-2]; - var w3 = seg[i-1]; - var w4 = seg[i]; - var w5 = seg[i+1]; - var w6 = seg[i+2]; - var c1 = ctype[i-3]; - var c2 = ctype[i-2]; - var c3 = ctype[i-1]; - var c4 = ctype[i]; - var c5 = ctype[i+1]; - var c6 = ctype[i+2]; - score += this.ts_(this.UP1__[p1]); - score += this.ts_(this.UP2__[p2]); - score += this.ts_(this.UP3__[p3]); - score += this.ts_(this.BP1__[p1 + p2]); - score += this.ts_(this.BP2__[p2 + p3]); - score += this.ts_(this.UW1__[w1]); - score += this.ts_(this.UW2__[w2]); - score += this.ts_(this.UW3__[w3]); - score += this.ts_(this.UW4__[w4]); - score += this.ts_(this.UW5__[w5]); - score += this.ts_(this.UW6__[w6]); - score += this.ts_(this.BW1__[w2 + w3]); - score += this.ts_(this.BW2__[w3 + w4]); - score += this.ts_(this.BW3__[w4 + w5]); - score += this.ts_(this.TW1__[w1 + w2 + w3]); - score += this.ts_(this.TW2__[w2 + w3 + w4]); - score += this.ts_(this.TW3__[w3 + w4 + w5]); - score += this.ts_(this.TW4__[w4 + w5 + w6]); - score += this.ts_(this.UC1__[c1]); - score += this.ts_(this.UC2__[c2]); - score += this.ts_(this.UC3__[c3]); - score += this.ts_(this.UC4__[c4]); - score += this.ts_(this.UC5__[c5]); - score += this.ts_(this.UC6__[c6]); - score += this.ts_(this.BC1__[c2 + c3]); - score += this.ts_(this.BC2__[c3 + c4]); - score += this.ts_(this.BC3__[c4 + c5]); - score += this.ts_(this.TC1__[c1 + c2 + c3]); - score += this.ts_(this.TC2__[c2 + c3 + c4]); - score += this.ts_(this.TC3__[c3 + c4 + c5]); - score += this.ts_(this.TC4__[c4 + c5 + c6]); - // score += this.ts_(this.TC5__[c4 + c5 + c6]); - score += this.ts_(this.UQ1__[p1 + c1]); - score += this.ts_(this.UQ2__[p2 + c2]); - score += this.ts_(this.UQ3__[p3 + c3]); - score += this.ts_(this.BQ1__[p2 + c2 + c3]); - score += this.ts_(this.BQ2__[p2 + c3 + c4]); - score += this.ts_(this.BQ3__[p3 + c2 + c3]); - score += this.ts_(this.BQ4__[p3 + c3 + c4]); - score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); - score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); - score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); - score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); - var p = "O"; - if (score > 0) { - result.push(word); - word = ""; - p = "B"; - } - p1 = p2; - p2 = p3; - p3 = p; - word += seg[i]; - } - result.push(word); - - return result; - } - - lunr.TinySegmenter = TinySegmenter; - }; - -})); \ No newline at end of file diff --git a/test/assets/javascripts/lunr/wordcut.js b/test/assets/javascripts/lunr/wordcut.js deleted file mode 100644 index 146f4b44bca1..000000000000 --- a/test/assets/javascripts/lunr/wordcut.js +++ /dev/null @@ -1,6708 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; - }) - this.addWords(words, false) - } - if(finalize){ - this.finalizeDict(); - } - }, - - dictSeek: function (l, r, ch, strOffset, pos) { - var ans = null; - while (l <= r) { - var m = Math.floor((l + r) / 2), - dict_item = this.dict[m], - len = dict_item.length; - if (len <= strOffset) { - l = m + 1; - } else { - var ch_ = dict_item[strOffset]; - if (ch_ < ch) { - l = m + 1; - } else if (ch_ > ch) { - r = m - 1; - } else { - ans = m; - if (pos == LEFT) { - r = m - 1; - } else { - l = m + 1; - } - } - } - } - return ans; - }, - - isFinal: function (acceptor) { - return this.dict[acceptor.l].length == acceptor.strOffset; - }, - - createAcceptor: function () { - return { - l: 0, - r: this.dict.length - 1, - strOffset: 0, - isFinal: false, - dict: this, - transit: function (ch) { - return this.dict.transit(this, ch); - }, - isError: false, - tag: "DICT", - w: 1, - type: "DICT" - }; - }, - - transit: function (acceptor, ch) { - var l = this.dictSeek(acceptor.l, - acceptor.r, - ch, - acceptor.strOffset, - LEFT); - if (l !== null) { - var r = this.dictSeek(l, - acceptor.r, - ch, - acceptor.strOffset, - RIGHT); - acceptor.l = l; - acceptor.r = r; - acceptor.strOffset++; - acceptor.isFinal = this.isFinal(acceptor); - } else { - acceptor.isError = true; - } - return acceptor; - }, - - sortuniq: function(a){ - return a.sort().filter(function(item, pos, arr){ - return !pos || item != arr[pos - 1]; - }) - }, - - flatten: function(a){ - //[[1,2],[3]] -> [1,2,3] - return [].concat.apply([], a); - } -}; -module.exports = WordcutDict; - -}).call(this,"/dist/tmp") -},{"glob":16,"path":22}],3:[function(require,module,exports){ -var WordRule = { - createAcceptor: function(tag) { - if (tag["WORD_RULE"]) - return null; - - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - var lch = ch.toLowerCase(); - if (lch >= "a" && lch <= "z") { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "WORD_RULE", - type: "WORD_RULE", - w: 1}; - } -}; - -var NumberRule = { - createAcceptor: function(tag) { - if (tag["NUMBER_RULE"]) - return null; - - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (ch >= "0" && ch <= "9") { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "NUMBER_RULE", - type: "NUMBER_RULE", - w: 1}; - } -}; - -var SpaceRule = { - tag: "SPACE_RULE", - createAcceptor: function(tag) { - - if (tag["SPACE_RULE"]) - return null; - - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || - ch == "\u00A0" || ch=="\u2003"//nbsp and emsp - ) { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: SpaceRule.tag, - w: 1, - type: "SPACE_RULE"}; - } -} - -var SingleSymbolRule = { - tag: "SINSYM", - createAcceptor: function(tag) { - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "SINSYM", - w: 1, - type: "SINSYM"}; - } -} - - -var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; - -module.exports = LatinRules; - -},{}],4:[function(require,module,exports){ -var _ = require("underscore") - , WordcutCore = require("./wordcut_core"); -var PathInfoBuilder = { - - /* - buildByPartAcceptors: function(path, acceptors, i) { - var - var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { - - }, []); - - return genInfos; - } - */ - - buildByAcceptors: function(path, finalAcceptors, i) { - var self = this; - var infos = finalAcceptors.map(function(acceptor) { - var p = i - acceptor.strOffset + 1 - , _info = path[p]; - - var info = {p: p, - mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), - w: acceptor.w + _info.w, - unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, - type: acceptor.type}; - - if (acceptor.type == "PART") { - for(var j = p + 1; j <= i; j++) { - path[j].merge = p; - } - info.merge = p; - } - - return info; - }); - return infos.filter(function(info) { return info; }); - }, - - fallback: function(path, leftBoundary, text, i) { - var _info = path[leftBoundary]; - if (text[i].match(/[\u0E48-\u0E4E]/)) { - if (leftBoundary != 0) - leftBoundary = path[leftBoundary].p; - return {p: leftBoundary, - mw: 0, - w: 1 + _info.w, - unk: 1 + _info.unk, - type: "UNK"}; -/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { - leftBoundary = path[leftBoundary].p; - return {p: leftBoundary, - w: 1 + _info.w, - unk: 1 + _info.unk, - type: "UNK"}; */ - } else { - return {p: leftBoundary, - mw: _info.mw, - w: 1 + _info.w, - unk: 1 + _info.unk, - type: "UNK"}; - } - }, - - build: function(path, finalAcceptors, i, leftBoundary, text) { - var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); - if (basicPathInfos.length > 0) { - return basicPathInfos; - } else { - return [this.fallback(path, leftBoundary, text, i)]; - } - } -}; - -module.exports = function() { - return _.clone(PathInfoBuilder); -} - -},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ -var _ = require("underscore"); - - -var PathSelector = { - selectPath: function(paths) { - var path = paths.reduce(function(selectedPath, path) { - if (selectedPath == null) { - return path; - } else { - if (path.unk < selectedPath.unk) - return path; - if (path.unk == selectedPath.unk) { - if (path.mw < selectedPath.mw) - return path - if (path.mw == selectedPath.mw) { - if (path.w < selectedPath.w) - return path; - } - } - return selectedPath; - } - }, null); - return path; - }, - - createPath: function() { - return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; - } -}; - -module.exports = function() { - return _.clone(PathSelector); -}; - -},{"underscore":25}],6:[function(require,module,exports){ -function isMatch(pat, offset, ch) { - if (pat.length <= offset) - return false; - var _ch = pat[offset]; - return _ch == ch || - (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || - (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || - (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); -} - -var Rule0 = { - pat: "เหก็ม", - createAcceptor: function(tag) { - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (isMatch(Rule0.pat, this.strOffset,ch)) { - this.isFinal = (this.strOffset + 1 == Rule0.pat.length); - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "THAI_RULE", - type: "THAI_RULE", - w: 1}; - } -}; - -var PartRule = { - createAcceptor: function(tag) { - return {strOffset: 0, - patterns: [ - "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" - ], - isFinal: false, - transit: function(ch) { - var offset = this.strOffset; - this.patterns = this.patterns.filter(function(pat) { - return isMatch(pat, offset, ch); - }); - - if (this.patterns.length > 0) { - var len = 1 + offset; - this.isFinal = this.patterns.some(function(pat) { - return pat.length == len; - }); - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "PART", - type: "PART", - unk: 1, - w: 1}; - } -}; - -var ThaiRules = [Rule0, PartRule]; - -module.exports = ThaiRules; - -},{}],7:[function(require,module,exports){ -var sys = require("sys") - , WordcutDict = require("./dict") - , WordcutCore = require("./wordcut_core") - , PathInfoBuilder = require("./path_info_builder") - , PathSelector = require("./path_selector") - , Acceptors = require("./acceptors") - , latinRules = require("./latin_rules") - , thaiRules = require("./thai_rules") - , _ = require("underscore"); - - -var Wordcut = Object.create(WordcutCore); -Wordcut.defaultPathInfoBuilder = PathInfoBuilder; -Wordcut.defaultPathSelector = PathSelector; -Wordcut.defaultAcceptors = Acceptors; -Wordcut.defaultLatinRules = latinRules; -Wordcut.defaultThaiRules = thaiRules; -Wordcut.defaultDict = WordcutDict; - - -Wordcut.initNoDict = function(dict_path) { - var self = this; - self.pathInfoBuilder = new self.defaultPathInfoBuilder; - self.pathSelector = new self.defaultPathSelector; - self.acceptors = new self.defaultAcceptors; - self.defaultLatinRules.forEach(function(rule) { - self.acceptors.creators.push(rule); - }); - self.defaultThaiRules.forEach(function(rule) { - self.acceptors.creators.push(rule); - }); -}; - -Wordcut.init = function(dict_path, withDefault, additionalWords) { - withDefault = withDefault || false; - this.initNoDict(); - var dict = _.clone(this.defaultDict); - dict.init(dict_path, withDefault, additionalWords); - this.acceptors.creators.push(dict); -}; - -module.exports = Wordcut; - -},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ -var WordcutCore = { - - buildPath: function(text) { - var self = this - , path = self.pathSelector.createPath() - , leftBoundary = 0; - self.acceptors.reset(); - for (var i = 0; i < text.length; i++) { - var ch = text[i]; - self.acceptors.transit(ch); - - var possiblePathInfos = self - .pathInfoBuilder - .build(path, - self.acceptors.getFinalAcceptors(), - i, - leftBoundary, - text); - var selectedPath = self.pathSelector.selectPath(possiblePathInfos) - - path.push(selectedPath); - if (selectedPath.type !== "UNK") { - leftBoundary = i; - } - } - return path; - }, - - pathToRanges: function(path) { - var e = path.length - 1 - , ranges = []; - - while (e > 0) { - var info = path[e] - , s = info.p; - - if (info.merge !== undefined && ranges.length > 0) { - var r = ranges[ranges.length - 1]; - r.s = info.merge; - s = r.s; - } else { - ranges.push({s:s, e:e}); - } - e = s; - } - return ranges.reverse(); - }, - - rangesToText: function(text, ranges, delimiter) { - return ranges.map(function(r) { - return text.substring(r.s, r.e); - }).join(delimiter); - }, - - cut: function(text, delimiter) { - var path = this.buildPath(text) - , ranges = this.pathToRanges(path); - return this - .rangesToText(text, ranges, - (delimiter === undefined ? "|" : delimiter)); - }, - - cutIntoRanges: function(text, noText) { - var path = this.buildPath(text) - , ranges = this.pathToRanges(path); - - if (!noText) { - ranges.forEach(function(r) { - r.text = text.substring(r.s, r.e); - }); - } - return ranges; - }, - - cutIntoArray: function(text) { - var path = this.buildPath(text) - , ranges = this.pathToRanges(path); - - return ranges.map(function(r) { - return text.substring(r.s, r.e) - }); - } -}; - -module.exports = WordcutCore; - -},{}],9:[function(require,module,exports){ -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -// when used in node, this will actually load the util module we depend on -// versus loading the builtin util module as happens otherwise -// this is a bug in node module loading as far as I am concerned -var util = require('util/'); - -var pSlice = Array.prototype.slice; -var hasOwn = Object.prototype.hasOwnProperty; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } - else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = stackStartFunction.name; - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function replacer(key, value) { - if (util.isUndefined(value)) { - return '' + value; - } - if (util.isNumber(value) && !isFinite(value)) { - return value.toString(); - } - if (util.isFunction(value) || util.isRegExp(value)) { - return value.toString(); - } - return value; -} - -function truncate(s, n) { - if (util.isString(s)) { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} - -function getMessage(self) { - return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + - self.operator + ' ' + - truncate(JSON.stringify(self.expected, replacer), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (util.isBuffer(actual) && util.isBuffer(expected)) { - if (actual.length != expected.length) return false; - - for (var i = 0; i < actual.length; i++) { - if (actual[i] !== expected[i]) return false; - } - - return true; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!util.isObject(actual) && !util.isObject(expected)) { - return actual == expected; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b) { - if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) { - return a === b; - } - var aIsArgs = isArguments(a), - bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - var ka = objectKeys(a), - kb = objectKeys(b), - key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key])) return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } else if (actual instanceof expected) { - return true; - } else if (expected.call({}, actual) === true) { - return true; - } - - return false; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (util.isString(expected)) { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - if (!shouldThrow && expectedException(actual, expected)) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function(err) { if (err) {throw err;}}; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -},{"util/":28}],10:[function(require,module,exports){ -'use strict'; -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} - -},{}],11:[function(require,module,exports){ -var concatMap = require('concat-map'); -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - - -},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ - -},{}],13:[function(require,module,exports){ -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -},{}],14:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); - } - } - - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} - -},{}],15:[function(require,module,exports){ -(function (process){ -exports.alphasort = alphasort -exports.alphasorti = alphasorti -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") -var Minimatch = minimatch.Minimatch - -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) -} - -function alphasort (a, b) { - return a.localeCompare(b) -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern) - } - - return { - matcher: new Minimatch(pattern), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = options.cwd - self.changedCwd = path.resolve(options.cwd) !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - self.nomount = !!options.nomount - - // disable comments and negation unless the user explicitly - // passes in false as the option. - options.nonegate = options.nonegate === false ? false : true - options.nocomment = options.nocomment === false ? false : true - deprecationWarning(options) - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -// TODO(isaacs): remove entirely in v6 -// exported to reset in tests -exports.deprecationWarned -function deprecationWarning(options) { - if (!options.nonegate || !options.nocomment) { - if (process.noDeprecation !== true && !exports.deprecationWarned) { - var msg = 'glob WARNING: comments and negation will be disabled in v6' - if (process.throwDeprecation) - throw new Error(msg) - else if (process.traceDeprecation) - console.trace(msg) - else - console.error(msg) - - exports.deprecationWarned = true - } - } -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - return !(/\/$/.test(e)) - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -}).call(this,require('_process')) -},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ -(function (process){ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var fs = require('fs') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var globSync = require('./sync.js') -var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -glob.hasMagic = function (pattern, options_) { - var options = util._extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - var n = this.minimatch.set.length - this._processing = 0 - this.matches = new Array(n) - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - - function done () { - --self._processing - if (self._processing <= 0) - self._finish() - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - fs.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (this.matches[index][e]) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = this._makeAbs(e) - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - if (this.mark) - e = this._mark(e) - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er) - return cb() - - var isSym = lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - this.cache[this._makeAbs(f)] = 'FILE' - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && !stat.isDirectory()) - return cb(null, false, stat) - - var c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c !== 'DIR') - return cb() - - return cb(null, c, stat) -} - -}).call(this,require('_process')) -},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ -(function (process){ -module.exports = globSync -globSync.GlobSync = GlobSync - -var fs = require('fs') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = fs.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this.matches[index][e] = true - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - var abs = this._makeAbs(e) - if (this.mark) - e = this._mark(e) - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[this._makeAbs(e)] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - // lstat failed, doesn't exist - return null - } - - var isSym = lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - this.cache[this._makeAbs(f)] = 'FILE' - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this.matches[index][prefix] = true -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - return false - } - - if (lstat.isSymbolicLink()) { - try { - stat = fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c !== 'DIR') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -}).call(this,require('_process')) -},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ -(function (process){ -var wrappy = require('wrappy') -var reqs = Object.create(null) -var once = require('once') - -module.exports = wrappy(inflight) - -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) - } -} - -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) - - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] - } - } - }) -} - -function slice (args) { - var length = args.length - var array = [] - - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} - -}).call(this,require('_process')) -},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - -},{}],20:[function(require,module,exports){ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = { sep: '/' } -try { - path = require('path') -} catch (er) {} - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - // "" only matches "" - if (pattern.trim() === '') return p === '' - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd - } - - // should be unreachable. - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} - -},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ -var wrappy = require('wrappy') -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) - -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) - -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f -} - -},{"wrappy":29}],22:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":24}],23:[function(require,module,exports){ -(function (process){ -'use strict'; - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; - -}).call(this,require('_process')) -},{"_process":24}],24:[function(require,module,exports){ -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],25:[function(require,module,exports){ -// Underscore.js 1.8.3 -// http://underscorejs.org -// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `exports` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var - push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind, - nativeCreate = Object.create; - - // Naked function reference for surrogate-prototype-swapping. - var Ctor = function(){}; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.8.3'; - - // Internal function that returns an efficient (for current engines) version - // of the passed-in callback, to be repeatedly applied in other Underscore - // functions. - var optimizeCb = function(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - case 2: return function(value, other) { - return func.call(context, value, other); - }; - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; - }; - - // A mostly-internal function to generate callbacks that can be applied - // to each element in a collection, returning the desired result — either - // identity, an arbitrary callback, a property matcher, or a property accessor. - var cb = function(value, context, argCount) { - if (value == null) return _.identity; - if (_.isFunction(value)) return optimizeCb(value, context, argCount); - if (_.isObject(value)) return _.matcher(value); - return _.property(value); - }; - _.iteratee = function(value, context) { - return cb(value, context, Infinity); - }; - - // An internal function for creating assigner functions. - var createAssigner = function(keysFunc, undefinedOnly) { - return function(obj) { - var length = arguments.length; - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; - } - } - return obj; - }; - }; - - // An internal function for creating a new object that inherits from another. - var baseCreate = function(prototype) { - if (!_.isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; - }; - - var property = function(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; - }; - - // Helper for collection methods to determine whether a collection - // should be iterated as an array or as an object - // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength - // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 - var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - var getLength = property('length'); - var isArrayLike = function(collection) { - var length = getLength(collection); - return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; - }; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles raw objects in addition to array-likes. Treats all - // sparse array-likes as if they were dense. - _.each = _.forEach = function(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var keys = _.keys(obj); - for (i = 0, length = keys.length; i < length; i++) { - iteratee(obj[keys[i]], keys[i], obj); - } - } - return obj; - }; - - // Return the results of applying the iteratee to each element. - _.map = _.collect = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Create a reducing function iterating left or right. - function createReduce(dir) { - // Optimized iterator function as using arguments.length - // in the main function will deoptimize the, see #1991. - function iterator(obj, iteratee, memo, keys, index, length) { - for (; index >= 0 && index < length; index += dir) { - var currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - } - - return function(obj, iteratee, memo, context) { - iteratee = optimizeCb(iteratee, context, 4); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - index = dir > 0 ? 0 : length - 1; - // Determine the initial value if none is provided. - if (arguments.length < 3) { - memo = obj[keys ? keys[index] : index]; - index += dir; - } - return iterator(obj, iteratee, memo, keys, index, length); - }; - } - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. - _.reduce = _.foldl = _.inject = createReduce(1); - - // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = createReduce(-1); - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, predicate, context) { - var key; - if (isArrayLike(obj)) { - key = _.findIndex(obj, predicate, context); - } else { - key = _.findKey(obj, predicate, context); - } - if (key !== void 0 && key !== -1) return obj[key]; - }; - - // Return all the elements that pass a truth test. - // Aliased as `select`. - _.filter = _.select = function(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - _.each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(cb(predicate)), context); - }; - - // Determine whether all of the elements match a truth test. - // Aliased as `all`. - _.every = _.all = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; - }; - - // Determine if at least one element in the object matches a truth test. - // Aliased as `any`. - _.some = _.any = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; - }; - - // Determine if the array or object contains a given item (using `===`). - // Aliased as `includes` and `include`. - _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return _.indexOf(obj, item, fromIndex) >= 0; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - var func = isFunc ? method : value[method]; - return func == null ? func : func.apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, _.property(key)); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs) { - return _.filter(obj, _.matcher(attrs)); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.find(obj, _.matcher(attrs)); - }; - - // Return the maximum element (or element-based computation). - _.max = function(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { - result = value; - lastComputed = computed; - } - }); - } - return result; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed < lastComputed || computed === Infinity && result === Infinity) { - result = value; - lastComputed = computed; - } - }); - } - return result; - }; - - // Shuffle a collection, using the modern version of the - // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). - _.shuffle = function(obj) { - var set = isArrayLike(obj) ? obj : _.values(obj); - var length = set.length; - var shuffled = Array(length); - for (var index = 0, rand; index < length; index++) { - rand = _.random(0, index); - if (rand !== index) shuffled[index] = shuffled[rand]; - shuffled[rand] = set[index]; - } - return shuffled; - }; - - // Sample **n** random values from a collection. - // If **n** is not specified, returns a single random element. - // The internal `guard` argument allows it to work with `map`. - _.sample = function(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - return obj[_.random(obj.length - 1)]; - } - return _.shuffle(obj).slice(0, Math.max(0, n)); - }; - - // Sort the object's values by a criterion produced by an iteratee. - _.sortBy = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value: value, - index: index, - criteria: iteratee(value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(behavior) { - return function(obj, iteratee, context) { - var result = {}; - iteratee = cb(iteratee, context); - _.each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = group(function(result, value, key) { - if (_.has(result, key)) result[key].push(value); else result[key] = [value]; - }); - - // Indexes the object's values by a criterion, similar to `groupBy`, but for - // when you know that your index values will be unique. - _.indexBy = group(function(result, value, key) { - result[key] = value; - }); - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = group(function(result, value, key) { - if (_.has(result, key)) result[key]++; else result[key] = 1; - }); - - // Safely create a real, live array from anything iterable. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (isArrayLike(obj)) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : _.keys(obj).length; - }; - - // Split a collection into two arrays: one whose elements all satisfy the given - // predicate, and one whose elements all do not satisfy the predicate. - _.partition = function(obj, predicate, context) { - predicate = cb(predicate, context); - var pass = [], fail = []; - _.each(obj, function(value, key, obj) { - (predicate(value, key, obj) ? pass : fail).push(value); - }); - return [pass, fail]; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - if (n == null || guard) return array[0]; - return _.initial(array, array.length - n); - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. - _.initial = function(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if (n == null || guard) return array[array.length - 1]; - return _.rest(array, Math.max(0, array.length - n)); - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, startIndex) { - var output = [], idx = 0; - for (var i = startIndex || 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { - //flatten current level of array or arguments object - if (!shallow) value = flatten(value, shallow, strict); - var j = 0, len = value.length; - output.length += len; - while (j < len) { - output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; - } - } - return output; - }; - - // Flatten out an array, either recursively (by default), or just one level. - _.flatten = function(array, shallow) { - return flatten(array, shallow, false); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iteratee, context) { - if (!_.isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!_.contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!_.contains(result, value)) { - result.push(value); - } - } - return result; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(flatten(arguments, true, true)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (_.contains(result, item)) continue; - for (var j = 1; j < argsLength; j++) { - if (!_.contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = flatten(arguments, true, true, 1); - return _.filter(array, function(value){ - return !_.contains(rest, value); - }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - return _.unzip(arguments); - }; - - // Complement of _.zip. Unzip accepts an array of arrays and groups - // each array's elements on shared indices - _.unzip = function(array) { - var length = array && _.max(array, getLength).length || 0; - var result = Array(length); - - for (var index = 0; index < length; index++) { - result[index] = _.pluck(array, index); - } - return result; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // Generator function to create the findIndex and findLastIndex functions - function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; - }; - } - - // Returns the first index on an array-like that passes a predicate test - _.findIndex = createPredicateIndexFinder(1); - _.findLastIndex = createPredicateIndexFinder(-1); - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - - // Generator function to create the indexOf and lastIndexOf functions - function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; - } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), _.isNaN); - return idx >= 0 ? idx + i : -1; - } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; - } - return -1; - }; - } - - // Return the position of the first occurrence of an item in an array, - // or -1 if the item is not included in the array. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); - _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - step = step || 1; - - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); - - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Determines whether to execute a function as a constructor - // or a normal function with the provided arguments - var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (_.isObject(result)) return result; - return self; - }; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - var args = slice.call(arguments, 2); - var bound = function() { - return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); - }; - return bound; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. _ acts - // as a placeholder, allowing any combination of arguments to be pre-filled. - _.partial = function(func) { - var boundArgs = slice.call(arguments, 1); - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; - }; - - // Bind a number of an object's methods to that object. Remaining arguments - // are the method names to be bound. Useful for ensuring that all callbacks - // defined on an object belong to it. - _.bindAll = function(obj) { - var i, length = arguments.length, key; - if (length <= 1) throw new Error('bindAll must be passed function names'); - for (i = 1; i < length; i++) { - key = arguments[i]; - obj[key] = _.bind(obj[key], obj); - } - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ - return func.apply(null, args); - }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = _.partial(_.delay, _, 1); - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. Normally, the throttled function will run - // as much as it can, without ever going more than once per `wait` duration; - // but if you'd like to disable the execution on the leading edge, pass - // `{leading: false}`. To disable execution on the trailing edge, ditto. - _.throttle = function(func, wait, options) { - var context, args, result; - var timeout = null; - var previous = 0; - if (!options) options = {}; - var later = function() { - previous = options.leading === false ? 0 : _.now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - return function() { - var now = _.now(); - if (!previous && options.leading === false) previous = now; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, args, context, timestamp, result; - - var later = function() { - var last = _.now() - timestamp; - - if (last < wait && last >= 0) { - timeout = setTimeout(later, wait - last); - } else { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - if (!timeout) context = args = null; - } - } - }; - - return function() { - context = this; - args = arguments; - timestamp = _.now(); - var callNow = immediate && !timeout; - if (!timeout) timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - context = args = null; - } - - return result; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return _.partial(wrapper, func); - }; - - // Returns a negated version of the passed-in predicate. - _.negate = function(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; - }; - - // Returns a function that will only be executed on and after the Nth call. - _.after = function(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Returns a function that will only be executed up to (but not including) the Nth call. - _.before = function(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); - } - if (times <= 1) func = null; - return memo; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = _.partial(_.before, 2); - - // Object Functions - // ---------------- - - // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. - var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); - var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - - function collectNonEnumProps(obj, keys) { - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; - - // Constructor is a special case. - var prop = 'constructor'; - if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); - - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { - keys.push(prop); - } - } - } - - // Retrieve the names of an object's own properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve all the property names of an object. - _.allKeys = function(obj) { - if (!_.isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - }; - - // Returns the results of applying the iteratee to each element of the object - // In contrast to _.map it returns an object - _.mapObject = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = _.keys(obj), - length = keys.length, - results = {}, - currentKey; - for (var index = 0; index < length; index++) { - currentKey = keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [keys[i], obj[keys[i]]]; - } - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - result[obj[keys[i]]] = keys[i]; - } - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = createAssigner(_.allKeys); - - // Assigns a given object with all the own properties in the passed-in object(s) - // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) - _.extendOwn = _.assign = createAssigner(_.keys); - - // Returns the first key on an object that passes a predicate test - _.findKey = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = _.keys(obj), key; - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (predicate(obj[key], key, obj)) return key; - } - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(object, oiteratee, context) { - var result = {}, obj = object, iteratee, keys; - if (obj == null) return result; - if (_.isFunction(oiteratee)) { - keys = _.allKeys(obj); - iteratee = optimizeCb(oiteratee, context); - } else { - keys = flatten(arguments, false, false, 1); - iteratee = function(value, key, obj) { return key in obj; }; - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj, iteratee, context) { - if (_.isFunction(iteratee)) { - iteratee = _.negate(iteratee); - } else { - var keys = _.map(flatten(arguments, false, false, 1), String); - iteratee = function(value, key) { - return !_.contains(keys, key); - }; - } - return _.pick(obj, iteratee, context); - }; - - // Fill in a given object with default properties. - _.defaults = createAssigner(_.allKeys, true); - - // Creates an object that inherits from the given prototype object. - // If additional properties are provided then they will be added to the - // created object. - _.create = function(prototype, props) { - var result = baseCreate(prototype); - if (props) _.extendOwn(result, props); - return result; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Returns whether an object has a given set of `key:value` pairs. - _.isMatch = function(object, attrs) { - var keys = _.keys(attrs), length = keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; - }; - - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - } - - var areArrays = className === '[object Array]'; - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var keys = _.keys(a), key; - length = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (_.keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = keys[length]; - if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; - return _.keys(obj).length === 0; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) === '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) === '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE < 9), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return _.has(obj, 'callee'); - }; - } - - // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, - // IE 11 (#1621), and in Safari 8 (#1929). - if (typeof /./ != 'function' && typeof Int8Array != 'object') { - _.isFunction = function(obj) { - return typeof obj == 'function' || false; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj !== +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iteratees. - _.identity = function(value) { - return value; - }; - - // Predicate-generating functions. Often useful outside of Underscore. - _.constant = function(value) { - return function() { - return value; - }; - }; - - _.noop = function(){}; - - _.property = property; - - // Generates a function for a given object that returns a given property. - _.propertyOf = function(obj) { - return obj == null ? function(){} : function(key) { - return obj[key]; - }; - }; - - // Returns a predicate for checking whether an object has a given set of - // `key:value` pairs. - _.matcher = _.matches = function(attrs) { - attrs = _.extendOwn({}, attrs); - return function(obj) { - return _.isMatch(obj, attrs); - }; - }; - - // Run a function **n** times. - _.times = function(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // A (possibly faster) way to get the current timestamp as an integer. - _.now = Date.now || function() { - return new Date().getTime(); - }; - - // List of HTML entities for escaping. - var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - var unescapeMap = _.invert(escapeMap); - - // Functions for escaping and unescaping strings to/from HTML interpolation. - var createEscaper = function(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped - var source = '(?:' + _.keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; - }; - _.escape = createEscaper(escapeMap); - _.unescape = createEscaper(unescapeMap); - - // If the value of the named `property` is a function then invoke it with the - // `object` as context; otherwise, return it. - _.result = function(object, property, fallback) { - var value = object == null ? void 0 : object[property]; - if (value === void 0) { - value = fallback; - } - return _.isFunction(value) ? value.call(object) : value; - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\u2028|\u2029/g; - - var escapeChar = function(match) { - return '\\' + escapes[match]; - }; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - // NB: `oldSettings` only exists for backwards compatibility. - _.template = function(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escaper, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offest. - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - try { - var render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled source as a convenience for precompilation. - var argument = settings.variable || 'obj'; - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function. Start chaining a wrapped Underscore object. - _.chain = function(obj) { - var instance = _(obj); - instance._chain = true; - return instance; - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(instance, obj) { - return instance._chain ? _(obj).chain() : obj; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - _.each(_.functions(obj), function(name) { - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result(this, func.apply(_, args)); - }; - }); - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return result(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - _.each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result(this, method.apply(this._wrapped, arguments)); - }; - }); - - // Extracts the result from a wrapped and chained object. - _.prototype.value = function() { - return this._wrapped; - }; - - // Provide unwrapping proxy for some methods used in engine operations - // such as arithmetic and JSON stringification. - _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; - - _.prototype.toString = function() { - return '' + this._wrapped; - }; - - // AMD registration happens at the end for compatibility with AMD loaders - // that may not enforce next-turn semantics on modules. Even though general - // practice for AMD registration is to be anonymous, underscore registers - // as a named module because, like jQuery, it is a base library that is - // popular enough to be bundled in a third party lib, but not be part of - // an AMD load request. Those cases could generate an error when an - // anonymous define() is called outside of a loader request. - if (typeof define === 'function' && define.amd) { - define('underscore', [], function() { - return _; - }); - } -}.call(this)); - -},{}],26:[function(require,module,exports){ -arguments[4][19][0].apply(exports,arguments) -},{"dup":19}],27:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],28:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} - -},{}]},{},[7])(7) -}); \ No newline at end of file diff --git a/test/assets/javascripts/workers/search.2a1c317c.min.js b/test/assets/javascripts/workers/search.2a1c317c.min.js deleted file mode 100644 index 59bf8384f59d..000000000000 --- a/test/assets/javascripts/workers/search.2a1c317c.min.js +++ /dev/null @@ -1,48 +0,0 @@ -(()=>{var ge=Object.create;var W=Object.defineProperty,ye=Object.defineProperties,me=Object.getOwnPropertyDescriptor,ve=Object.getOwnPropertyDescriptors,xe=Object.getOwnPropertyNames,G=Object.getOwnPropertySymbols,Se=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,Qe=Object.prototype.propertyIsEnumerable;var J=(t,e,r)=>e in t?W(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,M=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(G)for(var r of G(e))Qe.call(e,r)&&J(t,r,e[r]);return t},Z=(t,e)=>ye(t,ve(e));var K=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var be=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of xe(e))!X.call(t,i)&&i!==r&&W(t,i,{get:()=>e[i],enumerable:!(n=me(e,i))||n.enumerable});return t};var H=(t,e,r)=>(r=t!=null?ge(Se(t)):{},be(e||!t||!t.__esModule?W(r,"default",{value:t,enumerable:!0}):r,t));var z=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var re=K((ee,te)=>{/** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - */(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";/*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - */t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var h=t.utils.clone(r)||{};h.position=[a,c],h.index=s.length,s.push(new t.Token(n.slice(a,o),h))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;/*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - */t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?h+=2:a==u&&(r+=n[c+1]*i[h+1],c+=2,h+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var h=s.str.charAt(0),y=s.str.charAt(1),g;y in s.node.edges?g=s.node.edges[y]:(g=new t.TokenSet,s.node.edges[y]=g),s.str.length==1&&(g.final=!0),i.push({node:g,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};/*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - */t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof ee=="object"?te.exports=r():e.lunr=r()}(this,function(){return t})})()});var q=K((Re,ne)=>{"use strict";/*! - * escape-html - * Copyright(c) 2012-2013 TJ Holowaychuk - * Copyright(c) 2015 Andreas Lubbe - * Copyright(c) 2015 Tiancheng "Timothy" Gu - * MIT Licensed - */var Le=/["'&<>]/;ne.exports=we;function we(t){var e=""+t,r=Le.exec(e);if(!r)return e;var n,i="",s=0,o=0;for(s=r.index;s=0;r--){let n=t[r];typeof n!="object"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));var ie=H(q());function se(t){let e=new Map,r=new Set;for(let n of t){let[i,s]=n.location.split("#"),o=n.location,a=n.title,u=n.tags,c=(0,ie.default)(n.text).replace(/\s+(?=[,.:;!?])/g,"").replace(/\s+/g," ");if(s){let h=e.get(i);r.has(h)?e.set(o,{location:o,title:a,text:c,parent:h}):(h.title=n.title,h.text=c,r.add(h))}else e.set(o,M({location:o,title:a,text:c},u&&{tags:u}))}return e}var oe=H(q());function ae(t,e){let r=new RegExp(t.separator,"img"),n=(i,s,o)=>`${s}${o}`;return i=>{i=i.replace(/[\s*+\-:~^]+/g," ").trim();let s=new RegExp(`(^|${t.separator})(${i.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return o=>(e?(0,oe.default)(o):o).replace(s,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function ue(t){let e=new lunr.Query(["title","text"]);return new lunr.QueryParser(t,e).parse(),e.clauses}function ce(t,e){var i;let r=new Set(t),n={};for(let s=0;s!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){this.options=n,this.documents=se(r),this.highlight=ae(e,!1),lunr.tokenizer.separator=new RegExp(e.separator),this.index=lunr(function(){e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang));let i=Ee(["trimmer","stopWordFilter","stemmer"],n.pipeline);for(let s of e.lang.map(o=>o==="en"?lunr:lunr[o]))for(let o of i)this.pipeline.remove(s[o]),this.searchPipeline.remove(s[o]);this.ref("location"),this.field("title",{boost:1e3}),this.field("text"),this.field("tags",{boost:1e6});for(let s of r)this.add(s)})}search(e){if(e)try{let r=this.highlight(e),n=ue(e).filter(o=>o.presence!==lunr.Query.presence.PROHIBITED),i=this.index.search(`${e}*`).reduce((o,{ref:a,score:u,matchData:c})=>{let h=this.documents.get(a);if(typeof h!="undefined"){let{location:y,title:g,text:b,tags:m,parent:Q}=h,p=ce(n,Object.keys(c.metadata)),d=+!Q+ +Object.values(p).every(w=>w);o.push(Z(M({location:y,title:r(g),text:r(b)},m&&{tags:m.map(r)}),{score:u*(1+d),terms:p}))}return o},[]).sort((o,a)=>a.score-o.score).reduce((o,a)=>{let u=this.documents.get(a.location);if(typeof u!="undefined"){let c="parent"in u?u.parent.location:u.location;o.set(c,[...o.get(c)||[],a])}return o},new Map),s;if(this.options.suggestions){let o=this.index.query(a=>{for(let u of n)a.term(u.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});s=o.length?Object.keys(o[0].matchData.metadata):[]}return M({items:[...i.values()]},typeof s!="undefined"&&{suggestions:s})}catch(r){console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`)}return{items:[]}}};var Y;function ke(t){return z(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=document.querySelector("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Te(t){return z(this,null,function*(){switch(t.type){case 0:return yield ke(t.data.config),Y=new U(t.data),{type:1};case 2:return{type:3,data:Y?Y.search(t.data):{items:[]}};default:throw new TypeError("Invalid message type")}})}self.lunr=le.default;addEventListener("message",t=>z(void 0,null,function*(){postMessage(yield Te(t.data))}));})(); -//# sourceMappingURL=search.2a1c317c.min.js.map - diff --git a/test/assets/javascripts/workers/search.2a1c317c.min.js.map b/test/assets/javascripts/workers/search.2a1c317c.min.js.map deleted file mode 100644 index 06d43304ec09..000000000000 --- a/test/assets/javascripts/workers/search.2a1c317c.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ - "version": 3, - "sources": ["node_modules/lunr/lunr.js", "node_modules/escape-html/index.js", "src/assets/javascripts/integrations/search/worker/main/index.ts", "src/assets/javascripts/polyfills/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/_/index.ts", "src/assets/javascripts/integrations/search/_/index.ts"], - "sourceRoot": "../../../..", - "sourcesContent": ["/**\n * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9\n * Copyright (C) 2020 Oliver Nightingale\n * @license MIT\n */\n\n;(function(){\n\n/**\n * A convenience function for configuring and constructing\n * a new lunr Index.\n *\n * A lunr.Builder instance is created and the pipeline setup\n * with a trimmer, stop word filter and stemmer.\n *\n * This builder object is yielded to the configuration function\n * that is passed as a parameter, allowing the list of fields\n * and other builder parameters to be customised.\n *\n * All documents _must_ be added within the passed config function.\n *\n * @example\n * var idx = lunr(function () {\n * this.field('title')\n * this.field('body')\n * this.ref('id')\n *\n * documents.forEach(function (doc) {\n * this.add(doc)\n * }, this)\n * })\n *\n * @see {@link lunr.Builder}\n * @see {@link lunr.Pipeline}\n * @see {@link lunr.trimmer}\n * @see {@link lunr.stopWordFilter}\n * @see {@link lunr.stemmer}\n * @namespace {function} lunr\n */\nvar lunr = function (config) {\n var builder = new lunr.Builder\n\n builder.pipeline.add(\n lunr.trimmer,\n lunr.stopWordFilter,\n lunr.stemmer\n )\n\n builder.searchPipeline.add(\n lunr.stemmer\n )\n\n config.call(builder, builder)\n return builder.build()\n}\n\nlunr.version = \"2.3.9\"\n/*!\n * lunr.utils\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A namespace containing utils for the rest of the lunr library\n * @namespace lunr.utils\n */\nlunr.utils = {}\n\n/**\n * Print a warning message to the console.\n *\n * @param {String} message The message to be printed.\n * @memberOf lunr.utils\n * @function\n */\nlunr.utils.warn = (function (global) {\n /* eslint-disable no-console */\n return function (message) {\n if (global.console && console.warn) {\n console.warn(message)\n }\n }\n /* eslint-enable no-console */\n})(this)\n\n/**\n * Convert an object to a string.\n *\n * In the case of `null` and `undefined` the function returns\n * the empty string, in all other cases the result of calling\n * `toString` on the passed object is returned.\n *\n * @param {Any} obj The object to convert to a string.\n * @return {String} string representation of the passed object.\n * @memberOf lunr.utils\n */\nlunr.utils.asString = function (obj) {\n if (obj === void 0 || obj === null) {\n return \"\"\n } else {\n return obj.toString()\n }\n}\n\n/**\n * Clones an object.\n *\n * Will create a copy of an existing object such that any mutations\n * on the copy cannot affect the original.\n *\n * Only shallow objects are supported, passing a nested object to this\n * function will cause a TypeError.\n *\n * Objects with primitives, and arrays of primitives are supported.\n *\n * @param {Object} obj The object to clone.\n * @return {Object} a clone of the passed object.\n * @throws {TypeError} when a nested object is passed.\n * @memberOf Utils\n */\nlunr.utils.clone = function (obj) {\n if (obj === null || obj === undefined) {\n return obj\n }\n\n var clone = Object.create(null),\n keys = Object.keys(obj)\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i],\n val = obj[key]\n\n if (Array.isArray(val)) {\n clone[key] = val.slice()\n continue\n }\n\n if (typeof val === 'string' ||\n typeof val === 'number' ||\n typeof val === 'boolean') {\n clone[key] = val\n continue\n }\n\n throw new TypeError(\"clone is not deep and does not support nested objects\")\n }\n\n return clone\n}\nlunr.FieldRef = function (docRef, fieldName, stringValue) {\n this.docRef = docRef\n this.fieldName = fieldName\n this._stringValue = stringValue\n}\n\nlunr.FieldRef.joiner = \"/\"\n\nlunr.FieldRef.fromString = function (s) {\n var n = s.indexOf(lunr.FieldRef.joiner)\n\n if (n === -1) {\n throw \"malformed field ref string\"\n }\n\n var fieldRef = s.slice(0, n),\n docRef = s.slice(n + 1)\n\n return new lunr.FieldRef (docRef, fieldRef, s)\n}\n\nlunr.FieldRef.prototype.toString = function () {\n if (this._stringValue == undefined) {\n this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef\n }\n\n return this._stringValue\n}\n/*!\n * lunr.Set\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A lunr set.\n *\n * @constructor\n */\nlunr.Set = function (elements) {\n this.elements = Object.create(null)\n\n if (elements) {\n this.length = elements.length\n\n for (var i = 0; i < this.length; i++) {\n this.elements[elements[i]] = true\n }\n } else {\n this.length = 0\n }\n}\n\n/**\n * A complete set that contains all elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.complete = {\n intersect: function (other) {\n return other\n },\n\n union: function () {\n return this\n },\n\n contains: function () {\n return true\n }\n}\n\n/**\n * An empty set that contains no elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.empty = {\n intersect: function () {\n return this\n },\n\n union: function (other) {\n return other\n },\n\n contains: function () {\n return false\n }\n}\n\n/**\n * Returns true if this set contains the specified object.\n *\n * @param {object} object - Object whose presence in this set is to be tested.\n * @returns {boolean} - True if this set contains the specified object.\n */\nlunr.Set.prototype.contains = function (object) {\n return !!this.elements[object]\n}\n\n/**\n * Returns a new set containing only the elements that are present in both\n * this set and the specified set.\n *\n * @param {lunr.Set} other - set to intersect with this set.\n * @returns {lunr.Set} a new set that is the intersection of this and the specified set.\n */\n\nlunr.Set.prototype.intersect = function (other) {\n var a, b, elements, intersection = []\n\n if (other === lunr.Set.complete) {\n return this\n }\n\n if (other === lunr.Set.empty) {\n return other\n }\n\n if (this.length < other.length) {\n a = this\n b = other\n } else {\n a = other\n b = this\n }\n\n elements = Object.keys(a.elements)\n\n for (var i = 0; i < elements.length; i++) {\n var element = elements[i]\n if (element in b.elements) {\n intersection.push(element)\n }\n }\n\n return new lunr.Set (intersection)\n}\n\n/**\n * Returns a new set combining the elements of this and the specified set.\n *\n * @param {lunr.Set} other - set to union with this set.\n * @return {lunr.Set} a new set that is the union of this and the specified set.\n */\n\nlunr.Set.prototype.union = function (other) {\n if (other === lunr.Set.complete) {\n return lunr.Set.complete\n }\n\n if (other === lunr.Set.empty) {\n return this\n }\n\n return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements)))\n}\n/**\n * A function to calculate the inverse document frequency for\n * a posting. This is shared between the builder and the index\n *\n * @private\n * @param {object} posting - The posting for a given term\n * @param {number} documentCount - The total number of documents.\n */\nlunr.idf = function (posting, documentCount) {\n var documentsWithTerm = 0\n\n for (var fieldName in posting) {\n if (fieldName == '_index') continue // Ignore the term index, its not a field\n documentsWithTerm += Object.keys(posting[fieldName]).length\n }\n\n var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5)\n\n return Math.log(1 + Math.abs(x))\n}\n\n/**\n * A token wraps a string representation of a token\n * as it is passed through the text processing pipeline.\n *\n * @constructor\n * @param {string} [str=''] - The string token being wrapped.\n * @param {object} [metadata={}] - Metadata associated with this token.\n */\nlunr.Token = function (str, metadata) {\n this.str = str || \"\"\n this.metadata = metadata || {}\n}\n\n/**\n * Returns the token string that is being wrapped by this object.\n *\n * @returns {string}\n */\nlunr.Token.prototype.toString = function () {\n return this.str\n}\n\n/**\n * A token update function is used when updating or optionally\n * when cloning a token.\n *\n * @callback lunr.Token~updateFunction\n * @param {string} str - The string representation of the token.\n * @param {Object} metadata - All metadata associated with this token.\n */\n\n/**\n * Applies the given function to the wrapped string token.\n *\n * @example\n * token.update(function (str, metadata) {\n * return str.toUpperCase()\n * })\n *\n * @param {lunr.Token~updateFunction} fn - A function to apply to the token string.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.update = function (fn) {\n this.str = fn(this.str, this.metadata)\n return this\n}\n\n/**\n * Creates a clone of this token. Optionally a function can be\n * applied to the cloned token.\n *\n * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.clone = function (fn) {\n fn = fn || function (s) { return s }\n return new lunr.Token (fn(this.str, this.metadata), this.metadata)\n}\n/*!\n * lunr.tokenizer\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A function for splitting a string into tokens ready to be inserted into\n * the search index. Uses `lunr.tokenizer.separator` to split strings, change\n * the value of this property to change how strings are split into tokens.\n *\n * This tokenizer will convert its parameter to a string by calling `toString` and\n * then will split this string on the character in `lunr.tokenizer.separator`.\n * Arrays will have their elements converted to strings and wrapped in a lunr.Token.\n *\n * Optional metadata can be passed to the tokenizer, this metadata will be cloned and\n * added as metadata to every token that is created from the object to be tokenized.\n *\n * @static\n * @param {?(string|object|object[])} obj - The object to convert into tokens\n * @param {?object} metadata - Optional metadata to associate with every token\n * @returns {lunr.Token[]}\n * @see {@link lunr.Pipeline}\n */\nlunr.tokenizer = function (obj, metadata) {\n if (obj == null || obj == undefined) {\n return []\n }\n\n if (Array.isArray(obj)) {\n return obj.map(function (t) {\n return new lunr.Token(\n lunr.utils.asString(t).toLowerCase(),\n lunr.utils.clone(metadata)\n )\n })\n }\n\n var str = obj.toString().toLowerCase(),\n len = str.length,\n tokens = []\n\n for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {\n var char = str.charAt(sliceEnd),\n sliceLength = sliceEnd - sliceStart\n\n if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) {\n\n if (sliceLength > 0) {\n var tokenMetadata = lunr.utils.clone(metadata) || {}\n tokenMetadata[\"position\"] = [sliceStart, sliceLength]\n tokenMetadata[\"index\"] = tokens.length\n\n tokens.push(\n new lunr.Token (\n str.slice(sliceStart, sliceEnd),\n tokenMetadata\n )\n )\n }\n\n sliceStart = sliceEnd + 1\n }\n\n }\n\n return tokens\n}\n\n/**\n * The separator used to split a string into tokens. Override this property to change the behaviour of\n * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.\n *\n * @static\n * @see lunr.tokenizer\n */\nlunr.tokenizer.separator = /[\\s\\-]+/\n/*!\n * lunr.Pipeline\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.Pipelines maintain an ordered list of functions to be applied to all\n * tokens in documents entering the search index and queries being ran against\n * the index.\n *\n * An instance of lunr.Index created with the lunr shortcut will contain a\n * pipeline with a stop word filter and an English language stemmer. Extra\n * functions can be added before or after either of these functions or these\n * default functions can be removed.\n *\n * When run the pipeline will call each function in turn, passing a token, the\n * index of that token in the original list of all tokens and finally a list of\n * all the original tokens.\n *\n * The output of functions in the pipeline will be passed to the next function\n * in the pipeline. To exclude a token from entering the index the function\n * should return undefined, the rest of the pipeline will not be called with\n * this token.\n *\n * For serialisation of pipelines to work, all functions used in an instance of\n * a pipeline should be registered with lunr.Pipeline. Registered functions can\n * then be loaded. If trying to load a serialised pipeline that uses functions\n * that are not registered an error will be thrown.\n *\n * If not planning on serialising the pipeline then registering pipeline functions\n * is not necessary.\n *\n * @constructor\n */\nlunr.Pipeline = function () {\n this._stack = []\n}\n\nlunr.Pipeline.registeredFunctions = Object.create(null)\n\n/**\n * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token\n * string as well as all known metadata. A pipeline function can mutate the token string\n * or mutate (or add) metadata for a given token.\n *\n * A pipeline function can indicate that the passed token should be discarded by returning\n * null, undefined or an empty string. This token will not be passed to any downstream pipeline\n * functions and will not be added to the index.\n *\n * Multiple tokens can be returned by returning an array of tokens. Each token will be passed\n * to any downstream pipeline functions and all will returned tokens will be added to the index.\n *\n * Any number of pipeline functions may be chained together using a lunr.Pipeline.\n *\n * @interface lunr.PipelineFunction\n * @param {lunr.Token} token - A token from the document being processed.\n * @param {number} i - The index of this token in the complete list of tokens for this document/field.\n * @param {lunr.Token[]} tokens - All tokens for this document/field.\n * @returns {(?lunr.Token|lunr.Token[])}\n */\n\n/**\n * Register a function with the pipeline.\n *\n * Functions that are used in the pipeline should be registered if the pipeline\n * needs to be serialised, or a serialised pipeline needs to be loaded.\n *\n * Registering a function does not add it to a pipeline, functions must still be\n * added to instances of the pipeline for them to be used when running a pipeline.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @param {String} label - The label to register this function with\n */\nlunr.Pipeline.registerFunction = function (fn, label) {\n if (label in this.registeredFunctions) {\n lunr.utils.warn('Overwriting existing registered function: ' + label)\n }\n\n fn.label = label\n lunr.Pipeline.registeredFunctions[fn.label] = fn\n}\n\n/**\n * Warns if the function is not registered as a Pipeline function.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @private\n */\nlunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {\n var isRegistered = fn.label && (fn.label in this.registeredFunctions)\n\n if (!isRegistered) {\n lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\\n', fn)\n }\n}\n\n/**\n * Loads a previously serialised pipeline.\n *\n * All functions to be loaded must already be registered with lunr.Pipeline.\n * If any function from the serialised data has not been registered then an\n * error will be thrown.\n *\n * @param {Object} serialised - The serialised pipeline to load.\n * @returns {lunr.Pipeline}\n */\nlunr.Pipeline.load = function (serialised) {\n var pipeline = new lunr.Pipeline\n\n serialised.forEach(function (fnName) {\n var fn = lunr.Pipeline.registeredFunctions[fnName]\n\n if (fn) {\n pipeline.add(fn)\n } else {\n throw new Error('Cannot load unregistered function: ' + fnName)\n }\n })\n\n return pipeline\n}\n\n/**\n * Adds new functions to the end of the pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline.\n */\nlunr.Pipeline.prototype.add = function () {\n var fns = Array.prototype.slice.call(arguments)\n\n fns.forEach(function (fn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n this._stack.push(fn)\n }, this)\n}\n\n/**\n * Adds a single function after a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.after = function (existingFn, newFn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n var pos = this._stack.indexOf(existingFn)\n if (pos == -1) {\n throw new Error('Cannot find existingFn')\n }\n\n pos = pos + 1\n this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Adds a single function before a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.before = function (existingFn, newFn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n var pos = this._stack.indexOf(existingFn)\n if (pos == -1) {\n throw new Error('Cannot find existingFn')\n }\n\n this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Removes a function from the pipeline.\n *\n * @param {lunr.PipelineFunction} fn The function to remove from the pipeline.\n */\nlunr.Pipeline.prototype.remove = function (fn) {\n var pos = this._stack.indexOf(fn)\n if (pos == -1) {\n return\n }\n\n this._stack.splice(pos, 1)\n}\n\n/**\n * Runs the current list of functions that make up the pipeline against the\n * passed tokens.\n *\n * @param {Array} tokens The tokens to run through the pipeline.\n * @returns {Array}\n */\nlunr.Pipeline.prototype.run = function (tokens) {\n var stackLength = this._stack.length\n\n for (var i = 0; i < stackLength; i++) {\n var fn = this._stack[i]\n var memo = []\n\n for (var j = 0; j < tokens.length; j++) {\n var result = fn(tokens[j], j, tokens)\n\n if (result === null || result === void 0 || result === '') continue\n\n if (Array.isArray(result)) {\n for (var k = 0; k < result.length; k++) {\n memo.push(result[k])\n }\n } else {\n memo.push(result)\n }\n }\n\n tokens = memo\n }\n\n return tokens\n}\n\n/**\n * Convenience method for passing a string through a pipeline and getting\n * strings out. This method takes care of wrapping the passed string in a\n * token and mapping the resulting tokens back to strings.\n *\n * @param {string} str - The string to pass through the pipeline.\n * @param {?object} metadata - Optional metadata to associate with the token\n * passed to the pipeline.\n * @returns {string[]}\n */\nlunr.Pipeline.prototype.runString = function (str, metadata) {\n var token = new lunr.Token (str, metadata)\n\n return this.run([token]).map(function (t) {\n return t.toString()\n })\n}\n\n/**\n * Resets the pipeline by removing any existing processors.\n *\n */\nlunr.Pipeline.prototype.reset = function () {\n this._stack = []\n}\n\n/**\n * Returns a representation of the pipeline ready for serialisation.\n *\n * Logs a warning if the function has not been registered.\n *\n * @returns {Array}\n */\nlunr.Pipeline.prototype.toJSON = function () {\n return this._stack.map(function (fn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n\n return fn.label\n })\n}\n/*!\n * lunr.Vector\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A vector is used to construct the vector space of documents and queries. These\n * vectors support operations to determine the similarity between two documents or\n * a document and a query.\n *\n * Normally no parameters are required for initializing a vector, but in the case of\n * loading a previously dumped vector the raw elements can be provided to the constructor.\n *\n * For performance reasons vectors are implemented with a flat array, where an elements\n * index is immediately followed by its value. E.g. [index, value, index, value]. This\n * allows the underlying array to be as sparse as possible and still offer decent\n * performance when being used for vector calculations.\n *\n * @constructor\n * @param {Number[]} [elements] - The flat list of element index and element value pairs.\n */\nlunr.Vector = function (elements) {\n this._magnitude = 0\n this.elements = elements || []\n}\n\n\n/**\n * Calculates the position within the vector to insert a given index.\n *\n * This is used internally by insert and upsert. If there are duplicate indexes then\n * the position is returned as if the value for that index were to be updated, but it\n * is the callers responsibility to check whether there is a duplicate at that index\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @returns {Number}\n */\nlunr.Vector.prototype.positionForIndex = function (index) {\n // For an empty vector the tuple can be inserted at the beginning\n if (this.elements.length == 0) {\n return 0\n }\n\n var start = 0,\n end = this.elements.length / 2,\n sliceLength = end - start,\n pivotPoint = Math.floor(sliceLength / 2),\n pivotIndex = this.elements[pivotPoint * 2]\n\n while (sliceLength > 1) {\n if (pivotIndex < index) {\n start = pivotPoint\n }\n\n if (pivotIndex > index) {\n end = pivotPoint\n }\n\n if (pivotIndex == index) {\n break\n }\n\n sliceLength = end - start\n pivotPoint = start + Math.floor(sliceLength / 2)\n pivotIndex = this.elements[pivotPoint * 2]\n }\n\n if (pivotIndex == index) {\n return pivotPoint * 2\n }\n\n if (pivotIndex > index) {\n return pivotPoint * 2\n }\n\n if (pivotIndex < index) {\n return (pivotPoint + 1) * 2\n }\n}\n\n/**\n * Inserts an element at an index within the vector.\n *\n * Does not allow duplicates, will throw an error if there is already an entry\n * for this index.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n */\nlunr.Vector.prototype.insert = function (insertIdx, val) {\n this.upsert(insertIdx, val, function () {\n throw \"duplicate index\"\n })\n}\n\n/**\n * Inserts or updates an existing index within the vector.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n * @param {function} fn - A function that is called for updates, the existing value and the\n * requested value are passed as arguments\n */\nlunr.Vector.prototype.upsert = function (insertIdx, val, fn) {\n this._magnitude = 0\n var position = this.positionForIndex(insertIdx)\n\n if (this.elements[position] == insertIdx) {\n this.elements[position + 1] = fn(this.elements[position + 1], val)\n } else {\n this.elements.splice(position, 0, insertIdx, val)\n }\n}\n\n/**\n * Calculates the magnitude of this vector.\n *\n * @returns {Number}\n */\nlunr.Vector.prototype.magnitude = function () {\n if (this._magnitude) return this._magnitude\n\n var sumOfSquares = 0,\n elementsLength = this.elements.length\n\n for (var i = 1; i < elementsLength; i += 2) {\n var val = this.elements[i]\n sumOfSquares += val * val\n }\n\n return this._magnitude = Math.sqrt(sumOfSquares)\n}\n\n/**\n * Calculates the dot product of this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The vector to compute the dot product with.\n * @returns {Number}\n */\nlunr.Vector.prototype.dot = function (otherVector) {\n var dotProduct = 0,\n a = this.elements, b = otherVector.elements,\n aLen = a.length, bLen = b.length,\n aVal = 0, bVal = 0,\n i = 0, j = 0\n\n while (i < aLen && j < bLen) {\n aVal = a[i], bVal = b[j]\n if (aVal < bVal) {\n i += 2\n } else if (aVal > bVal) {\n j += 2\n } else if (aVal == bVal) {\n dotProduct += a[i + 1] * b[j + 1]\n i += 2\n j += 2\n }\n }\n\n return dotProduct\n}\n\n/**\n * Calculates the similarity between this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The other vector to calculate the\n * similarity with.\n * @returns {Number}\n */\nlunr.Vector.prototype.similarity = function (otherVector) {\n return this.dot(otherVector) / this.magnitude() || 0\n}\n\n/**\n * Converts the vector to an array of the elements within the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toArray = function () {\n var output = new Array (this.elements.length / 2)\n\n for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) {\n output[j] = this.elements[i]\n }\n\n return output\n}\n\n/**\n * A JSON serializable representation of the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toJSON = function () {\n return this.elements\n}\n/* eslint-disable */\n/*!\n * lunr.stemmer\n * Copyright (C) 2020 Oliver Nightingale\n * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n */\n\n/**\n * lunr.stemmer is an english language stemmer, this is a JavaScript\n * implementation of the PorterStemmer taken from http://tartarus.org/~martin\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token - The string to stem\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n * @function\n */\nlunr.stemmer = (function(){\n var step2list = {\n \"ational\" : \"ate\",\n \"tional\" : \"tion\",\n \"enci\" : \"ence\",\n \"anci\" : \"ance\",\n \"izer\" : \"ize\",\n \"bli\" : \"ble\",\n \"alli\" : \"al\",\n \"entli\" : \"ent\",\n \"eli\" : \"e\",\n \"ousli\" : \"ous\",\n \"ization\" : \"ize\",\n \"ation\" : \"ate\",\n \"ator\" : \"ate\",\n \"alism\" : \"al\",\n \"iveness\" : \"ive\",\n \"fulness\" : \"ful\",\n \"ousness\" : \"ous\",\n \"aliti\" : \"al\",\n \"iviti\" : \"ive\",\n \"biliti\" : \"ble\",\n \"logi\" : \"log\"\n },\n\n step3list = {\n \"icate\" : \"ic\",\n \"ative\" : \"\",\n \"alize\" : \"al\",\n \"iciti\" : \"ic\",\n \"ical\" : \"ic\",\n \"ful\" : \"\",\n \"ness\" : \"\"\n },\n\n c = \"[^aeiou]\", // consonant\n v = \"[aeiouy]\", // vowel\n C = c + \"[^aeiouy]*\", // consonant sequence\n V = v + \"[aeiou]*\", // vowel sequence\n\n mgr0 = \"^(\" + C + \")?\" + V + C, // [C]VC... is m>0\n meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\", // [C]VC[V] is m=1\n mgr1 = \"^(\" + C + \")?\" + V + C + V + C, // [C]VCVC... is m>1\n s_v = \"^(\" + C + \")?\" + v; // vowel in stem\n\n var re_mgr0 = new RegExp(mgr0);\n var re_mgr1 = new RegExp(mgr1);\n var re_meq1 = new RegExp(meq1);\n var re_s_v = new RegExp(s_v);\n\n var re_1a = /^(.+?)(ss|i)es$/;\n var re2_1a = /^(.+?)([^s])s$/;\n var re_1b = /^(.+?)eed$/;\n var re2_1b = /^(.+?)(ed|ing)$/;\n var re_1b_2 = /.$/;\n var re2_1b_2 = /(at|bl|iz)$/;\n var re3_1b_2 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n var re4_1b_2 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var re_1c = /^(.+?[^aeiou])y$/;\n var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n\n var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n\n var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n var re2_4 = /^(.+?)(s|t)(ion)$/;\n\n var re_5 = /^(.+?)e$/;\n var re_5_1 = /ll$/;\n var re3_5 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var porterStemmer = function porterStemmer(w) {\n var stem,\n suffix,\n firstch,\n re,\n re2,\n re3,\n re4;\n\n if (w.length < 3) { return w; }\n\n firstch = w.substr(0,1);\n if (firstch == \"y\") {\n w = firstch.toUpperCase() + w.substr(1);\n }\n\n // Step 1a\n re = re_1a\n re2 = re2_1a;\n\n if (re.test(w)) { w = w.replace(re,\"$1$2\"); }\n else if (re2.test(w)) { w = w.replace(re2,\"$1$2\"); }\n\n // Step 1b\n re = re_1b;\n re2 = re2_1b;\n if (re.test(w)) {\n var fp = re.exec(w);\n re = re_mgr0;\n if (re.test(fp[1])) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1];\n re2 = re_s_v;\n if (re2.test(stem)) {\n w = stem;\n re2 = re2_1b_2;\n re3 = re3_1b_2;\n re4 = re4_1b_2;\n if (re2.test(w)) { w = w + \"e\"; }\n else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,\"\"); }\n else if (re4.test(w)) { w = w + \"e\"; }\n }\n }\n\n // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)\n re = re_1c;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n w = stem + \"i\";\n }\n\n // Step 2\n re = re_2;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step2list[suffix];\n }\n }\n\n // Step 3\n re = re_3;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step3list[suffix];\n }\n }\n\n // Step 4\n re = re_4;\n re2 = re2_4;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n if (re.test(stem)) {\n w = stem;\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1] + fp[2];\n re2 = re_mgr1;\n if (re2.test(stem)) {\n w = stem;\n }\n }\n\n // Step 5\n re = re_5;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n re2 = re_meq1;\n re3 = re3_5;\n if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {\n w = stem;\n }\n }\n\n re = re_5_1;\n re2 = re_mgr1;\n if (re.test(w) && re2.test(w)) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n\n // and turn initial Y back to y\n\n if (firstch == \"y\") {\n w = firstch.toLowerCase() + w.substr(1);\n }\n\n return w;\n };\n\n return function (token) {\n return token.update(porterStemmer);\n }\n})();\n\nlunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')\n/*!\n * lunr.stopWordFilter\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.generateStopWordFilter builds a stopWordFilter function from the provided\n * list of stop words.\n *\n * The built in lunr.stopWordFilter is built using this generator and can be used\n * to generate custom stopWordFilters for applications or non English languages.\n *\n * @function\n * @param {Array} token The token to pass through the filter\n * @returns {lunr.PipelineFunction}\n * @see lunr.Pipeline\n * @see lunr.stopWordFilter\n */\nlunr.generateStopWordFilter = function (stopWords) {\n var words = stopWords.reduce(function (memo, stopWord) {\n memo[stopWord] = stopWord\n return memo\n }, {})\n\n return function (token) {\n if (token && words[token.toString()] !== token.toString()) return token\n }\n}\n\n/**\n * lunr.stopWordFilter is an English language stop word list filter, any words\n * contained in the list will not be passed through the filter.\n *\n * This is intended to be used in the Pipeline. If the token does not pass the\n * filter then undefined will be returned.\n *\n * @function\n * @implements {lunr.PipelineFunction}\n * @params {lunr.Token} token - A token to check for being a stop word.\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n */\nlunr.stopWordFilter = lunr.generateStopWordFilter([\n 'a',\n 'able',\n 'about',\n 'across',\n 'after',\n 'all',\n 'almost',\n 'also',\n 'am',\n 'among',\n 'an',\n 'and',\n 'any',\n 'are',\n 'as',\n 'at',\n 'be',\n 'because',\n 'been',\n 'but',\n 'by',\n 'can',\n 'cannot',\n 'could',\n 'dear',\n 'did',\n 'do',\n 'does',\n 'either',\n 'else',\n 'ever',\n 'every',\n 'for',\n 'from',\n 'get',\n 'got',\n 'had',\n 'has',\n 'have',\n 'he',\n 'her',\n 'hers',\n 'him',\n 'his',\n 'how',\n 'however',\n 'i',\n 'if',\n 'in',\n 'into',\n 'is',\n 'it',\n 'its',\n 'just',\n 'least',\n 'let',\n 'like',\n 'likely',\n 'may',\n 'me',\n 'might',\n 'most',\n 'must',\n 'my',\n 'neither',\n 'no',\n 'nor',\n 'not',\n 'of',\n 'off',\n 'often',\n 'on',\n 'only',\n 'or',\n 'other',\n 'our',\n 'own',\n 'rather',\n 'said',\n 'say',\n 'says',\n 'she',\n 'should',\n 'since',\n 'so',\n 'some',\n 'than',\n 'that',\n 'the',\n 'their',\n 'them',\n 'then',\n 'there',\n 'these',\n 'they',\n 'this',\n 'tis',\n 'to',\n 'too',\n 'twas',\n 'us',\n 'wants',\n 'was',\n 'we',\n 'were',\n 'what',\n 'when',\n 'where',\n 'which',\n 'while',\n 'who',\n 'whom',\n 'why',\n 'will',\n 'with',\n 'would',\n 'yet',\n 'you',\n 'your'\n])\n\nlunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')\n/*!\n * lunr.trimmer\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.trimmer is a pipeline function for trimming non word\n * characters from the beginning and end of tokens before they\n * enter the index.\n *\n * This implementation may not work correctly for non latin\n * characters and should either be removed or adapted for use\n * with languages with non-latin characters.\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token The token to pass through the filter\n * @returns {lunr.Token}\n * @see lunr.Pipeline\n */\nlunr.trimmer = function (token) {\n return token.update(function (s) {\n return s.replace(/^\\W+/, '').replace(/\\W+$/, '')\n })\n}\n\nlunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')\n/*!\n * lunr.TokenSet\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A token set is used to store the unique list of all tokens\n * within an index. Token sets are also used to represent an\n * incoming query to the index, this query token set and index\n * token set are then intersected to find which tokens to look\n * up in the inverted index.\n *\n * A token set can hold multiple tokens, as in the case of the\n * index token set, or it can hold a single token as in the\n * case of a simple query token set.\n *\n * Additionally token sets are used to perform wildcard matching.\n * Leading, contained and trailing wildcards are supported, and\n * from this edit distance matching can also be provided.\n *\n * Token sets are implemented as a minimal finite state automata,\n * where both common prefixes and suffixes are shared between tokens.\n * This helps to reduce the space used for storing the token set.\n *\n * @constructor\n */\nlunr.TokenSet = function () {\n this.final = false\n this.edges = {}\n this.id = lunr.TokenSet._nextId\n lunr.TokenSet._nextId += 1\n}\n\n/**\n * Keeps track of the next, auto increment, identifier to assign\n * to a new tokenSet.\n *\n * TokenSets require a unique identifier to be correctly minimised.\n *\n * @private\n */\nlunr.TokenSet._nextId = 1\n\n/**\n * Creates a TokenSet instance from the given sorted array of words.\n *\n * @param {String[]} arr - A sorted array of strings to create the set from.\n * @returns {lunr.TokenSet}\n * @throws Will throw an error if the input array is not sorted.\n */\nlunr.TokenSet.fromArray = function (arr) {\n var builder = new lunr.TokenSet.Builder\n\n for (var i = 0, len = arr.length; i < len; i++) {\n builder.insert(arr[i])\n }\n\n builder.finish()\n return builder.root\n}\n\n/**\n * Creates a token set from a query clause.\n *\n * @private\n * @param {Object} clause - A single clause from lunr.Query.\n * @param {string} clause.term - The query clause term.\n * @param {number} [clause.editDistance] - The optional edit distance for the term.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromClause = function (clause) {\n if ('editDistance' in clause) {\n return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance)\n } else {\n return lunr.TokenSet.fromString(clause.term)\n }\n}\n\n/**\n * Creates a token set representing a single string with a specified\n * edit distance.\n *\n * Insertions, deletions, substitutions and transpositions are each\n * treated as an edit distance of 1.\n *\n * Increasing the allowed edit distance will have a dramatic impact\n * on the performance of both creating and intersecting these TokenSets.\n * It is advised to keep the edit distance less than 3.\n *\n * @param {string} str - The string to create the token set from.\n * @param {number} editDistance - The allowed edit distance to match.\n * @returns {lunr.Vector}\n */\nlunr.TokenSet.fromFuzzyString = function (str, editDistance) {\n var root = new lunr.TokenSet\n\n var stack = [{\n node: root,\n editsRemaining: editDistance,\n str: str\n }]\n\n while (stack.length) {\n var frame = stack.pop()\n\n // no edit\n if (frame.str.length > 0) {\n var char = frame.str.charAt(0),\n noEditNode\n\n if (char in frame.node.edges) {\n noEditNode = frame.node.edges[char]\n } else {\n noEditNode = new lunr.TokenSet\n frame.node.edges[char] = noEditNode\n }\n\n if (frame.str.length == 1) {\n noEditNode.final = true\n }\n\n stack.push({\n node: noEditNode,\n editsRemaining: frame.editsRemaining,\n str: frame.str.slice(1)\n })\n }\n\n if (frame.editsRemaining == 0) {\n continue\n }\n\n // insertion\n if (\"*\" in frame.node.edges) {\n var insertionNode = frame.node.edges[\"*\"]\n } else {\n var insertionNode = new lunr.TokenSet\n frame.node.edges[\"*\"] = insertionNode\n }\n\n if (frame.str.length == 0) {\n insertionNode.final = true\n }\n\n stack.push({\n node: insertionNode,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str\n })\n\n // deletion\n // can only do a deletion if we have enough edits remaining\n // and if there are characters left to delete in the string\n if (frame.str.length > 1) {\n stack.push({\n node: frame.node,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str.slice(1)\n })\n }\n\n // deletion\n // just removing the last character from the str\n if (frame.str.length == 1) {\n frame.node.final = true\n }\n\n // substitution\n // can only do a substitution if we have enough edits remaining\n // and if there are characters left to substitute\n if (frame.str.length >= 1) {\n if (\"*\" in frame.node.edges) {\n var substitutionNode = frame.node.edges[\"*\"]\n } else {\n var substitutionNode = new lunr.TokenSet\n frame.node.edges[\"*\"] = substitutionNode\n }\n\n if (frame.str.length == 1) {\n substitutionNode.final = true\n }\n\n stack.push({\n node: substitutionNode,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str.slice(1)\n })\n }\n\n // transposition\n // can only do a transposition if there are edits remaining\n // and there are enough characters to transpose\n if (frame.str.length > 1) {\n var charA = frame.str.charAt(0),\n charB = frame.str.charAt(1),\n transposeNode\n\n if (charB in frame.node.edges) {\n transposeNode = frame.node.edges[charB]\n } else {\n transposeNode = new lunr.TokenSet\n frame.node.edges[charB] = transposeNode\n }\n\n if (frame.str.length == 1) {\n transposeNode.final = true\n }\n\n stack.push({\n node: transposeNode,\n editsRemaining: frame.editsRemaining - 1,\n str: charA + frame.str.slice(2)\n })\n }\n }\n\n return root\n}\n\n/**\n * Creates a TokenSet from a string.\n *\n * The string may contain one or more wildcard characters (*)\n * that will allow wildcard matching when intersecting with\n * another TokenSet.\n *\n * @param {string} str - The string to create a TokenSet from.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromString = function (str) {\n var node = new lunr.TokenSet,\n root = node\n\n /*\n * Iterates through all characters within the passed string\n * appending a node for each character.\n *\n * When a wildcard character is found then a self\n * referencing edge is introduced to continually match\n * any number of any characters.\n */\n for (var i = 0, len = str.length; i < len; i++) {\n var char = str[i],\n final = (i == len - 1)\n\n if (char == \"*\") {\n node.edges[char] = node\n node.final = final\n\n } else {\n var next = new lunr.TokenSet\n next.final = final\n\n node.edges[char] = next\n node = next\n }\n }\n\n return root\n}\n\n/**\n * Converts this TokenSet into an array of strings\n * contained within the TokenSet.\n *\n * This is not intended to be used on a TokenSet that\n * contains wildcards, in these cases the results are\n * undefined and are likely to cause an infinite loop.\n *\n * @returns {string[]}\n */\nlunr.TokenSet.prototype.toArray = function () {\n var words = []\n\n var stack = [{\n prefix: \"\",\n node: this\n }]\n\n while (stack.length) {\n var frame = stack.pop(),\n edges = Object.keys(frame.node.edges),\n len = edges.length\n\n if (frame.node.final) {\n /* In Safari, at this point the prefix is sometimes corrupted, see:\n * https://github.com/olivernn/lunr.js/issues/279 Calling any\n * String.prototype method forces Safari to \"cast\" this string to what\n * it's supposed to be, fixing the bug. */\n frame.prefix.charAt(0)\n words.push(frame.prefix)\n }\n\n for (var i = 0; i < len; i++) {\n var edge = edges[i]\n\n stack.push({\n prefix: frame.prefix.concat(edge),\n node: frame.node.edges[edge]\n })\n }\n }\n\n return words\n}\n\n/**\n * Generates a string representation of a TokenSet.\n *\n * This is intended to allow TokenSets to be used as keys\n * in objects, largely to aid the construction and minimisation\n * of a TokenSet. As such it is not designed to be a human\n * friendly representation of the TokenSet.\n *\n * @returns {string}\n */\nlunr.TokenSet.prototype.toString = function () {\n // NOTE: Using Object.keys here as this.edges is very likely\n // to enter 'hash-mode' with many keys being added\n //\n // avoiding a for-in loop here as it leads to the function\n // being de-optimised (at least in V8). From some simple\n // benchmarks the performance is comparable, but allowing\n // V8 to optimize may mean easy performance wins in the future.\n\n if (this._str) {\n return this._str\n }\n\n var str = this.final ? '1' : '0',\n labels = Object.keys(this.edges).sort(),\n len = labels.length\n\n for (var i = 0; i < len; i++) {\n var label = labels[i],\n node = this.edges[label]\n\n str = str + label + node.id\n }\n\n return str\n}\n\n/**\n * Returns a new TokenSet that is the intersection of\n * this TokenSet and the passed TokenSet.\n *\n * This intersection will take into account any wildcards\n * contained within the TokenSet.\n *\n * @param {lunr.TokenSet} b - An other TokenSet to intersect with.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.prototype.intersect = function (b) {\n var output = new lunr.TokenSet,\n frame = undefined\n\n var stack = [{\n qNode: b,\n output: output,\n node: this\n }]\n\n while (stack.length) {\n frame = stack.pop()\n\n // NOTE: As with the #toString method, we are using\n // Object.keys and a for loop instead of a for-in loop\n // as both of these objects enter 'hash' mode, causing\n // the function to be de-optimised in V8\n var qEdges = Object.keys(frame.qNode.edges),\n qLen = qEdges.length,\n nEdges = Object.keys(frame.node.edges),\n nLen = nEdges.length\n\n for (var q = 0; q < qLen; q++) {\n var qEdge = qEdges[q]\n\n for (var n = 0; n < nLen; n++) {\n var nEdge = nEdges[n]\n\n if (nEdge == qEdge || qEdge == '*') {\n var node = frame.node.edges[nEdge],\n qNode = frame.qNode.edges[qEdge],\n final = node.final && qNode.final,\n next = undefined\n\n if (nEdge in frame.output.edges) {\n // an edge already exists for this character\n // no need to create a new node, just set the finality\n // bit unless this node is already final\n next = frame.output.edges[nEdge]\n next.final = next.final || final\n\n } else {\n // no edge exists yet, must create one\n // set the finality bit and insert it\n // into the output\n next = new lunr.TokenSet\n next.final = final\n frame.output.edges[nEdge] = next\n }\n\n stack.push({\n qNode: qNode,\n output: next,\n node: node\n })\n }\n }\n }\n }\n\n return output\n}\nlunr.TokenSet.Builder = function () {\n this.previousWord = \"\"\n this.root = new lunr.TokenSet\n this.uncheckedNodes = []\n this.minimizedNodes = {}\n}\n\nlunr.TokenSet.Builder.prototype.insert = function (word) {\n var node,\n commonPrefix = 0\n\n if (word < this.previousWord) {\n throw new Error (\"Out of order word insertion\")\n }\n\n for (var i = 0; i < word.length && i < this.previousWord.length; i++) {\n if (word[i] != this.previousWord[i]) break\n commonPrefix++\n }\n\n this.minimize(commonPrefix)\n\n if (this.uncheckedNodes.length == 0) {\n node = this.root\n } else {\n node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child\n }\n\n for (var i = commonPrefix; i < word.length; i++) {\n var nextNode = new lunr.TokenSet,\n char = word[i]\n\n node.edges[char] = nextNode\n\n this.uncheckedNodes.push({\n parent: node,\n char: char,\n child: nextNode\n })\n\n node = nextNode\n }\n\n node.final = true\n this.previousWord = word\n}\n\nlunr.TokenSet.Builder.prototype.finish = function () {\n this.minimize(0)\n}\n\nlunr.TokenSet.Builder.prototype.minimize = function (downTo) {\n for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) {\n var node = this.uncheckedNodes[i],\n childKey = node.child.toString()\n\n if (childKey in this.minimizedNodes) {\n node.parent.edges[node.char] = this.minimizedNodes[childKey]\n } else {\n // Cache the key for this node since\n // we know it can't change anymore\n node.child._str = childKey\n\n this.minimizedNodes[childKey] = node.child\n }\n\n this.uncheckedNodes.pop()\n }\n}\n/*!\n * lunr.Index\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * An index contains the built index of all documents and provides a query interface\n * to the index.\n *\n * Usually instances of lunr.Index will not be created using this constructor, instead\n * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be\n * used to load previously built and serialized indexes.\n *\n * @constructor\n * @param {Object} attrs - The attributes of the built search index.\n * @param {Object} attrs.invertedIndex - An index of term/field to document reference.\n * @param {Object} attrs.fieldVectors - Field vectors\n * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens.\n * @param {string[]} attrs.fields - The names of indexed document fields.\n * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms.\n */\nlunr.Index = function (attrs) {\n this.invertedIndex = attrs.invertedIndex\n this.fieldVectors = attrs.fieldVectors\n this.tokenSet = attrs.tokenSet\n this.fields = attrs.fields\n this.pipeline = attrs.pipeline\n}\n\n/**\n * A result contains details of a document matching a search query.\n * @typedef {Object} lunr.Index~Result\n * @property {string} ref - The reference of the document this result represents.\n * @property {number} score - A number between 0 and 1 representing how similar this document is to the query.\n * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match.\n */\n\n/**\n * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple\n * query language which itself is parsed into an instance of lunr.Query.\n *\n * For programmatically building queries it is advised to directly use lunr.Query, the query language\n * is best used for human entered text rather than program generated text.\n *\n * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported\n * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello'\n * or 'world', though those that contain both will rank higher in the results.\n *\n * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can\n * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding\n * wildcards will increase the number of documents that will be found but can also have a negative\n * impact on query performance, especially with wildcards at the beginning of a term.\n *\n * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term\n * hello in the title field will match this query. Using a field not present in the index will lead\n * to an error being thrown.\n *\n * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term\n * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported\n * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2.\n * Avoid large values for edit distance to improve query performance.\n *\n * Each term also supports a presence modifier. By default a term's presence in document is optional, however\n * this can be changed to either required or prohibited. For a term's presence to be required in a document the\n * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and\n * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not\n * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'.\n *\n * To escape special characters the backslash character '\\' can be used, this allows searches to include\n * characters that would normally be considered modifiers, e.g. `foo\\~2` will search for a term \"foo~2\" instead\n * of attempting to apply a boost of 2 to the search term \"foo\".\n *\n * @typedef {string} lunr.Index~QueryString\n * @example Simple single term query\n * hello\n * @example Multiple term query\n * hello world\n * @example term scoped to a field\n * title:hello\n * @example term with a boost of 10\n * hello^10\n * @example term with an edit distance of 2\n * hello~2\n * @example terms with presence modifiers\n * -foo +bar baz\n */\n\n/**\n * Performs a search against the index using lunr query syntax.\n *\n * Results will be returned sorted by their score, the most relevant results\n * will be returned first. For details on how the score is calculated, please see\n * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}.\n *\n * For more programmatic querying use lunr.Index#query.\n *\n * @param {lunr.Index~QueryString} queryString - A string containing a lunr query.\n * @throws {lunr.QueryParseError} If the passed query string cannot be parsed.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.search = function (queryString) {\n return this.query(function (query) {\n var parser = new lunr.QueryParser(queryString, query)\n parser.parse()\n })\n}\n\n/**\n * A query builder callback provides a query object to be used to express\n * the query to perform on the index.\n *\n * @callback lunr.Index~queryBuilder\n * @param {lunr.Query} query - The query object to build up.\n * @this lunr.Query\n */\n\n/**\n * Performs a query against the index using the yielded lunr.Query object.\n *\n * If performing programmatic queries against the index, this method is preferred\n * over lunr.Index#search so as to avoid the additional query parsing overhead.\n *\n * A query object is yielded to the supplied function which should be used to\n * express the query to be run against the index.\n *\n * Note that although this function takes a callback parameter it is _not_ an\n * asynchronous operation, the callback is just yielded a query object to be\n * customized.\n *\n * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.query = function (fn) {\n // for each query clause\n // * process terms\n // * expand terms from token set\n // * find matching documents and metadata\n // * get document vectors\n // * score documents\n\n var query = new lunr.Query(this.fields),\n matchingFields = Object.create(null),\n queryVectors = Object.create(null),\n termFieldCache = Object.create(null),\n requiredMatches = Object.create(null),\n prohibitedMatches = Object.create(null)\n\n /*\n * To support field level boosts a query vector is created per\n * field. An empty vector is eagerly created to support negated\n * queries.\n */\n for (var i = 0; i < this.fields.length; i++) {\n queryVectors[this.fields[i]] = new lunr.Vector\n }\n\n fn.call(query, query)\n\n for (var i = 0; i < query.clauses.length; i++) {\n /*\n * Unless the pipeline has been disabled for this term, which is\n * the case for terms with wildcards, we need to pass the clause\n * term through the search pipeline. A pipeline returns an array\n * of processed terms. Pipeline functions may expand the passed\n * term, which means we may end up performing multiple index lookups\n * for a single query term.\n */\n var clause = query.clauses[i],\n terms = null,\n clauseMatches = lunr.Set.empty\n\n if (clause.usePipeline) {\n terms = this.pipeline.runString(clause.term, {\n fields: clause.fields\n })\n } else {\n terms = [clause.term]\n }\n\n for (var m = 0; m < terms.length; m++) {\n var term = terms[m]\n\n /*\n * Each term returned from the pipeline needs to use the same query\n * clause object, e.g. the same boost and or edit distance. The\n * simplest way to do this is to re-use the clause object but mutate\n * its term property.\n */\n clause.term = term\n\n /*\n * From the term in the clause we create a token set which will then\n * be used to intersect the indexes token set to get a list of terms\n * to lookup in the inverted index\n */\n var termTokenSet = lunr.TokenSet.fromClause(clause),\n expandedTerms = this.tokenSet.intersect(termTokenSet).toArray()\n\n /*\n * If a term marked as required does not exist in the tokenSet it is\n * impossible for the search to return any matches. We set all the field\n * scoped required matches set to empty and stop examining any further\n * clauses.\n */\n if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) {\n for (var k = 0; k < clause.fields.length; k++) {\n var field = clause.fields[k]\n requiredMatches[field] = lunr.Set.empty\n }\n\n break\n }\n\n for (var j = 0; j < expandedTerms.length; j++) {\n /*\n * For each term get the posting and termIndex, this is required for\n * building the query vector.\n */\n var expandedTerm = expandedTerms[j],\n posting = this.invertedIndex[expandedTerm],\n termIndex = posting._index\n\n for (var k = 0; k < clause.fields.length; k++) {\n /*\n * For each field that this query term is scoped by (by default\n * all fields are in scope) we need to get all the document refs\n * that have this term in that field.\n *\n * The posting is the entry in the invertedIndex for the matching\n * term from above.\n */\n var field = clause.fields[k],\n fieldPosting = posting[field],\n matchingDocumentRefs = Object.keys(fieldPosting),\n termField = expandedTerm + \"/\" + field,\n matchingDocumentsSet = new lunr.Set(matchingDocumentRefs)\n\n /*\n * if the presence of this term is required ensure that the matching\n * documents are added to the set of required matches for this clause.\n *\n */\n if (clause.presence == lunr.Query.presence.REQUIRED) {\n clauseMatches = clauseMatches.union(matchingDocumentsSet)\n\n if (requiredMatches[field] === undefined) {\n requiredMatches[field] = lunr.Set.complete\n }\n }\n\n /*\n * if the presence of this term is prohibited ensure that the matching\n * documents are added to the set of prohibited matches for this field,\n * creating that set if it does not yet exist.\n */\n if (clause.presence == lunr.Query.presence.PROHIBITED) {\n if (prohibitedMatches[field] === undefined) {\n prohibitedMatches[field] = lunr.Set.empty\n }\n\n prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet)\n\n /*\n * Prohibited matches should not be part of the query vector used for\n * similarity scoring and no metadata should be extracted so we continue\n * to the next field\n */\n continue\n }\n\n /*\n * The query field vector is populated using the termIndex found for\n * the term and a unit value with the appropriate boost applied.\n * Using upsert because there could already be an entry in the vector\n * for the term we are working with. In that case we just add the scores\n * together.\n */\n queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b })\n\n /**\n * If we've already seen this term, field combo then we've already collected\n * the matching documents and metadata, no need to go through all that again\n */\n if (termFieldCache[termField]) {\n continue\n }\n\n for (var l = 0; l < matchingDocumentRefs.length; l++) {\n /*\n * All metadata for this term/field/document triple\n * are then extracted and collected into an instance\n * of lunr.MatchData ready to be returned in the query\n * results\n */\n var matchingDocumentRef = matchingDocumentRefs[l],\n matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field),\n metadata = fieldPosting[matchingDocumentRef],\n fieldMatch\n\n if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) {\n matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata)\n } else {\n fieldMatch.add(expandedTerm, field, metadata)\n }\n\n }\n\n termFieldCache[termField] = true\n }\n }\n }\n\n /**\n * If the presence was required we need to update the requiredMatches field sets.\n * We do this after all fields for the term have collected their matches because\n * the clause terms presence is required in _any_ of the fields not _all_ of the\n * fields.\n */\n if (clause.presence === lunr.Query.presence.REQUIRED) {\n for (var k = 0; k < clause.fields.length; k++) {\n var field = clause.fields[k]\n requiredMatches[field] = requiredMatches[field].intersect(clauseMatches)\n }\n }\n }\n\n /**\n * Need to combine the field scoped required and prohibited\n * matching documents into a global set of required and prohibited\n * matches\n */\n var allRequiredMatches = lunr.Set.complete,\n allProhibitedMatches = lunr.Set.empty\n\n for (var i = 0; i < this.fields.length; i++) {\n var field = this.fields[i]\n\n if (requiredMatches[field]) {\n allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field])\n }\n\n if (prohibitedMatches[field]) {\n allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field])\n }\n }\n\n var matchingFieldRefs = Object.keys(matchingFields),\n results = [],\n matches = Object.create(null)\n\n /*\n * If the query is negated (contains only prohibited terms)\n * we need to get _all_ fieldRefs currently existing in the\n * index. This is only done when we know that the query is\n * entirely prohibited terms to avoid any cost of getting all\n * fieldRefs unnecessarily.\n *\n * Additionally, blank MatchData must be created to correctly\n * populate the results.\n */\n if (query.isNegated()) {\n matchingFieldRefs = Object.keys(this.fieldVectors)\n\n for (var i = 0; i < matchingFieldRefs.length; i++) {\n var matchingFieldRef = matchingFieldRefs[i]\n var fieldRef = lunr.FieldRef.fromString(matchingFieldRef)\n matchingFields[matchingFieldRef] = new lunr.MatchData\n }\n }\n\n for (var i = 0; i < matchingFieldRefs.length; i++) {\n /*\n * Currently we have document fields that match the query, but we\n * need to return documents. The matchData and scores are combined\n * from multiple fields belonging to the same document.\n *\n * Scores are calculated by field, using the query vectors created\n * above, and combined into a final document score using addition.\n */\n var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]),\n docRef = fieldRef.docRef\n\n if (!allRequiredMatches.contains(docRef)) {\n continue\n }\n\n if (allProhibitedMatches.contains(docRef)) {\n continue\n }\n\n var fieldVector = this.fieldVectors[fieldRef],\n score = queryVectors[fieldRef.fieldName].similarity(fieldVector),\n docMatch\n\n if ((docMatch = matches[docRef]) !== undefined) {\n docMatch.score += score\n docMatch.matchData.combine(matchingFields[fieldRef])\n } else {\n var match = {\n ref: docRef,\n score: score,\n matchData: matchingFields[fieldRef]\n }\n matches[docRef] = match\n results.push(match)\n }\n }\n\n /*\n * Sort the results objects by score, highest first.\n */\n return results.sort(function (a, b) {\n return b.score - a.score\n })\n}\n\n/**\n * Prepares the index for JSON serialization.\n *\n * The schema for this JSON blob will be described in a\n * separate JSON schema file.\n *\n * @returns {Object}\n */\nlunr.Index.prototype.toJSON = function () {\n var invertedIndex = Object.keys(this.invertedIndex)\n .sort()\n .map(function (term) {\n return [term, this.invertedIndex[term]]\n }, this)\n\n var fieldVectors = Object.keys(this.fieldVectors)\n .map(function (ref) {\n return [ref, this.fieldVectors[ref].toJSON()]\n }, this)\n\n return {\n version: lunr.version,\n fields: this.fields,\n fieldVectors: fieldVectors,\n invertedIndex: invertedIndex,\n pipeline: this.pipeline.toJSON()\n }\n}\n\n/**\n * Loads a previously serialized lunr.Index\n *\n * @param {Object} serializedIndex - A previously serialized lunr.Index\n * @returns {lunr.Index}\n */\nlunr.Index.load = function (serializedIndex) {\n var attrs = {},\n fieldVectors = {},\n serializedVectors = serializedIndex.fieldVectors,\n invertedIndex = Object.create(null),\n serializedInvertedIndex = serializedIndex.invertedIndex,\n tokenSetBuilder = new lunr.TokenSet.Builder,\n pipeline = lunr.Pipeline.load(serializedIndex.pipeline)\n\n if (serializedIndex.version != lunr.version) {\n lunr.utils.warn(\"Version mismatch when loading serialised index. Current version of lunr '\" + lunr.version + \"' does not match serialized index '\" + serializedIndex.version + \"'\")\n }\n\n for (var i = 0; i < serializedVectors.length; i++) {\n var tuple = serializedVectors[i],\n ref = tuple[0],\n elements = tuple[1]\n\n fieldVectors[ref] = new lunr.Vector(elements)\n }\n\n for (var i = 0; i < serializedInvertedIndex.length; i++) {\n var tuple = serializedInvertedIndex[i],\n term = tuple[0],\n posting = tuple[1]\n\n tokenSetBuilder.insert(term)\n invertedIndex[term] = posting\n }\n\n tokenSetBuilder.finish()\n\n attrs.fields = serializedIndex.fields\n\n attrs.fieldVectors = fieldVectors\n attrs.invertedIndex = invertedIndex\n attrs.tokenSet = tokenSetBuilder.root\n attrs.pipeline = pipeline\n\n return new lunr.Index(attrs)\n}\n/*!\n * lunr.Builder\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.Builder performs indexing on a set of documents and\n * returns instances of lunr.Index ready for querying.\n *\n * All configuration of the index is done via the builder, the\n * fields to index, the document reference, the text processing\n * pipeline and document scoring parameters are all set on the\n * builder before indexing.\n *\n * @constructor\n * @property {string} _ref - Internal reference to the document reference field.\n * @property {string[]} _fields - Internal reference to the document fields to index.\n * @property {object} invertedIndex - The inverted index maps terms to document fields.\n * @property {object} documentTermFrequencies - Keeps track of document term frequencies.\n * @property {object} documentLengths - Keeps track of the length of documents added to the index.\n * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing.\n * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing.\n * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index.\n * @property {number} documentCount - Keeps track of the total number of documents indexed.\n * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75.\n * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2.\n * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space.\n * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index.\n */\nlunr.Builder = function () {\n this._ref = \"id\"\n this._fields = Object.create(null)\n this._documents = Object.create(null)\n this.invertedIndex = Object.create(null)\n this.fieldTermFrequencies = {}\n this.fieldLengths = {}\n this.tokenizer = lunr.tokenizer\n this.pipeline = new lunr.Pipeline\n this.searchPipeline = new lunr.Pipeline\n this.documentCount = 0\n this._b = 0.75\n this._k1 = 1.2\n this.termIndex = 0\n this.metadataWhitelist = []\n}\n\n/**\n * Sets the document field used as the document reference. Every document must have this field.\n * The type of this field in the document should be a string, if it is not a string it will be\n * coerced into a string by calling toString.\n *\n * The default ref is 'id'.\n *\n * The ref should _not_ be changed during indexing, it should be set before any documents are\n * added to the index. Changing it during indexing can lead to inconsistent results.\n *\n * @param {string} ref - The name of the reference field in the document.\n */\nlunr.Builder.prototype.ref = function (ref) {\n this._ref = ref\n}\n\n/**\n * A function that is used to extract a field from a document.\n *\n * Lunr expects a field to be at the top level of a document, if however the field\n * is deeply nested within a document an extractor function can be used to extract\n * the right field for indexing.\n *\n * @callback fieldExtractor\n * @param {object} doc - The document being added to the index.\n * @returns {?(string|object|object[])} obj - The object that will be indexed for this field.\n * @example Extracting a nested field\n * function (doc) { return doc.nested.field }\n */\n\n/**\n * Adds a field to the list of document fields that will be indexed. Every document being\n * indexed should have this field. Null values for this field in indexed documents will\n * not cause errors but will limit the chance of that document being retrieved by searches.\n *\n * All fields should be added before adding documents to the index. Adding fields after\n * a document has been indexed will have no effect on already indexed documents.\n *\n * Fields can be boosted at build time. This allows terms within that field to have more\n * importance when ranking search results. Use a field boost to specify that matches within\n * one field are more important than other fields.\n *\n * @param {string} fieldName - The name of a field to index in all documents.\n * @param {object} attributes - Optional attributes associated with this field.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this field.\n * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document.\n * @throws {RangeError} fieldName cannot contain unsupported characters '/'\n */\nlunr.Builder.prototype.field = function (fieldName, attributes) {\n if (/\\//.test(fieldName)) {\n throw new RangeError (\"Field '\" + fieldName + \"' contains illegal character '/'\")\n }\n\n this._fields[fieldName] = attributes || {}\n}\n\n/**\n * A parameter to tune the amount of field length normalisation that is applied when\n * calculating relevance scores. A value of 0 will completely disable any normalisation\n * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b\n * will be clamped to the range 0 - 1.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.b = function (number) {\n if (number < 0) {\n this._b = 0\n } else if (number > 1) {\n this._b = 1\n } else {\n this._b = number\n }\n}\n\n/**\n * A parameter that controls the speed at which a rise in term frequency results in term\n * frequency saturation. The default value is 1.2. Setting this to a higher value will give\n * slower saturation levels, a lower value will result in quicker saturation.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.k1 = function (number) {\n this._k1 = number\n}\n\n/**\n * Adds a document to the index.\n *\n * Before adding fields to the index the index should have been fully setup, with the document\n * ref and all fields to index already having been specified.\n *\n * The document must have a field name as specified by the ref (by default this is 'id') and\n * it should have all fields defined for indexing, though null or undefined values will not\n * cause errors.\n *\n * Entire documents can be boosted at build time. Applying a boost to a document indicates that\n * this document should rank higher in search results than other documents.\n *\n * @param {object} doc - The document to add to the index.\n * @param {object} attributes - Optional attributes associated with this document.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this document.\n */\nlunr.Builder.prototype.add = function (doc, attributes) {\n var docRef = doc[this._ref],\n fields = Object.keys(this._fields)\n\n this._documents[docRef] = attributes || {}\n this.documentCount += 1\n\n for (var i = 0; i < fields.length; i++) {\n var fieldName = fields[i],\n extractor = this._fields[fieldName].extractor,\n field = extractor ? extractor(doc) : doc[fieldName],\n tokens = this.tokenizer(field, {\n fields: [fieldName]\n }),\n terms = this.pipeline.run(tokens),\n fieldRef = new lunr.FieldRef (docRef, fieldName),\n fieldTerms = Object.create(null)\n\n this.fieldTermFrequencies[fieldRef] = fieldTerms\n this.fieldLengths[fieldRef] = 0\n\n // store the length of this field for this document\n this.fieldLengths[fieldRef] += terms.length\n\n // calculate term frequencies for this field\n for (var j = 0; j < terms.length; j++) {\n var term = terms[j]\n\n if (fieldTerms[term] == undefined) {\n fieldTerms[term] = 0\n }\n\n fieldTerms[term] += 1\n\n // add to inverted index\n // create an initial posting if one doesn't exist\n if (this.invertedIndex[term] == undefined) {\n var posting = Object.create(null)\n posting[\"_index\"] = this.termIndex\n this.termIndex += 1\n\n for (var k = 0; k < fields.length; k++) {\n posting[fields[k]] = Object.create(null)\n }\n\n this.invertedIndex[term] = posting\n }\n\n // add an entry for this term/fieldName/docRef to the invertedIndex\n if (this.invertedIndex[term][fieldName][docRef] == undefined) {\n this.invertedIndex[term][fieldName][docRef] = Object.create(null)\n }\n\n // store all whitelisted metadata about this token in the\n // inverted index\n for (var l = 0; l < this.metadataWhitelist.length; l++) {\n var metadataKey = this.metadataWhitelist[l],\n metadata = term.metadata[metadataKey]\n\n if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) {\n this.invertedIndex[term][fieldName][docRef][metadataKey] = []\n }\n\n this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata)\n }\n }\n\n }\n}\n\n/**\n * Calculates the average document length for this index\n *\n * @private\n */\nlunr.Builder.prototype.calculateAverageFieldLengths = function () {\n\n var fieldRefs = Object.keys(this.fieldLengths),\n numberOfFields = fieldRefs.length,\n accumulator = {},\n documentsWithField = {}\n\n for (var i = 0; i < numberOfFields; i++) {\n var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n field = fieldRef.fieldName\n\n documentsWithField[field] || (documentsWithField[field] = 0)\n documentsWithField[field] += 1\n\n accumulator[field] || (accumulator[field] = 0)\n accumulator[field] += this.fieldLengths[fieldRef]\n }\n\n var fields = Object.keys(this._fields)\n\n for (var i = 0; i < fields.length; i++) {\n var fieldName = fields[i]\n accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName]\n }\n\n this.averageFieldLength = accumulator\n}\n\n/**\n * Builds a vector space model of every document using lunr.Vector\n *\n * @private\n */\nlunr.Builder.prototype.createFieldVectors = function () {\n var fieldVectors = {},\n fieldRefs = Object.keys(this.fieldTermFrequencies),\n fieldRefsLength = fieldRefs.length,\n termIdfCache = Object.create(null)\n\n for (var i = 0; i < fieldRefsLength; i++) {\n var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n fieldName = fieldRef.fieldName,\n fieldLength = this.fieldLengths[fieldRef],\n fieldVector = new lunr.Vector,\n termFrequencies = this.fieldTermFrequencies[fieldRef],\n terms = Object.keys(termFrequencies),\n termsLength = terms.length\n\n\n var fieldBoost = this._fields[fieldName].boost || 1,\n docBoost = this._documents[fieldRef.docRef].boost || 1\n\n for (var j = 0; j < termsLength; j++) {\n var term = terms[j],\n tf = termFrequencies[term],\n termIndex = this.invertedIndex[term]._index,\n idf, score, scoreWithPrecision\n\n if (termIdfCache[term] === undefined) {\n idf = lunr.idf(this.invertedIndex[term], this.documentCount)\n termIdfCache[term] = idf\n } else {\n idf = termIdfCache[term]\n }\n\n score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf)\n score *= fieldBoost\n score *= docBoost\n scoreWithPrecision = Math.round(score * 1000) / 1000\n // Converts 1.23456789 to 1.234.\n // Reducing the precision so that the vectors take up less\n // space when serialised. Doing it now so that they behave\n // the same before and after serialisation. Also, this is\n // the fastest approach to reducing a number's precision in\n // JavaScript.\n\n fieldVector.insert(termIndex, scoreWithPrecision)\n }\n\n fieldVectors[fieldRef] = fieldVector\n }\n\n this.fieldVectors = fieldVectors\n}\n\n/**\n * Creates a token set of all tokens in the index using lunr.TokenSet\n *\n * @private\n */\nlunr.Builder.prototype.createTokenSet = function () {\n this.tokenSet = lunr.TokenSet.fromArray(\n Object.keys(this.invertedIndex).sort()\n )\n}\n\n/**\n * Builds the index, creating an instance of lunr.Index.\n *\n * This completes the indexing process and should only be called\n * once all documents have been added to the index.\n *\n * @returns {lunr.Index}\n */\nlunr.Builder.prototype.build = function () {\n this.calculateAverageFieldLengths()\n this.createFieldVectors()\n this.createTokenSet()\n\n return new lunr.Index({\n invertedIndex: this.invertedIndex,\n fieldVectors: this.fieldVectors,\n tokenSet: this.tokenSet,\n fields: Object.keys(this._fields),\n pipeline: this.searchPipeline\n })\n}\n\n/**\n * Applies a plugin to the index builder.\n *\n * A plugin is a function that is called with the index builder as its context.\n * Plugins can be used to customise or extend the behaviour of the index\n * in some way. A plugin is just a function, that encapsulated the custom\n * behaviour that should be applied when building the index.\n *\n * The plugin function will be called with the index builder as its argument, additional\n * arguments can also be passed when calling use. The function will be called\n * with the index builder as its context.\n *\n * @param {Function} plugin The plugin to apply.\n */\nlunr.Builder.prototype.use = function (fn) {\n var args = Array.prototype.slice.call(arguments, 1)\n args.unshift(this)\n fn.apply(this, args)\n}\n/**\n * Contains and collects metadata about a matching document.\n * A single instance of lunr.MatchData is returned as part of every\n * lunr.Index~Result.\n *\n * @constructor\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n * @property {object} metadata - A cloned collection of metadata associated with this document.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData = function (term, field, metadata) {\n var clonedMetadata = Object.create(null),\n metadataKeys = Object.keys(metadata || {})\n\n // Cloning the metadata to prevent the original\n // being mutated during match data combination.\n // Metadata is kept in an array within the inverted\n // index so cloning the data can be done with\n // Array#slice\n for (var i = 0; i < metadataKeys.length; i++) {\n var key = metadataKeys[i]\n clonedMetadata[key] = metadata[key].slice()\n }\n\n this.metadata = Object.create(null)\n\n if (term !== undefined) {\n this.metadata[term] = Object.create(null)\n this.metadata[term][field] = clonedMetadata\n }\n}\n\n/**\n * An instance of lunr.MatchData will be created for every term that matches a\n * document. However only one instance is required in a lunr.Index~Result. This\n * method combines metadata from another instance of lunr.MatchData with this\n * objects metadata.\n *\n * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData.prototype.combine = function (otherMatchData) {\n var terms = Object.keys(otherMatchData.metadata)\n\n for (var i = 0; i < terms.length; i++) {\n var term = terms[i],\n fields = Object.keys(otherMatchData.metadata[term])\n\n if (this.metadata[term] == undefined) {\n this.metadata[term] = Object.create(null)\n }\n\n for (var j = 0; j < fields.length; j++) {\n var field = fields[j],\n keys = Object.keys(otherMatchData.metadata[term][field])\n\n if (this.metadata[term][field] == undefined) {\n this.metadata[term][field] = Object.create(null)\n }\n\n for (var k = 0; k < keys.length; k++) {\n var key = keys[k]\n\n if (this.metadata[term][field][key] == undefined) {\n this.metadata[term][field][key] = otherMatchData.metadata[term][field][key]\n } else {\n this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key])\n }\n\n }\n }\n }\n}\n\n/**\n * Add metadata for a term/field pair to this instance of match data.\n *\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n */\nlunr.MatchData.prototype.add = function (term, field, metadata) {\n if (!(term in this.metadata)) {\n this.metadata[term] = Object.create(null)\n this.metadata[term][field] = metadata\n return\n }\n\n if (!(field in this.metadata[term])) {\n this.metadata[term][field] = metadata\n return\n }\n\n var metadataKeys = Object.keys(metadata)\n\n for (var i = 0; i < metadataKeys.length; i++) {\n var key = metadataKeys[i]\n\n if (key in this.metadata[term][field]) {\n this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key])\n } else {\n this.metadata[term][field][key] = metadata[key]\n }\n }\n}\n/**\n * A lunr.Query provides a programmatic way of defining queries to be performed\n * against a {@link lunr.Index}.\n *\n * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method\n * so the query object is pre-initialized with the right index fields.\n *\n * @constructor\n * @property {lunr.Query~Clause[]} clauses - An array of query clauses.\n * @property {string[]} allFields - An array of all available fields in a lunr.Index.\n */\nlunr.Query = function (allFields) {\n this.clauses = []\n this.allFields = allFields\n}\n\n/**\n * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause.\n *\n * This allows wildcards to be added to the beginning and end of a term without having to manually do any string\n * concatenation.\n *\n * The wildcard constants can be bitwise combined to select both leading and trailing wildcards.\n *\n * @constant\n * @default\n * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour\n * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists\n * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example query term with trailing wildcard\n * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING })\n * @example query term with leading and trailing wildcard\n * query.term('foo', {\n * wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING\n * })\n */\n\nlunr.Query.wildcard = new String (\"*\")\nlunr.Query.wildcard.NONE = 0\nlunr.Query.wildcard.LEADING = 1\nlunr.Query.wildcard.TRAILING = 2\n\n/**\n * Constants for indicating what kind of presence a term must have in matching documents.\n *\n * @constant\n * @enum {number}\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example query term with required presence\n * query.term('foo', { presence: lunr.Query.presence.REQUIRED })\n */\nlunr.Query.presence = {\n /**\n * Term's presence in a document is optional, this is the default value.\n */\n OPTIONAL: 1,\n\n /**\n * Term's presence in a document is required, documents that do not contain\n * this term will not be returned.\n */\n REQUIRED: 2,\n\n /**\n * Term's presence in a document is prohibited, documents that do contain\n * this term will not be returned.\n */\n PROHIBITED: 3\n}\n\n/**\n * A single clause in a {@link lunr.Query} contains a term and details on how to\n * match that term against a {@link lunr.Index}.\n *\n * @typedef {Object} lunr.Query~Clause\n * @property {string[]} fields - The fields in an index this clause should be matched against.\n * @property {number} [boost=1] - Any boost that should be applied when matching this clause.\n * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be.\n * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline.\n * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended.\n * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents.\n */\n\n/**\n * Adds a {@link lunr.Query~Clause} to this query.\n *\n * Unless the clause contains the fields to be matched all fields will be matched. In addition\n * a default boost of 1 is applied to the clause.\n *\n * @param {lunr.Query~Clause} clause - The clause to add to this query.\n * @see lunr.Query~Clause\n * @returns {lunr.Query}\n */\nlunr.Query.prototype.clause = function (clause) {\n if (!('fields' in clause)) {\n clause.fields = this.allFields\n }\n\n if (!('boost' in clause)) {\n clause.boost = 1\n }\n\n if (!('usePipeline' in clause)) {\n clause.usePipeline = true\n }\n\n if (!('wildcard' in clause)) {\n clause.wildcard = lunr.Query.wildcard.NONE\n }\n\n if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) {\n clause.term = \"*\" + clause.term\n }\n\n if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) {\n clause.term = \"\" + clause.term + \"*\"\n }\n\n if (!('presence' in clause)) {\n clause.presence = lunr.Query.presence.OPTIONAL\n }\n\n this.clauses.push(clause)\n\n return this\n}\n\n/**\n * A negated query is one in which every clause has a presence of\n * prohibited. These queries require some special processing to return\n * the expected results.\n *\n * @returns boolean\n */\nlunr.Query.prototype.isNegated = function () {\n for (var i = 0; i < this.clauses.length; i++) {\n if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause}\n * to the list of clauses that make up this query.\n *\n * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion\n * to a token or token-like string should be done before calling this method.\n *\n * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an\n * array, each term in the array will share the same options.\n *\n * @param {object|object[]} term - The term(s) to add to the query.\n * @param {object} [options] - Any additional properties to add to the query clause.\n * @returns {lunr.Query}\n * @see lunr.Query#clause\n * @see lunr.Query~Clause\n * @example adding a single term to a query\n * query.term(\"foo\")\n * @example adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard\n * query.term(\"foo\", {\n * fields: [\"title\"],\n * boost: 10,\n * wildcard: lunr.Query.wildcard.TRAILING\n * })\n * @example using lunr.tokenizer to convert a string to tokens before using them as terms\n * query.term(lunr.tokenizer(\"foo bar\"))\n */\nlunr.Query.prototype.term = function (term, options) {\n if (Array.isArray(term)) {\n term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this)\n return this\n }\n\n var clause = options || {}\n clause.term = term.toString()\n\n this.clause(clause)\n\n return this\n}\nlunr.QueryParseError = function (message, start, end) {\n this.name = \"QueryParseError\"\n this.message = message\n this.start = start\n this.end = end\n}\n\nlunr.QueryParseError.prototype = new Error\nlunr.QueryLexer = function (str) {\n this.lexemes = []\n this.str = str\n this.length = str.length\n this.pos = 0\n this.start = 0\n this.escapeCharPositions = []\n}\n\nlunr.QueryLexer.prototype.run = function () {\n var state = lunr.QueryLexer.lexText\n\n while (state) {\n state = state(this)\n }\n}\n\nlunr.QueryLexer.prototype.sliceString = function () {\n var subSlices = [],\n sliceStart = this.start,\n sliceEnd = this.pos\n\n for (var i = 0; i < this.escapeCharPositions.length; i++) {\n sliceEnd = this.escapeCharPositions[i]\n subSlices.push(this.str.slice(sliceStart, sliceEnd))\n sliceStart = sliceEnd + 1\n }\n\n subSlices.push(this.str.slice(sliceStart, this.pos))\n this.escapeCharPositions.length = 0\n\n return subSlices.join('')\n}\n\nlunr.QueryLexer.prototype.emit = function (type) {\n this.lexemes.push({\n type: type,\n str: this.sliceString(),\n start: this.start,\n end: this.pos\n })\n\n this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.escapeCharacter = function () {\n this.escapeCharPositions.push(this.pos - 1)\n this.pos += 1\n}\n\nlunr.QueryLexer.prototype.next = function () {\n if (this.pos >= this.length) {\n return lunr.QueryLexer.EOS\n }\n\n var char = this.str.charAt(this.pos)\n this.pos += 1\n return char\n}\n\nlunr.QueryLexer.prototype.width = function () {\n return this.pos - this.start\n}\n\nlunr.QueryLexer.prototype.ignore = function () {\n if (this.start == this.pos) {\n this.pos += 1\n }\n\n this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.backup = function () {\n this.pos -= 1\n}\n\nlunr.QueryLexer.prototype.acceptDigitRun = function () {\n var char, charCode\n\n do {\n char = this.next()\n charCode = char.charCodeAt(0)\n } while (charCode > 47 && charCode < 58)\n\n if (char != lunr.QueryLexer.EOS) {\n this.backup()\n }\n}\n\nlunr.QueryLexer.prototype.more = function () {\n return this.pos < this.length\n}\n\nlunr.QueryLexer.EOS = 'EOS'\nlunr.QueryLexer.FIELD = 'FIELD'\nlunr.QueryLexer.TERM = 'TERM'\nlunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE'\nlunr.QueryLexer.BOOST = 'BOOST'\nlunr.QueryLexer.PRESENCE = 'PRESENCE'\n\nlunr.QueryLexer.lexField = function (lexer) {\n lexer.backup()\n lexer.emit(lunr.QueryLexer.FIELD)\n lexer.ignore()\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexTerm = function (lexer) {\n if (lexer.width() > 1) {\n lexer.backup()\n lexer.emit(lunr.QueryLexer.TERM)\n }\n\n lexer.ignore()\n\n if (lexer.more()) {\n return lunr.QueryLexer.lexText\n }\n}\n\nlunr.QueryLexer.lexEditDistance = function (lexer) {\n lexer.ignore()\n lexer.acceptDigitRun()\n lexer.emit(lunr.QueryLexer.EDIT_DISTANCE)\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexBoost = function (lexer) {\n lexer.ignore()\n lexer.acceptDigitRun()\n lexer.emit(lunr.QueryLexer.BOOST)\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexEOS = function (lexer) {\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n}\n\n// This matches the separator used when tokenising fields\n// within a document. These should match otherwise it is\n// not possible to search for some tokens within a document.\n//\n// It is possible for the user to change the separator on the\n// tokenizer so it _might_ clash with any other of the special\n// characters already used within the search string, e.g. :.\n//\n// This means that it is possible to change the separator in\n// such a way that makes some words unsearchable using a search\n// string.\nlunr.QueryLexer.termSeparator = lunr.tokenizer.separator\n\nlunr.QueryLexer.lexText = function (lexer) {\n while (true) {\n var char = lexer.next()\n\n if (char == lunr.QueryLexer.EOS) {\n return lunr.QueryLexer.lexEOS\n }\n\n // Escape character is '\\'\n if (char.charCodeAt(0) == 92) {\n lexer.escapeCharacter()\n continue\n }\n\n if (char == \":\") {\n return lunr.QueryLexer.lexField\n }\n\n if (char == \"~\") {\n lexer.backup()\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n return lunr.QueryLexer.lexEditDistance\n }\n\n if (char == \"^\") {\n lexer.backup()\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n return lunr.QueryLexer.lexBoost\n }\n\n // \"+\" indicates term presence is required\n // checking for length to ensure that only\n // leading \"+\" are considered\n if (char == \"+\" && lexer.width() === 1) {\n lexer.emit(lunr.QueryLexer.PRESENCE)\n return lunr.QueryLexer.lexText\n }\n\n // \"-\" indicates term presence is prohibited\n // checking for length to ensure that only\n // leading \"-\" are considered\n if (char == \"-\" && lexer.width() === 1) {\n lexer.emit(lunr.QueryLexer.PRESENCE)\n return lunr.QueryLexer.lexText\n }\n\n if (char.match(lunr.QueryLexer.termSeparator)) {\n return lunr.QueryLexer.lexTerm\n }\n }\n}\n\nlunr.QueryParser = function (str, query) {\n this.lexer = new lunr.QueryLexer (str)\n this.query = query\n this.currentClause = {}\n this.lexemeIdx = 0\n}\n\nlunr.QueryParser.prototype.parse = function () {\n this.lexer.run()\n this.lexemes = this.lexer.lexemes\n\n var state = lunr.QueryParser.parseClause\n\n while (state) {\n state = state(this)\n }\n\n return this.query\n}\n\nlunr.QueryParser.prototype.peekLexeme = function () {\n return this.lexemes[this.lexemeIdx]\n}\n\nlunr.QueryParser.prototype.consumeLexeme = function () {\n var lexeme = this.peekLexeme()\n this.lexemeIdx += 1\n return lexeme\n}\n\nlunr.QueryParser.prototype.nextClause = function () {\n var completedClause = this.currentClause\n this.query.clause(completedClause)\n this.currentClause = {}\n}\n\nlunr.QueryParser.parseClause = function (parser) {\n var lexeme = parser.peekLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n switch (lexeme.type) {\n case lunr.QueryLexer.PRESENCE:\n return lunr.QueryParser.parsePresence\n case lunr.QueryLexer.FIELD:\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expected either a field or a term, found \" + lexeme.type\n\n if (lexeme.str.length >= 1) {\n errorMessage += \" with value '\" + lexeme.str + \"'\"\n }\n\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n}\n\nlunr.QueryParser.parsePresence = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n switch (lexeme.str) {\n case \"-\":\n parser.currentClause.presence = lunr.Query.presence.PROHIBITED\n break\n case \"+\":\n parser.currentClause.presence = lunr.Query.presence.REQUIRED\n break\n default:\n var errorMessage = \"unrecognised presence operator'\" + lexeme.str + \"'\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n var errorMessage = \"expecting term or field, found nothing\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.FIELD:\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expecting term or field, found '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseField = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n if (parser.query.allFields.indexOf(lexeme.str) == -1) {\n var possibleFields = parser.query.allFields.map(function (f) { return \"'\" + f + \"'\" }).join(', '),\n errorMessage = \"unrecognised field '\" + lexeme.str + \"', possible fields: \" + possibleFields\n\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.fields = [lexeme.str]\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n var errorMessage = \"expecting term, found nothing\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expecting term, found '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseTerm = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n parser.currentClause.term = lexeme.str.toLowerCase()\n\n if (lexeme.str.indexOf(\"*\") != -1) {\n parser.currentClause.usePipeline = false\n }\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseEditDistance = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n var editDistance = parseInt(lexeme.str, 10)\n\n if (isNaN(editDistance)) {\n var errorMessage = \"edit distance must be numeric\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.editDistance = editDistance\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseBoost = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n var boost = parseInt(lexeme.str, 10)\n\n if (isNaN(boost)) {\n var errorMessage = \"boost must be numeric\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.boost = boost\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\n /**\n * export the module via AMD, CommonJS or as a browser global\n * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n */\n ;(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(factory)\n } else if (typeof exports === 'object') {\n /**\n * Node. Does not work with strict CommonJS, but\n * only CommonJS-like enviroments that support module.exports,\n * like Node.\n */\n module.exports = factory()\n } else {\n // Browser globals (root is window)\n root.lunr = factory()\n }\n }(this, function () {\n /**\n * Just return a value to define the module export.\n * This example returns an object, but the module\n * can return a function as the exported value.\n */\n return lunr\n }))\n})();\n", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport lunr from \"lunr\"\n\nimport \"~/polyfills\"\n\nimport { Search, SearchIndexConfig } from \"../../_\"\nimport {\n SearchMessage,\n SearchMessageType\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Add support for usage with `iframe-worker` polyfill\n *\n * While `importScripts` is synchronous when executed inside of a web worker,\n * it's not possible to provide a synchronous polyfilled implementation. The\n * cool thing is that awaiting a non-Promise is a noop, so extending the type\n * definition to return a `Promise` shouldn't break anything.\n *\n * @see https://bit.ly/2PjDnXi - GitHub comment\n */\ndeclare global {\n function importScripts(...urls: string[]): Promise | void\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n */\nlet index: Search\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch (= import) multi-language support through `lunr-languages`\n *\n * This function automatically imports the stemmers necessary to process the\n * languages, which are defined through the search index configuration.\n *\n * If the worker runs inside of an `iframe` (when using `iframe-worker` as\n * a shim), the base URL for the stemmers to be loaded must be determined by\n * searching for the first `script` element with a `src` attribute, which will\n * contain the contents of this script.\n *\n * @param config - Search index configuration\n *\n * @returns Promise resolving with no result\n */\nasync function setupSearchLanguages(\n config: SearchIndexConfig\n): Promise {\n let base = \"../lunr\"\n\n /* Detect `iframe-worker` and fix base URL */\n if (typeof parent !== \"undefined\" && \"IFrameWorker\" in parent) {\n const worker = document.querySelector(\"script[src]\")!\n const [path] = worker.src.split(\"/worker\")\n\n /* Prefix base with path */\n base = base.replace(\"..\", path)\n }\n\n /* Add scripts for languages */\n const scripts = []\n for (const lang of config.lang) {\n switch (lang) {\n\n /* Add segmenter for Japanese */\n case \"ja\":\n scripts.push(`${base}/tinyseg.js`)\n break\n\n /* Add segmenter for Hindi and Thai */\n case \"hi\":\n case \"th\":\n scripts.push(`${base}/wordcut.js`)\n break\n }\n\n /* Add language support */\n if (lang !== \"en\")\n scripts.push(`${base}/min/lunr.${lang}.min.js`)\n }\n\n /* Add multi-language support */\n if (config.lang.length > 1)\n scripts.push(`${base}/min/lunr.multi.min.js`)\n\n /* Load scripts synchronously */\n if (scripts.length)\n await importScripts(\n `${base}/min/lunr.stemmer.support.min.js`,\n ...scripts\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Message handler\n *\n * @param message - Source message\n *\n * @returns Target message\n */\nexport async function handler(\n message: SearchMessage\n): Promise {\n switch (message.type) {\n\n /* Search setup message */\n case SearchMessageType.SETUP:\n await setupSearchLanguages(message.data.config)\n index = new Search(message.data)\n return {\n type: SearchMessageType.READY\n }\n\n /* Search query message */\n case SearchMessageType.QUERY:\n return {\n type: SearchMessageType.RESULT,\n data: index ? index.search(message.data) : { items: [] }\n }\n\n /* All other messages */\n default:\n throw new TypeError(\"Invalid message type\")\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Worker\n * ------------------------------------------------------------------------- */\n\n/* @ts-expect-error - expose Lunr.js in global scope, or stemmers won't work */\nself.lunr = lunr\n\n/* Handle messages */\naddEventListener(\"message\", async ev => {\n postMessage(await handler(ev.data))\n})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node !== \"object\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query clause\n */\nexport interface SearchQueryClause {\n presence: lunr.Query.presence /* Clause presence */\n term: string /* Clause term */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search query terms\n */\nexport type SearchQueryTerms = Record\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Parse a search query for analysis\n *\n * @param value - Query value\n *\n * @returns Search query clauses\n */\nexport function parseSearchQuery(\n value: string\n): SearchQueryClause[] {\n const query = new (lunr as any).Query([\"title\", \"text\"])\n const parser = new (lunr as any).QueryParser(value, query)\n\n /* Parse and return query clauses */\n parser.parse()\n return query.clauses\n}\n\n/**\n * Analyze the search query clauses in regard to the search terms found\n *\n * @param query - Search query clauses\n * @param terms - Search terms\n *\n * @returns Search query terms\n */\nexport function getSearchQueryTerms(\n query: SearchQueryClause[], terms: string[]\n): SearchQueryTerms {\n const clauses = new Set(query)\n\n /* Match query clauses against terms */\n const result: SearchQueryTerms = {}\n for (let t = 0; t < terms.length; t++)\n for (const clause of clauses)\n if (terms[t].startsWith(clause.term)) {\n result[clause.term] = true\n clauses.delete(clause)\n }\n\n /* Annotate unmatched non-stopword query clauses */\n for (const clause of clauses)\n if (lunr.stopWordFilter?.(clause.term as any))\n result[clause.term] = false\n\n /* Return query terms */\n return result\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n SearchDocument,\n SearchDocumentMap,\n setupSearchDocumentMap\n} from \"../document\"\nimport {\n SearchHighlightFactoryFn,\n setupSearchHighlighter\n} from \"../highlighter\"\nimport { SearchOptions } from \"../options\"\nimport {\n SearchQueryTerms,\n getSearchQueryTerms,\n parseSearchQuery\n} from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index configuration\n */\nexport interface SearchIndexConfig {\n lang: string[] /* Search languages */\n separator: string /* Search separator */\n}\n\n/**\n * Search index document\n */\nexport interface SearchIndexDocument {\n location: string /* Document location */\n title: string /* Document title */\n text: string /* Document text */\n tags?: string[] /* Document tags */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search index\n *\n * This interfaces describes the format of the `search_index.json` file which\n * is automatically built by the MkDocs search plugin.\n */\nexport interface SearchIndex {\n config: SearchIndexConfig /* Search index configuration */\n docs: SearchIndexDocument[] /* Search index documents */\n options: SearchOptions /* Search options */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search metadata\n */\nexport interface SearchMetadata {\n score: number /* Score (relevance) */\n terms: SearchQueryTerms /* Search query terms */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result document\n */\nexport type SearchResultDocument = SearchDocument & SearchMetadata\n\n/**\n * Search result item\n */\nexport type SearchResultItem = SearchResultDocument[]\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result\n */\nexport interface SearchResult {\n items: SearchResultItem[] /* Search result items */\n suggestions?: string[] /* Search suggestions */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute the difference of two lists of strings\n *\n * @param a - 1st list of strings\n * @param b - 2nd list of strings\n *\n * @returns Difference\n */\nfunction difference(a: string[], b: string[]): string[] {\n const [x, y] = [new Set(a), new Set(b)]\n return [\n ...new Set([...x].filter(value => !y.has(value)))\n ]\n}\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n */\nexport class Search {\n\n /**\n * Search document mapping\n *\n * A mapping of URLs (including hash fragments) to the actual articles and\n * sections of the documentation. The search document mapping must be created\n * regardless of whether the index was prebuilt or not, as Lunr.js itself\n * only stores the actual index.\n */\n protected documents: SearchDocumentMap\n\n /**\n * Search highlight factory function\n */\n protected highlight: SearchHighlightFactoryFn\n\n /**\n * The underlying Lunr.js search index\n */\n protected index: lunr.Index\n\n /**\n * Search options\n */\n protected options: SearchOptions\n\n /**\n * Create the search integration\n *\n * @param data - Search index\n */\n public constructor({ config, docs, options }: SearchIndex) {\n this.options = options\n\n /* Set up document map and highlighter factory */\n this.documents = setupSearchDocumentMap(docs)\n this.highlight = setupSearchHighlighter(config, false)\n\n /* Set separator for tokenizer */\n lunr.tokenizer.separator = new RegExp(config.separator)\n\n /* Create search index */\n this.index = lunr(function () {\n\n /* Set up multi-language support */\n if (config.lang.length === 1 && config.lang[0] !== \"en\") {\n this.use((lunr as any)[config.lang[0]])\n } else if (config.lang.length > 1) {\n this.use((lunr as any).multiLanguage(...config.lang))\n }\n\n /* Compute functions to be removed from the pipeline */\n const fns = difference([\n \"trimmer\", \"stopWordFilter\", \"stemmer\"\n ], options.pipeline)\n\n /* Remove functions from the pipeline for registered languages */\n for (const lang of config.lang.map(language => (\n language === \"en\" ? lunr : (lunr as any)[language]\n ))) {\n for (const fn of fns) {\n this.pipeline.remove(lang[fn])\n this.searchPipeline.remove(lang[fn])\n }\n }\n\n /* Set up reference */\n this.ref(\"location\")\n\n /* Set up fields */\n this.field(\"title\", { boost: 1e3 })\n this.field(\"text\")\n this.field(\"tags\", { boost: 1e6 })\n\n /* Index documents */\n for (const doc of docs)\n this.add(doc)\n })\n }\n\n /**\n * Search for matching documents\n *\n * The search index which MkDocs provides is divided up into articles, which\n * contain the whole content of the individual pages, and sections, which only\n * contain the contents of the subsections obtained by breaking the individual\n * pages up at `h1` ... `h6`. As there may be many sections on different pages\n * with identical titles (for example within this very project, e.g. \"Usage\"\n * or \"Installation\"), they need to be put into the context of the containing\n * page. For this reason, section results are grouped within their respective\n * articles which are the top-level results that are returned.\n *\n * @param query - Query value\n *\n * @returns Search results\n */\n public search(query: string): SearchResult {\n if (query) {\n try {\n const highlight = this.highlight(query)\n\n /* Parse query to extract clauses for analysis */\n const clauses = parseSearchQuery(query)\n .filter(clause => (\n clause.presence !== lunr.Query.presence.PROHIBITED\n ))\n\n /* Perform search and post-process results */\n const groups = this.index.search(`${query}*`)\n\n /* Apply post-query boosts based on title and search query terms */\n .reduce((item, { ref, score, matchData }) => {\n const document = this.documents.get(ref)\n if (typeof document !== \"undefined\") {\n const { location, title, text, tags, parent } = document\n\n /* Compute and analyze search query terms */\n const terms = getSearchQueryTerms(\n clauses,\n Object.keys(matchData.metadata)\n )\n\n /* Highlight title and text and apply post-query boosts */\n const boost = +!parent + +Object.values(terms).every(t => t)\n item.push({\n location,\n title: highlight(title),\n text: highlight(text),\n ...tags && { tags: tags.map(highlight) },\n score: score * (1 + boost),\n terms\n })\n }\n return item\n }, [])\n\n /* Sort search results again after applying boosts */\n .sort((a, b) => b.score - a.score)\n\n /* Group search results by page */\n .reduce((items, result) => {\n const document = this.documents.get(result.location)\n if (typeof document !== \"undefined\") {\n const ref = \"parent\" in document\n ? document.parent!.location\n : document.location\n items.set(ref, [...items.get(ref) || [], result])\n }\n return items\n }, new Map())\n\n /* Generate search suggestions, if desired */\n let suggestions: string[] | undefined\n if (this.options.suggestions) {\n const titles = this.index.query(builder => {\n for (const clause of clauses)\n builder.term(clause.term, {\n fields: [\"title\"],\n presence: lunr.Query.presence.REQUIRED,\n wildcard: lunr.Query.wildcard.TRAILING\n })\n })\n\n /* Retrieve suggestions for best match */\n suggestions = titles.length\n ? Object.keys(titles[0].matchData.metadata)\n : []\n }\n\n /* Return items and suggestions */\n return {\n items: [...groups.values()],\n ...typeof suggestions !== \"undefined\" && { suggestions }\n }\n\n /* Log errors to console (for now) */\n } catch {\n console.warn(`Invalid query: ${query} \u2013 see https://bit.ly/2s3ChXG`)\n }\n }\n\n /* Return nothing in case of error or empty query */\n return { items: [] }\n }\n}\n"], - "mappings": "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", - "names": [] -} diff --git a/test/assets/stylesheets/main.e411adfe.min.css b/test/assets/stylesheets/main.e411adfe.min.css deleted file mode 100644 index 6a5a6a542ba3..000000000000 --- a/test/assets/stylesheets/main.e411adfe.min.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:transparent;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-default-fg-color:rgba(0,0,0,.87);--md-default-fg-color--light:rgba(0,0,0,.54);--md-default-fg-color--lighter:rgba(0,0,0,.32);--md-default-fg-color--lightest:rgba(0,0,0,.07);--md-default-bg-color:#fff;--md-default-bg-color--light:hsla(0,0%,100%,.7);--md-default-bg-color--lighter:hsla(0,0%,100%,.3);--md-default-bg-color--lightest:hsla(0,0%,100%,.12);--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.05),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.35)}:root>*{--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:rgba(255,255,0,.5);--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:rgba(255,255,0,.5);--md-typeset-del-color:rgba(245,80,61,.15);--md-typeset-ins-color:rgba(11,213,112,.15);--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:rgba(0,0,0,.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:hsla(0,0%,100%,.7);--md-footer-fg-color--lighter:hsla(0,0%,100%,.3);--md-footer-bg-color:rgba(0,0,0,.87);--md-footer-bg-color--dark:rgba(0,0,0,.32)}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}body,input{font-feature-settings:"kern","liga";font-family:var(--md-text-font-family)}body,code,input,kbd,pre{color:var(--md-typeset-color)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;-moz-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}@media (hover:none){.md-typeset abbr{position:relative}.md-typeset abbr[title]:-webkit-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}.md-typeset abbr[title]:-moz-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}[dir=ltr] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:is(:focus,:hover):after{left:0}[dir=rtl] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:is(:focus,:hover):after{right:0}.md-typeset abbr[title]:is(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg{height:auto;max-width:100%}.md-typeset img[align=left],.md-typeset svg[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right],.md-typeset svg[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child,.md-typeset svg[align]:only-child{margin-top:0}.md-typeset img[src$="#gh-dark-mode-only"],.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) th a{color:inherit}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:rgba(0,0,0,.035);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.9375em){body[data-md-state=lock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{float:right;margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}[dir=rtl] .md-content__button{float:left}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog[data-md-state=open]{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{display:flex;justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,:hover){color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem transparent,0 .2rem .4rem transparent;color:var(--md-primary-bg-color);left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[data-md-state=shadow]{box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header[data-md-state=hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title[data-md-state=active] .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title[data-md-state=active] .md-header__topic{transform:translateX(1.25rem)}.md-header__title[data-md-state=active] .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;justify-content:space-between;margin-top:.625em;overflow:hidden;scroll-snap-align:start;text-overflow:ellipsis;transition:color 125ms}.md-nav__link[data-md-state=blur]{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__item .md-nav__link--index [href]{width:100%}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__link>*{cursor:pointer;display:flex}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest);padding:0}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.9375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700;pointer-events:none}.md-nav__item--section>.md-nav__link--index [href]{pointer-events:auto}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;float:right;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{float:left;transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{font-weight:700;margin-top:0;padding:0 .6rem;pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link--index [href]{pointer-events:auto}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:rgba(0,0,0,.54);cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){.md-search__inner{float:right;padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}[dir=rtl] .md-search__inner{float:left}}@media screen and (min-width:60em) and (max-width:76.1875em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem transparent;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:rgba(0,0,0,.26);border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:hsla(0,0%,100%,.12)}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem rgba(0,0,0,.07);color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:transparent;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::-moz-placeholder{-moz-transition:color .25s;transition:color .25s}.md-search__input::-ms-input-placeholder{-ms-transition:color .25s;transition:color .25s}.md-search__input::placeholder{transition:color .25s}.md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.9375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::-moz-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.9375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more summary{color:var(--md-typeset-a-color);cursor:pointer;display:block;font-size:.64rem;outline:none;padding:.75em .8rem;scroll-snap-align:start;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more summary{padding-left:2.2rem}[dir=rtl] .md-search-result__more summary{padding-right:2.2rem}}.md-search-result__more summary:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary::marker{display:none}.md-search-result__more summary::-webkit-details-marker{display:none}.md-search-result__more summary~*>*{opacity:.65}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}.md-search-result__article--document .md-search-result__title{font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.9375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result__title{font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result__teaser{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-default-fg-color--light);display:-webkit-box;font-size:.64rem;line-height:1.6;margin:.5em 0;max-height:2rem;overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:44.9375em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}.md-search-result__teaser mark{background-color:initial;text-decoration:underline}.md-search-result__terms{font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color)}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid transparent;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid transparent;border-right:.2rem solid transparent;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;-ms-scroll-snap-type:none;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media screen and (max-width:76.1875em){.md-overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@-webkit-keyframes facts{0%{height:0}to{height:.65rem}}@keyframes facts{0%{height:0}to{height:.65rem}}@-webkit-keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{font-size:.55rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0}[data-md-state=done] .md-source__facts{-webkit-animation:facts .25s ease-in;animation:facts .25s ease-in}.md-source__fact{display:inline-block}[data-md-state=done] .md-source__fact{-webkit-animation:fact .4s ease-out;animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}[dir=ltr] .md-source__fact:nth-child(1n+2):before{margin-left:.4rem}[dir=rtl] .md-source__fact:nth-child(1n+2):before{margin-right:.4rem}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);overflow:auto;width:100%}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs[data-md-state=hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;list-style:none;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:inline-block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[data-md-state=hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}.md-tags{margin-bottom:.75em}[dir=ltr] .md-tag{margin-right:.5em}[dir=rtl] .md-tag{margin-left:.5em}.md-tag{background:var(--md-default-fg-color--lightest);border-radius:.4rem;display:inline-block;font-size:.64rem;font-weight:700;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-tag[href]:focus,.md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-tag{vertical-align:text-top}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}:root{--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),(100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem));max-height:0;max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,max-height 0ms .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}:focus-within>.md-tooltip{max-height:1000%;opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height .25s,z-index 0ms}.focus-visible>.md-tooltip{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation:focus-within>*{z-index:2}.md-annotation__inner{font-family:var(--md-text-font-family);top:calc(var(--md-tooltip-y) + 1.2ch)}:not(:focus-within)>.md-annotation__inner{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-annotation__index{color:#fff;cursor:pointer;margin:0 1ch;position:relative;transition:z-index .25s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0}.md-annotation__index:after{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.126em;margin:0 -.4ch;padding:0 .4ch;position:absolute;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media (prefers-reduced-motion){.md-annotation__index:after{-webkit-animation:none;animation:none}}:-webkit-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:is(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:focus-within>.md-annotation__index:after{-webkit-animation:none;animation:none;transition:color .25s,background-color .25s}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}:-webkit-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:is(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:focus-within>.md-annotation__index{-webkit-animation:none;animation:none;transition:none}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[data-md-state=hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[data-md-state=hidden]{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@-webkit-keyframes hoverfix{0%{pointer-events:none}}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{-webkit-animation:hoverfix .25s forwards;animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{-webkit-animation:none;animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset :-webkit-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}.md-typeset :-moz-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}[dir=ltr] .md-typeset :-webkit-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition,details){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition,details){border-right-width:.2rem}.md-typeset :is(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}@media print{.md-typeset :-webkit-any(.admonition,details){box-shadow:none}.md-typeset :-moz-any(.admonition,details){box-shadow:none}.md-typeset :is(.admonition,details){box-shadow:none}}.md-typeset :-webkit-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :-moz-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :is(.admonition,details)>*{box-sizing:border-box}.md-typeset :-webkit-any(.admonition,details) :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-moz-any(.admonition,details) :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :is(.admonition,details) :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-webkit-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :is(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-webkit-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :is(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-webkit-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :-moz-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :is(.admonition,details)>.tabbed-set:only-child{margin-top:0}html .md-typeset :-webkit-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :-moz-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :is(.admonition,details)>:last-child{margin-bottom:.6rem}.md-typeset :-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}.md-typeset :-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-right-width:.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}.md-typeset :is(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset :-webkit-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :-moz-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :is(.admonition-title,summary):last-child{margin-bottom:0}.md-typeset :-webkit-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-moz-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain;position:absolute;top:.625em;width:1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :is(.admonition-title,summary):before{left:.8rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary):before{right:.8rem}.md-typeset :is(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color);display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,td){display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;-ms-scroll-snap-type:x proximity;scroll-snap-type:x proximity;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid transparent;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-snap-align:start;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-accent-fg-color)}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.tabbed-set{margin:0}@media screen and (max-width:44.9375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-accent-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){background-color:var(--md-accent-fg-color--transparent)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color)}.mermaid{line-height:normal;margin:1em 0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{float:left;margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}.md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}} \ No newline at end of file diff --git a/test/assets/stylesheets/main.e411adfe.min.css.map b/test/assets/stylesheets/main.e411adfe.min.css.map deleted file mode 100644 index 6f41c2b02d94..000000000000 --- a/test/assets/stylesheets/main.e411adfe.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["src/assets/stylesheets/main/extensions/pymdownx/_keys.scss","../../../src/assets/stylesheets/main.scss","src/assets/stylesheets/main/_resets.scss","src/assets/stylesheets/main/_colors.scss","src/assets/stylesheets/main/_icons.scss","src/assets/stylesheets/main/_typeset.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/main/layout/_banner.scss","src/assets/stylesheets/main/layout/_base.scss","src/assets/stylesheets/main/layout/_clipboard.scss","src/assets/stylesheets/main/layout/_content.scss","src/assets/stylesheets/main/layout/_dialog.scss","src/assets/stylesheets/main/layout/_footer.scss","src/assets/stylesheets/main/layout/_form.scss","src/assets/stylesheets/main/layout/_header.scss","src/assets/stylesheets/main/layout/_nav.scss","src/assets/stylesheets/main/layout/_search.scss","src/assets/stylesheets/main/layout/_select.scss","src/assets/stylesheets/main/layout/_sidebar.scss","src/assets/stylesheets/main/layout/_source.scss","src/assets/stylesheets/main/layout/_tabs.scss","src/assets/stylesheets/main/layout/_tag.scss","src/assets/stylesheets/main/layout/_tooltip.scss","src/assets/stylesheets/main/layout/_top.scss","src/assets/stylesheets/main/layout/_version.scss","src/assets/stylesheets/main/extensions/markdown/_admonition.scss","node_modules/material-design-color/material-color.scss","src/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/assets/stylesheets/main/extensions/markdown/_toc.scss","src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/assets/stylesheets/main/integrations/_mermaid.scss","src/assets/stylesheets/main/_modifiers.scss"],"names":[],"mappings":"AAgGM,gBCyvGN,CC7zGA,KAEE,6BAAA,CAAA,0BAAA,CAAA,yBAAA,CAAA,qBAAA,CADA,qBDzBF,CC8BA,iBAGE,kBD3BF,CC8BE,gCANF,iBAOI,yBDzBF,CACF,CC6BA,KACE,QD1BF,CC8BA,qBAIE,uCD3BF,CC+BA,EACE,aAAA,CACA,oBD5BF,CCgCA,GAME,QAAA,CAJA,kBAAA,CADA,aAAA,CAEA,aAAA,CAEA,gBAAA,CADA,SD3BF,CCiCA,MACE,aD9BF,CCkCA,QAEE,eD/BF,CCmCA,IACE,iBDhCF,CCoCA,MACE,uBAAA,CACA,gBDjCF,CCqCA,MAEE,eAAA,CACA,kBDlCF,CCsCA,OAKE,sBAAA,CACA,QAAA,CAFA,mBAAA,CADA,iBAAA,CAFA,QAAA,CACA,SD/BF,CCuCA,MACE,QAAA,CACA,YDpCF,CErDA,MAGE,qCAAA,CACA,4CAAA,CACA,8CAAA,CACA,+CAAA,CACA,0BAAA,CACA,+CAAA,CACA,iDAAA,CACA,mDAAA,CAGA,6BAAA,CACA,oCAAA,CACA,mCAAA,CACA,0BAAA,CACA,+CAAA,CAGA,4BAAA,CACA,qDAAA,CACA,yBAAA,CACA,8CAAA,CA0DA,yEAAA,CAKA,yEAAA,CAKA,yEFTF,CExDE,QAGE,0BAAA,CACA,0BAAA,CAGA,qCAAA,CACA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,0CAAA,CAGA,0CAAA,CACA,2CAAA,CAGA,8BAAA,CACA,kCAAA,CACA,qCAAA,CAGA,wCAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,yBAAA,CACA,8CAAA,CACA,gDAAA,CACA,oCAAA,CACA,0CFsCJ,CGhHE,aAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,YHqHJ,CI1HA,KACE,kCAAA,CACA,iCAAA,CAGA,uGAAA,CAKA,mFJ2HF,CIrHA,WAGE,mCAAA,CACA,sCJwHF,CIpHA,wBANE,6BJkIF,CI5HA,aAIE,4BAAA,CACA,sCJuHF,CI/GA,MACE,0NAAA,CACA,mNAAA,CACA,oNJkHF,CI3GA,YAGE,gCAAA,CAAA,6BAAA,CAAA,kBAAA,CAFA,eAAA,CACA,eJ+GF,CI1GE,aAPF,YAQI,gBJ6GF,CACF,CI1GE,uGAME,iBAAA,CAAA,cJ4GJ,CIxGE,eAEE,uCAAA,CAEA,aAAA,CACA,eAAA,CAJA,iBJ+GJ,CItGE,8BAPE,eAAA,CAGA,qBJiHJ,CI7GE,eAGE,kBAAA,CACA,eAAA,CAHA,oBJ4GJ,CIpGE,eAGE,gBAAA,CADA,eAAA,CAGA,qBAAA,CADA,eAAA,CAHA,mBJ0GJ,CIlGE,kBACE,eJoGJ,CIhGE,eAEE,eAAA,CACA,qBAAA,CAFA,YJoGJ,CI9FE,8BAGE,uCAAA,CAEA,cAAA,CADA,eAAA,CAEA,qBAAA,CAJA,eJoGJ,CI5FE,eACE,wBJ8FJ,CI1FE,eAGE,+DAAA,CAFA,iBAAA,CACA,cJ6FJ,CIxFE,cACE,+BAAA,CACA,qBJ0FJ,CIvFI,mCAEE,sBJwFN,CIpFI,wCAEE,+BJqFN,CIlFM,kDACE,uDJoFR,CI/EI,mBACE,kBAAA,CACA,iCJiFN,CI7EI,4BACE,uCAAA,CACA,oBJ+EN,CI1EE,iDAGE,6BAAA,CACA,aJ4EJ,CIzEI,aAPF,iDAQI,oBJ8EJ,CACF,CI1EE,iBAIE,wCAAA,CACA,mBAAA,CACA,kCAAA,CAAA,0BAAA,CAJA,eAAA,CADA,uBAAA,CAEA,qBJ+EJ,CIzEI,qCAEE,uCAAA,CADA,YJ4EN,CItEE,gBAEE,iBAAA,CACA,eAAA,CAFA,iBJ0EJ,CIrEI,qBAQE,kCAAA,CAAA,0BAAA,CADA,eAAA,CANA,aAAA,CACA,QAAA,CAIA,uCAAA,CAFA,aAAA,CADA,oCAAA,CAQA,+DAAA,CADA,oBAAA,CADA,iBAAA,CAJA,iBJ6EN,CIpEM,2BACE,qDJsER,CIlEM,wCAEE,YAAA,CADA,WJqER,CIhEM,8CACE,oDJkER,CI/DQ,oDACE,0CJiEV,CI1DE,gBAOE,4CAAA,CACA,mBAAA,CACA,mKACE,CAPF,gCAAA,CAFA,oBAAA,CAGA,eAAA,CAFA,uBAAA,CAGA,uBAAA,CACA,qBJ+DJ,CIrDE,iBAGE,6CAAA,CACA,kCAAA,CAAA,0BAAA,CAHA,aAAA,CACA,qBJyDJ,CInDE,iBAEE,6DAAA,CACA,WAAA,CAFA,oBJuDJ,CIlDI,oBANF,iBAOI,iBJqDJ,CIlDI,yDAWE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CAKA,mBAAA,CAXA,oBAAA,CAOA,eAAA,CAHA,cAAA,CADA,aAAA,CADA,6BAAA,CAAA,qBAAA,CAGA,mBAAA,CAPA,iBAAA,CAGA,UJ8DN,CIlEI,sDAWE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CAKA,mBAAA,CAXA,oBAAA,CAOA,eAAA,CAHA,cAAA,CADA,aAAA,CADA,0BAAA,CAAA,qBAAA,CAGA,mBAAA,CAPA,iBAAA,CAGA,UJ8DN,CIlEI,mEAEE,MJgEN,CIlEI,gEAEE,MJgEN,CIlEI,0DAEE,MJgEN,CIlEI,mEAEE,OJgEN,CIlEI,gEAEE,OJgEN,CIlEI,0DAEE,OJgEN,CIlEI,gDAWE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CAKA,mBAAA,CAXA,oBAAA,CAOA,eAAA,CAHA,cAAA,CADA,aAAA,CADA,6BAAA,CAAA,0BAAA,CAAA,qBAAA,CAGA,mBAAA,CAPA,iBAAA,CAGA,UJ8DN,CACF,CI/CE,kBACE,WJiDJ,CI7CE,oDAEE,qBJ+CJ,CIjDE,oDAEE,sBJ+CJ,CI3CE,iCACE,kBJgDJ,CIjDE,iCACE,mBJgDJ,CIjDE,iCAIE,2DJ6CJ,CIjDE,iCAIE,4DJ6CJ,CIjDE,uBAGE,uCAAA,CADA,aAAA,CAAA,cJ+CJ,CIzCE,eACE,oBJ2CJ,CIvCE,kDAEE,kBJ0CJ,CI5CE,kDAEE,mBJ0CJ,CI5CE,8BAGE,SJyCJ,CItCI,0DACE,iBJyCN,CIrCI,oCACE,2BJwCN,CIrCM,0CACE,2BJwCR,CInCI,wDAEE,kBJsCN,CIxCI,wDAEE,mBJsCN,CIxCI,oCACE,kBJuCN,CInCM,kGAEE,aJuCR,CInCM,0DACE,eJsCR,CIlCM,4EACE,kBAAA,CAAA,eJsCR,CIvCM,sEACE,kBAAA,CAAA,eJsCR,CIvCM,gGAEE,kBJqCR,CIvCM,0FAEE,kBJqCR,CIvCM,8EAEE,kBJqCR,CIvCM,gGAEE,mBJqCR,CIvCM,0FAEE,mBJqCR,CIvCM,8EAEE,mBJqCR,CIvCM,0DACE,kBAAA,CAAA,eJsCR,CI/BE,yBAEE,mBJiCJ,CInCE,yBAEE,oBJiCJ,CInCE,eACE,mBAAA,CAAA,cJkCJ,CI7BE,gCAGE,WAAA,CADA,cJgCJ,CI5BI,wDAEE,oBJ+BN,CI3BI,0DAEE,oBJ8BN,CI1BI,oEACE,YJ6BN,CIxBE,8EAEE,YJ0BJ,CItBE,mBACE,iBAAA,CAGA,eAAA,CADA,cAAA,CAEA,iBAAA,CAHA,yBAAA,CAAA,sBAAA,CAAA,iBJ2BJ,CIrBI,uBACE,aJuBN,CIlBE,uBAGE,iBAAA,CADA,eAAA,CADA,eJsBJ,CIhBE,mBACE,cJkBJ,CIdE,+BAKE,2CAAA,CACA,iDAAA,CACA,mBAAA,CANA,oBAAA,CAGA,gBAAA,CAFA,cAAA,CACA,aAAA,CAKA,iBJgBJ,CIbI,aAXF,+BAYI,aJgBJ,CACF,CIXI,iCACE,gBJaN,CINM,gEACE,YJQR,CITM,6DACE,YJQR,CITM,uDACE,YJQR,CIJM,+DACE,eJMR,CIPM,4DACE,eJMR,CIPM,sDACE,eJMR,CIDI,gEACE,eJGN,CIJI,6DACE,eJGN,CIJI,uDACE,eJGN,CIAM,0EACE,gBJER,CIHM,uEACE,gBJER,CIHM,iEACE,gBJER,CIGI,kCAGE,eAAA,CAFA,cAAA,CACA,sBAAA,CAEA,kBJDN,CIIM,oCACE,aJFR,CIOI,kCAGE,qDAAA,CAFA,sBAAA,CACA,kBJJN,CISI,wCACE,iCJPN,CIUM,8CACE,iCAAA,CACA,sDJRR,CIaI,iCACE,iBJXN,CIgBE,wCACE,cJdJ,CIiBI,wDAIE,gBJTN,CIKI,wDAIE,iBJTN,CIKI,8CAUE,UAAA,CATA,oBAAA,CAEA,YAAA,CAGA,oDAAA,CAAA,4CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CACA,iCAAA,CAJA,0BAAA,CAHA,WJPN,CImBI,oDACE,oDJjBN,CIqBI,mEACE,kDAAA,CACA,yDAAA,CAAA,iDJnBN,CIuBI,oEACE,kDAAA,CACA,0DAAA,CAAA,kDJrBN,CI0BE,wBACE,iBAAA,CACA,eAAA,CACA,iBJxBJ,CI4BE,mBACE,oBAAA,CACA,kBAAA,CACA,eJ1BJ,CI6BI,aANF,mBAOI,aJ1BJ,CACF,CI6BI,8BACE,aAAA,CAEA,QAAA,CACA,eAAA,CAFA,UJzBN,CKjWI,wCDyYF,uBACE,iBJpCF,CIuCE,4BACE,eJrCJ,CACF,CMniBA,WAGE,0CAAA,CADA,+BAAA,CADA,aNuiBF,CMliBE,aANF,WAOI,YNqiBF,CACF,CMliBE,oBAEE,uCAAA,CADA,gCNqiBJ,CMhiBE,kBAGE,eAAA,CAFA,iBAAA,CACA,eNmiBJ,COtjBA,KASE,cAAA,CARA,WAAA,CACA,iBP0jBF,CKtZI,oCEtKJ,KAaI,gBPmjBF,CACF,CK3ZI,oCEtKJ,KAkBI,cPmjBF,CACF,CO9iBA,KASE,2CAAA,CAPA,YAAA,CACA,qBAAA,CAKA,eAAA,CAHA,eAAA,CAJA,iBAAA,CAGA,UPojBF,CO5iBE,aAZF,KAaI,aP+iBF,CACF,CK5ZI,wCEhJF,yBAII,cP4iBJ,CACF,COniBA,SAEE,gBAAA,CAAA,iBAAA,CADA,ePuiBF,COliBA,cACE,YAAA,CACA,qBAAA,CACA,WPqiBF,COliBE,aANF,cAOI,aPqiBF,CACF,COjiBA,SACE,WPoiBF,COjiBE,gBACE,YAAA,CACA,WAAA,CACA,iBPmiBJ,CO9hBA,aACE,eAAA,CAEA,sBAAA,CADA,kBPkiBF,COxhBA,WACE,YP2hBF,COthBA,WAGE,QAAA,CACA,SAAA,CAHA,iBAAA,CACA,OP2hBF,COthBE,uCACE,aPwhBJ,COphBE,+BAEE,uCAAA,CADA,kBPuhBJ,COjhBA,SASE,2CAAA,CACA,mBAAA,CAHA,gCAAA,CACA,gBAAA,CAHA,YAAA,CAQA,SAAA,CAFA,uCAAA,CALA,mBAAA,CALA,cAAA,CAWA,2BAAA,CARA,UP2hBF,CO/gBE,eAGE,SAAA,CADA,uBAAA,CAEA,oEACE,CAJF,UPohBJ,COtgBA,MACE,WPygBF,CQnqBA,MACE,+PRqqBF,CQ/pBA,cAQE,mBAAA,CADA,0CAAA,CAIA,cAAA,CALA,YAAA,CAGA,uCAAA,CACA,oBAAA,CATA,iBAAA,CAEA,UAAA,CADA,QAAA,CAUA,qBAAA,CAPA,WAAA,CADA,SR0qBF,CQ/pBE,aAfF,cAgBI,YRkqBF,CACF,CQ/pBE,kCAEE,uCAAA,CADA,YRkqBJ,CQ7pBE,qBACE,uCR+pBJ,CQ3pBE,yCACE,+BR6pBJ,CQ9pBE,sCACE,+BR6pBJ,CQ9pBE,gCACE,+BR6pBJ,CQxpBE,oBAKE,6BAAA,CAIA,UAAA,CARA,aAAA,CAEA,cAAA,CACA,aAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CANA,aRiqBJ,CQtpBE,sBACE,cRwpBJ,CQrpBI,2BACE,2CRupBN,CQjpBI,sDAEE,uDAAA,CADA,+BRopBN,CQrpBI,mDAEE,uDAAA,CADA,+BRopBN,CQrpBI,6CAEE,uDAAA,CADA,+BRopBN,CSztBA,YACE,WAAA,CAIA,WTytBF,CSttBE,mBACE,qBAAA,CACA,iBTwtBJ,CK5jBI,sCItJE,4EACE,kBTqtBN,CSjtBI,0JACE,mBTmtBN,CSptBI,8EACE,kBTmtBN,CACF,CS9sBI,0BAGE,UAAA,CAFA,aAAA,CACA,YTitBN,CS5sBI,+BACE,eT8sBN,CSxsBE,8BAGE,iBT2sBJ,CS9sBE,8BAGE,kBT2sBJ,CS9sBE,oBACE,WAAA,CACA,cAAA,CAEA,ST0sBJ,CSvsBI,aAPF,oBAQI,YT0sBJ,CACF,CSvsBI,8BACE,UTysBN,CSrsBI,gCACE,yCTusBN,CSnsBI,wBACE,cAAA,CACA,kBTqsBN,CSlsBM,kCACE,oBTosBR,CU1wBA,qBAEE,WVwxBF,CU1xBA,qBAEE,UVwxBF,CU1xBA,WAOE,2CAAA,CACA,mBAAA,CALA,YAAA,CAMA,8BAAA,CAJA,iBAAA,CAMA,SAAA,CALA,mBAAA,CASA,mBAAA,CAdA,cAAA,CASA,0BAAA,CAEA,wCACE,CATF,SVsxBF,CUxwBE,aAlBF,WAmBI,YV2wBF,CACF,CUxwBE,+BAEE,SAAA,CAIA,mBAAA,CALA,uBAAA,CAEA,kEV2wBJ,CUpwBE,kBACE,gCAAA,CACA,eVswBJ,CWzyBA,WAEE,0CAAA,CADA,+BX6yBF,CWzyBE,aALF,WAMI,YX4yBF,CACF,CWzyBE,kBACE,YAAA,CACA,6BAAA,CAEA,aAAA,CADA,aX4yBJ,CWvyBE,iBACE,YAAA,CAKA,cAAA,CAIA,uCAAA,CADA,eAAA,CADA,oBAAA,CADA,kBAAA,CAIA,uBXqyBJ,CWlyBI,4CACE,UXoyBN,CWryBI,yCACE,UXoyBN,CWryBI,mCACE,UXoyBN,CWhyBI,+BACE,oBXkyBN,CK/oBI,wCMzII,yCACE,YX2xBR,CACF,CWtxBI,iCACE,gBXyxBN,CW1xBI,iCACE,iBXyxBN,CW1xBI,uBAEE,gBXwxBN,CWrxBM,iCACE,eXuxBR,CWjxBE,kBAEE,WAAA,CAGA,eAAA,CACA,kBAAA,CAHA,6BAAA,CACA,cAAA,CAHA,iBXwxBJ,CW/wBE,mBACE,YAAA,CACA,aXixBJ,CW7wBE,sBAKE,gBAAA,CAHA,MAAA,CACA,gBAAA,CAGA,UAAA,CAFA,cAAA,CAHA,iBAAA,CACA,OXmxBJ,CW1wBA,gBACE,gDX6wBF,CW1wBE,uBACE,YAAA,CACA,cAAA,CACA,6BAAA,CACA,aX4wBJ,CWxwBE,kCACE,sCX0wBJ,CWvwBI,6DACE,+BXywBN,CW1wBI,0DACE,+BXywBN,CW1wBI,oDACE,+BXywBN,CWjwBA,cAIE,wCAAA,CACA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAFA,UXwwBF,CK1tBI,mCM/CJ,cASI,UXowBF,CACF,CWhwBE,yBACE,sCXkwBJ,CW3vBA,WACE,cAAA,CACA,qBX8vBF,CKvuBI,mCMzBJ,WAMI,eX8vBF,CACF,CW3vBE,iBACE,oBAAA,CAEA,aAAA,CACA,iBAAA,CAFA,YX+vBJ,CW1vBI,wBACE,eX4vBN,CWxvBI,qBAGE,iBAAA,CAFA,gBAAA,CACA,mBX2vBN,CY75BE,uBAKE,kBAAA,CACA,mBAAA,CAHA,gCAAA,CAIA,cAAA,CANA,oBAAA,CAGA,eAAA,CAFA,kBAAA,CAMA,gEZg6BJ,CY15BI,gCAEE,2CAAA,CACA,uCAAA,CAFA,gCZ85BN,CYx5BI,kDAEE,0CAAA,CACA,sCAAA,CAFA,+BZ45BN,CY75BI,+CAEE,0CAAA,CACA,sCAAA,CAFA,+BZ45BN,CY75BI,yCAEE,0CAAA,CACA,sCAAA,CAFA,+BZ45BN,CYr5BE,gCAKE,4BZ05BJ,CY/5BE,gEAME,6BZy5BJ,CY/5BE,gCAME,4BZy5BJ,CY/5BE,sBAIE,6DAAA,CAGA,8BAAA,CAJA,eAAA,CAFA,aAAA,CACA,eAAA,CAMA,sCZu5BJ,CYl5BI,iDACE,6CAAA,CACA,8BZo5BN,CYt5BI,8CACE,6CAAA,CACA,8BZo5BN,CYt5BI,wCACE,6CAAA,CACA,8BZo5BN,CYh5BI,+BACE,UZk5BN,Car8BA,WAME,2CAAA,CAGA,0DACE,CALF,gCAAA,CAFA,MAAA,CAFA,uBAAA,CAAA,eAAA,CAEA,OAAA,CADA,KAAA,CAEA,Sb28BF,Caj8BE,aAdF,WAeI,Ybo8BF,CACF,Caj8BE,iCACE,gEACE,CAEF,kEbi8BJ,Ca37BE,iCACE,2BAAA,CACA,iEb67BJ,Cav7BE,kBAEE,kBAAA,CADA,YAAA,CAEA,eby7BJ,Car7BE,mBAKE,kBAAA,CAGA,cAAA,CALA,YAAA,CAIA,uCAAA,CAHA,aAAA,CAHA,iBAAA,CAQA,uBAAA,CAHA,qBAAA,CAJA,Sb87BJ,Cap7BI,yBACE,Ubs7BN,Cal7BI,iCACE,oBbo7BN,Cah7BI,uCAEE,uCAAA,CADA,Ybm7BN,Ca96BI,2BACE,YAAA,CACA,abg7BN,CKl0BI,wCQhHA,2BAMI,Ybg7BN,CACF,Ca76BM,iDAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,Ubi7BR,Can7BM,8CAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,Ubi7BR,Can7BM,wCAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,Ubi7BR,CKh2BI,mCQ1EA,iCAII,Yb06BN,CACF,Cav6BM,wCACE,Yby6BR,Car6BM,+CACE,oBbu6BR,CK32BI,sCQvDA,iCAII,Ybk6BN,CACF,Ca75BE,kBAEE,YAAA,CACA,cAAA,CAFA,iBAAA,CAGA,8Db+5BJ,Ca15BI,oCAGE,SAAA,CAIA,mBAAA,CALA,6BAAA,CAEA,8DACE,CAJF,Ubg6BN,Cav5BM,8CACE,8Bby5BR,Cap5BI,8BACE,ebs5BN,Caj5BE,4BAGE,kBbs5BJ,Caz5BE,4BAGE,iBbs5BJ,Caz5BE,4BAIE,gBbq5BJ,Caz5BE,4BAIE,iBbq5BJ,Caz5BE,kBACE,WAAA,CAIA,eAAA,CAHA,aAAA,CAIA,kBbm5BJ,Cah5BI,0DAGE,SAAA,CAIA,mBAAA,CALA,8BAAA,CAEA,8DACE,CAJF,Ubs5BN,Ca74BM,oEACE,6Bb+4BR,Ca34BM,4EAGE,SAAA,CAIA,mBAAA,CALA,uBAAA,CAEA,8DACE,CAJF,Sbi5BR,Cat4BI,uCAGE,WAAA,CAFA,iBAAA,CACA,Uby4BN,Can4BE,mBACE,YAAA,CACA,aAAA,CACA,cAAA,CAEA,+CACE,CAFF,kBbs4BJ,Cah4BI,8DACE,WAAA,CACA,SAAA,CACA,oCbk4BN,Ca33BE,mBACE,Yb63BJ,CKh7BI,mCQkDF,6BAQI,gBb63BJ,Car4BA,6BAQI,iBb63BJ,Car4BA,mBAKI,aAAA,CAEA,iBAAA,CADA,ab+3BJ,CACF,CKx7BI,sCQkDF,6BAaI,kBb63BJ,Ca14BA,6BAaI,mBb63BJ,CACF,CcnmCA,MACE,0MAAA,CACA,gMAAA,CACA,yNdsmCF,CchmCA,QACE,eAAA,CACA,edmmCF,CchmCE,eACE,aAAA,CAGA,eAAA,CADA,eAAA,CADA,eAAA,CAGA,sBdkmCJ,Cc/lCI,+BACE,YdimCN,Cc9lCM,mCAEE,WAAA,CADA,UdimCR,CczlCQ,6DAME,iBAAA,CALA,aAAA,CAGA,aAAA,CADA,cAAA,CAEA,kBAAA,CAHA,Ud+lCV,CcjmCQ,0DAME,iBAAA,CALA,aAAA,CAGA,aAAA,CADA,cAAA,CAEA,kBAAA,CAHA,Ud+lCV,CcjmCQ,oDAME,iBAAA,CALA,aAAA,CAGA,aAAA,CADA,cAAA,CAEA,kBAAA,CAHA,Ud+lCV,CcplCE,cAGE,eAAA,CAFA,QAAA,CACA,SdulCJ,CcllCE,cACE,edolCJ,CcjlCI,sCACE,edmlCN,CcplCI,sCACE,cdmlCN,Cc9kCE,cAEE,kBAAA,CAKA,cAAA,CANA,YAAA,CAEA,6BAAA,CACA,iBAAA,CACA,eAAA,CAIA,uBAAA,CAHA,sBAAA,CAEA,sBdilCJ,Cc7kCI,kCACE,uCd+kCN,Cc3kCI,oCACE,+Bd6kCN,CczkCI,0CACE,Ud2kCN,CcvkCI,yCACE,+BdykCN,Cc1kCI,sCACE,+BdykCN,Cc1kCI,gCACE,+BdykCN,CcrkCI,4BACE,uCAAA,CACA,oBdukCN,CcnkCI,0CACE,YdqkCN,CclkCM,yDAKE,6BAAA,CAJA,aAAA,CAEA,WAAA,CACA,qCAAA,CAAA,6BAAA,CAFA,UdukCR,CchkCM,kDACE,YdkkCR,Cc7jCI,gBAEE,cAAA,CADA,YdgkCN,Cc1jCE,cACE,ad4jCJ,CcxjCE,gBACE,Yd0jCJ,CKxgCI,wCS3CA,0CASE,2CAAA,CAHA,YAAA,CACA,qBAAA,CACA,WAAA,CAJA,MAAA,CAFA,iBAAA,CAEA,OAAA,CADA,KAAA,CAEA,SdyjCJ,Cc9iCI,4DACE,eAAA,CACA,edgjCN,CcljCI,yDACE,eAAA,CACA,edgjCN,CcljCI,mDACE,eAAA,CACA,edgjCN,Cc5iCI,gCAOE,qDAAA,CAHA,uCAAA,CAIA,cAAA,CANA,aAAA,CAGA,kBAAA,CAFA,wBAAA,CAFA,iBAAA,CAKA,kBdgjCN,Cc3iCM,wDAGE,UdijCR,CcpjCM,wDAGE,WdijCR,CcpjCM,8CAIE,aAAA,CAEA,aAAA,CACA,YAAA,CANA,iBAAA,CACA,SAAA,CAGA,Yd+iCR,Cc1iCQ,oDAIE,6BAAA,CAIA,UAAA,CAPA,aAAA,CAEA,WAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,UdkjCV,CcviCM,8CAEE,2CAAA,CACA,gEACE,CAHF,eAAA,CAIA,gCAAA,CAAA,4BAAA,CACA,kBdwiCR,CcriCQ,2DACE,YduiCV,CcliCM,8CAGE,2CAAA,CAFA,gCAAA,CACA,edqiCR,CchiCM,yCAIE,aAAA,CADA,UAAA,CAEA,YAAA,CACA,aAAA,CALA,iBAAA,CAEA,WAAA,CADA,SdsiCR,Cc7hCI,+BACE,Md+hCN,Cc3hCI,+BAEE,4DAAA,CADA,Sd8hCN,Cc1hCM,qDACE,+Bd4hCR,CczhCQ,gFACE,+Bd2hCV,Cc5hCQ,6EACE,+Bd2hCV,Cc5hCQ,uEACE,+Bd2hCV,CcrhCI,+BACE,YAAA,CACA,mBduhCN,CcphCM,uDAGE,mBduhCR,Cc1hCM,uDAGE,kBduhCR,Cc1hCM,6CAIE,gBAAA,CAFA,aAAA,CADA,YdyhCR,CcnhCQ,mDAIE,6BAAA,CAIA,UAAA,CAPA,aAAA,CAEA,WAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,Ud2hCV,Cc5gCM,+CACE,mBd8gCR,CctgCM,4CAEE,wBAAA,CADA,edygCR,CcrgCQ,oEACE,mBdugCV,CcxgCQ,oEACE,oBdugCV,CcngCQ,4EACE,iBdqgCV,CctgCQ,4EACE,kBdqgCV,CcjgCQ,oFACE,mBdmgCV,CcpgCQ,oFACE,oBdmgCV,Cc//BQ,4FACE,mBdigCV,CclgCQ,4FACE,oBdigCV,Cc1/BE,mBACE,wBd4/BJ,Ccx/BE,wBACE,YAAA,CAEA,SAAA,CADA,0BAAA,CAEA,oEd0/BJ,Ccr/BI,kCACE,2Bdu/BN,Ccl/BE,gCAEE,SAAA,CADA,uBAAA,CAEA,qEdo/BJ,Cc/+BI,8CAEE,kCAAA,CAAA,0Bdg/BN,CACF,CKppCI,wCS4KA,0CACE,Yd2+BJ,Ccx+BI,yDACE,Ud0+BN,Cct+BI,wDACE,Ydw+BN,Ccp+BI,kDACE,Yds+BN,Ccj+BE,gBAIE,iDAAA,CADA,gCAAA,CAFA,aAAA,CACA,edq+BJ,CACF,CKjtCM,6DSqPF,6CACE,Yd+9BJ,Cc59BI,4DACE,Ud89BN,Cc19BI,2DACE,Yd49BN,Ccx9BI,qDACE,Yd09BN,CACF,CKzsCI,mCS0PE,6CACE,uBdk9BN,Cc98BI,gDACE,Ydg9BN,CACF,CKjtCI,sCS7JJ,QAoaI,oDd88BF,Ccx8BI,8CACE,uBd08BN,Cch8BE,sEACE,Ydq8BJ,Ccj8BE,6DACE,adm8BJ,Ccp8BE,0DACE,adm8BJ,Ccp8BE,oDACE,adm8BJ,Cc/7BE,6CACE,Ydi8BJ,Cc77BE,uBACE,aAAA,CACA,ed+7BJ,Cc57BI,kCACE,ed87BN,Cc17BI,qCACE,eAAA,CACA,mBd47BN,Ccz7BM,mDACE,mBd27BR,Ccv7BM,mDACE,Ydy7BR,Ccp7BI,+BACE,ads7BN,Ccn7BM,2DACE,Sdq7BR,Cc/6BE,cAIE,kBAAA,CAHA,WAAA,CAEA,YAAA,CAEA,+CACE,CAJF,Wdo7BJ,Cc56BI,wBACE,UAAA,CACA,wBd86BN,Cc16BI,oBACE,uDd46BN,Ccx6BI,oBAKE,6BAAA,CAIA,UAAA,CARA,oBAAA,CAEA,WAAA,CAGA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CAJA,qBAAA,CAFA,Udi7BN,Cct6BI,0JAEE,uBdu6BN,Ccz5BI,+HACE,Yd+5BN,Cc55BM,oDACE,aAAA,CACA,Sd85BR,Cc35BQ,kEAGE,eAAA,CAFA,YAAA,CACA,eAAA,CAEA,mBd65BV,Cc15BU,gFACE,mBd45BZ,Ccx5BU,gFACE,Yd05BZ,Ccl5BI,2CACE,ado5BN,Ccj5BM,iFACE,mBdm5BR,Ccp5BM,iFACE,kBdm5BR,Cc14BI,mFACE,ed44BN,Ccz4BM,iGACE,Sd24BR,Cct4BI,qFAGE,mDdw4BN,Cc34BI,qFAGE,oDdw4BN,Cc34BI,2EACE,aAAA,CACA,oBdy4BN,Ccr4BM,0FACE,Ydu4BR,CACF,Cez+CA,MACE,igBf4+CF,Cet+CA,WACE,iBfy+CF,CK30CI,mCU/JJ,WAKI,efy+CF,CACF,Cet+CE,kBACE,Yfw+CJ,Cep+CE,oBAEE,SAAA,CADA,Sfu+CJ,CKp0CI,wCUpKF,8BAQI,Yf8+CJ,Cet/CA,8BAQI,af8+CJ,Cet/CA,oBAYI,2CAAA,CACA,kBAAA,CAHA,WAAA,CACA,eAAA,CAOA,mBAAA,CAZA,iBAAA,CACA,SAAA,CAOA,uBAAA,CACA,4CACE,CAPF,Uf6+CJ,Cej+CI,+DACE,SAAA,CACA,oCfm+CN,CACF,CK12CI,mCUjJF,8BAiCI,Mfq+CJ,CetgDA,8BAiCI,Ofq+CJ,CetgDA,oBAoCI,gCAAA,CACA,cAAA,CAFA,QAAA,CAJA,cAAA,CACA,KAAA,CAMA,sDACE,CALF,Ofo+CJ,Ce19CI,+DAME,YAAA,CACA,SAAA,CACA,4CACE,CARF,Uf+9CN,CACF,CKz2CI,wCUxGA,+DAII,mBfi9CN,CACF,CKv5CM,6DU/DF,+DASI,mBfi9CN,CACF,CK55CM,6DU/DF,+DAcI,mBfi9CN,CACF,Ce58CE,kBAEE,kCAAA,CAAA,0Bf68CJ,CK33CI,wCUpFF,4BAQI,Mfo9CJ,Ce59CA,4BAQI,Ofo9CJ,Ce59CA,kBAWI,QAAA,CAGA,SAAA,CAFA,eAAA,CANA,cAAA,CACA,KAAA,CAMA,wBAAA,CAEA,qGACE,CANF,OAAA,CADA,Sfm9CJ,Cet8CI,4BACE,yBfw8CN,Cep8CI,6DAEE,WAAA,CAEA,SAAA,CADA,uBAAA,CAEA,sGACE,CALF,Uf08CN,CACF,CKt6CI,mCUjEF,kBA2CI,WAAA,CAEA,eAAA,CAHA,iBAAA,CAIA,8CAAA,CAFA,afm8CJ,Ce97CI,4BACE,Ufg8CN,CACF,CKx8CM,6DUYF,6DAII,af47CN,CACF,CKv7CI,sCUVA,6DASI,af47CN,CACF,Cev7CE,iBAIE,2CAAA,CACA,gCAAA,CAFA,aAAA,CAFA,iBAAA,CAKA,2CACE,CALF,Sf67CJ,CKp8CI,mCUKF,iBAaI,gCAAA,CACA,mBAAA,CAFA,afy7CJ,Cep7CI,uBACE,oCfs7CN,CACF,Cel7CI,4DAEE,2CAAA,CACA,6BAAA,CACA,oCAAA,CAHA,gCfu7CN,Ce/6CE,4BAKE,mBAAA,CAAA,oBfo7CJ,Cez7CE,4BAKE,mBAAA,CAAA,oBfo7CJ,Cez7CE,kBAQE,sBAAA,CAFA,eAAA,CAFA,WAAA,CAHA,iBAAA,CAMA,sBAAA,CAJA,UAAA,CADA,Sfu7CJ,Ce96CI,oCACE,0BAAA,CAAA,qBfg7CN,Cej7CI,yCACE,yBAAA,CAAA,qBfg7CN,Cej7CI,+BACE,qBfg7CN,Ce56CI,oCAEE,uCf66CN,Ce/6CI,yCAEE,uCf66CN,Ce/6CI,kEAEE,uCf66CN,Cez6CI,6BACE,Yf26CN,CKp9CI,wCUkBF,kBA8BI,eAAA,CADA,aAAA,CADA,Uf46CJ,CACF,CK9+CI,mCUqCF,4BAmCI,mBf46CJ,Ce/8CA,4BAmCI,oBf46CJ,Ce/8CA,kBAoCI,aAAA,CACA,ef06CJ,Cev6CI,oCACE,uCfy6CN,Ce16CI,yCACE,uCfy6CN,Ce16CI,+BACE,uCfy6CN,Cer6CI,mCACE,gCfu6CN,Cen6CI,6DACE,kBfq6CN,Cel6CM,+EAEE,uCfm6CR,Cer6CM,oFAEE,uCfm6CR,Cer6CM,wJAEE,uCfm6CR,CACF,Ce75CE,iBAIE,cAAA,CAHA,oBAAA,CAEA,aAAA,CAEA,kCACE,CAJF,Yfk6CJ,Ce15CI,uBACE,Uf45CN,Cex5CI,yCAGE,Uf25CN,Ce95CI,yCAGE,Wf25CN,Ce95CI,+BACE,iBAAA,CACA,SAAA,CAEA,Sf05CN,Cev5CM,6CACE,oBfy5CR,CKjgDI,wCUgGA,yCAcI,Ufw5CN,Cet6CE,yCAcI,Wfw5CN,Cet6CE,+BAaI,Sfy5CN,Cer5CM,+CACE,Yfu5CR,CACF,CK7hDI,mCUmHA,+BAwBI,mBfs5CN,Cen5CM,8CACE,Yfq5CR,CACF,Ce/4CE,8BAGE,Wfm5CJ,Cet5CE,8BAGE,Ufm5CJ,Cet5CE,oBAKE,mBAAA,CAJA,iBAAA,CACA,SAAA,CAEA,Sfk5CJ,CKzhDI,wCUmIF,8BAUI,Wfi5CJ,Ce35CA,8BAUI,Ufi5CJ,Ce35CA,oBASI,Sfk5CJ,CACF,Ce94CI,gCACE,iBfo5CN,Cer5CI,gCACE,kBfo5CN,Cer5CI,sBAEE,uCAAA,CAEA,SAAA,CADA,oBAAA,CAEA,+Dfg5CN,Ce34CM,yCAEE,uCAAA,CADA,Yf84CR,Cez4CM,yFAGE,SAAA,CACA,mBAAA,CAFA,kBf44CR,Cev4CQ,8FACE,Ufy4CV,Cel4CE,8BAOE,mBAAA,CAAA,oBfy4CJ,Ceh5CE,8BAOE,mBAAA,CAAA,oBfy4CJ,Ceh5CE,oBAIE,kBAAA,CAIA,yCAAA,CALA,YAAA,CAMA,eAAA,CAHA,WAAA,CAKA,SAAA,CAVA,iBAAA,CACA,KAAA,CAUA,uBAAA,CAFA,kBAAA,CALA,Uf24CJ,CKnlDI,mCUmMF,8BAgBI,mBfq4CJ,Cer5CA,8BAgBI,oBfq4CJ,Cer5CA,oBAiBI,efo4CJ,CACF,Cej4CI,+DACE,SAAA,CACA,0Bfm4CN,Ce93CE,6BAKE,+Bfi4CJ,Cet4CE,0DAME,gCfg4CJ,Cet4CE,6BAME,+Bfg4CJ,Cet4CE,mBAIE,eAAA,CAHA,iBAAA,CAEA,UAAA,CADA,Sfo4CJ,CKllDI,wCU4MF,mBAWI,QAAA,CADA,Ufi4CJ,CACF,CK3mDI,mCU+NF,mBAiBI,SAAA,CADA,UAAA,CAEA,sBfg4CJ,Ce73CI,8DACE,8BAAA,CACA,Sf+3CN,CACF,Ce13CE,uBAKE,kCAAA,CAAA,0BAAA,CAFA,2CAAA,CAFA,WAAA,CACA,eAAA,CAOA,kBfw3CJ,Cer3CI,iEAZF,uBAaI,uBfw3CJ,CACF,CKxpDM,6DUkRJ,uBAkBI,afw3CJ,CACF,CKvoDI,sCU4PF,uBAuBI,afw3CJ,CACF,CK5oDI,mCU4PF,uBA4BI,YAAA,CAEA,+DAAA,CADA,oBfy3CJ,Cer3CI,kEACE,efu3CN,Cen3CI,6BACE,qDfq3CN,Cej3CI,0CAEE,YAAA,CADA,Wfo3CN,Ce/2CI,gDACE,oDfi3CN,Ce92CM,sDACE,0Cfg3CR,CACF,Cez2CA,kBACE,gCAAA,CACA,qBf42CF,Cez2CE,wBAKE,qDAAA,CAHA,uCAAA,CACA,gBAAA,CACA,kBAAA,CAHA,eAAA,CAKA,uBf22CJ,CKhrDI,mCU+TF,kCAUI,mBf22CJ,Cer3CA,kCAUI,oBf22CJ,CACF,Cev2CE,wBAGE,eAAA,CAFA,QAAA,CACA,Sf02CJ,Cer2CE,wBACE,yDfu2CJ,Cep2CI,oCACE,efs2CN,Cej2CE,wBACE,aAAA,CACA,YAAA,CAEA,uBAAA,CADA,gCfo2CJ,Ceh2CI,mDACE,uDfk2CN,Cen2CI,gDACE,uDfk2CN,Cen2CI,0CACE,uDfk2CN,Ce91CI,gDACE,mBfg2CN,Ce31CE,gCAGE,+BAAA,CAGA,cAAA,CALA,aAAA,CAGA,gBAAA,CACA,YAAA,CAHA,mBAAA,CAQA,uBAAA,CAHA,2Cf81CJ,CKttDI,mCUiXF,0CAcI,mBf21CJ,Cez2CA,0CAcI,oBf21CJ,CACF,Cex1CI,2DAEE,uDAAA,CADA,+Bf21CN,Ce51CI,wDAEE,uDAAA,CADA,+Bf21CN,Ce51CI,kDAEE,uDAAA,CADA,+Bf21CN,Cet1CI,wCACE,Yfw1CN,Cen1CI,wDACE,Yfq1CN,Cej1CI,oCACE,Wfm1CN,Ce90CE,2BAGE,eAAA,CADA,eAAA,CADA,iBfk1CJ,CK7uDI,mCU0ZF,qCAOI,mBfg1CJ,Cev1CA,qCAOI,oBfg1CJ,CACF,Ce10CM,8DAGE,eAAA,CADA,eAAA,CAEA,eAAA,CAHA,ef+0CR,Cet0CE,kCAEE,Mf40CJ,Ce90CE,kCAEE,Of40CJ,Ce90CE,wBAME,uCAAA,CAFA,aAAA,CACA,YAAA,CAJA,iBAAA,CAEA,Yf20CJ,CK7uDI,wCU+ZF,wBAUI,Yfw0CJ,CACF,Cer0CI,8BAIE,6BAAA,CAIA,UAAA,CAPA,oBAAA,CAEA,WAAA,CAEA,+CAAA,CAAA,uCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,Uf60CN,Cep0CM,wCACE,oBfs0CR,Ceh0CE,yBAGE,gBAAA,CADA,eAAA,CAEA,eAAA,CAHA,afq0CJ,Ce9zCE,0BASE,2BAAA,CACA,oBAAA,CALA,uCAAA,CAJA,mBAAA,CAKA,gBAAA,CACA,eAAA,CAJA,aAAA,CADA,eAAA,CAEA,eAAA,CAIA,sBfk0CJ,CKjxDI,wCUucF,0BAeI,oBAAA,CADA,efi0CJ,CACF,CKh0DM,6DUgfJ,0BAqBI,oBAAA,CADA,efi0CJ,CACF,Ce7zCI,+BAEE,wBAAA,CADA,yBfg0CN,Ce1zCE,yBAEE,gBAAA,CACA,iBAAA,CAFA,af8zCJ,CexzCE,uBAEE,wBAAA,CADA,+Bf2zCJ,CgBn+DA,WACE,iBAAA,CACA,ShBs+DF,CgBn+DE,kBAOE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAHA,gCAAA,CAHA,QAAA,CAEA,gBAAA,CADA,YAAA,CAOA,SAAA,CAVA,iBAAA,CACA,sBAAA,CAQA,mCAAA,CAEA,oEhBq+DJ,CgB/9DI,+DACE,gBAAA,CAEA,SAAA,CADA,+BAAA,CAEA,sFACE,CADF,8EhBi+DN,CgBr+DI,4DACE,gBAAA,CAEA,SAAA,CADA,+BAAA,CAEA,mFACE,CADF,8EhBi+DN,CgBr+DI,sDACE,gBAAA,CAEA,SAAA,CADA,+BAAA,CAEA,8EhBi+DN,CgB19DI,wBAUE,qCAAA,CAAA,8CAAA,CAFA,mCAAA,CAAA,oCAAA,CACA,YAAA,CAEA,UAAA,CANA,QAAA,CAFA,QAAA,CAIA,kBAAA,CADA,iBAAA,CALA,iBAAA,CACA,KAAA,CAEA,OhBm+DN,CgBv9DE,iBAOE,mBAAA,CAFA,eAAA,CACA,oBAAA,CAJA,QAAA,CADA,kBAAA,CAGA,aAAA,CADA,ShB69DJ,CgBr9DE,iBACE,kBhBu9DJ,CgBn9DE,2BAGE,kBAAA,CAAA,oBhBy9DJ,CgB59DE,2BAGE,mBAAA,CAAA,mBhBy9DJ,CgB59DE,iBAKE,cAAA,CAJA,aAAA,CAGA,YAAA,CAKA,uBAAA,CAHA,2CACE,CALF,UhB09DJ,CgBh9DI,4CACE,+BhBk9DN,CgBn9DI,yCACE,+BhBk9DN,CgBn9DI,mCACE,+BhBk9DN,CgB98DI,uBACE,qDhBg9DN,CiBpiEA,YAIE,qBAAA,CADA,aAAA,CAGA,gBAAA,CALA,uBAAA,CAAA,eAAA,CACA,UAAA,CAGA,ajBwiEF,CiBpiEE,aATF,YAUI,YjBuiEF,CACF,CKz3DI,wCYxKA,+BAGE,ajB2iEJ,CiB9iEE,+BAGE,cjB2iEJ,CiB9iEE,qBAQE,2CAAA,CAHA,aAAA,CAEA,WAAA,CANA,cAAA,CACA,KAAA,CAOA,uBAAA,CACA,iEACE,CALF,aAAA,CAFA,SjB0iEJ,CiB/hEI,mEACE,8BAAA,CACA,6BjBiiEN,CiB9hEM,6EACE,8BjBgiER,CiB3hEI,6CAEE,QAAA,CAAA,MAAA,CACA,QAAA,CAEA,eAAA,CAJA,iBAAA,CACA,OAAA,CAEA,yBAAA,CAAA,qBAAA,CAFA,KjBgiEN,CACF,CKx6DI,sCYtKJ,YAuDI,QjB2hEF,CiBxhEE,mBACE,WjB0hEJ,CACF,CiBthEE,uBACE,YAAA,CACA,OjBwhEJ,CKp7DI,mCYtGF,uBAMI,QjBwhEJ,CiBrhEI,8BACE,WjBuhEN,CiBnhEI,qCACE,ajBqhEN,CiBjhEI,+CACE,kBjBmhEN,CACF,CiB9gEE,wBAIE,kCAAA,CAAA,0BAAA,CAHA,cAAA,CACA,eAAA,CAQA,+DAAA,CADA,oBjB4gEJ,CiBxgEI,8BACE,qDjB0gEN,CiBtgEI,2CAEE,YAAA,CADA,WjBygEN,CiBpgEI,iDACE,oDjBsgEN,CiBngEM,uDACE,0CjBqgER,CKn8DI,wCYxDF,YAME,gCAAA,CADA,QAAA,CAEA,SAAA,CANA,cAAA,CACA,KAAA,CAMA,sDACE,CALF,OAAA,CADA,SjBogEF,CiBz/DE,4CAEE,WAAA,CACA,SAAA,CACA,4CACE,CAJF,UjB8/DJ,CACF,CkB/oEA,yBACE,GACE,QlBipEF,CkB9oEA,GACE,alBgpEF,CACF,CkBvpEA,iBACE,GACE,QlBipEF,CkB9oEA,GACE,alBgpEF,CACF,CkB5oEA,wBACE,GAEE,SAAA,CADA,0BlB+oEF,CkB3oEA,IACE,SlB6oEF,CkB1oEA,GAEE,SAAA,CADA,uBlB6oEF,CACF,CkBzpEA,gBACE,GAEE,SAAA,CADA,0BlB+oEF,CkB3oEA,IACE,SlB6oEF,CkB1oEA,GAEE,SAAA,CADA,uBlB6oEF,CACF,CkBpoEA,MACE,mgBAAA,CACA,oiBAAA,CACA,0nBAAA,CACA,mhBlBsoEF,CkBhoEA,WAOE,kCAAA,CAAA,0BAAA,CANA,aAAA,CACA,gBAAA,CACA,eAAA,CAEA,uCAAA,CAGA,uBAAA,CAJA,kBlBsoEF,CkB/nEE,iBACE,UlBioEJ,CkB7nEE,iBACE,oBAAA,CAEA,aAAA,CACA,qBAAA,CAFA,UlBioEJ,CkB5nEI,+BAEE,iBlB8nEN,CkBhoEI,+BAEE,kBlB8nEN,CkBhoEI,qBACE,gBlB+nEN,CkB1nEI,kDACE,iBlB6nEN,CkB9nEI,kDACE,kBlB6nEN,CkB9nEI,kDAEE,iBlB4nEN,CkB9nEI,kDAEE,kBlB4nEN,CkBvnEE,iCAGE,iBlB4nEJ,CkB/nEE,iCAGE,kBlB4nEJ,CkB/nEE,uBACE,oBAAA,CACA,6BAAA,CAEA,eAAA,CACA,sBAAA,CACA,qBlBynEJ,CkBrnEE,kBAIE,gBAAA,CACA,oBAAA,CAJA,gBAAA,CAKA,WAAA,CAHA,eAAA,CADA,SlB2nEJ,CkBpnEI,uCACE,oCAAA,CAAA,4BlBsnEN,CkBjnEE,iBACE,oBlBmnEJ,CkBhnEI,sCACE,mCAAA,CAAA,2BlBknEN,CkB9mEI,kCAIE,kBlBqnEN,CkBznEI,kCAIE,iBlBqnEN,CkBznEI,wBAME,6BAAA,CAGA,UAAA,CARA,oBAAA,CAEA,YAAA,CAIA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CAHA,uBAAA,CAHA,WlBunEN,CkB5mEI,kDACE,iBlB8mEN,CkB/mEI,kDACE,kBlB8mEN,CkB1mEI,iCACE,gDAAA,CAAA,wClB4mEN,CkBxmEI,+BACE,8CAAA,CAAA,sClB0mEN,CkBtmEI,+BACE,8CAAA,CAAA,sClBwmEN,CkBpmEI,sCACE,qDAAA,CAAA,6ClBsmEN,CmBxvEA,SAIE,2CAAA,CADA,gCAAA,CADA,aAAA,CADA,UnB8vEF,CmBxvEE,aAPF,SAQI,YnB2vEF,CACF,CK3kEI,wCczLJ,SAaI,YnB2vEF,CACF,CmBxvEE,+BACE,mBnB0vEJ,CmBtvEE,yBAEE,iBnB4vEJ,CmB9vEE,yBAEE,kBnB4vEJ,CmB9vEE,eAME,eAAA,CADA,eAAA,CAJA,QAAA,CAEA,SAAA,CACA,kBnB0vEJ,CmBpvEE,eACE,oBAAA,CACA,aAAA,CACA,kBAAA,CAAA,mBnBsvEJ,CmBjvEE,eAOE,kCAAA,CAAA,0BAAA,CANA,aAAA,CAEA,eAAA,CADA,gBAAA,CAMA,UAAA,CAJA,uCAAA,CACA,oBAAA,CAIA,8DnBkvEJ,CmB7uEI,iEAEE,aAAA,CACA,SnB8uEN,CmBjvEI,8DAEE,aAAA,CACA,SnB8uEN,CmBjvEI,wDAEE,aAAA,CACA,SnB8uEN,CmBzuEM,2CACE,qBnB2uER,CmB5uEM,2CACE,qBnB8uER,CmB/uEM,2CACE,qBnBivER,CmBlvEM,2CACE,qBnBovER,CmBrvEM,2CACE,oBnBuvER,CmBxvEM,2CACE,qBnB0vER,CmB3vEM,2CACE,qBnB6vER,CmB9vEM,2CACE,qBnBgwER,CmBjwEM,4CACE,qBnBmwER,CmBpwEM,4CACE,oBnBswER,CmBvwEM,4CACE,qBnBywER,CmB1wEM,4CACE,qBnB4wER,CmB7wEM,4CACE,qBnB+wER,CmBhxEM,4CACE,qBnBkxER,CmBnxEM,4CACE,oBnBqxER,CmB/wEI,8CAEE,SAAA,CADA,yBAAA,CAEA,wCnBixEN,CoBz1EA,SACE,mBpB41EF,CoBx1EA,kBAEE,iBpBk2EF,CoBp2EA,kBAEE,gBpBk2EF,CoBp2EA,QAQE,+CAAA,CACA,mBAAA,CARA,oBAAA,CAKA,gBAAA,CADA,eAAA,CAEA,eAAA,CAJA,kBAAA,CACA,uBpBg2EF,CoBx1EE,cAGE,uCAAA,CAFA,aAAA,CACA,YAAA,CAEA,6CpB01EJ,CoBr1EI,wCAGE,0CAAA,CADA,+BpBu1EN,CoBj1EE,aACE,uBpBm1EJ,CqBt3EA,yBACE,GACE,uDrBy3EF,CqBt3EA,IACE,mCrBw3EF,CqBr3EA,GACE,8BrBu3EF,CACF,CqBl4EA,iBACE,GACE,uDrBy3EF,CqBt3EA,IACE,mCrBw3EF,CqBr3EA,GACE,8BrBu3EF,CACF,CqB/2EA,MACE,wBrBi3EF,CqB32EA,YA0BE,kCAAA,CAAA,0BAAA,CALA,2CAAA,CACA,mBAAA,CACA,8BAAA,CAHA,gCAAA,CAjBA,iJACE,CAeF,YAAA,CADA,8BAAA,CASA,SAAA,CA1BA,iBAAA,CACA,uBAAA,CAsBA,4BAAA,CAIA,2EACE,CAZF,6BAAA,CADA,SrBs3EF,CqBn2EE,0BACE,gBAAA,CAEA,SAAA,CADA,uBAAA,CAEA,2FrBq2EJ,CqB71EE,2BACE,sCrB+1EJ,CqB31EE,mBAEE,gBAAA,CADA,arB81EJ,CqB11EI,2CACE,YrB41EN,CqBx1EI,0CACE,erB01EN,CqBl1EA,eAEE,YAAA,CADA,kBrBs1EF,CqBl1EE,yBACE,arBo1EJ,CqBh1EE,6BACE,oBAAA,CAGA,iBrBg1EJ,CqB50EE,8BACE,SrB80EJ,CqB10EE,sBAEE,sCAAA,CADA,qCrB60EJ,CqBz0EI,0CAEE,mBAAA,CADA,wBAAA,CAAA,qBAAA,CAAA,oBAAA,CAAA,gBrB40EN,CqBt0EE,sBAIE,UAAA,CACA,cAAA,CAFA,YAAA,CAFA,iBAAA,CAKA,uBAAA,CACA,wBAAA,CAAA,qBAAA,CAAA,oBAAA,CAAA,gBAAA,CALA,SrB60EJ,CqBl0EI,4BAgBE,mCAAA,CAAA,2BAAA,CALA,oDAAA,CACA,iBAAA,CAKA,UAAA,CATA,YAAA,CANA,YAAA,CAOA,cAAA,CACA,cAAA,CATA,iBAAA,CAYA,2CACE,CARF,wBAAA,CACA,6BAAA,CAJA,UrB80EN,CqB7zEM,gCApBF,4BAqBI,sBAAA,CAAA,crBg0EN,CACF,CqB7zEM,+DACE,0CrB+zER,CqBh0EM,4DACE,0CrB+zER,CqBh0EM,sDACE,0CrB+zER,CqB3zEM,0CAIE,sBAAA,CAAA,cAAA,CAHA,2CrB8zER,CqBtzEI,8CACE,oBAAA,CACA,erBwzEN,CqBrzEM,qDAME,mCAAA,CALA,oBAAA,CACA,mBAAA,CAEA,qBAAA,CACA,iDAAA,CAFA,qBrB0zER,CqBnzEQ,iBAVF,qDAWI,WrBszER,CqBnzEQ,mEACE,mCrBqzEV,CACF,CqB/yEI,yDACE,+BrBizEN,CqBlzEI,sDACE,+BrBizEN,CqBlzEI,gDACE,+BrBizEN,CqB7yEI,oCAEE,sBAAA,CAAA,cAAA,CADA,erBgzEN,CsBzgFA,kBAIE,etBqhFF,CsBzhFA,kBAIE,gBtBqhFF,CsBzhFA,QAQE,2CAAA,CACA,oBAAA,CAEA,8BAAA,CALA,uCAAA,CACA,eAAA,CAGA,YAAA,CALA,mBAAA,CAJA,cAAA,CACA,UAAA,CAUA,yBAAA,CACA,mGACE,CAXF,StBshFF,CsBrgFE,aApBF,QAqBI,YtBwgFF,CACF,CsBrgFE,kBACE,wBtBugFJ,CsBngFE,8BAEE,SAAA,CAEA,mBAAA,CAHA,+BAAA,CAEA,uBtBsgFJ,CsBlgFI,wCACE,8BtBogFN,CsB//EE,mCAEE,0CAAA,CADA,+BtBkgFJ,CsBngFE,gCAEE,0CAAA,CADA,+BtBkgFJ,CsBngFE,0BAEE,0CAAA,CADA,+BtBkgFJ,CsB7/EE,YACE,oBAAA,CACA,oBtB+/EJ,CuBljFA,4BACE,GACE,mBvBqjFF,CACF,CuBxjFA,oBACE,GACE,mBvBqjFF,CACF,CuB7iFA,MACE,kiBvB+iFF,CuBziFA,YACE,aAAA,CAEA,eAAA,CADA,avB6iFF,CuBziFE,+BAOE,kBAAA,CAAA,kBvB0iFJ,CuBjjFE,+BAOE,iBAAA,CAAA,mBvB0iFJ,CuBjjFE,qBAQE,aAAA,CAEA,cAAA,CADA,YAAA,CARA,iBAAA,CAKA,UvB2iFJ,CuBpiFI,qCAIE,iBvB0iFN,CuB9iFI,qCAIE,kBvB0iFN,CuB9iFI,2BAKE,6BAAA,CAGA,UAAA,CAPA,oBAAA,CAEA,YAAA,CAGA,yCAAA,CAAA,iCAAA,CACA,6BAAA,CAAA,qBAAA,CALA,WvB4iFN,CuBjiFE,kBAUE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CACA,oBAAA,CAJA,kBAAA,CADA,YAAA,CASA,SAAA,CANA,aAAA,CADA,SAAA,CALA,iBAAA,CAgBA,gCAAA,CAAA,4BAAA,CAfA,UAAA,CAYA,+CACE,CAZF,SvB+iFJ,CuB9hFI,gEACE,gBAAA,CACA,SAAA,CACA,8CACE,CADF,sCvBgiFN,CuBniFI,6DACE,gBAAA,CACA,SAAA,CACA,2CACE,CADF,sCvBgiFN,CuBniFI,uDACE,gBAAA,CACA,SAAA,CACA,sCvBgiFN,CuB1hFI,wBAGE,oCACE,wCAAA,CAAA,gCvB0hFN,CuBthFI,2CACE,sBAAA,CAAA,cvBwhFN,CACF,CuBnhFE,kBACE,kBvBqhFJ,CuBjhFE,4BAGE,kBAAA,CAAA,oBvBwhFJ,CuB3hFE,4BAGE,mBAAA,CAAA,mBvBwhFJ,CuB3hFE,kBAME,cAAA,CALA,aAAA,CAIA,YAAA,CAKA,uBAAA,CAHA,2CACE,CAJF,kBAAA,CAFA,UvByhFJ,CuB9gFI,6CACE,+BvBghFN,CuBjhFI,0CACE,+BvBghFN,CuBjhFI,oCACE,+BvBghFN,CuB5gFI,wBACE,qDvB8gFN,CwB7mFA,MAEI,2RAAA,CAAA,8WAAA,CAAA,sPAAA,CAAA,8xBAAA,CAAA,qNAAA,CAAA,gbAAA,CAAA,gMAAA,CAAA,+PAAA,CAAA,8KAAA,CAAA,0eAAA,CAAA,kUAAA,CAAA,gMxBsoFJ,CwB1nFE,8CAOE,8CAAA,CACA,sBAAA,CAEA,mBAAA,CACA,8BAAA,CAPA,mCAAA,CAHA,iBAAA,CAIA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAGA,uBxBkoFJ,CwBxoFE,2CAOE,8CAAA,CACA,sBAAA,CAEA,mBAAA,CACA,8BAAA,CAPA,mCAAA,CAHA,iBAAA,CAIA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAGA,uBxBkoFJ,CwBxoFE,wDASE,uBxB+nFJ,CwBxoFE,qDASE,uBxB+nFJ,CwBxoFE,+CASE,uBxB+nFJ,CwBxoFE,wDASE,wBxB+nFJ,CwBxoFE,qDASE,wBxB+nFJ,CwBxoFE,+CASE,wBxB+nFJ,CwBxoFE,qCAOE,8CAAA,CACA,sBAAA,CAEA,mBAAA,CACA,8BAAA,CAPA,mCAAA,CAHA,iBAAA,CAIA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAGA,uBxBkoFJ,CwB1nFI,aAdF,8CAeI,exB6nFJ,CwB5oFA,2CAeI,exB6nFJ,CwB5oFA,qCAeI,exB6nFJ,CACF,CwBznFI,gDACE,qBxB2nFN,CwB5nFI,6CACE,qBxB2nFN,CwB5nFI,uCACE,qBxB2nFN,CwBvnFI,gFAEE,iBAAA,CADA,cxB0nFN,CwB3nFI,0EAEE,iBAAA,CADA,cxB0nFN,CwB3nFI,8DAEE,iBAAA,CADA,cxB0nFN,CwBrnFI,sEACE,iBxBunFN,CwBxnFI,mEACE,iBxBunFN,CwBxnFI,6DACE,iBxBunFN,CwBnnFI,iEACE,exBqnFN,CwBtnFI,8DACE,exBqnFN,CwBtnFI,wDACE,exBqnFN,CwBjnFI,qEACE,YxBmnFN,CwBpnFI,kEACE,YxBmnFN,CwBpnFI,4DACE,YxBmnFN,CwB/mFI,+DACE,mBxBinFN,CwBlnFI,4DACE,mBxBinFN,CwBlnFI,sDACE,mBxBinFN,CwB5mFE,oDAOE,oCAAA,CACA,WAAA,CAFA,eAAA,CAJA,eAAA,CAAA,YAAA,CAEA,oBAAA,CAAA,iBAAA,CAHA,iBxBunFJ,CwBxnFE,iDAOE,oCAAA,CACA,WAAA,CAFA,eAAA,CAJA,eAAA,CAAA,YAAA,CAEA,oBAAA,CAAA,iBAAA,CAHA,iBxBunFJ,CwBxnFE,8DAGE,kBAAA,CAAA,mBxBqnFJ,CwBxnFE,2DAGE,kBAAA,CAAA,mBxBqnFJ,CwBxnFE,qDAGE,kBAAA,CAAA,mBxBqnFJ,CwBxnFE,8DAGE,kBAAA,CAAA,mBxBqnFJ,CwBxnFE,2DAGE,kBAAA,CAAA,mBxBqnFJ,CwBxnFE,qDAGE,kBAAA,CAAA,mBxBqnFJ,CwBxnFE,8DAKE,mBAAA,CAAA,mBxBmnFJ,CwBxnFE,2DAKE,mBAAA,CAAA,mBxBmnFJ,CwBxnFE,qDAKE,mBAAA,CAAA,mBxBmnFJ,CwBxnFE,8DAKE,kBAAA,CAAA,oBxBmnFJ,CwBxnFE,2DAKE,kBAAA,CAAA,oBxBmnFJ,CwBxnFE,qDAKE,kBAAA,CAAA,oBxBmnFJ,CwBxnFE,8DASE,uBxB+mFJ,CwBxnFE,2DASE,uBxB+mFJ,CwBxnFE,qDASE,uBxB+mFJ,CwBxnFE,8DASE,wBxB+mFJ,CwBxnFE,2DASE,wBxB+mFJ,CwBxnFE,qDASE,wBxB+mFJ,CwBxnFE,8DAUE,4BxB8mFJ,CwBxnFE,2DAUE,4BxB8mFJ,CwBxnFE,qDAUE,4BxB8mFJ,CwBxnFE,8DAUE,6BxB8mFJ,CwBxnFE,2DAUE,6BxB8mFJ,CwBxnFE,qDAUE,6BxB8mFJ,CwBxnFE,2CAOE,oCAAA,CACA,WAAA,CAFA,eAAA,CAJA,eAAA,CAAA,YAAA,CAEA,oBAAA,CAAA,iBAAA,CAHA,iBxBunFJ,CwB3mFI,oEACE,exB6mFN,CwB9mFI,iEACE,exB6mFN,CwB9mFI,2DACE,exB6mFN,CwBzmFI,2DAME,wBCwIU,CDpIV,UAAA,CALA,WAAA,CAEA,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,UAAA,CAEA,UxBinFN,CwBrnFI,wDAME,wBCwIU,CDpIV,UAAA,CALA,WAAA,CAEA,0CAAA,CACA,qBAAA,CACA,iBAAA,CARA,iBAAA,CACA,UAAA,CAEA,UxBinFN,CwBrnFI,qEAGE,UxBknFN,CwBrnFI,kEAGE,UxBknFN,CwBrnFI,4DAGE,UxBknFN,CwBrnFI,qEAGE,WxBknFN,CwBrnFI,kEAGE,WxBknFN,CwBrnFI,4DAGE,WxBknFN,CwBrnFI,kDAME,wBCwIU,CDpIV,UAAA,CALA,WAAA,CAEA,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,UAAA,CAEA,UxBinFN,CwBvlFE,iEACE,oBxB0lFJ,CwB3lFE,2DACE,oBxB0lFJ,CwB3lFE,+CACE,oBxB0lFJ,CwBtlFE,wEACE,oCxBylFJ,CwB1lFE,kEACE,oCxBylFJ,CwB1lFE,sDACE,oCxBylFJ,CwBtlFI,+EACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBwlFN,CwB5lFI,yEACE,wBAnBG,CAoBH,0CAAA,CACA,qBAAA,CACA,iBxBwlFN,CwB5lFI,6DACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBwlFN,CwBrmFE,oFACE,oBxBwmFJ,CwBzmFE,8EACE,oBxBwmFJ,CwBzmFE,kEACE,oBxBwmFJ,CwBpmFE,2FACE,mCxBumFJ,CwBxmFE,qFACE,mCxBumFJ,CwBxmFE,yEACE,mCxBumFJ,CwBpmFI,kGACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBsmFN,CwB1mFI,4FACE,wBAnBG,CAoBH,8CAAA,CACA,qBAAA,CACA,iBxBsmFN,CwB1mFI,gFACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBsmFN,CwBnnFE,uEACE,oBxBsnFJ,CwBvnFE,iEACE,oBxBsnFJ,CwBvnFE,qDACE,oBxBsnFJ,CwBlnFE,8EACE,mCxBqnFJ,CwBtnFE,wEACE,mCxBqnFJ,CwBtnFE,4DACE,mCxBqnFJ,CwBlnFI,qFACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBonFN,CwBxnFI,+EACE,wBAnBG,CAoBH,0CAAA,CACA,qBAAA,CACA,iBxBonFN,CwBxnFI,mEACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBonFN,CwBjoFE,iFACE,oBxBooFJ,CwBroFE,2EACE,oBxBooFJ,CwBroFE,+DACE,oBxBooFJ,CwBhoFE,wFACE,mCxBmoFJ,CwBpoFE,kFACE,mCxBmoFJ,CwBpoFE,sEACE,mCxBmoFJ,CwBhoFI,+FACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBkoFN,CwBtoFI,yFACE,wBAnBG,CAoBH,yCAAA,CACA,qBAAA,CACA,iBxBkoFN,CwBtoFI,6EACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBkoFN,CwB/oFE,iFACE,oBxBkpFJ,CwBnpFE,2EACE,oBxBkpFJ,CwBnpFE,+DACE,oBxBkpFJ,CwB9oFE,wFACE,kCxBipFJ,CwBlpFE,kFACE,kCxBipFJ,CwBlpFE,sEACE,kCxBipFJ,CwB9oFI,+FACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBgpFN,CwBppFI,yFACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxBgpFN,CwBppFI,6EACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBgpFN,CwB7pFE,gFACE,oBxBgqFJ,CwBjqFE,0EACE,oBxBgqFJ,CwBjqFE,8DACE,oBxBgqFJ,CwB5pFE,uFACE,oCxB+pFJ,CwBhqFE,iFACE,oCxB+pFJ,CwBhqFE,qEACE,oCxB+pFJ,CwB5pFI,8FACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB8pFN,CwBlqFI,wFACE,wBAnBG,CAoBH,8CAAA,CACA,qBAAA,CACA,iBxB8pFN,CwBlqFI,4EACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB8pFN,CwB3qFE,wFACE,oBxB8qFJ,CwB/qFE,kFACE,oBxB8qFJ,CwB/qFE,sEACE,oBxB8qFJ,CwB1qFE,+FACE,mCxB6qFJ,CwB9qFE,yFACE,mCxB6qFJ,CwB9qFE,6EACE,mCxB6qFJ,CwB1qFI,sGACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB4qFN,CwBhrFI,gGACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxB4qFN,CwBhrFI,oFACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB4qFN,CwBzrFE,mFACE,oBxB4rFJ,CwB7rFE,6EACE,oBxB4rFJ,CwB7rFE,iEACE,oBxB4rFJ,CwBxrFE,0FACE,mCxB2rFJ,CwB5rFE,oFACE,mCxB2rFJ,CwB5rFE,wEACE,mCxB2rFJ,CwBxrFI,iGACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB0rFN,CwB9rFI,2FACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxB0rFN,CwB9rFI,+EACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB0rFN,CwBvsFE,0EACE,oBxB0sFJ,CwB3sFE,oEACE,oBxB0sFJ,CwB3sFE,wDACE,oBxB0sFJ,CwBtsFE,iFACE,mCxBysFJ,CwB1sFE,2EACE,mCxBysFJ,CwB1sFE,+DACE,mCxBysFJ,CwBtsFI,wFACE,wBAnBG,CAoBH,oDAAA,CAAA,4CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBwsFN,CwB5sFI,kFACE,wBAnBG,CAoBH,4CAAA,CACA,qBAAA,CACA,iBxBwsFN,CwB5sFI,sEACE,wBAnBG,CAoBH,oDAAA,CAAA,4CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBwsFN,CwBrtFE,gEACE,oBxBwtFJ,CwBztFE,0DACE,oBxBwtFJ,CwBztFE,8CACE,oBxBwtFJ,CwBptFE,uEACE,kCxButFJ,CwBxtFE,iEACE,kCxButFJ,CwBxtFE,qDACE,kCxButFJ,CwBptFI,8EACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBstFN,CwB1tFI,wEACE,wBAnBG,CAoBH,yCAAA,CACA,qBAAA,CACA,iBxBstFN,CwB1tFI,4DACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBstFN,CwBnuFE,oEACE,oBxBsuFJ,CwBvuFE,8DACE,oBxBsuFJ,CwBvuFE,kDACE,oBxBsuFJ,CwBluFE,2EACE,oCxBquFJ,CwBtuFE,qEACE,oCxBquFJ,CwBtuFE,yDACE,oCxBquFJ,CwBluFI,kFACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBouFN,CwBxuFI,4EACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxBouFN,CwBxuFI,gEACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBouFN,CwBjvFE,wEACE,oBxBovFJ,CwBrvFE,kEACE,oBxBovFJ,CwBrvFE,sDACE,oBxBovFJ,CwBhvFE,+EACE,kCxBmvFJ,CwBpvFE,yEACE,kCxBmvFJ,CwBpvFE,6DACE,kCxBmvFJ,CwBhvFI,sFACE,wBAnBG,CAoBH,mDAAA,CAAA,2CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBkvFN,CwBtvFI,gFACE,wBAnBG,CAoBH,2CAAA,CACA,qBAAA,CACA,iBxBkvFN,CwBtvFI,oEACE,wBAnBG,CAoBH,mDAAA,CAAA,2CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBkvFN,C0Bx4FA,MACE,wM1B24FF,C0Bl4FE,sBACE,uCAAA,CACA,gB1Bq4FJ,C0Bl4FI,mCACE,a1Bo4FN,C0Br4FI,mCACE,c1Bo4FN,C0Bh4FM,4BACE,sB1Bk4FR,C0B/3FQ,mCACE,gC1Bi4FV,C0B73FQ,2DAEE,SAAA,CADA,uBAAA,CAEA,e1B+3FV,C0B33FQ,0EAEE,SAAA,CADA,uB1B83FV,C0B/3FQ,uEAEE,SAAA,CADA,uB1B83FV,C0B/3FQ,iEAEE,SAAA,CADA,uB1B83FV,C0Bz3FQ,yCACE,Y1B23FV,C0Bp3FE,0BAEE,eAAA,CADA,e1Bu3FJ,C0Bn3FI,+BACE,oB1Bq3FN,C0Bh3FE,gDACE,Y1Bk3FJ,C0B92FE,8BAEE,+BAAA,CADA,oBAAA,CAGA,WAAA,CAGA,SAAA,CADA,4BAAA,CAEA,4DACE,CAJF,0B1Bk3FJ,C0Bz2FI,aAdF,8BAeI,+BAAA,CAEA,SAAA,CADA,uB1B62FJ,CACF,C0Bz2FI,wCACE,6B1B22FN,C0Bv2FI,oCACE,+B1By2FN,C0Br2FI,qCAIE,6BAAA,CAIA,UAAA,CAPA,oBAAA,CAEA,YAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,W1B62FN,C0Bj2FQ,mDACE,oB1Bm2FV,C2Bh9FE,kCAEE,iB3Bs9FJ,C2Bx9FE,kCAEE,kB3Bs9FJ,C2Bx9FE,wBAGE,yCAAA,CAFA,oBAAA,CAGA,SAAA,CACA,mC3Bm9FJ,C2B98FI,aAVF,wBAWI,Y3Bi9FJ,CACF,C2B78FE,mFAEE,SAAA,CACA,2CACE,CADF,mC3B+8FJ,C2Bl9FE,gFAEE,SAAA,CACA,wCACE,CADF,mC3B+8FJ,C2Bl9FE,0EAEE,SAAA,CACA,mC3B+8FJ,C2Bz8FE,mFAEE,+B3B28FJ,C2B78FE,gFAEE,+B3B28FJ,C2B78FE,0EAEE,+B3B28FJ,C2Bv8FE,oBACE,yBAAA,CACA,uBAAA,CAGA,yE3Bu8FJ,CKx0FI,sCsBrHE,qDACE,uB3Bg8FN,CACF,C2B37FE,0CACE,yB3B67FJ,C2B97FE,uCACE,yB3B67FJ,C2B97FE,iCACE,yB3B67FJ,C2Bz7FE,sBACE,0B3B27FJ,C4Bt/FE,2BACE,a5By/FJ,CKp0FI,wCuBtLF,2BAKI,e5By/FJ,CACF,C4Bt/FI,6BAEE,0BAAA,CAAA,2BAAA,CACA,eAAA,CACA,iBAAA,CAHA,yBAAA,CAAA,sBAAA,CAAA,iB5B2/FN,C4Br/FM,2CACE,kB5Bu/FR,C6BxgGE,kDACE,kCAAA,CAAA,0B7B2gGJ,C6B5gGE,+CACE,0B7B2gGJ,C6B5gGE,yCACE,kCAAA,CAAA,0B7B2gGJ,C6BvgGE,uBACE,4C7BygGJ,C6BrgGE,uBACE,4C7BugGJ,C6BngGE,4BACE,qC7BqgGJ,C6BlgGI,mCACE,a7BogGN,C6BhgGI,kCACE,a7BkgGN,C6B7/FE,0BAKE,eAAA,CAJA,aAAA,CACA,YAAA,CAEA,aAAA,CADA,kBAAA,CAAA,mB7BigGJ,C6B5/FI,uCACE,e7B8/FN,C6B1/FI,sCACE,kB7B4/FN,C8B3iGA,MACE,8L9B8iGF,C8BriGE,oBACE,iBAAA,CAEA,gBAAA,CADA,a9ByiGJ,C8BriGI,wCACE,uB9BuiGN,C8BniGI,gCAEE,eAAA,CADA,gB9BsiGN,C8B/hGM,wCACE,mB9BiiGR,C8B3hGE,8BAGE,oB9BgiGJ,C8BniGE,8BAGE,mB9BgiGJ,C8BniGE,8BAIE,4B9B+hGJ,C8BniGE,4DAKE,6B9B8hGJ,C8BniGE,8BAKE,4B9B8hGJ,C8BniGE,oBAME,cAAA,CALA,aAAA,CACA,e9BiiGJ,C8B1hGI,kCACE,uCAAA,CACA,oB9B4hGN,C8BxhGI,wCAEE,uCAAA,CADA,Y9B2hGN,C8BthGI,oCAGE,W9BiiGN,C8BpiGI,oCAGE,U9BiiGN,C8BpiGI,0BAME,6BAAA,CAMA,UAAA,CAPA,WAAA,CAEA,yCAAA,CAAA,iCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,UAAA,CAQA,sBAAA,CACA,yBAAA,CAPA,U9BgiGN,C8BrhGM,oCACE,wB9BuhGR,C8BlhGI,4BACE,Y9BohGN,C8B/gGI,4CACE,Y9BihGN,C+BnmGE,qDACE,mBAAA,CACA,cAAA,CACA,uB/BsmGJ,C+BzmGE,kDACE,mBAAA,CACA,cAAA,CACA,uB/BsmGJ,C+BzmGE,4CACE,mBAAA,CACA,cAAA,CACA,uB/BsmGJ,C+BnmGI,yDAGE,iBAAA,CADA,eAAA,CADA,a/BumGN,C+BxmGI,sDAGE,iBAAA,CADA,eAAA,CADA,a/BumGN,C+BxmGI,gDAGE,iBAAA,CADA,eAAA,CADA,a/BumGN,CgC7mGE,gCACE,sChCgnGJ,CgCjnGE,6BACE,sChCgnGJ,CgCjnGE,uBACE,sChCgnGJ,CgC7mGE,cACE,yChC+mGJ,CgCnmGE,4DACE,oChCqmGJ,CgCtmGE,yDACE,oChCqmGJ,CgCtmGE,mDACE,oChCqmGJ,CgC7lGE,6CACE,qChC+lGJ,CgChmGE,0CACE,qChC+lGJ,CgChmGE,oCACE,qChC+lGJ,CgCrlGE,oDACE,oChCulGJ,CgCxlGE,iDACE,oChCulGJ,CgCxlGE,2CACE,oChCulGJ,CgC9kGE,gDACE,qChCglGJ,CgCjlGE,6CACE,qChCglGJ,CgCjlGE,uCACE,qChCglGJ,CgC3kGE,gCACE,kChC6kGJ,CgC9kGE,6BACE,kChC6kGJ,CgC9kGE,uBACE,kChC6kGJ,CgCvkGE,qCACE,sChCykGJ,CgC1kGE,kCACE,sChCykGJ,CgC1kGE,4BACE,sChCykGJ,CgClkGE,yCACE,sChCokGJ,CgCrkGE,sCACE,sChCokGJ,CgCrkGE,gCACE,sChCokGJ,CgC7jGE,yCACE,qChC+jGJ,CgChkGE,sCACE,qChC+jGJ,CgChkGE,gCACE,qChC+jGJ,CgCtjGE,gDACE,qChCwjGJ,CgCzjGE,6CACE,qChCwjGJ,CgCzjGE,uCACE,qChCwjGJ,CgChjGE,6CACE,sChCkjGJ,CgCnjGE,0CACE,sChCkjGJ,CgCnjGE,oCACE,sChCkjGJ,CgCviGE,yDACE,qChCyiGJ,CgC1iGE,sDACE,qChCyiGJ,CgC1iGE,gDACE,qChCyiGJ,CgCpiGE,iCAGE,mBAAA,CAFA,gBAAA,CACA,gBhCuiGJ,CgCziGE,8BAGE,mBAAA,CAFA,gBAAA,CACA,gBhCuiGJ,CgCziGE,wBAGE,mBAAA,CAFA,gBAAA,CACA,gBhCuiGJ,CgCniGE,eACE,4ChCqiGJ,CgCliGE,eACE,4ChCoiGJ,CgChiGE,gBAIE,wCAAA,CAHA,aAAA,CACA,wBAAA,CACA,wBhCmiGJ,CgC9hGE,yBAOE,wCAAA,CACA,+DAAA,CACA,4BAAA,CACA,6BAAA,CARA,iBAAA,CAIA,eAAA,CADA,eAAA,CAFA,cAAA,CACA,oCAAA,CAHA,iBhCyiGJ,CgC7hGI,6BACE,Yh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","file":"main.css"} \ No newline at end of file diff --git a/test/assets/stylesheets/palette.cc9b2e1e.min.css b/test/assets/stylesheets/palette.cc9b2e1e.min.css deleted file mode 100644 index d0fd19a25ed1..000000000000 --- a/test/assets/stylesheets/palette.cc9b2e1e.min.css +++ /dev/null @@ -1 +0,0 @@ -[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:rgba(255,25,71,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:rgba(245,0,86,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:rgba(223,65,251,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:rgba(124,77,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:rgba(66,135,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:rgba(0,145,235,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:rgba(0,186,214,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:rgba(0,189,164,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:rgba(0,199,83,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:rgba(99,222,23,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:rgba(176,235,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:rgba(255,213,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:rgba(255,170,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:rgba(255,145,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:rgba(255,110,66,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=white]{--md-primary-fg-color:#fff;--md-primary-fg-color--light:hsla(0,0%,100%,.7);--md-primary-fg-color--dark:rgba(0,0,0,.07);--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54);--md-typeset-a-color:#4051b5}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:rgba(0,0,0,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:rgba(0,0,0,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:rgba(0,0,0,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid rgba(0,0,0,.07)}}[data-md-color-primary=black]{--md-primary-fg-color:#000;--md-primary-fg-color--light:rgba(0,0,0,.54);--md-primary-fg-color--dark:#000;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-header{background-color:#000}@media screen and (max-width:59.9375em){[data-md-color-primary=black] .md-nav__source{background-color:rgba(0,0,0,.87)}}@media screen and (min-width:60em){[data-md-color-primary=black] .md-search__form{background-color:hsla(0,0%,100%,.12)}[data-md-color-primary=black] .md-search__form:hover{background-color:hsla(0,0%,100%,.3)}}@media screen and (max-width:76.1875em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:#000}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:#000}}@media screen{[data-md-color-scheme=slate]{--md-hue:232;--md-default-fg-color:hsla(var(--md-hue),75%,95%,1);--md-default-fg-color--light:hsla(var(--md-hue),75%,90%,0.62);--md-default-fg-color--lighter:hsla(var(--md-hue),75%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),75%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,21%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,21%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,21%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,21%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,1);--md-code-bg-color:hsla(var(--md-hue),15%,15%,1);--md-code-hl-color:rgba(66,135,255,.15);--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:rgba(66,135,255,.3);--md-typeset-kbd-color:hsla(var(--md-hue),15%,94%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,94%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-table-color:hsla(var(--md-hue),75%,95%,0.12);--md-admonition-bg-color:hsla(var(--md-hue),0%,100%,0.025);--md-footer-bg-color:hsla(var(--md-hue),15%,12%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,10%,1)}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5d6cc0}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=slate] img[src$="#only-dark"]{display:initial}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}} \ No newline at end of file diff --git a/test/assets/stylesheets/palette.cc9b2e1e.min.css.map b/test/assets/stylesheets/palette.cc9b2e1e.min.css.map deleted file mode 100644 index 46620900a836..000000000000 --- a/test/assets/stylesheets/palette.cc9b2e1e.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["src/assets/stylesheets/palette/_accent.scss","../../../src/assets/stylesheets/palette.scss","src/assets/stylesheets/palette/_primary.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/palette/_scheme.scss"],"names":[],"mappings":"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","file":"palette.css"} \ No newline at end of file diff --git a/test/build/Dockerfile b/test/build/Dockerfile deleted file mode 100644 index 7ebaa1edc0c0..000000000000 --- a/test/build/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM squidfunk/mkdocs-material:8.3.9 - -## If you want to see exactly the same version as is published to GitHub pages -## use a private image for insiders, which requires authentication. - -# docker login -u ${GITHUB_USERNAME} -p ${GITHUB_TOKEN} ghcr.io -# FROM ghcr.io/squidfunk/mkdocs-material-insiders - -COPY requirements.txt . -RUN pip install -r requirements.txt diff --git a/test/build/requirements.txt b/test/build/requirements.txt deleted file mode 100644 index 6ca9dba41a1d..000000000000 --- a/test/build/requirements.txt +++ /dev/null @@ -1,30 +0,0 @@ -click==8.1.2 -csscompressor==0.9.5 -ghp-import==2.0.2 -htmlmin==0.1.12 -importlib-metadata==4.11.3 -Jinja2==3.1.1 -jsmin==3.0.1 -Markdown==3.3.6 -MarkupSafe==2.1.1 -mergedeep==1.3.4 -mike==1.1.2 -mkdocs==1.3.0 -mkdocs-macros-plugin==0.7.0 -mkdocs-material==8.3.9 -mkdocs-material-extensions==1.0.3 -mkdocs-minify-plugin==0.5.0 -mkdocs-redirects==1.0.4 -packaging==21.3 -Pygments==2.12.0 -pymdown-extensions==9.5 -pyparsing==3.0.8 -python-dateutil==2.8.2 -PyYAML==6.0 -pyyaml-env-tag==0.1 -six==1.16.0 -termcolor==1.1.0 -verspec==0.1.0 -watchdog==2.1.7 -zipp==3.8.0 - diff --git a/test/community/contribute/discussion/index.html b/test/community/contribute/discussion/index.html deleted file mode 100644 index d3bc046b94dd..000000000000 --- a/test/community/contribute/discussion/index.html +++ /dev/null @@ -1,3157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Discussions - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Discussions

    -

    Thank you for taking interest in contributing to Trivy!

    -

    Trivy uses GitHub Discussion for bug reports, feature requests, and questions. -If maintainers decide to accept a new feature or confirm that it is a bug, they will close the discussion and create a GitHub Issue associated with that discussion.

    -
      -
    • Feel free to open discussions for any reason. When you open a new discussion, you'll have to select a discussion category as described below.
    • -
    • Please spend a small amount of time giving due diligence to the issue/discussion tracker. Your discussion might be a duplicate. If it is, please add your comment to the existing issue/discussion.
    • -
    • Remember that users might search for your issue/discussion in the future, so please give it a meaningful title to help others.
    • -
    • The issue should clearly explain the reason for opening, the proposal if you have any, and any relevant technical information.
    • -
    -

    There are 4 categories:

    -
      -
    • 💡 Ideas
        -
      • Share ideas for new features
      • -
      -
    • -
    • 🔎 False Detection
        -
      • Report false positives/negatives
      • -
      -
    • -
    • 🐛 Bugs
        -
      • Report something that is not working as expected
      • -
      -
    • -
    • 🙏 Q&A
        -
      • Ask the community for help
      • -
      -
    • -
    -
    -

    Note

    -

    If you find any false positives or false negatives, please make sure to report them under the "False Detection" category, not "Bugs".

    -
    -

    False detection

    -

    Trivy depends on multiple data sources. -Sometime these databases contain mistakes.

    -

    If Trivy can't detect any CVE-IDs or shows false positive result, at first please follow the next steps:

    -
      -
    1. Run Trivy with -f json that shows data sources.
    2. -
    3. According to the shown data source, make sure that the security advisory in the data source is correct.
    4. -
    -

    If the data source is correct and Trivy shows wrong results, please raise an issue on Trivy.

    -

    GitHub Advisory Database

    -

    Visit here and search CVE-ID.

    -

    If you find a problem, it'll be nice to fix it: How to contribute to a GitHub security advisory

    -

    GitLab Advisory Database

    -

    Visit here and search CVE-ID.

    -

    If you find a problem, it'll be nice to fix it: Create an issue to GitLab Advisory Database

    -

    Red Hat CVE Database

    -

    Visit here and search CVE-ID.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/community/contribute/issue/index.html b/test/community/contribute/issue/index.html deleted file mode 100644 index b5fd58b7eac3..000000000000 --- a/test/community/contribute/issue/index.html +++ /dev/null @@ -1,3010 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Issues - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Issues

    -

    Thank you for taking interest in contributing to Trivy!

    -

    Trivy uses GitHub Discussion for bug reports, feature requests, and questions.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/community/contribute/pr/index.html b/test/community/contribute/pr/index.html deleted file mode 100644 index 75b221151aab..000000000000 --- a/test/community/contribute/pr/index.html +++ /dev/null @@ -1,3385 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Pull Requests - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Pull Requests

    - -

    Thank you for taking interest in contributing to Trivy!

    -
      -
    1. Every Pull Request should have an associated bug or feature issue unless you are fixing a trivial documentation issue.
    2. -
    3. Please add the associated Issue link in the PR description.
    4. -
    5. Your PR is more likely to be accepted if it focuses on just one change.
    6. -
    7. There's no need to add or tag reviewers.
    8. -
    9. If a reviewer commented on your code or asked for changes, please remember to respond with comment. Do not mark discussion as resolved. It's up to reviewer to mark it resolved (in case if suggested fix addresses problem properly). PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).
    10. -
    11. Please include a comment with the results before and after your change.
    12. -
    13. Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!).
    14. -
    15. If your PR affects the user experience in some way, please update the README.md and the CLI help accordingly.
    16. -
    -

    Development

    -

    Install the necessary tools for development by following their respective installation instructions.

    - -

    Build

    -

    After making changes to the Go source code, build the project with the following command:

    -
    $ mage build
    -$ ./trivy -h
    -
    -

    Lint

    -

    You must pass the linter checks:

    -
    $ mage lint
    -
    -

    Additionally, you need to have run go mod tidy, so execute the following command as well:

    -
    $ mage tidy
    -
    -

    Unit tests

    -

    Your PR must pass all the unit tests. You can test it as below.

    -
    $ mage test:unit
    -
    -

    Integration tests

    -

    Your PR must pass all the integration tests. You can test it as below.

    -
    $ mage test:integration
    -
    -

    Documentation

    -

    If you update CLI flags, you need to generate the CLI references. -The test will fail if they are not up-to-date.

    -
    $ mage docs:generate
    -
    -

    You can build the documents as below and view it at http://localhost:8000.

    -
    $ mage docs:serve
    -
    -

    Title

    -

    It is not that strict, but we use the title conventions in this repository. -Each commit message doesn't have to follow the conventions as long as it is clear and descriptive since it will be squashed and merged.

    -

    Format of the title

    -
    <type>(<scope>): <subject>
    -
    -

    The type and scope should always be lowercase as shown below.

    -

    Allowed <type> values:

    -
      -
    • feat for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version.
    • -
    • fix for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version.
    • -
    • perf for performance improvements. Such commit will trigger a release bumping a PATCH version.
    • -
    • docs for changes to the documentation.
    • -
    • style for formatting changes, missing semicolons, etc.
    • -
    • refactor for refactoring production code, e.g. renaming a variable.
    • -
    • test for adding missing tests, refactoring tests; no production code change.
    • -
    • build for updating build configuration, development tools or other changes irrelevant to the user.
    • -
    • chore for updates that do not apply to the above, such as dependency updates.
    • -
    • ci for changes to CI configuration files and scripts
    • -
    • revert for revert to a previous commit
    • -
    -

    Allowed <scope> values:

    -

    checks:

    -
      -
    • vuln
    • -
    • misconf
    • -
    • secret
    • -
    • license
    • -
    -

    mode:

    -
      -
    • image
    • -
    • fs
    • -
    • repo
    • -
    • sbom
    • -
    • k8s
    • -
    • server
    • -
    • aws
    • -
    • vm
    • -
    -

    os:

    -
      -
    • alpine
    • -
    • redhat
    • -
    • alma
    • -
    • rocky
    • -
    • mariner
    • -
    • oracle
    • -
    • debian
    • -
    • ubuntu
    • -
    • amazon
    • -
    • suse
    • -
    • photon
    • -
    • distroless
    • -
    -

    language:

    -
      -
    • ruby
    • -
    • php
    • -
    • python
    • -
    • nodejs
    • -
    • rust
    • -
    • dotnet
    • -
    • java
    • -
    • go
    • -
    • elixir
    • -
    • dart
    • -
    -

    vuln:

    -
      -
    • os
    • -
    • lang
    • -
    -

    config:

    -
      -
    • kubernetes
    • -
    • dockerfile
    • -
    • terraform
    • -
    • cloudformation
    • -
    -

    container

    -
      -
    • docker
    • -
    • podman
    • -
    • containerd
    • -
    • oci
    • -
    -

    cli:

    -
      -
    • cli
    • -
    • flag
    • -
    -

    SBOM:

    -
      -
    • cyclonedx
    • -
    • spdx
    • -
    • purl
    • -
    -

    others:

    -
      -
    • helm
    • -
    • report
    • -
    • db
    • -
    • deps
    • -
    -

    The <scope> can be empty (e.g. if the change is a global or difficult to assign to a single component), in which case the parentheses are omitted.

    -

    Example titles

    -
    feat(alma): add support for AlmaLinux
    -
    -
    fix(oracle): handle advisories with ksplice versions
    -
    -
    docs(misconf): add comparison with Conftest and TFsec
    -
    -
    chore(deps): bump go.uber.org/zap from 1.19.1 to 1.20.0
    -
    -

    NOTE: please do not use chore(deps): update fanal and something like that if you add new features or fix bugs in Trivy-related projects. -The PR title should describe what the PR adds or fixes even though it just updates the dependency in Trivy.

    -

    Commits

    -

    Understand where your pull request belongs

    -

    Trivy is composed of several repositories that work together:

    -
      -
    • Trivy is the client-side, user-facing, command line tool.
    • -
    • vuln-list is a vulnerability database, aggregated from different sources, and normalized for easy consumption. Think of this as the "server" side of the trivy command line tool. There should be no pull requests to this repo
    • -
    • vuln-list-update is the code that maintains the vuln-list database.
    • -
    • trivy-db maintains the vulnerability database pulled by Trivy CLI.
    • -
    • go-dep-parser is a library for parsing lock files such as package-lock.json and Gemfile.lock.
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/community/maintainer/help-wanted/index.html b/test/community/maintainer/help-wanted/index.html deleted file mode 100644 index 8a52c49852a3..000000000000 --- a/test/community/maintainer/help-wanted/index.html +++ /dev/null @@ -1,3136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Help Wanted - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Overview

    -

    We use two labels help wanted and good first -issue to identify issues that have been specially groomed -for new contributors. The good first issue label is a subset of help wanted -label, indicating that members have committed to providing extra assistance for -new contributors. All good first issue items also have the help wanted -label.

    -

    Help Wanted

    -

    Items marked with the help wanted label need to ensure that they are:

    -
      -
    • Low Barrier to Entry
    • -
    -

    It should be tractable for new contributors. Documentation on how that type of - change should be made should already exist.

    -
      -
    • Clear Task
    • -
    -

    The task is agreed upon and does not require further discussions in the - community. Call out if that area of code is untested and requires new - fixtures.

    -

    API / CLI behavior is decided and included in the OP issue, for example: "The - new command syntax is trivy --format yaml IMAGE_NAME"_ with - expected validations called out.

    -
      -
    • Goldilocks priority
    • -
    -

    Not too high that a core contributor should do it, but not too low that it - isn't useful enough for a core contributor to spend time to review it, answer - questions, help get it into a release, etc.

    -
      -
    • Up-To-Date
    • -
    -

    Often these issues become obsolete and have already been done, are no longer - desired, no longer make sense, have changed priority or difficulty , etc.

    -

    Good First Issue

    -

    Items marked with the good first issue label are intended for first-time -contributors. It indicates that members will keep an eye out for these pull -requests and shepherd it through our processes.

    -

    These items need to ensure that they follow the guidelines for help wanted -labels (above) in addition to meeting the following criteria:

    -
      -
    • No Barrier to Entry
    • -
    -

    The task is something that a new contributor can tackle without advanced - setup, or domain knowledge.

    -
      -
    • Solution Explained
    • -
    -

    The recommended solution is clearly described in the issue.

    -
      -
    • Provides Context
    • -
    -

    If background knowledge is required, this should be explicitly mentioned and a - list of suggested readings included.

    -
      -
    • Gives Examples
    • -
    -

    Link to examples of similar implementations so new contributors have a - reference guide for their changes.

    -
      -
    • Identifies Relevant Code
    • -
    -

    The relevant code and tests to be changed should be linked in the issue.

    -
      -
    • Ready to Test
    • -
    -

    There should be existing tests that can be modified, or existing test cases - fit to be copied. If the area of code doesn't have tests, before labeling the - issue, add a test fixture. This prep often makes a great help wanted task!

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/community/maintainer/triage/index.html b/test/community/maintainer/triage/index.html deleted file mode 100644 index 78883b991c51..000000000000 --- a/test/community/maintainer/triage/index.html +++ /dev/null @@ -1,3140 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Triage - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Triage

    -

    Triage is an important part of maintaining the health of the trivy repo. -A well organized repo allows maintainers to prioritize feature requests, fix bugs, and respond to users facing difficulty with the tool as quickly as possible.

    -

    Triage includes:

    -
      -
    • Labeling issues
    • -
    • Responding to issues
    • -
    • Closing issues
    • -
    -

    Daily Triage

    -

    Daily triage has two goals:

    -
      -
    1. Responsiveness for new issues
    2. -
    3. Responsiveness when explicitly requested information was provided
    4. -
    -

    It covers:

    -
      -
    1. Issues without a kind/ or triage/ label
    2. -
    3. Issues without a priority/ label
    4. -
    5. triage/needs-information issues which the user has followed up on, and now require a response.
    6. -
    -

    Categorization

    -

    The most important level of categorizing the issue is defining what type it is. -We typically want at least one of the following labels on every issue, and some issues may fall into multiple categories:

    -
      -
    • triage/support - The default for most incoming issues
    • -
    • kind/bug - When it’s a bug or we aren’t delivering the best user experience
    • -
    -

    Other possibilities: -- kind/feature- Identify new feature requests -- kind/testing - Update or fix unit/integration tests -- kind/cleanup - Cleaning up/refactoring the codebase -- kind/documentation - Updates or additions to trivy documentation

    -

    If the issue is specific to a driver for OS packages or libraries:

    -

    co/[driver for OS packages]

    -
      -
    • co/alpine
    • -
    • co/amazon
    • -
    • co/debian
    • -
    • co/oracle
    • -
    • co/photon
    • -
    • co/redhat
    • -
    • co/suse
    • -
    • co/ubuntu
    • -
    -

    co/[driver for libraries of programming languages]

    -
      -
    • co/bundler
    • -
    • co/cargo
    • -
    • co/composer
    • -
    • co/npm
    • -
    • co/yarn
    • -
    • co/pipenv
    • -
    • co/poetry
    • -
    -

    Help wanted?

    -

    Good First Issue - bug has a proposed solution, can be implemented w/o further discussion.

    -

    Help wanted - if the bug could use help from a contributor

    -

    Prioritization

    -

    If the issue is not triage/support, it needs a priority label.

    -

    priority/critical-urgent - someones top priority ASAP, such as security issue, user-visible bug, or build breakage. Rarely used.

    -

    priority/important-soon: in time for the next two releases. It should be attached to a milestone.

    -

    priority/important-longterm: 2-4 releases from now

    -

    priority/backlog: agreed that this would be good to have, but no one is available at the moment. Consider tagging as help wanted

    -

    priority/awaiting-more-evidence: may be useful, but there is not yet enough support.

    -

    Weekly Triage

    -

    Weekly triage has three goals:

    -
      -
    1. Catching up on unresponded issues
    2. -
    3. Reviewing and closing PR’s
    4. -
    5. Closing stale issues
    6. -
    -

    Post-Release Triage

    -

    Post-release triage occurs after a major release (around every 4-6 weeks). -It focuses on:

    -
      -
    1. Closing bugs that have been resolved by the release
    2. -
    3. Reprioritizing bugs that have not been resolved by the release
    4. -
    5. Letting users know if we believe that there is still an issue
    6. -
    -

    This includes reviewing:

    -
      -
    1. Every issue that hasn’t been touched in the last 2 days
    2. -
    3. Re-evaluation of long-term issues
    4. -
    5. Re-evaluation of short-term issues
    6. -
    -

    Responding to Issues

    -

    Needs More Information

    -

    A sample response to ask for more info:

    -
    -

    I don’t yet have a clear way to replicate this issue. Do you mind adding some additional details. Here is additional information that would be helpful:

    -

    * The exact trivy command line used

    -

    * The exact image you want to scan

    -

    * The full output of the trivy command, preferably with --debug for extra logging.

    -

    Thank you for sharing your experience!

    -
    -

    Then: Label with triage/needs-information.

    -

    Issue might be resolved

    -

    If you think a release may have resolved an issue, ask the author to see if their issue has been resolved:

    -
    -

    Could you please check to see if trivy addresses this issue? We've made some changes with how this is handled, and improved the trivy logs output to help us debug tricky cases like this.

    -
    -

    Then: Label with triage/needs-information.

    -

    Closing with Care

    -

    Issues typically need to be closed for the following reasons:

    -
      -
    • The issue has been addressed
    • -
    • The issue is a duplicate of an existing issue
    • -
    • There has been a lack of information over a long period of time
    • -
    -

    In any of these situations, we aim to be kind when closing the issue, and offer the author action items should they need to reopen their issue or still require a solution.

    -

    Samples responses for these situations include:

    -

    Issue has been addressed

    -
    -

    @author: I believe this issue is now addressed by trivy v1.0.0, as it . If you still see this issue with trivy v1.0 or higher, please reopen this issue.

    -

    Thank you for reporting this issue!

    -
    -

    Then: Close the issue

    -

    Duplicate Issue

    -
    -

    This issue appears to be a duplicate of #X, do you mind if we move the conversation there?

    -

    This way we can centralize the content relating to the issue. If you feel that this issue is not in fact a duplicate, please re-open it. If you have additional information to share, please add it to the new issue.

    -

    Thank you for reporting this!

    -
    -

    Then: Label with triage/duplicate and close the issue.

    -

    Lack of Information

    -

    If an issue hasn't been active for more than four weeks, and the author has been pinged at least once, then the issue can be closed.

    -
    -

    Hey @author -- hopefully it's OK if I close this - there wasn't enough information to make it actionable, and some time has already passed. If you are able to provide additional details, you may reopen it at any point.

    -

    Here is additional information that may be helpful to us:

    -

    * Whether the issue occurs with the latest trivy release

    -

    * The exact trivy command line used

    -

    * The exact image you want to scan

    -

    * The full output of the trivy command, preferably with --debug for extra logging.

    -

    Thank you for sharing your experience!

    -
    -

    Then: Close the issue.

    -

    Help Wanted issues

    -

    We use two labels help wanted -and good first issue -to identify issues that have been specially groomed for new contributors.

    -

    We have specific guidelines -for how to use these labels. If you see an issue that satisfies these -guidelines, you can add the help wanted label and the good first issue label. -Please note that adding the good first issue label must also -add the help wanted label.

    -

    If an issue has these labels but does not satisfy the guidelines, please -ask for more details to be added to the issue or remove the labels.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/air-gap/index.html b/test/docs/advanced/air-gap/index.html deleted file mode 100644 index 31595f844162..000000000000 --- a/test/docs/advanced/air-gap/index.html +++ /dev/null @@ -1,3297 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Air-Gapped Environment - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Air-Gapped Environment

    -

    Trivy can be used in air-gapped environments. Note that an allowlist is here.

    -

    Air-Gapped Environment for vulnerabilities

    -

    Download the vulnerability database

    -

    At first, you need to download the vulnerability database for use in air-gapped environments.

    -
    -
    -
    -
    TRIVY_TEMP_DIR=$(mktemp -d)
    -trivy --cache-dir $TRIVY_TEMP_DIR image --download-db-only
    -tar -cf ./db.tar.gz -C $TRIVY_TEMP_DIR/db metadata.json trivy.db
    -rm -rf $TRIVY_TEMP_DIR
    -
    -
    -
    -

    Please follow oras installation instruction.

    -

    Download db.tar.gz:

    -
    $ oras pull ghcr.io/aquasecurity/trivy-db:2
    -
    -
    -
    -

    Please follow oras installation instruction.

    -

    Download db.tar.gz:

    -
    $ oras pull -a ghcr.io/aquasecurity/trivy-db:2
    -
    -
    -
    -
    -

    Download the Java index database1

    -

    Java users also need to download the Java index database for use in air-gapped environments.

    -
    -

    Note

    -

    You container image may contain JAR files even though you don't use Java directly. -In that case, you also need to download the Java index database.

    -
    -
    -
    -
    -
    TRIVY_TEMP_DIR=$(mktemp -d)
    -trivy --cache-dir $TRIVY_TEMP_DIR image --download-java-db-only
    -tar -cf ./javadb.tar.gz -C $TRIVY_TEMP_DIR/java-db metadata.json trivy-java.db
    -rm -rf $TRIVY_TEMP_DIR
    -
    -
    -
    -

    Please follow oras installation instruction.

    -

    Download javadb.tar.gz:

    -
    $ oras pull ghcr.io/aquasecurity/trivy-java-db:1
    -
    -
    -
    -

    Please follow oras installation instruction.

    -

    Download javadb.tar.gz:

    -
    $ oras pull -a ghcr.io/aquasecurity/trivy-java-db:1
    -
    -
    -
    -
    -

    Transfer the DB files into the air-gapped environment

    -

    The way of transfer depends on the environment.

    -
    -
    -
    -
    $ rsync -av -e ssh /path/to/db.tar.gz [user]@[host]:dst
    -
    -
    -
    -
    $ rsync -av -e ssh /path/to/javadb.tar.gz [user]@[host]:dst
    -
    -
    -
    -
    -

    Put the DB files in Trivy's cache directory

    -

    You have to know where to put the DB files. The following command shows the default cache directory.

    -
    $ ssh user@host
    -$ trivy -h | grep cache
    -   --cache-dir value  cache directory (default: "/home/myuser/.cache/trivy") [$TRIVY_CACHE_DIR]
    -
    -
    -
    -
    -

    Put the DB file in the cache directory + /db.

    -
    $ mkdir -p /home/myuser/.cache/trivy/db
    -$ cd /home/myuser/.cache/trivy/db
    -$ tar xvf /path/to/db.tar.gz -C /home/myuser/.cache/trivy/db
    -x trivy.db
    -x metadata.json
    -$ rm /path/to/db.tar.gz
    -
    -
    -
    -

    Put the DB file in the cache directory + /java-db.

    -
    $ mkdir -p /home/myuser/.cache/trivy/java-db
    -$ cd /home/myuser/.cache/trivy/java-db
    -$ tar xvf /path/to/javadb.tar.gz -C /home/myuser/.cache/trivy/java-db
    -x trivy-java.db
    -x metadata.json
    -$ rm /path/to/javadb.tar.gz
    -
    -
    -
    -
    -

    In an air-gapped environment it is your responsibility to update the Trivy databases on a regular basis, so that the scanner can detect recently-identified vulnerabilities.

    -

    Run Trivy with the specific flags.

    -

    In an air-gapped environment, you have to specify --skip-db-update and --skip-java-db-update1 so that Trivy doesn't attempt to download the latest database files. -In addition, if you want to scan pom.xml dependencies, you need to specify --offline-scan since Trivy tries to issue API requests for scanning Java applications by default.

    -
    $ trivy image --skip-db-update --skip-java-db-update --offline-scan alpine:3.12
    -
    -

    Air-Gapped Environment for misconfigurations

    -

    No special measures are required to detect misconfigurations in an air-gapped environment.

    -

    Run Trivy with --skip-policy-update option

    -

    In an air-gapped environment, specify --skip-policy-update so that Trivy doesn't attempt to download the latest misconfiguration policies.

    -
    $ trivy conf --skip-policy-update /path/to/conf
    -
    -
    -
    -
      -
    1. -

      This is only required to scan jar files. More information about Java index db here 

      -
    2. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/container/embed-in-dockerfile/index.html b/test/docs/advanced/container/embed-in-dockerfile/index.html deleted file mode 100644 index bdbdb2b7a552..000000000000 --- a/test/docs/advanced/container/embed-in-dockerfile/index.html +++ /dev/null @@ -1,3031 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Embed in Dockerfile - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Embed in Dockerfile

    -

    Scan your image as part of the build process by embedding Trivy in the -Dockerfile. This approach can be used to update Dockerfiles currently using -Aqua’s Microscanner.

    -

    $ cat Dockerfile
    -FROM alpine:3.7
    -
    -RUN apk add curl \
    -    && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \
    -    && trivy rootfs --exit-code 1 --no-progress /
    -
    -$ docker build -t vulnerable-image .
    -
    -Alternatively you can use Trivy in a multistage build. Thus avoiding the -insecure curl | sh. Also the image is not changed. -
    [...]
    -# Run vulnerability scan on build image
    -FROM build AS vulnscan
    -COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy
    -RUN trivy rootfs --exit-code 1 --no-progress /
    -[...]
    -

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/container/unpacked-filesystem/index.html b/test/docs/advanced/container/unpacked-filesystem/index.html deleted file mode 100644 index 7a358ed6ace6..000000000000 --- a/test/docs/advanced/container/unpacked-filesystem/index.html +++ /dev/null @@ -1,3119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Unpacked container image filesystem - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Unpacked Filesystem

    -

    Scan an unpacked container image filesystem.

    -

    In this case, Trivy works the same way when scanning containers

    -
    $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
    -$ trivy rootfs /tmp/rootfs
    -
    -
    -Result - -
    2021-03-08T05:22:26.378Z        INFO    Need to update DB
    -2021-03-08T05:22:26.380Z        INFO    Downloading DB...
    -20.37 MiB / 20.37 MiB [-------------------------------------------------------------------------------------------------------------------------------------] 100.00% 8.24 MiB p/s 2s
    -2021-03-08T05:22:30.134Z        INFO    Detecting Alpine vulnerabilities...
    -
    -/tmp/rootfs (alpine 3.10.2)
    -===========================
    -Total: 20 (UNKNOWN: 0, LOW: 2, MEDIUM: 10, HIGH: 8, CRITICAL: 0)
    -
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| libcrypto1.1 | CVE-2020-1967    | HIGH     | 1.1.1c-r0         | 1.1.1g-r0     | openssl: Segmentation                 |
    -|              |                  |          |                   |               | fault in SSL_check_chain              |
    -|              |                  |          |                   |               | causes denial of service              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1967  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2021-23839   |          |                   | 1.1.1j-r0     | openssl: incorrect SSLv2              |
    -|              |                  |          |                   |               | rollback protection                   |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23839 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23840   |          |                   |               | openssl: integer                      |
    -|              |                  |          |                   |               | overflow in CipherUpdate              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23840 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23841   |          |                   |               | openssl: NULL pointer dereference     |
    -|              |                  |          |                   |               | in X509_issuer_and_serial_hash()      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23841 |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1547    | MEDIUM   |                   | 1.1.1d-r0     | openssl: side-channel weak            |
    -|              |                  |          |                   |               | encryption vulnerability              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1547  |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2019-1549    |          |                   |               | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in fork()                  |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1549  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2019-1551    |          |                   | 1.1.1d-r2     | openssl: Integer overflow in RSAZ     |
    -|              |                  |          |                   |               | modular exponentiation on x86_64      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1551  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2020-1971    |          |                   | 1.1.1i-r0     | openssl: EDIPARTYNAME                 |
    -|              |                  |          |                   |               | NULL pointer de-reference             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1971  |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1563    | LOW      |                   | 1.1.1d-r0     | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in PKCS7_dataDecode        |
    -|              |                  |          |                   |               | and CMS_decrypt_set1_pkey             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1563  |
    -+--------------+------------------+----------+                   +---------------+---------------------------------------+
    -| libssl1.1    | CVE-2020-1967    | HIGH     |                   | 1.1.1g-r0     | openssl: Segmentation                 |
    -|              |                  |          |                   |               | fault in SSL_check_chain              |
    -|              |                  |          |                   |               | causes denial of service              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1967  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2021-23839   |          |                   | 1.1.1j-r0     | openssl: incorrect SSLv2              |
    -|              |                  |          |                   |               | rollback protection                   |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23839 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23840   |          |                   |               | openssl: integer                      |
    -|              |                  |          |                   |               | overflow in CipherUpdate              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23840 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23841   |          |                   |               | openssl: NULL pointer dereference     |
    -|              |                  |          |                   |               | in X509_issuer_and_serial_hash()      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23841 |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1547    | MEDIUM   |                   | 1.1.1d-r0     | openssl: side-channel weak            |
    -|              |                  |          |                   |               | encryption vulnerability              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1547  |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2019-1549    |          |                   |               | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in fork()                  |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1549  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2019-1551    |          |                   | 1.1.1d-r2     | openssl: Integer overflow in RSAZ     |
    -|              |                  |          |                   |               | modular exponentiation on x86_64      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1551  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2020-1971    |          |                   | 1.1.1i-r0     | openssl: EDIPARTYNAME                 |
    -|              |                  |          |                   |               | NULL pointer de-reference             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1971  |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1563    | LOW      |                   | 1.1.1d-r0     | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in PKCS7_dataDecode        |
    -|              |                  |          |                   |               | and CMS_decrypt_set1_pkey             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1563  |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| musl         | CVE-2020-28928   | MEDIUM   | 1.1.22-r3         | 1.1.22-r4     | In musl libc through 1.2.1,           |
    -|              |                  |          |                   |               | wcsnrtombs mishandles particular      |
    -|              |                  |          |                   |               | combinations of destination buffer... |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-28928 |
    -+--------------+                  +          +                   +               +                                       +
    -| musl-utils   |                  |          |                   |               |                                       |
    -|              |                  |          |                   |               |                                       |
    -|              |                  |          |                   |               |                                       |
    -|              |                  |          |                   |               |                                       |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -
    - -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/modules/index.html b/test/docs/advanced/modules/index.html deleted file mode 100644 index d456f190a30d..000000000000 --- a/test/docs/advanced/modules/index.html +++ /dev/null @@ -1,3557 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Modules - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Modules

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy provides a module feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. -It changes the behavior during scanning by WebAssembly.

    -

    Overview

    -

    Trivy modules are add-on tools that integrate seamlessly with Trivy. -They provide a way to extend the core feature set of Trivy, but without updating the Trivy binary.

    -
      -
    • They can be added and removed from a Trivy installation without impacting the core Trivy tool.
    • -
    • They can be written in any programming language supporting WebAssembly.
    • -
    • It supports only TinyGo at the moment.
    • -
    -

    You can write your own detection logic.

    -
      -
    • Evaluate complex vulnerability conditions like Spring4Shell
    • -
    • Detect a shell script communicating with malicious domains
    • -
    • Detect malicious python install script (setup.py)
    • -
    • Even detect misconfigurations in WordPress setting
    • -
    • etc.
    • -
    -

    Then, you can update the scan result however you want.

    -
      -
    • Change a severity
    • -
    • Remove a vulnerability
    • -
    • Add a new vulnerability
    • -
    • etc.
    • -
    -

    Modules should be distributed in OCI registries like GitHub Container Registry.

    -
    -

    Warning

    -

    WebAssembly doesn't allow file access and network access by default. -Modules can read required files only, but cannot overwrite them. -WebAssembly is sandboxed and secure by design, but Trivy modules available in public are not audited for security. -You should install and run third-party modules at your own risk even though

    -
    -

    Under the hood Trivy leverages wazero to run WebAssembly modules without CGO.

    -

    Installing a Module

    -

    A module can be installed using the trivy module install command. -This command takes an url. It will download the module and install it in the module cache.

    -

    Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. -Trivy will now search XDG_DATA_HOME for the location of the Trivy modules cache. -The preference order is as follows:

    -
      -
    • XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir
    • -
    • $HOME/.trivy/plugins
    • -
    -

    For example, to download the WebAssembly module, you can execute the following command:

    -
    $ trivy module install ghcr.io/aquasecurity/trivy-module-spring4shell
    -
    -

    Using Modules

    -

    Once the module is installed, Trivy will load all available modules in the cache on the start of the next Trivy execution. -The modules may inject custom logic into scanning and change the result. -You can run Trivy as usual and modules are loaded automatically.

    -

    You will see the log messages about WASM modules.

    -
    $ trivy image ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8
    -2022-06-12T12:57:13.210+0300    INFO    Loading ghcr.io/aquasecurity/trivy-module-spring4shell/spring4shell.wasm...
    -2022-06-12T12:57:13.596+0300    INFO    Registering WASM module: spring4shell@v1
    -...
    -2022-06-12T12:57:14.865+0300    INFO    Module spring4shell: Java Version: 8, Tomcat Version: 8.5.77
    -2022-06-12T12:57:14.865+0300    INFO    Module spring4shell: change CVE-2022-22965 severity from CRITICAL to LOW
    -
    -Java (jar)
    -
    -Total: 9 (UNKNOWN: 1, LOW: 3, MEDIUM: 2, HIGH: 3, CRITICAL: 0)
    -
    -┌──────────────────────────────────────────────────────────────┬─────────────────────┬──────────┬───────────────────┬────────────────────────┬────────────────────────────────────────────────────────────┐
    -│                           Library                            │    Vulnerability    │ Severity │ Installed Version │     Fixed Version      │                           Title                            │
    -├──────────────────────────────────────────────────────────────┼─────────────────────┼──────────┼───────────────────┼────────────────────────┼────────────────────────────────────────────────────────────┤
    -│ org.springframework.boot:spring-boot (helloworld.war)        │ CVE-2022-22965      │ LOW      │ 2.6.3             │ 2.5.12, 2.6.6          │ spring-framework: RCE via Data Binding on JDK 9+           │
    -│                                                              │                     │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2022-22965                 │
    -├──────────────────────────────────────────────────────────────┼─────────────────────┼──────────┼───────────────────┼────────────────────────┼────────────────────────────────────────────────────────────┤
    -...(snip)...
    -
    -

    In the above example, the Spring4Shell module changed the severity from CRITICAL to LOW because the application doesn't satisfy one of conditions.

    -

    Uninstalling Modules

    -

    Specify a module repository with trivy module uninstall command.

    -
    $ trivy module uninstall ghcr.io/aquasecurity/trivy-module-spring4shell
    -
    -

    Building Modules

    -

    It supports TinyGo only at the moment.

    -

    TinyGo

    -

    Trivy provides Go SDK including three interfaces. -Your own module needs to implement either or both Analyzer and PostScanner in addition to Module.

    -
    type Module interface {
    -    Version() int
    -    Name() string
    -}
    -
    -type Analyzer interface {
    -    RequiredFiles() []string
    -    Analyze(filePath string) (*serialize.AnalysisResult, error)
    -}
    -
    -type PostScanner interface {
    -    PostScanSpec() serialize.PostScanSpec
    -    PostScan(serialize.Results) (serialize.Results, error)
    -}
    -
    -

    In the following tutorial, it creates a WordPress module that detects a WordPress version and a critical vulnerability accordingly.

    -
    -

    Tips

    -

    You can use logging functions such as Debug and Info for debugging. -See examples for the detail.

    -
    -

    Initialize your module

    -

    Replace the repository name with yours.

    -
    $ go mod init github.com/aquasecurity/trivy-module-wordpress
    -
    -

    Module interface

    -

    Version() returns your module version and should be incremented after updates. -Name() returns your module name.

    -
    package main
    -
    -const (
    -    version = 1
    -    name = "wordpress-module"
    -)
    -
    -type WordpressModule struct{
    -    // Cannot define fields as modules can't keep state.
    -}
    -
    -func (WordpressModule) Version() int {
    -    return version
    -}
    -
    -func (WordpressModule) Name() string {
    -    return name
    -}
    -
    -
    -

    Info

    -

    A struct cannot have any fields. Each method invocation is performed in different states.

    -
    -

    Analyzer interface

    -

    If you implement the Analyzer interface, Analyze method is called when the file path is matched to file patterns returned by RequiredFiles(). -A file pattern must be a regular expression. The syntax detail is here.

    -

    Analyze takes the matched file path, then the file can be opened by os.Open().

    -
    const typeWPVersion = "wordpress-version"
    -
    -func (WordpressModule) RequiredFiles() []string {
    -    return []string{
    -        `wp-includes\/version.php`,
    -    }
    -}
    -
    -func (WordpressModule) Analyze(filePath string) (*serialize.AnalysisResult, error) {
    -    f, err := os.Open(filePath) // e.g. filePath: /usr/src/wordpress/wp-includes/version.php
    -    if err != nil {
    -        return nil, err
    -    }
    -    defer f.Close()
    -
    -    var wpVersion string
    -    scanner := bufio.NewScanner(f)
    -    for scanner.Scan() {
    -        line := scanner.Text()
    -        if !strings.HasPrefix(line, "$wp_version=") {
    -            continue
    -        }
    -
    -        ss := strings.Split(line, "=")
    -        if len(ss) != 2 {
    -            return nil, fmt.Errorf("invalid wordpress version: %s", line)
    -        }
    -
    -        // NOTE: it is an example; you actually need to handle comments, etc
    -        ss[1] = strings.TrimSpace(ss[1])
    -        wpVersion = strings.Trim(ss[1], `";`)
    -    }
    -
    -    if err = scanner.Err(); err != nil {
    -        return nil, err
    -    }
    -
    -    return &serialize.AnalysisResult{
    -        CustomResources: []serialize.CustomResource{
    -            {
    -                Type:     typeWPVersion,
    -                FilePath: filePath,
    -                Data:     wpVersion,
    -            },
    -        },
    -    }, nil
    -}
    -
    -
    -

    Tips

    -

    Trivy caches analysis results according to the module version. -We'd recommend cleaning the cache or changing the module version every time you update Analyzer.

    -
    -

    PostScanner interface

    -

    PostScan is called after scanning and takes the scan result as an argument from Trivy. -In post scanning, your module can perform one of three actions:

    -
      -
    • Insert
        -
      • Add a new security finding
      • -
      • e.g. Add a new vulnerability and misconfiguration
      • -
      -
    • -
    • Update
        -
      • Update the detected vulnerability and misconfiguration
      • -
      • e.g. Change a severity
      • -
      -
    • -
    • Delete
        -
      • Delete the detected vulnerability and misconfiguration
      • -
      • e.g. Remove Spring4Shell because it is not actually affected.
      • -
      -
    • -
    -

    PostScanSpec() returns which action the module does. -If it is Update or Delete, it also needs to return IDs such as CVE-ID and misconfiguration ID, which your module wants to update or delete.

    -

    serialize.Results contains the filtered results matching IDs you specified. -Also, it includes CustomResources with the values your Analyze returns, so you can modify the scan result according to the custom resources.

    -
    func (WordpressModule) PostScanSpec() serialize.PostScanSpec {
    -    return serialize.PostScanSpec{
    -        Action: api.ActionInsert, // Add new vulnerabilities
    -    }
    -}
    -
    -func (WordpressModule) PostScan(results serialize.Results) (serialize.Results, error) {
    -    // e.g. results
    -    // [
    -    //   {
    -    //     "Target": "",
    -    //     "Class": "custom",
    -    //     "CustomResources": [
    -    //       {
    -    //         "Type": "wordpress-version",
    -    //         "FilePath": "/usr/src/wordpress/wp-includes/version.php",
    -    //         "Layer": {
    -    //           "DiffID": "sha256:057649e61046e02c975b84557c03c6cca095b8c9accd3bd20eb4e432f7aec887"
    -    //         },
    -    //         "Data": "5.7.1"
    -    //       }
    -    //     ]
    -    //   }
    -    // ]   
    -    var wpVersion int
    -    for _, result := range results {
    -        if result.Class != types.ClassCustom {
    -            continue
    -        }
    -
    -        for _, c := range result.CustomResources {
    -            if c.Type != typeWPVersion {
    -                continue
    -            }
    -            wpVersion = c.Data.(string)
    -            wasm.Info(fmt.Sprintf("WordPress Version: %s", wpVersion))
    -
    -            ...snip...
    -
    -            if affectedVersion.Check(ver) {
    -                vulnerable = true
    -            }
    -            break
    -        }
    -    }
    -
    -    if vulnerable {
    -        // Add CVE-2020-36326
    -        results = append(results, serialize.Result{
    -            Target: wpPath,
    -            Class:  types.ClassLangPkg,
    -            Type:   "wordpress",
    -            Vulnerabilities: []types.DetectedVulnerability {
    -                {
    -                    VulnerabilityID:  "CVE-2020-36326",
    -                    PkgName:          "wordpress",
    -                    InstalledVersion: wpVersion,
    -                    FixedVersion:     "5.7.2",
    -                    Vulnerability: dbTypes.Vulnerability{
    -                        Title:    "PHPMailer 6.1.8 through 6.4.0 allows object injection through Phar Deserialization via addAttachment with a UNC pathname.",
    -                        Severity: "CRITICAL",
    -                    },
    -                },
    -            },
    -        })
    -    }
    -    return results, nil
    -}
    -
    -

    The new vulnerability will be added to the scan results. -This example shows how the module inserts a new finding. -If you are interested in Update, you can see an example of Spring4Shell.

    -

    In the Delete action, PostScan needs to return results you want to delete. -If PostScan returns an empty, Trivy will not delete anything.

    -

    Build

    -

    Follow the install guide and install TinyGo.

    -
    $ tinygo build -o wordpress.wasm -scheduler=none -target=wasi --no-debug wordpress.go
    -
    -

    Put the built binary to the module directory that is under the home directory by default.

    -
    $ mkdir -p ~/.trivy/modules
    -$ cp spring4shell.wasm ~/.trivy/modules
    -
    -

    Distribute Your Module

    -

    You can distribute your own module in OCI registries. Please follow the oras installation instruction.

    -
    oras push ghcr.io/aquasecurity/trivy-module-wordpress:latest wordpress.wasm:application/vnd.module.wasm.content.layer.v1+wasm
    -Uploading 3daa3dac086b wordpress.wasm
    -Pushed ghcr.io/aquasecurity/trivy-module-wordpress:latest
    -Digest: sha256:6416d0199d66ce52ced19f01d75454b22692ff3aa7737e45f7a189880840424f
    -
    -

    Examples

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/plugins/index.html b/test/docs/advanced/plugins/index.html deleted file mode 100644 index ede2f0611398..000000000000 --- a/test/docs/advanced/plugins/index.html +++ /dev/null @@ -1,3291 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugins - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugins

    -

    Trivy provides a plugin feature to allow others to extend the Trivy CLI without the need to change the Trivycode base. -This plugin system was inspired by the plugin system used in kubectl, Helm, and Conftest.

    -

    Overview

    -

    Trivy plugins are add-on tools that integrate seamlessly with Trivy. -They provide a way to extend the core feature set of Trivy, but without requiring every new feature to be written in Go and added to the core tool.

    -
      -
    • They can be added and removed from a Trivy installation without impacting the core Trivy tool.
    • -
    • They can be written in any programming language.
    • -
    • They integrate with Trivy, and will show up in Trivy help and subcommands.
    • -
    -
    -

    Warning

    -

    Trivy plugins available in public are not audited for security. -You should install and run third-party plugins at your own risk, since they are arbitrary programs running on your machine.

    -
    -

    Installing a Plugin

    -

    A plugin can be installed using the trivy plugin install command. -This command takes a url and will download the plugin and install it in the plugin cache.

    -

    Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. -Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache. -The preference order is as follows:

    -
      -
    • XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir
    • -
    • ~/.trivy/plugins
    • -
    -

    Under the hood Trivy leverages go-getter to download plugins. -This means the following protocols are supported for downloading plugins:

    -
      -
    • OCI Registries
    • -
    • Local Files
    • -
    • Git
    • -
    • HTTP/HTTPS
    • -
    • Mercurial
    • -
    • Amazon S3
    • -
    • Google Cloud Storage
    • -
    -

    For example, to download the Kubernetes Trivy plugin you can execute the following command:

    -

    $ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl
    -
    -Also, Trivy plugin can be installed from a local archive: -
    $ trivy plugin install myplugin.tar.gz
    -

    -

    Using Plugins

    -

    Once the plugin is installed, Trivy will load all available plugins in the cache on the start of the next Trivy execution. -A plugin will be made in the Trivy CLI based on the plugin name. -To display all plugins, you can list them by trivy --help

    -
    $ trivy --help
    -NAME:
    -   trivy - A simple and comprehensive vulnerability scanner for containers
    -
    -USAGE:
    -   trivy [global options] command [command options] target
    -
    -VERSION:
    -   dev
    -
    -COMMANDS:
    -   image, i          scan an image
    -   filesystem, fs    scan local filesystem
    -   repository, repo  scan remote repository
    -   client, c         client mode
    -   server, s         server mode
    -   plugin, p         manage plugins
    -   kubectl           scan kubectl resources
    -   help, h           Shows a list of commands or help for one command
    -
    -

    As shown above, kubectl subcommand exists in the COMMANDS section. -To call the kubectl plugin and scan existing Kubernetes deployments, you can execute the following command:

    -
    $ trivy kubectl deployment <deployment-id> -- --ignore-unfixed --severity CRITICAL
    -
    -

    Internally the kubectl plugin calls the kubectl binary to fetch information about that deployment and passes the using images to Trivy. -You can see the detail here.

    -

    If you want to omit even the subcommand, you can use TRIVY_RUN_AS_PLUGIN environment variable.

    -
    $ TRIVY_RUN_AS_PLUGIN=kubectl trivy job your-job -- --format json
    -
    -

    Installing and Running Plugins on the fly

    -

    trivy plugin run installs a plugin and runs it on the fly. -If the plugin is already present in the cache, the installation is skipped.

    -
    trivy plugin run github.com/aquasecurity/trivy-plugin-kubectl pod your-pod -- --exit-code 1
    -
    -

    Uninstalling Plugins

    -

    Specify a plugin name with trivy plugin uninstall command.

    -
    $ trivy plugin uninstall kubectl
    -
    -

    Building Plugins

    -

    Each plugin has a top-level directory, and then a plugin.yaml file.

    -
    your-plugin/
    -  |
    -  |- plugin.yaml
    -  |- your-plugin.sh
    -
    -

    In the example above, the plugin is contained inside of a directory named your-plugin. -It has two files: plugin.yaml (required) and an executable script, your-plugin.sh (optional).

    -

    The core of a plugin is a simple YAML file named plugin.yaml. -Here is an example YAML of trivy-plugin-kubectl plugin that adds support for Kubernetes scanning.

    -
    name: "kubectl"
    -repository: github.com/aquasecurity/trivy-plugin-kubectl
    -version: "0.1.0"
    -usage: scan kubectl resources
    -description: |-
    -  A Trivy plugin that scans the images of a kubernetes resource.
    -  Usage: trivy kubectl TYPE[.VERSION][.GROUP] NAME
    -platforms:
    -  - selector: # optional
    -      os: darwin
    -      arch: amd64
    -    uri: ./trivy-kubectl # where the execution file is (local file, http, git, etc.)
    -    bin: ./trivy-kubectl # path to the execution file
    -  - selector: # optional
    -      os: linux
    -      arch: amd64
    -    uri: https://github.com/aquasecurity/trivy-plugin-kubectl/releases/download/v0.1.0/trivy-kubectl.tar.gz
    -    bin: ./trivy-kubectl
    -
    -

    The plugin.yaml field should contain the following information:

    -
      -
    • name: The name of the plugin. This also determines how the plugin will be made available in the Trivy CLI. For example, if the plugin is named kubectl, you can call the plugin with trivy kubectl. (required)
    • -
    • version: The version of the plugin. (required)
    • -
    • usage: A short usage description. (required)
    • -
    • description: A long description of the plugin. This is where you could provide a helpful documentation of your plugin. (required)
    • -
    • platforms: (required)
    • -
    • selector: The OS/Architecture specific variations of a execution file. (optional)
        -
      • os: OS information based on GOOS (linux, darwin, etc.) (optional)
      • -
      • arch: The architecture information based on GOARCH (amd64, arm64, etc.) (optional)
      • -
      -
    • -
    • uri: Where the executable file is. Relative path from the root directory of the plugin or remote URL such as HTTP and S3. (required)
    • -
    • bin: Which file to call when the plugin is executed. Relative path from the root directory of the plugin. (required)
    • -
    -

    The following rules will apply in deciding which platform to select:

    -
      -
    • If both os and arch under selector match the current platform, search will stop and the platform will be used.
    • -
    • If selector is not present, the platform will be used.
    • -
    • If os matches and there is no more specific arch match, the platform will be used.
    • -
    • If no platform match is found, Trivy will exit with an error.
    • -
    -

    After determining platform, Trivy will download the execution file from uri and store it in the plugin cache. -When the plugin is called via Trivy CLI, bin command will be executed.

    -

    The plugin is responsible for handling flags and arguments. Any arguments are passed to the plugin from the trivy command.

    -

    A plugin should be archived *.tar.gz.

    -
    $ tar -czvf myplugin.tar.gz plugin.yaml script.py
    -plugin.yaml
    -script.py
    -
    -$ trivy plugin install myplugin.tar.gz
    -2023-03-03T19:04:42.026+0600    INFO    Installing the plugin from myplugin.tar.gz...
    -2023-03-03T19:04:42.026+0600    INFO    Loading the plugin metadata...
    -
    -$ trivy myplugin
    -Hello from Trivy demo plugin!
    -
    -

    Example

    -

    https://github.com/aquasecurity/trivy-plugin-kubectl

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/private-registries/acr/index.html b/test/docs/advanced/private-registries/acr/index.html deleted file mode 100644 index f262fede298a..000000000000 --- a/test/docs/advanced/private-registries/acr/index.html +++ /dev/null @@ -1,3030 +0,0 @@ - - - - - - - - - - - - - - - - - - - - ACR (Azure Container Registry) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Requirements

    -

    None, Trivy uses Azure SDK for Go. You don't need to install az command.

    -

    Privileges

    -

    Service principal must have the AcrPull permissions.

    -

    Creation of a service principal

    -
    export SP_DATA=$(az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.ContainerRegistry/registries/<registry_name>")
    -
    -

    Usage

    -
    # must set TRIVY_USERNAME empty char
    -export AZURE_CLIENT_ID$(echo $SP_DATA | jq -r .appId)
    -export AZURE_CLIENT_SECRET$(echo $SP_DATA | jq -r .password)
    -export AZURE_TENANT_ID$(echo $SP_DATA | jq -r .tenant)
    -
    -

    Testing

    -

    You can test credentials in the following manner.

    -
    docker run -it --rm -v /tmp:/tmp\
    -  -e AZURE_CLIENT_ID=${AZURE_CLIENT_ID} -e AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET} \
    -  -e AZURE_TENANT_ID=${AZURE_TENANT_ID} aquasec/trivy image your_special_project.azurecr.io/your_special_image:your_special_tag
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/private-registries/docker-hub/index.html b/test/docs/advanced/private-registries/docker-hub/index.html deleted file mode 100644 index 41586dc415da..000000000000 --- a/test/docs/advanced/private-registries/docker-hub/index.html +++ /dev/null @@ -1,3006 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Docker Hub - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Docker Hub

    - -

    See here for the detail. -You don't need to provide a credential when download from public repository.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/private-registries/ecr/index.html b/test/docs/advanced/private-registries/ecr/index.html deleted file mode 100644 index 08813ddb8fff..000000000000 --- a/test/docs/advanced/private-registries/ecr/index.html +++ /dev/null @@ -1,3116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AWS ECR (Elastic Container Registry) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    AWS ECR (Elastic Container Registry)

    - -

    Trivy uses AWS SDK. You don't need to install aws CLI tool. -You can use AWS CLI's ENV Vars.

    -

    AWS private registry permissions

    -

    You may need to grant permissions to allow Trivy to pull images from private ECR.

    -

    It depends on how you want to provide AWS Role to trivy.

    - -

    IAM Role Service account

    -

    Add the AWS role in trivy's service account annotations:

    -
    trivy:
    -
    -  serviceAccount:
    -    annotations: {}
    -      # eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
    -
    -

    Kube2iam or Kiam

    -

    Add the AWS role to pod's annotations:

    -
    podAnnotations: {}
    -  ## kube2iam/kiam annotation
    -  # iam.amazonaws.com/role: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/private-registries/gcr/index.html b/test/docs/advanced/private-registries/gcr/index.html deleted file mode 100644 index 7ebf21d1b635..000000000000 --- a/test/docs/advanced/private-registries/gcr/index.html +++ /dev/null @@ -1,3042 +0,0 @@ - - - - - - - - - - - - - - - - - - - - GCR (Google Container Registry) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Requirements

    -

    None, Trivy uses Google Cloud SDK. You don't need to install gcloud command.

    -

    Privileges

    -

    Credential file must have the roles/storage.objectViewer permissions. -More information can be found in Google's documentation

    -

    JSON File Format

    -

    The JSON file specified should have the following format provided by google's service account mechanisms:

    -
    {
    -  "type": "service_account",
    -  "project_id": "your_special_project",
    -  "private_key_id": "XXXXXXXXXXXXXXXXXXXXxx",
    -  "private_key": "-----BEGIN PRIVATE KEY-----\nNONONONO\n-----END PRIVATE KEY-----\n",
    -  "client_email": "somedude@your_special_project.iam.gserviceaccount.com",
    -  "client_id": "1234567890",
    -  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    -  "token_uri": "https://oauth2.googleapis.com/token",
    -  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    -  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/somedude%40your_special_project.iam.gserviceaccount.com"
    -}
    -
    -

    Usage

    -

    If you want to use target project's repository, you can set them via GOOGLE_APPLICATION_CREDENTIALS. -

    # must set TRIVY_USERNAME empty char
    -export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json
    -

    -

    Testing

    -

    You can test credentials in the following manner (assuming they are in /tmp on host machine).

    -
    docker run -it --rm -v /tmp:/tmp\
    -  -e GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json\
    -  aquasec/trivy image gcr.io/your_special_project/your_special_image:your_special_tag
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/private-registries/index.html b/test/docs/advanced/private-registries/index.html deleted file mode 100644 index a188478e1c8c..000000000000 --- a/test/docs/advanced/private-registries/index.html +++ /dev/null @@ -1,3104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Overview

    - -

    Trivy can download images from a private registry without the need for installing Docker or any other 3rd party tools. -This makes it easy to run within a CI process.

    -

    Credential

    -

    To use Trivy with private images, simply install it and provide your credentials:

    -
    $ TRIVY_USERNAME=YOUR_USERNAME TRIVY_PASSWORD=YOUR_PASSWORD trivy image YOUR_PRIVATE_IMAGE
    -
    -

    Trivy also supports providing credentials through CLI flags:

    -
    $ TRIVY_PASSWORD=YOUR_PASSWORD trivy image --username YOUR_USERNAME YOUR_PRIVATE_IMAGE
    -
    -
    -

    Warning

    -

    The CLI flag --password is available, but its use is not recommended for security reasons.

    -
    -

    You can also store your credentials in trivy.yaml. -For more information, please refer to the documentation.

    -

    It can handle multiple sets of credentials as well:

    -
    $ export TRIVY_USERNAME=USERNAME1,USERNAME2
    -$ export TRIVY_PASSWORD=PASSWORD1,PASSWORD2
    -$ trivy image YOUR_PRIVATE_IMAGE
    -
    -

    In the example above, Trivy attempts to use two pairs of credentials:

    -
      -
    • USERNAME1/PASSWORD1
    • -
    • USERNAME2/PASSWORD2
    • -
    -

    Please note that the number of usernames and passwords must be the same.

    -

    docker login

    -

    If you have Docker configured locally and have set up the credentials, Trivy can access them.

    -
    $ docker login ghcr.io
    -Username: 
    -Password:
    -$ trivy image ghcr.io/your/private_image
    -
    -
    -

    Note

    -

    docker login can be used with any container runtime, such as Podman.

    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/advanced/private-registries/self/index.html b/test/docs/advanced/private-registries/self/index.html deleted file mode 100644 index 252ccaa10727..000000000000 --- a/test/docs/advanced/private-registries/self/index.html +++ /dev/null @@ -1,3011 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Self-Hosted - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Self-Hosted

    - -

    BasicAuth server needs TRIVY_USERNAME and TRIVY_PASSWORD.

    -
    export TRIVY_USERNAME={USERNAME}
    -export TRIVY_PASSWORD={PASSWORD}
    -
    -# if you want to use 80 port, use NonSSL
    -export TRIVY_NON_SSL=true
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/compliance/compliance/index.html b/test/docs/compliance/compliance/index.html deleted file mode 100644 index d3c9509f257b..000000000000 --- a/test/docs/compliance/compliance/index.html +++ /dev/null @@ -1,3184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Reports - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Compliance Reports

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy’s compliance flag lets you curate a specific set of checks into a report. In a typical Trivy scan, there are hundreds of different checks for many different components and configurations, but sometimes you already know which specific checks you are interested in. Often this would be an industry accepted set of checks such as CIS, or some vendor specific guideline, or your own organization policy that you want to comply with. These are all possible using the flexible compliance infrastructure that's built into Trivy. Compliance reports are defined as simple YAML documents that select checks to include in the report.

    -

    Usage

    -

    Compliance report is currently supported in the following targets (trivy sub-commands):

    -
      -
    • trivy image
    • -
    • trivy aws
    • -
    • trivy k8s
    • -
    -

    Add the --compliance flag to the command line, and set it's value to desired report. -For example: trivy k8s cluster --compliance k8s-nsa (see below for built-in and custom reports)

    -

    Options

    -

    The following flags are compatible with --compliance flag and allows customizing it's output:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    flageffect
    --report summaryshows a summary of the results. for every control shows the number of failed checks.
    --report allshows fully detailed results. for every control shows where it failed and why.
    --format tableshows results in textual table format (good for human readability).
    --format jsonshows results in json format (good for machine readability).
    -

    Built-in compliance

    -

    Trivy has a number of built-in compliance reports that you can asses right out of the box. -to specify a built-in compliance report, select it by ID like trivy --compliance <compliance_id>.

    -

    For the list of built-in compliance reports, please see the relevant section:

    - -

    Custom compliance

    -

    You can create your own custom compliance report. A compliance report is a simple YAML document in the following format:

    -
    spec:
    -  id: "k8s-myreport" # report unique identifier. this should not container spaces.
    -  title: "My custom Kubernetes report" # report title. Any one-line title.
    -  description: "Describe your report" # description of the report. Any text.
    -  relatedResources :
    -    - https://some.url # useful references. URLs only.
    -  version: "1.0" # spec version (string)
    -  controls:
    -    - name: "Non-root containers" # Name for the control (appears in the report as is). Any one-line name.
    -      description: 'Check that container is not running as root' # Description (appears in the report as is). Any text.
    -      id: "1.0" # control identifier (string)
    -      checks:   # list of existing Trivy checks that define the control
    -        - id: AVD-KSV-0012 # check ID. Must start with `AVD-` or `CVE-` 
    -      severity: "MEDIUM" # Severity for the control (note that checks severity isn't used)
    -    - name: "Immutable container file systems"
    -      description: 'Check that container root file system is immutable'
    -      id: "1.1"
    -      checks:
    -        - id: AVD-KSV-0014
    -      severity: "LOW"
    -
    -

    The check id field (controls[].checks[].id) is referring to existing check by it's "AVD ID". This AVD ID is easily located in the check's source code metadata header, or by browsing Aqua vulnerability DB, specifically in the Misconfigurations and Vulnerabilities sections.

    -

    Once you have a compliance spec, you can select it by file path: trivy --compliance @</path/to/compliance.yaml> (note the @ indicating file path instead of report id).

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/cache/index.html b/test/docs/configuration/cache/index.html deleted file mode 100644 index 256f0faba917..000000000000 --- a/test/docs/configuration/cache/index.html +++ /dev/null @@ -1,3152 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Cache - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Cache

    -

    The cache directory includes

    - -

    The cache option is common to all scanners.

    -

    Clear Caches

    -

    The --clear-cache option removes caches.

    -

    The scan is not performed.

    -
    $ trivy image --clear-cache
    -
    -
    -Result - -
    2019-11-15T15:13:26.209+0200    INFO    Reopening vulnerability DB
    -2019-11-15T15:13:26.209+0200    INFO    Removing image caches...
    -
    - -
    - -

    Cache Directory

    -

    Specify where the cache is stored with --cache-dir.

    -
    $ trivy --cache-dir /tmp/trivy/ image python:3.4-alpine3.9
    -
    -

    Cache Backend

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy supports local filesystem and Redis as the cache backend. This option is useful especially for client/server mode.

    -

    Two options:

    -
      -
    • fs
        -
      • the cache path can be specified by --cache-dir
      • -
      -
    • -
    • redis://
        -
      • redis://[HOST]:[PORT]
      • -
      • TTL can be configured via --cache-ttl
      • -
      -
    • -
    -
    $ trivy server --cache-backend redis://localhost:6379
    -
    -

    If you want to use TLS with Redis, you can enable it by specifying the --redis-tls flag.

    -
    $ trivy server --cache-backend redis://localhost:6379 --redis-tls
    -
    -

    Trivy also supports for connecting to Redis with your certificates. -You need to specify --redis-ca , --redis-cert , and --redis-key options.

    -
    $ trivy server --cache-backend redis://localhost:6379 \
    -  --redis-ca /path/to/ca-cert.pem \
    -  --redis-cert /path/to/cert.pem \
    -  --redis-key /path/to/key.pem
    -
    -
    -
    -
      -
    1. -

      Downloaded when scanning for vulnerabilities 

      -
    2. -
    3. -

      Downloaded when scanning jar/war/par/ear files 

      -
    4. -
    5. -

      Downloaded when scanning for misconfigurations 

      -
    6. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/db/index.html b/test/docs/configuration/db/index.html deleted file mode 100644 index 0490a2d40098..000000000000 --- a/test/docs/configuration/db/index.html +++ /dev/null @@ -1,3207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - DB - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    DB

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    The vulnerability database and the Java index database are needed only for vulnerability scanning. -See here for the detail.

    -

    Vulnerability Database

    -

    Skip update of vulnerability DB

    -

    If you want to skip downloading the vulnerability database, use the --skip-db-update option.

    -
    $ trivy image --skip-db-update python:3.4-alpine3.9
    -
    -
    -Result - -
    2019-05-16T12:48:08.703+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |
    -|         |                  |          |                   |               | with long nonces               |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -
    - -
    - -

    Only download vulnerability database

    -

    You can also ask Trivy to simply retrieve the vulnerability database. -This is useful to initialize workers in Continuous Integration systems.

    -
    $ trivy image --download-db-only
    -
    -

    DB Repository

    -

    Trivy could also download the vulnerability database from an external OCI registry by using --db-repository option.

    -
    $ trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db
    -
    -

    Java Index Database

    -

    The same options are also available for the Java index DB, which is used for scanning Java applications. -Skipping an update can be done by using the --skip-java-db-update option, while --download-java-db-only can be used to only download the Java index DB.

    -

    Downloading the Java index DB from an external OCI registry can be done by using the --java-db-repository option.

    -
    $ trivy image --java-db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-java-db --download-java-db-only
    -
    -

    Remove DBs

    -

    The --reset flag removes all caches and databases.

    -
    $ trivy image --reset
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/filtering/index.html b/test/docs/configuration/filtering/index.html deleted file mode 100644 index 8c4e22e2ce30..000000000000 --- a/test/docs/configuration/filtering/index.html +++ /dev/null @@ -1,3605 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Filtering - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Filtering

    -

    Trivy provides various methods for filtering the results.

    -

    Hide Unfixed Vulnerabilities

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy also detects unpatched/unfixed vulnerabilities. -This means you can't fix these vulnerabilities even if you update all packages. -If you would like to ignore them, use the --ignore-unfixed option.

    -
    $ trivy image --ignore-unfixed ruby:2.4.0
    -
    -
    -Result - -
    2019-05-16T12:49:52.656+0900    INFO    Updating vulnerability database...
    -2019-05-16T12:50:14.786+0900    INFO    Detecting Debian vulnerabilities...
    -
    -ruby:2.4.0 (debian 8.7)
    -=======================
    -Total: 4730 (UNKNOWN: 1, LOW: 145, MEDIUM: 3487, HIGH: 1014, CRITICAL: 83)
    -
    -+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
    -|           LIBRARY            | VULNERABILITY ID | SEVERITY |     INSTALLED VERSION      |          FIXED VERSION           |                        TITLE                        |
    -+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
    -| apt                          | CVE-2019-3462    | CRITICAL | 1.0.9.8.3                  | 1.0.9.8.5                        | Incorrect sanitation of the                         |
    -|                              |                  |          |                            |                                  | 302 redirect field in HTTP                          |
    -|                              |                  |          |                            |                                  | transport method of...                              |
    -+                              +------------------+----------+                            +----------------------------------+-----------------------------------------------------+
    -|                              | CVE-2016-1252    | MEDIUM   |                            | 1.0.9.8.4                        | The apt package in Debian                           |
    -|                              |                  |          |                            |                                  | jessie before 1.0.9.8.4, in                         |
    -|                              |                  |          |                            |                                  | Debian unstable before...                           |
    -+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
    -| bash                         | CVE-2019-9924    | HIGH     | 4.3-11                     | 4.3-11+deb8u2                    | bash: BASH_CMD is writable in                       |
    -|                              |                  |          |                            |                                  | restricted bash shells                              |
    -+                              +------------------+          +                            +----------------------------------+-----------------------------------------------------+
    -|                              | CVE-2016-7543    |          |                            | 4.3-11+deb8u1                    | bash: Specially crafted                             |
    -|                              |                  |          |                            |                                  | SHELLOPTS+PS4 variables allows                      |
    -|                              |                  |          |                            |                                  | command substitution                                |
    -+                              +------------------+----------+                            +                                  +-----------------------------------------------------+
    -|                              | CVE-2016-0634    | MEDIUM   |                            |                                  | bash: Arbitrary code execution                      |
    -|                              |                  |          |                            |                                  | via malicious hostname                              |
    -+                              +------------------+----------+                            +----------------------------------+-----------------------------------------------------+
    -|                              | CVE-2016-9401    | LOW      |                            | 4.3-11+deb8u2                    | bash: popd controlled free                          |
    -+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
    -...
    -
    - -
    - -

    By Severity

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Use --severity option.

    -
    $ trivy image --severity HIGH,CRITICAL ruby:2.4.0
    -
    -
    -Result - -
    2019-05-16T01:51:46.255+0900    INFO    Updating vulnerability database...
    -2019-05-16T01:51:49.213+0900    INFO    Detecting Debian vulnerabilities...
    -
    -ruby:2.4.0 (debian 8.7)
    -=======================
    -Total: 1785 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1680, CRITICAL: 105)
    -
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -|           LIBRARY           | VULNERABILITY ID | SEVERITY |     INSTALLED VERSION     |          FIXED VERSION           |                      TITLE                      |
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -| apt                         | CVE-2019-3462    | CRITICAL | 1.0.9.8.3                 | 1.0.9.8.5                        | Incorrect sanitation of the                     |
    -|                             |                  |          |                           |                                  | 302 redirect field in HTTP                      |
    -|                             |                  |          |                           |                                  | transport method of...                          |
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -| bash                        | CVE-2019-9924    | HIGH     | 4.3-11                    | 4.3-11+deb8u2                    | bash: BASH_CMD is writable in                   |
    -|                             |                  |          |                           |                                  | restricted bash shells                          |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2016-7543    |          |                           | 4.3-11+deb8u1                    | bash: Specially crafted                         |
    -|                             |                  |          |                           |                                  | SHELLOPTS+PS4 variables allows                  |
    -|                             |                  |          |                           |                                  | command substitution                            |
    -+-----------------------------+------------------+          +---------------------------+----------------------------------+-------------------------------------------------+
    -| binutils                    | CVE-2017-8421    |          | 2.25-5                    |                                  | binutils: Memory exhaustion in                  |
    -|                             |                  |          |                           |                                  | objdump via a crafted PE file                   |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2017-14930   |          |                           |                                  | binutils: Memory leak in                        |
    -|                             |                  |          |                           |                                  | decode_line_info                                |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2017-7614    |          |                           |                                  | binutils: NULL                                  |
    -|                             |                  |          |                           |                                  | pointer dereference in                          |
    -|                             |                  |          |                           |                                  | bfd_elf_final_link function                     |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2014-9939    |          |                           |                                  | binutils: buffer overflow in                    |
    -|                             |                  |          |                           |                                  | ihex.c                                          |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2017-13716   |          |                           |                                  | binutils: Memory leak with the                  |
    -|                             |                  |          |                           |                                  | C++ symbol demangler routine                    |
    -|                             |                  |          |                           |                                  | in libiberty                                    |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2018-12699   |          |                           |                                  | binutils: heap-based buffer                     |
    -|                             |                  |          |                           |                                  | overflow in finish_stab in                      |
    -|                             |                  |          |                           |                                  | stabs.c                                         |
    -+-----------------------------+------------------+          +---------------------------+----------------------------------+-------------------------------------------------+
    -| bsdutils                    | CVE-2015-5224    |          | 2.25.2-6                  |                                  | util-linux: File name                           |
    -|                             |                  |          |                           |                                  | collision due to incorrect                      |
    -|                             |                  |          |                           |                                  | mkstemp use                                     |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2016-2779    |          |                           |                                  | util-linux: runuser tty hijack                  |
    -|                             |                  |          |                           |                                  | via TIOCSTI ioctl                               |
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -
    - -
    - -
    trivy conf --severity HIGH,CRITICAL examples/misconf/mixed
    -
    -
    -Result - -
    2022-05-16T13:50:42.718+0100    INFO    Detected config files: 3
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 17 (SUCCESSES: 16, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Last USER command in Dockerfile should not be 'root'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - Dockerfile:3
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   3 [ USER root
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -deployment.yaml (kubernetes)
    -============================
    -Tests: 8 (SUCCESSES: 8, FAILURES: 0, EXCEPTIONS: 0)
    -Failures: 0 (HIGH: 0, CRITICAL: 0)
    -
    -
    -main.tf (terraform)
    -===================
    -Tests: 1 (SUCCESSES: 0, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (HIGH: 0, CRITICAL: 1)
    -
    -CRITICAL: Classic resources should not be used.
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -AWS Classic resources run in a shared environment with infrastructure owned by other AWS customers. You should run
    -resources in a VPC instead.
    -
    -See https://avd.aquasec.com/misconfig/avd-aws-0081
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - main.tf:2-4
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   2 ┌ resource "aws_db_security_group" "sg" {
    -   3 │
    -   4}
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    - -

    By Finding IDs

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Use .trivyignore.

    -
    $ cat .trivyignore
    -# Accept the risk
    -CVE-2018-14618
    -
    -# Accept the risk until 2023-01-01
    -CVE-2019-14697 exp:2023-01-01
    -
    -# No impact in our settings
    -CVE-2019-1543
    -
    -# Ignore misconfigurations
    -AVD-DS-0002
    -
    -# Ignore secrets
    -generic-unwanted-rule
    -aws-account-id
    -
    -
    $ trivy image python:3.4-alpine3.9
    -
    -
    -Result - -
    2019-05-16T12:53:10.076+0900    INFO    Updating vulnerability database...
    -2019-05-16T12:53:28.134+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    - -
    - -

    By Vulnerability Target

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Use --vuln-type option.

    -
    $ trivy image --vuln-type os ruby:2.4.0
    -
    -

    Available values:

    -
      -
    • library
    • -
    • os
    • -
    -
    -Result - -
    2019-05-22T19:36:50.530+0200    INFO    Updating vulnerability database...
    -2019-05-22T19:36:51.681+0200    INFO    Detecting Alpine vulnerabilities...
    -2019-05-22T19:36:51.685+0200    INFO    Updating npm Security DB...
    -2019-05-22T19:36:52.389+0200    INFO    Detecting npm vulnerabilities...
    -2019-05-22T19:36:52.390+0200    INFO    Updating pipenv Security DB...
    -2019-05-22T19:36:53.406+0200    INFO    Detecting pipenv vulnerabilities...
    -
    -ruby:2.4.0 (debian 8.7)
    -=======================
    -Total: 7 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 3, CRITICAL: 2)
    -
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |              TITLE               |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| curl    | CVE-2018-14618   | CRITICAL | 7.61.0-r0         | 7.61.1-r0     | curl: NTLM password overflow     |
    -|         |                  |          |                   |               | via integer overflow             |
    -+         +------------------+----------+                   +---------------+----------------------------------+
    -|         | CVE-2018-16839   | HIGH     |                   | 7.61.1-r1     | curl: Integer overflow leading   |
    -|         |                  |          |                   |               | to heap-based buffer overflow in |
    -|         |                  |          |                   |               | Curl_sasl_create_plain_message() |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| git     | CVE-2018-17456   | HIGH     | 2.15.2-r0         | 2.15.3-r0     | git: arbitrary code execution    |
    -|         |                  |          |                   |               | via .gitmodules                  |
    -+         +------------------+          +                   +               +----------------------------------+
    -|         | CVE-2018-19486   |          |                   |               | git: Improper handling of        |
    -|         |                  |          |                   |               | PATH allows for commands to be   |
    -|         |                  |          |                   |               | executed from...                 |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| libssh2 | CVE-2019-3855    | CRITICAL | 1.8.0-r2          | 1.8.1-r0      | libssh2: Integer overflow in     |
    -|         |                  |          |                   |               | transport read resulting in      |
    -|         |                  |          |                   |               | out of bounds write...           |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| sqlite  | CVE-2018-20346   | MEDIUM   | 3.21.0-r1         | 3.25.3-r0     | CVE-2018-20505 CVE-2018-20506    |
    -|         |                  |          |                   |               | sqlite: Multiple flaws in        |
    -|         |                  |          |                   |               | sqlite which can be triggered    |
    -|         |                  |          |                   |               | via...                           |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| tar     | CVE-2018-20482   | LOW      | 1.29-r1           | 1.31-r0       | tar: Infinite read loop in       |
    -|         |                  |          |                   |               | sparse_dump_region function in   |
    -|         |                  |          |                   |               | sparse.c                         |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -
    - -
    - -

    By Open Policy Agent

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy supports Open Policy Agent (OPA) to filter vulnerabilities. -You can specify a Rego file with --ignore-policy option.

    -

    The Rego package name must be trivy and it must include a rule called ignore which determines if each individual vulnerability should be excluded (ignore=true) or not (ignore=false). In the policy, each vulnerability will be available for inspection as the input variable. The structure of each vulnerability input is the same as for the Trivy JSON output.
    -There is a built-in Rego library with helper functions that you can import into your policy using: import data.lib.trivy. For more info about the helper functions, look at the library here

    -

    To get started, see the example policy.

    -
    $ trivy image --ignore-policy contrib/example_policy/basic.rego centos:7
    -
    -
    -Result - -
    centos:7 (centos 7.9.2009)
    -==========================
    -Total: 9 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 4, CRITICAL: 5)
    -
    -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+
    -|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |   FIXED VERSION   |                  TITLE                  |
    -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+
    -| glib2        | CVE-2015-8385    | HIGH     | 2.56.1-7.el7      |                   | pcre: buffer overflow caused            |
    -|              |                  |          |                   |                   | by named forward reference              |
    -|              |                  |          |                   |                   | to duplicate group number...            |
    -|              |                  |          |                   |                   | -->avd.aquasec.com/nvd/cve-2015-8385    |
    -+              +------------------+          +                   +-------------------+-----------------------------------------+
    -|              | CVE-2016-3191    |          |                   |                   | pcre: workspace overflow for            |
    -|              |                  |          |                   |                   | (*ACCEPT) with deeply nested            |
    -|              |                  |          |                   |                   | parentheses (8.39/13, 10.22/12)         |
    -|              |                  |          |                   |                   | -->avd.aquasec.com/nvd/cve-2016-3191    |
    -+              +------------------+          +                   +-------------------+-----------------------------------------+
    -|              | CVE-2021-27219   |          |                   | 2.56.1-9.el7_9    | glib: integer overflow in               |
    -|              |                  |          |                   |                   | g_bytes_new function on                 |
    -|              |                  |          |                   |                   | 64-bit platforms due to an...           |
    -|              |                  |          |                   |                   | -->avd.aquasec.com/nvd/cve-2021-27219   |
    -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+
    -| glibc        | CVE-2019-1010022 | CRITICAL | 2.17-317.el7      |                   | glibc: stack guard protection bypass    |
    -|              |                  |          |                   |                   | -->avd.aquasec.com/nvd/cve-2019-1010022 |
    -+--------------+                  +          +                   +-------------------+                                         +
    -| glibc-common |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -+--------------+------------------+          +-------------------+-------------------+-----------------------------------------+
    -| nss          | CVE-2021-43527   |          | 3.53.1-3.el7_9    | 3.67.0-4.el7_9    | nss: Memory corruption in               |
    -|              |                  |          |                   |                   | decodeECorDsaSignature with             |
    -|              |                  |          |                   |                   | DSA signatures (and RSA-PSS)            |
    -|              |                  |          |                   |                   | -->avd.aquasec.com/nvd/cve-2021-43527   |
    -+--------------+                  +          +                   +                   +                                         +
    -| nss-sysinit  |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -+--------------+                  +          +                   +                   +                                         +
    -| nss-tools    |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -|              |                  |          |                   |                   |                                         |
    -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+
    -| openssl-libs | CVE-2020-1971    | HIGH     | 1:1.0.2k-19.el7   | 1:1.0.2k-21.el7_9 | openssl: EDIPARTYNAME                   |
    -|              |                  |          |                   |                   | NULL pointer de-reference               |
    -|              |                  |          |                   |                   | -->avd.aquasec.com/nvd/cve-2020-1971    |
    -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+
    -
    - -
    - -

    By Inline Comments

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Some configuration file formats (e.g. Terraform) support inline comments.

    -

    In cases where trivy can detect comments of a specific format immediately adjacent to resource definitions, it is possible to filter/ignore findings from a single point of resource definition (in contrast to .trivyignore, which has a directory-wide scope on all of the files scanned).

    -

    The format for these comments is trivy:ignore:<Vulnerability ID> immediately following the format-specific line-comment token.

    -

    For example, to filter a Vulnerability ID "AVD-GCP-0051" in a Terraform HCL file:

    -
    #trivy:ignore:AVD-GCP-0051
    -resource "google_container_cluster" "one_off_test" {
    -  name     = var.cluster_name
    -  location = var.region
    -}
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/index.html b/test/docs/configuration/index.html deleted file mode 100644 index 8ac39720fccb..000000000000 --- a/test/docs/configuration/index.html +++ /dev/null @@ -1,3109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Configuration

    -

    Trivy can be configured using the following ways. Each item takes precedence over the item below it:

    -
      -
    • CLI flags
    • -
    • Environment variables
    • -
    • Configuration file
    • -
    -

    CLI Flags

    -

    You can view the list of available flags using the --help option. -For more details, please refer to the CLI reference.

    -

    Environment Variables

    -

    Trivy can be customized by environment variables. -The environment variable key is the flag name converted by the following procedure.

    -
      -
    • Add TRIVY_ prefix
    • -
    • Make it all uppercase
    • -
    • Replace - with _
    • -
    -

    For example,

    -
      -
    • --debug => TRIVY_DEBUG
    • -
    • --cache-dir => TRIVY_CACHE_DIR
    • -
    -
    $ TRIVY_DEBUG=true TRIVY_SEVERITY=CRITICAL trivy image alpine:3.15
    -
    -

    Configuration File

    -

    By default, Trivy reads the trivy.yaml file. -For more details, please refer to the page.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/others/index.html b/test/docs/configuration/others/index.html deleted file mode 100644 index e30bf821ae50..000000000000 --- a/test/docs/configuration/others/index.html +++ /dev/null @@ -1,3221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Others - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Others

    -

    Enable/Disable Scanners

    -

    You can enable/disable scanners with the --scanners flag.

    -

    Supported values:

    -
      -
    • vuln
    • -
    • config
    • -
    • secret
    • -
    • license
    • -
    -

    For example, container image scanning enables vulnerability and secret scanners by default. -If you don't need secret scanning, it can be disabled.

    -
    $ trivy image --scanners vuln alpine:3.15
    -
    -

    Exit Code

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy exits with code 0 even when security issues are detected. -Use the --exit-code option if you want to exit with a non-zero exit code.

    -
    $ trivy image --exit-code 1 python:3.4-alpine3.9
    -
    -
    -Result - -
    2019-05-16T12:51:43.500+0900    INFO    Updating vulnerability database...
    -2019-05-16T12:52:00.387+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |
    -|         |                  |          |                   |               | with long nonces               |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -
    - -
    - -

    This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found.

    -
    $ trivy image --exit-code 0 --severity MEDIUM,HIGH ruby:2.4.0
    -$ trivy image --exit-code 1 --severity CRITICAL ruby:2.4.0
    -
    -

    Exit on EOL

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Sometimes you may surprisingly get 0 vulnerabilities in an old image:

    -
      -
    • Enabling --ignore-unfixed option while all packages have no fixed versions.
    • -
    • Scanning a rather outdated OS (e.g. Ubuntu 10.04).
    • -
    -

    An OS at the end of service/life (EOL) usually gets into this situation, which is definitely full of vulnerabilities. ---exit-on-eol can fail scanning on EOL OS with a non-zero code. -This flag is available with the following targets.

    -
      -
    • Container images (trivy image)
    • -
    • Virtual machine images (trivy vm)
    • -
    • SBOM (trivy sbom)
    • -
    • Root filesystem (trivy rootfs)
    • -
    -
    $ trivy image --exit-on-eol 1 alpine:3.10
    -
    -
    -Result - -
    2023-03-01T11:07:15.455+0200    INFO    Vulnerability scanning is enabled
    -...
    -2023-03-01T11:07:17.938+0200    WARN    This OS version is no longer supported by the distribution: alpine 3.10.9
    -2023-03-01T11:07:17.938+0200    WARN    The vulnerability detection may be insufficient because security updates are not provided
    -
    -alpine:3.10 (alpine 3.10.9)
    -===========================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
    -
    -┌───────────┬────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│  Library  │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├───────────┼────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ apk-tools │ CVE-2021-36159 │ CRITICAL │ 2.10.6-r0         │ 2.10.7-r0     │ libfetch before 2021-07-26, as used in apk-tools, xbps, and │
    -│           │                │          │                   │               │ other products, mishandles...                               │
    -│           │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-36159                  │
    -└───────────┴────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -2023-03-01T11:07:17.941+0200    ERROR   Detected EOL OS: alpine 3.10.9
    -
    - -
    - -

    This option is useful for CI/CD. -The following example will fail when a critical vulnerability is found or the OS is EOSL:

    -
    $ trivy image --exit-code 1 --exit-on-eol 1 --severity CRITICAL alpine:3.16.3
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/reporting/index.html b/test/docs/configuration/reporting/index.html deleted file mode 100644 index af1353f54d05..000000000000 --- a/test/docs/configuration/reporting/index.html +++ /dev/null @@ -1,3719 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Reporting - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Reporting

    -

    Trivy supports the following formats:

    -
      -
    • Table
    • -
    • JSON
    • -
    • SARIF
    • -
    • Template
    • -
    • SBOM
    • -
    -

    Table (Default)

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ trivy image -f table golang:1.12-alpine
    -
    -

    Show origins of vulnerable dependencies

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Modern software development relies on the use of third-party libraries. -Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph. -In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree. -To make this task simpler Trivy can show a dependency origin tree with the --dependency-tree flag. -This flag is only available with the --format table flag.

    -

    The following packages/languages are currently supported:

    -
      -
    • OS packages
        -
      • apk
      • -
      • dpkg
      • -
      • rpm
      • -
      -
    • -
    • Node.js
        -
      • npm: package-lock.json
      • -
      • pnpm: pnpm-lock.yaml
      • -
      • yarn: yarn.lock
      • -
      -
    • -
    • .NET
        -
      • NuGet: packages.lock.json
      • -
      -
    • -
    • Python
        -
      • Poetry: poetry.lock
      • -
      -
    • -
    • Ruby
        -
      • Bundler: Gemfile.lock
      • -
      -
    • -
    • Rust -
    • -
    • Go
        -
      • Modules: go.mod
      • -
      -
    • -
    • PHP
        -
      • Composer
      • -
      -
    • -
    -

    This tree is the reverse of the npm list command. -However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update.

    -

    In table output, it looks like:

    -
    $ trivy fs --severity HIGH,CRITICAL --dependency-tree /path/to/your_node_project
    -
    -package-lock.json (npm)
    -=======================
    -Total: 2 (HIGH: 1, CRITICAL: 1)
    -
    -┌──────────────────┬────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│     Library      │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                           Title                            │
    -├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ follow-redirects │ CVE-2022-0155  │ HIGH     │ 1.14.6            │ 1.14.7        │ follow-redirects: Exposure of Private Personal Information │
    -│                  │                │          │                   │               │ to an Unauthorized Actor                                   │
    -│                  │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-0155                  │
    -├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ glob-parent      │ CVE-2020-28469 │ CRITICAL │ 3.1.0             │ 5.1.2         │ nodejs-glob-parent: Regular expression denial of service   │
    -│                  │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2020-28469                 │
    -└──────────────────┴────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -Dependency Origin Tree (Reversed)
    -=================================
    -package-lock.json
    -├── follow-redirects@1.14.6, (HIGH: 1, CRITICAL: 0)
    -│   └── axios@0.21.4
    -└── glob-parent@3.1.0, (HIGH: 0, CRITICAL: 1)
    -    └── chokidar@2.1.8
    -        └── watchpack-chokidar2@2.0.1
    -            └── watchpack@1.7.5
    -                └── webpack@4.46.0
    -                    └── cra-append-sw@2.7.0
    -
    -

    Vulnerable dependencies are shown in the top level of the tree. -Lower levels show how those vulnerabilities are introduced. -In the example above axios@0.21.4 included in the project directly depends on the vulnerable follow-redirects@1.14.6. -Also, glob-parent@3.1.0 with some vulnerabilities is included through chain of dependencies that is added by cra-append-sw@2.7.0.

    -

    Then, you can try to update axios@0.21.4 and cra-append-sw@2.7.0 to resolve vulnerabilities in follow-redirects@1.14.6 and glob-parent@3.1.0.

    -

    JSON

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ trivy image -f json -o results.json golang:1.12-alpine
    -
    -
    -Result - -
    2019-05-16T01:46:31.777+0900    INFO    Updating vulnerability database...
    -2019-05-16T01:47:03.007+0900    INFO    Detecting Alpine vulnerabilities...
    -
    - -
    - -
    -JSON - -
    [
    -  {
    -    "Target": "php-app/composer.lock",
    -    "Vulnerabilities": null
    -  },
    -  {
    -    "Target": "node-app/package-lock.json",
    -    "Vulnerabilities": [
    -      {
    -        "VulnerabilityID": "CVE-2018-16487",
    -        "PkgName": "lodash",
    -        "InstalledVersion": "4.17.4",
    -        "FixedVersion": "\u003e=4.17.11",
    -        "Title": "lodash: Prototype pollution in utilities function",
    -        "Description": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487",
    -        ]
    -      }
    -    ]
    -  },
    -  {
    -    "Target": "trivy-ci-test (alpine 3.7.1)",
    -    "Vulnerabilities": [
    -      {
    -        "VulnerabilityID": "CVE-2018-16840",
    -        "PkgName": "curl",
    -        "InstalledVersion": "7.61.0-r0",
    -        "FixedVersion": "7.61.1-r1",
    -        "Title": "curl: Use-after-free when closing \"easy\" handle in Curl_close()",
    -        "Description": "A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. ",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840",
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2019-3822",
    -        "PkgName": "curl",
    -        "InstalledVersion": "7.61.0-r0",
    -        "FixedVersion": "7.61.1-r2",
    -        "Title": "curl: NTLMv2 type-3 header stack buffer overflow",
    -        "Description": "libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. ",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://curl.haxx.se/docs/CVE-2019-3822.html",
    -          "https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E"
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2018-16839",
    -        "PkgName": "curl",
    -        "InstalledVersion": "7.61.0-r0",
    -        "FixedVersion": "7.61.1-r1",
    -        "Title": "curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()",
    -        "Description": "Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5",
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2018-19486",
    -        "PkgName": "git",
    -        "InstalledVersion": "2.15.2-r0",
    -        "FixedVersion": "2.15.3-r0",
    -        "Title": "git: Improper handling of PATH allows for commands to be executed from the current directory",
    -        "Description": "Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://usn.ubuntu.com/3829-1/",
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2018-17456",
    -        "PkgName": "git",
    -        "InstalledVersion": "2.15.2-r0",
    -        "FixedVersion": "2.15.3-r0",
    -        "Title": "git: arbitrary code execution via .gitmodules",
    -        "Description": "Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \"git clone\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "http://www.securitytracker.com/id/1041811",
    -        ]
    -      }
    -    ]
    -  },
    -  {
    -    "Target": "python-app/Pipfile.lock",
    -    "Vulnerabilities": null
    -  },
    -  {
    -    "Target": "ruby-app/Gemfile.lock",
    -    "Vulnerabilities": null
    -  },
    -  {
    -    "Target": "rust-app/Cargo.lock",
    -    "Vulnerabilities": null
    -  }
    -]
    -
    - -
    - -

    VulnerabilityID, PkgName, InstalledVersion, and Severity in Vulnerabilities are always filled with values, but other fields might be empty.

    -

    SARIF

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    SARIF can be generated with the --format sarif flag.

    -
    $ trivy image --format sarif -o report.sarif  golang:1.12-alpine
    -
    -

    This SARIF file can be uploaded to GitHub code scanning results, and there is a Trivy GitHub Action for automating this process.

    -

    Template

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Custom Template

    -
    $ trivy image --format template --template "{{ range . }} {{ .Target }} {{ end }}" golang:1.12-alpine
    -
    -
    -Result - -
    2020-01-02T18:02:32.856+0100    INFO    Detecting Alpine vulnerabilities...
    - golang:1.12-alpine (alpine 3.10.2)
    -
    -
    - -

    You can compute different figures within the template using sprig functions. -As an example you can summarize the different classes of issues:

    -
    $ trivy image --format template --template '{{- $critical := 0 }}{{- $high := 0 }}{{- range . }}{{- range .Vulnerabilities }}{{- if  eq .Severity "CRITICAL" }}{{- $critical = add $critical 1 }}{{- end }}{{- if  eq .Severity "HIGH" }}{{- $high = add $high 1 }}{{- end }}{{- end }}{{- end }}Critical: {{ $critical }}, High: {{ $high }}' golang:1.12-alpine
    -
    -
    -Result - -
    Critical: 0, High: 2
    -
    -
    - -

    For other features of sprig, see the official sprig documentation.

    -

    Load templates from a file

    -

    You can load templates from a file prefixing the template path with an @.

    -
    $ trivy image --format template --template "@/path/to/template" golang:1.12-alpine
    -
    -

    Default Templates

    -

    If Trivy is installed using rpm then default templates can be found at /usr/local/share/trivy/templates.

    -

    JUnit

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    In the following example using the template junit.tpl XML can be generated. -

    $ trivy image --format template --template "@contrib/junit.tpl" -o junit-report.xml  golang:1.12-alpine
    -

    -

    ASFF

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Trivy also supports an ASFF template for reporting findings to AWS Security Hub

    -

    HTML

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ trivy image --format template --template "@contrib/html.tpl" -o report.html golang:1.12-alpine
    -
    -

    The following example shows use of default HTML template when Trivy is installed using rpm.

    -
    $ trivy image --format template --template "@/usr/local/share/trivy/templates/html.tpl" -o report.html golang:1.12-alpine
    -
    -

    SBOM

    -

    See here for details.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/configuration/skipping/index.html b/test/docs/configuration/skipping/index.html deleted file mode 100644 index 111a43ef6576..000000000000 --- a/test/docs/configuration/skipping/index.html +++ /dev/null @@ -1,3224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Skipping Files - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Skipping Files and Directories

    -

    This section details ways to specify the files and directories that Trivy should not scan.

    -

    Skip Files

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy traverses directories and searches for all necessary files for scanning. -You can skip files that you don't maintain using the --skip-files flag.

    -
    $ trivy image --skip-files "/Gemfile.lock" --skip-files "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
    -
    -

    It's possible to specify globs as part of the value.

    -
    $ trivy image --skip-files "./testdata/*/bar" .
    -
    -

    Will skip any file named bar in the subdirectories of testdata.

    -

    Skip Directories

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy traverses directories and searches for all necessary files for scanning. -You can skip directories that you don't maintain using the --skip-dirs flag.

    -
    $ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
    -
    -

    It's possible to specify globs as part of the value.

    -
    $ trivy image --skip-dirs "./testdata/*" .
    -
    -

    Will skip all subdirectories of the testdata directory.

    -
    -

    Tip

    -

    Glob patterns work with any trivy subcommand (image, config, etc.) and can be specified to skip both directories (with --skip-dirs) and files (with --skip-files).

    -
    -

    Advanced globbing

    -

    Trivy also supports the globstar pattern matching.

    -
    $ trivy image --skip-files "**/foo" image:tag
    -
    -

    Will skip the file foo that happens to be nested under any parent(s).

    -

    File patterns

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    When a directory is given as an input, Trivy will recursively look for and test all files based on file patterns. -The default file patterns are here.

    -

    In addition to the default file patterns, the --file-patterns option takes regexp patterns to look for your files. -For example, it may be useful when your file name of Dockerfile doesn't match the default patterns.

    -

    This can be repeated for specifying multiple file patterns.

    -

    A file pattern contains the analyzer it is used for, and the pattern itself, joined by a semicolon. For example: -

    --file-patterns "dockerfile:.*.docker" --file-patterns "yaml:deployment" --file-patterns "pip:requirements-.*\.txt"
    -

    -

    The prefixes are listed here

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/index.html b/test/docs/index.html deleted file mode 100644 index b1e64406c2cb..000000000000 --- a/test/docs/index.html +++ /dev/null @@ -1,3008 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Docs

    -

    In this section you can find the complete reference documentation for all of the different features and settings that Trivy has to offer.

    -

    👈 Please use the side-navigation on the left in order to browse the different topics.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy/index.html b/test/docs/references/configuration/cli/trivy/index.html deleted file mode 100644 index e9073fda982f..000000000000 --- a/test/docs/references/configuration/cli/trivy/index.html +++ /dev/null @@ -1,3168 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Overview

    - -

    trivy

    -

    Unified security scanner

    -

    Synopsis

    -

    Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets

    -
    trivy [global flags] command [flags] target
    -
    -

    Examples

    -
      # Scan a container image
    -  $ trivy image python:3.4-alpine
    -
    -  # Scan a container image from a tar archive
    -  $ trivy image --input ruby-3.1.tar
    -
    -  # Scan local filesystem
    -  $ trivy fs .
    -
    -  # Run in server mode
    -  $ trivy server
    -
    -

    Options

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -  -f, --format string             version format (json)
    -      --generate-default-config   write the default config to trivy-default.yaml
    -  -h, --help                      help for trivy
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_aws/index.html b/test/docs/references/configuration/cli/trivy_aws/index.html deleted file mode 100644 index dc8f53695915..000000000000 --- a/test/docs/references/configuration/cli/trivy_aws/index.html +++ /dev/null @@ -1,3233 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AWS - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    AWS

    - -

    trivy aws

    -

    [EXPERIMENTAL] Scan AWS account

    -

    Synopsis

    -

    Scan an AWS account for misconfigurations. Trivy uses the same authentication methods as the AWS CLI. See https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html

    -

    The following services are supported: -- accessanalyzer -- api-gateway -- athena -- cloudfront -- cloudtrail -- cloudwatch -- codebuild -- documentdb -- dynamodb -- ec2 -- ecr -- ecs -- efs -- eks -- elasticache -- elasticsearch -- elb -- emr -- iam -- kinesis -- kms -- lambda -- mq -- msk -- neptune -- rds -- redshift -- s3 -- sns -- sqs -- ssm -- workspaces

    -
    trivy aws [flags]
    -
    -

    Examples

    -
      # basic scanning
    -  $ trivy aws --region us-east-1
    -
    -  # limit scan to a single service:
    -  $ trivy aws --region us-east-1 --service s3
    -
    -  # limit scan to multiple services:
    -  $ trivy aws --region us-east-1 --service s3 --service ec2
    -
    -  # force refresh of cache for fresh results
    -  $ trivy aws --region us-east-1 --update-cache
    -
    -

    Options

    -
          --account string              The AWS account to scan. It's useful to specify this when reviewing cached results for multiple accounts.
    -      --arn string                  The AWS ARN to show results for. Useful to filter results once a scan is cached.
    -      --compliance string           compliance report to generate (aws-cis-1.2, aws-cis-1.4)
    -      --config-data strings         specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings       specify paths to the Rego policy files directory, applying config files
    -      --dependency-tree             [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --endpoint string             AWS Endpoint override
    -      --exit-code int               specify exit code when any security issues are found
    -  -f, --format string               format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings            specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings       specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings     specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings         specify paths to override the Helm values.yaml files
    -  -h, --help                        help for aws
    -      --ignore-policy string        specify the Rego file path to evaluate each vulnerability
    -      --ignorefile string           specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures        include successes and exceptions, available with '--scanners config'
    -      --list-all-pkgs               enabling the option will output all packages regardless of vulnerability
    -      --max-cache-age duration      The maximum age of the cloud cache. Cached data will be requeried from the cloud provider if it is older than this. (default 24h0m0s)
    -  -o, --output string               output file name
    -      --policy-namespaces strings   Rego namespaces
    -      --region string               AWS Region to scan
    -      --report string               specify a report format for the output. (all,summary) (default "all")
    -      --service strings             Only scan AWS Service(s) specified with this flag. Can specify multiple services using --service A --service B etc.
    -  -s, --severity string             severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-policy-update          skip fetching rego policy updates
    -  -t, --template string             output template
    -      --tf-vars strings             specify paths to override the Terraform tfvars files
    -      --trace                       enable more verbose trace output for custom queries
    -      --update-cache                Update the cache for the applicable cloud provider instead of using cached results.
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_config/index.html b/test/docs/references/configuration/cli/trivy_config/index.html deleted file mode 100644 index 79818f7d78a0..000000000000 --- a/test/docs/references/configuration/cli/trivy_config/index.html +++ /dev/null @@ -1,3163 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Config - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Config

    - -

    trivy config

    -

    Scan config files for misconfigurations

    -
    trivy config [flags] DIR
    -
    -

    Options

    -
          --cache-backend string        cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration          cache TTL when using redis as cache backend
    -      --clear-cache                 clear image caches without scanning
    -      --compliance string           compliance report to generate
    -      --config-data strings         specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings       specify paths to the Rego policy files directory, applying config files
    -      --enable-modules strings      [EXPERIMENTAL] module names to enable
    -      --exit-code int               specify exit code when any security issues are found
    -      --file-patterns strings       specify config file patterns
    -  -f, --format string               format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings            specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings       specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings     specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings         specify paths to override the Helm values.yaml files
    -  -h, --help                        help for config
    -      --ignorefile string           specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures        include successes and exceptions, available with '--scanners config'
    -      --k8s-version string          specify k8s version to validate outdated api by it (example: 1.21.0)
    -      --module-dir string           specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -  -o, --output string               output file name
    -      --password strings            password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --policy-namespaces strings   Rego namespaces
    -      --redis-ca string             redis ca file location, if using redis as cache backend
    -      --redis-cert string           redis certificate file location, if using redis as cache backend
    -      --redis-key string            redis key file location, if using redis as cache backend
    -      --redis-tls                   enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string       registry token
    -      --report string               specify a compliance report format for the output. (all,summary) (default "all")
    -  -s, --severity string             severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-dirs strings           specify the directories where the traversal is skipped
    -      --skip-files strings          specify the file paths to skip traversal
    -      --skip-policy-update          skip fetching rego policy updates
    -  -t, --template string             output template
    -      --tf-vars strings             specify paths to override the Terraform tfvars files
    -      --trace                       enable more verbose trace output for custom queries
    -      --username strings            username. Comma-separated usernames allowed.
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_filesystem/index.html b/test/docs/references/configuration/cli/trivy_filesystem/index.html deleted file mode 100644 index 3b3b1bf1f62b..000000000000 --- a/test/docs/references/configuration/cli/trivy_filesystem/index.html +++ /dev/null @@ -1,3209 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Filesystem - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Filesystem

    - -

    trivy filesystem

    -

    Scan local filesystem

    -
    trivy filesystem [flags] PATH
    -
    -

    Examples

    -
      # Scan a local project including language-specific files
    -  $ trivy fs /path/to/your_project
    -
    -  # Scan a single file
    -  $ trivy fs ./trivy-ci-test/Pipfile.lock
    -
    -

    Options

    -
          --cache-backend string             cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration               cache TTL when using redis as cache backend
    -      --clear-cache                      clear image caches without scanning
    -      --compliance string                compliance report to generate
    -      --config-data strings              specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings            specify paths to the Rego policy files directory, applying config files
    -      --custom-headers strings           custom headers in client mode
    -      --db-repository string             OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --dependency-tree                  [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --download-db-only                 download/update vulnerability database but don't run a scan
    -      --download-java-db-only            download/update Java index database but don't run a scan
    -      --enable-modules strings           [EXPERIMENTAL] module names to enable
    -      --exit-code int                    specify exit code when any security issues are found
    -      --file-patterns strings            specify config file patterns
    -  -f, --format string                    format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings                 specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings            specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings          specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings              specify paths to override the Helm values.yaml files
    -  -h, --help                             help for filesystem
    -      --ignore-policy string             specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed                   display only fixed vulnerabilities
    -      --ignored-licenses strings         specify a list of license to ignore
    -      --ignorefile string                specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures             include successes and exceptions, available with '--scanners config'
    -      --java-db-repository string        OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --license-confidence-level float   specify license classifier's confidence level (default 0.9)
    -      --license-full                     eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                    enabling the option will output all packages regardless of vulnerability
    -      --module-dir string                specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                      suppress progress bar
    -      --offline-scan                     do not issue API requests to identify dependencies
    -  -o, --output string                    output file name
    -      --password strings                 password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --policy-namespaces strings        Rego namespaces
    -      --redis-ca string                  redis ca file location, if using redis as cache backend
    -      --redis-cert string                redis certificate file location, if using redis as cache backend
    -      --redis-key string                 redis key file location, if using redis as cache backend
    -      --redis-tls                        enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string            registry token
    -      --rekor-url string                 [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --report string                    specify a compliance report format for the output. (all,summary) (default "all")
    -      --reset                            remove all caches and database
    -      --sbom-sources strings             [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                 comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
    -      --secret-config string             specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                    server address in client mode
    -  -s, --severity string                  severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update                   skip updating vulnerability database
    -      --skip-dirs strings                specify the directories where the traversal is skipped
    -      --skip-files strings               specify the file paths to skip traversal
    -      --skip-java-db-update              skip updating Java index database
    -      --skip-policy-update               skip fetching rego policy updates
    -      --slow                             scan over time with lower CPU and memory utilization
    -  -t, --template string                  output template
    -      --tf-vars strings                  specify paths to override the Terraform tfvars files
    -      --token string                     for authentication in client/server mode
    -      --token-header string              specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                            enable more verbose trace output for custom queries
    -      --username strings                 username. Comma-separated usernames allowed.
    -      --vuln-type strings                comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_image/index.html b/test/docs/references/configuration/cli/trivy_image/index.html deleted file mode 100644 index 166b9069f635..000000000000 --- a/test/docs/references/configuration/cli/trivy_image/index.html +++ /dev/null @@ -1,3231 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Image - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Image

    - -

    trivy image

    -

    Scan a container image

    -
    trivy image [flags] IMAGE_NAME
    -
    -

    Examples

    -
      # Scan a container image
    -  $ trivy image python:3.4-alpine
    -
    -  # Scan a container image from a tar archive
    -  $ trivy image --input ruby-3.1.tar
    -
    -  # Filter by severities
    -  $ trivy image --severity HIGH,CRITICAL alpine:3.15
    -
    -  # Ignore unfixed/unpatched vulnerabilities
    -  $ trivy image --ignore-unfixed alpine:3.15
    -
    -  # Scan a container image in client mode
    -  $ trivy image --server http://127.0.0.1:4954 alpine:latest
    -
    -  # Generate json result
    -  $ trivy image --format json --output result.json alpine:3.15
    -
    -  # Generate a report in the CycloneDX format
    -  $ trivy image --format cyclonedx --output result.cdx alpine:3.15
    -
    -

    Options

    -
          --cache-backend string             cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration               cache TTL when using redis as cache backend
    -      --clear-cache                      clear image caches without scanning
    -      --compliance string                compliance report to generate (docker-cis)
    -      --config-data strings              specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings            specify paths to the Rego policy files directory, applying config files
    -      --custom-headers strings           custom headers in client mode
    -      --db-repository string             OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --dependency-tree                  [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --docker-host string               unix domain socket path to use for docker scanning
    -      --download-db-only                 download/update vulnerability database but don't run a scan
    -      --download-java-db-only            download/update Java index database but don't run a scan
    -      --enable-modules strings           [EXPERIMENTAL] module names to enable
    -      --exit-code int                    specify exit code when any security issues are found
    -      --exit-on-eol int                  exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings            specify config file patterns
    -  -f, --format string                    format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings                 specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings            specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings          specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings              specify paths to override the Helm values.yaml files
    -  -h, --help                             help for image
    -      --ignore-policy string             specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed                   display only fixed vulnerabilities
    -      --ignored-licenses strings         specify a list of license to ignore
    -      --ignorefile string                specify .trivyignore file (default ".trivyignore")
    -      --image-config-scanners string     comma-separated list of what security issues to detect on container image configurations (config,secret)
    -      --image-src strings                image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
    -      --include-non-failures             include successes and exceptions, available with '--scanners config'
    -      --input string                     input file path instead of image name
    -      --java-db-repository string        OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --license-confidence-level float   specify license classifier's confidence level (default 0.9)
    -      --license-full                     eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                    enabling the option will output all packages regardless of vulnerability
    -      --module-dir string                specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                      suppress progress bar
    -      --offline-scan                     do not issue API requests to identify dependencies
    -  -o, --output string                    output file name
    -      --password strings                 password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --platform string                  set platform in the form os/arch if image is multi-platform capable
    -      --policy-namespaces strings        Rego namespaces
    -      --redis-ca string                  redis ca file location, if using redis as cache backend
    -      --redis-cert string                redis certificate file location, if using redis as cache backend
    -      --redis-key string                 redis key file location, if using redis as cache backend
    -      --redis-tls                        enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string            registry token
    -      --rekor-url string                 [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --removed-pkgs                     detect vulnerabilities of removed packages (only for Alpine)
    -      --report string                    specify a format for the compliance report. (default "summary")
    -      --reset                            remove all caches and database
    -      --sbom-sources strings             [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                 comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
    -      --secret-config string             specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                    server address in client mode
    -  -s, --severity string                  severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update                   skip updating vulnerability database
    -      --skip-dirs strings                specify the directories where the traversal is skipped
    -      --skip-files strings               specify the file paths to skip traversal
    -      --skip-java-db-update              skip updating Java index database
    -      --skip-policy-update               skip fetching rego policy updates
    -      --slow                             scan over time with lower CPU and memory utilization
    -  -t, --template string                  output template
    -      --tf-vars strings                  specify paths to override the Terraform tfvars files
    -      --token string                     for authentication in client/server mode
    -      --token-header string              specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                            enable more verbose trace output for custom queries
    -      --username strings                 username. Comma-separated usernames allowed.
    -      --vuln-type strings                comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_kubernetes/index.html b/test/docs/references/configuration/cli/trivy_kubernetes/index.html deleted file mode 100644 index 99a342a2bcd8..000000000000 --- a/test/docs/references/configuration/cli/trivy_kubernetes/index.html +++ /dev/null @@ -1,3212 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Kubernetes - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Kubernetes

    - -

    trivy kubernetes

    -

    [EXPERIMENTAL] Scan kubernetes cluster

    -
    trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: pods, pod/NAME }
    -
    -

    Examples

    -
      # cluster scanning
    -  $ trivy k8s --report summary cluster
    -
    -  # namespace scanning:
    -  $ trivy k8s -n kube-system --report summary all
    -
    -  # resources scanning:
    -  $ trivy k8s --report=summary deploy
    -  $ trivy k8s --namespace=kube-system --report=summary deploy,configmaps
    -
    -  # resource scanning:
    -  $ trivy k8s deployment/orion
    -
    -

    Options

    -
      -A, --all-namespaces              fetch resources from all cluster namespaces
    -      --cache-backend string        cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration          cache TTL when using redis as cache backend
    -      --clear-cache                 clear image caches without scanning
    -      --compliance string           compliance report to generate (k8s-nsa,k8s-cis, k8s-pss-baseline, k8s-pss-restricted)
    -      --components strings          specify which components to scan (default [workload,infra])
    -      --config-data strings         specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings       specify paths to the Rego policy files directory, applying config files
    -      --context string              specify a context to scan
    -      --db-repository string        OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --dependency-tree             [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --download-db-only            download/update vulnerability database but don't run a scan
    -      --download-java-db-only       download/update Java index database but don't run a scan
    -      --exit-code int               specify exit code when any security issues are found
    -      --file-patterns strings       specify config file patterns
    -  -f, --format string               format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings            specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings       specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings     specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings         specify paths to override the Helm values.yaml files
    -  -h, --help                        help for kubernetes
    -      --ignore-policy string        specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed              display only fixed vulnerabilities
    -      --ignorefile string           specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures        include successes and exceptions, available with '--scanners config'
    -      --java-db-repository string   OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --k8s-version string          specify k8s version to validate outdated api by it (example: 1.21.0)
    -      --kubeconfig string           specify the kubeconfig file path to use
    -      --list-all-pkgs               enabling the option will output all packages regardless of vulnerability
    -  -n, --namespace string            specify a namespace to scan
    -      --no-progress                 suppress progress bar
    -      --offline-scan                do not issue API requests to identify dependencies
    -  -o, --output string               output file name
    -      --parallel int                number (between 1-20) of goroutines enabled for parallel scanning (default 5)
    -      --policy-namespaces strings   Rego namespaces
    -      --redis-ca string             redis ca file location, if using redis as cache backend
    -      --redis-cert string           redis certificate file location, if using redis as cache backend
    -      --redis-key string            redis key file location, if using redis as cache backend
    -      --redis-tls                   enable redis TLS with public certificates, if using redis as cache backend
    -      --rekor-url string            [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --report string               specify a report format for the output. (all,summary) (default "all")
    -      --reset                       remove all caches and database
    -      --sbom-sources strings        [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners string             comma-separated list of what security issues to detect (vuln,config,secret,license) (default "vuln,config,secret,rbac")
    -      --secret-config string        specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -  -s, --severity string             severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update              skip updating vulnerability database
    -      --skip-dirs strings           specify the directories where the traversal is skipped
    -      --skip-files strings          specify the file paths to skip traversal
    -      --skip-java-db-update         skip updating Java index database
    -      --skip-policy-update          skip fetching rego policy updates
    -      --slow                        scan over time with lower CPU and memory utilization
    -  -t, --template string             output template
    -      --tf-vars strings             specify paths to override the Terraform tfvars files
    -      --tolerations strings         specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)
    -      --trace                       enable more verbose trace output for custom queries
    -      --vuln-type strings           comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_module/index.html b/test/docs/references/configuration/cli/trivy_module/index.html deleted file mode 100644 index d2a1003bc56c..000000000000 --- a/test/docs/references/configuration/cli/trivy_module/index.html +++ /dev/null @@ -1,3130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Module - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Module

    - -

    trivy module

    -

    Manage modules

    -

    Options

    -
          --enable-modules strings   [EXPERIMENTAL] module names to enable
    -  -h, --help                     help for module
    -      --module-dir string        specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_module_install/index.html b/test/docs/references/configuration/cli/trivy_module_install/index.html deleted file mode 100644 index 5b7167743010..000000000000 --- a/test/docs/references/configuration/cli/trivy_module_install/index.html +++ /dev/null @@ -1,3130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Module Install - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Module Install

    - -

    trivy module install

    -

    Install a module

    -
    trivy module install [flags] REPOSITORY
    -
    -

    Options

    -
      -h, --help   help for install
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --enable-modules strings    [EXPERIMENTAL] module names to enable
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -      --module-dir string         specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_module_uninstall/index.html b/test/docs/references/configuration/cli/trivy_module_uninstall/index.html deleted file mode 100644 index 7153e7a3cbca..000000000000 --- a/test/docs/references/configuration/cli/trivy_module_uninstall/index.html +++ /dev/null @@ -1,3130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Module Uninstall - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Module Uninstall

    - -

    trivy module uninstall

    -

    Uninstall a module

    -
    trivy module uninstall [flags] REPOSITORY
    -
    -

    Options

    -
      -h, --help   help for uninstall
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --enable-modules strings    [EXPERIMENTAL] module names to enable
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -      --module-dir string         specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin/index.html b/test/docs/references/configuration/cli/trivy_plugin/index.html deleted file mode 100644 index 5326dff957ae..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin/index.html +++ /dev/null @@ -1,3132 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin

    - -

    trivy plugin

    -

    Manage plugins

    -

    Options

    -
      -h, --help   help for plugin
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin_info/index.html b/test/docs/references/configuration/cli/trivy_plugin_info/index.html deleted file mode 100644 index 23c2c6089d46..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin_info/index.html +++ /dev/null @@ -1,3128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin Info - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin Info

    - -

    trivy plugin info

    -

    Show information about the specified plugin

    -
    trivy plugin info PLUGIN_NAME
    -
    -

    Options

    -
      -h, --help   help for info
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin_install/index.html b/test/docs/references/configuration/cli/trivy_plugin_install/index.html deleted file mode 100644 index 74ca01b78cd8..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin_install/index.html +++ /dev/null @@ -1,3128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin Install - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin Install

    - -

    trivy plugin install

    -

    Install a plugin

    -
    trivy plugin install URL | FILE_PATH
    -
    -

    Options

    -
      -h, --help   help for install
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin_list/index.html b/test/docs/references/configuration/cli/trivy_plugin_list/index.html deleted file mode 100644 index 3d0865ff8ab6..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin_list/index.html +++ /dev/null @@ -1,3128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin List - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin List

    - -

    trivy plugin list

    -

    List installed plugin

    -
    trivy plugin list
    -
    -

    Options

    -
      -h, --help   help for list
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin_run/index.html b/test/docs/references/configuration/cli/trivy_plugin_run/index.html deleted file mode 100644 index 2a212b8f0796..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin_run/index.html +++ /dev/null @@ -1,3128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin Run - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin Run

    - -

    trivy plugin run

    -

    Run a plugin on the fly

    -
    trivy plugin run URL | FILE_PATH
    -
    -

    Options

    -
      -h, --help   help for run
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin_uninstall/index.html b/test/docs/references/configuration/cli/trivy_plugin_uninstall/index.html deleted file mode 100644 index 4668384bbbc9..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin_uninstall/index.html +++ /dev/null @@ -1,3128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin Uninstall - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin Uninstall

    - -

    trivy plugin uninstall

    -

    Uninstall a plugin

    -
    trivy plugin uninstall PLUGIN_NAME
    -
    -

    Options

    -
      -h, --help   help for uninstall
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_plugin_update/index.html b/test/docs/references/configuration/cli/trivy_plugin_update/index.html deleted file mode 100644 index 8a79af9fdab1..000000000000 --- a/test/docs/references/configuration/cli/trivy_plugin_update/index.html +++ /dev/null @@ -1,3128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Plugin Update - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Plugin Update

    - -

    trivy plugin update

    -

    Update an existing plugin

    -
    trivy plugin update PLUGIN_NAME
    -
    -

    Options

    -
      -h, --help   help for update
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_repository/index.html b/test/docs/references/configuration/cli/trivy_repository/index.html deleted file mode 100644 index a1254766b4a9..000000000000 --- a/test/docs/references/configuration/cli/trivy_repository/index.html +++ /dev/null @@ -1,3207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Repository - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Repository

    - -

    trivy repository

    -

    Scan a remote repository

    -
    trivy repository [flags] REPO_URL
    -
    -

    Examples

    -
      # Scan your remote git repository
    -  $ trivy repo https://github.com/knqyf263/trivy-ci-test
    -
    -

    Options

    -
          --branch string                    pass the branch name to be scanned
    -      --cache-backend string             cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration               cache TTL when using redis as cache backend
    -      --clear-cache                      clear image caches without scanning
    -      --commit string                    pass the commit hash to be scanned
    -      --config-data strings              specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings            specify paths to the Rego policy files directory, applying config files
    -      --custom-headers strings           custom headers in client mode
    -      --db-repository string             OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --dependency-tree                  [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --download-db-only                 download/update vulnerability database but don't run a scan
    -      --download-java-db-only            download/update Java index database but don't run a scan
    -      --enable-modules strings           [EXPERIMENTAL] module names to enable
    -      --exit-code int                    specify exit code when any security issues are found
    -      --file-patterns strings            specify config file patterns
    -  -f, --format string                    format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings                 specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings            specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings          specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings              specify paths to override the Helm values.yaml files
    -  -h, --help                             help for repository
    -      --ignore-policy string             specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed                   display only fixed vulnerabilities
    -      --ignored-licenses strings         specify a list of license to ignore
    -      --ignorefile string                specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures             include successes and exceptions, available with '--scanners config'
    -      --java-db-repository string        OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --license-confidence-level float   specify license classifier's confidence level (default 0.9)
    -      --license-full                     eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                    enabling the option will output all packages regardless of vulnerability
    -      --module-dir string                specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                      suppress progress bar
    -      --offline-scan                     do not issue API requests to identify dependencies
    -  -o, --output string                    output file name
    -      --password strings                 password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --policy-namespaces strings        Rego namespaces
    -      --redis-ca string                  redis ca file location, if using redis as cache backend
    -      --redis-cert string                redis certificate file location, if using redis as cache backend
    -      --redis-key string                 redis key file location, if using redis as cache backend
    -      --redis-tls                        enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string            registry token
    -      --rekor-url string                 [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --reset                            remove all caches and database
    -      --sbom-sources strings             [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                 comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
    -      --secret-config string             specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                    server address in client mode
    -  -s, --severity string                  severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update                   skip updating vulnerability database
    -      --skip-dirs strings                specify the directories where the traversal is skipped
    -      --skip-files strings               specify the file paths to skip traversal
    -      --skip-java-db-update              skip updating Java index database
    -      --skip-policy-update               skip fetching rego policy updates
    -      --slow                             scan over time with lower CPU and memory utilization
    -      --tag string                       pass the tag name to be scanned
    -  -t, --template string                  output template
    -      --tf-vars strings                  specify paths to override the Terraform tfvars files
    -      --token string                     for authentication in client/server mode
    -      --token-header string              specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                            enable more verbose trace output for custom queries
    -      --username strings                 username. Comma-separated usernames allowed.
    -      --vuln-type strings                comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_rootfs/index.html b/test/docs/references/configuration/cli/trivy_rootfs/index.html deleted file mode 100644 index 73b2a20c4267..000000000000 --- a/test/docs/references/configuration/cli/trivy_rootfs/index.html +++ /dev/null @@ -1,3211 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Rootfs - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Rootfs

    - -

    trivy rootfs

    -

    Scan rootfs

    -
    trivy rootfs [flags] ROOTDIR
    -
    -

    Examples

    -
      # Scan unpacked filesystem
    -  $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
    -  $ trivy rootfs /tmp/rootfs
    -
    -  # Scan from inside a container
    -  $ docker run --rm -it alpine:3.11
    -  / # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
    -  / # trivy rootfs /
    -
    -

    Options

    -
          --cache-backend string             cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration               cache TTL when using redis as cache backend
    -      --clear-cache                      clear image caches without scanning
    -      --config-data strings              specify paths from which data for the Rego policies will be recursively loaded
    -      --config-policy strings            specify paths to the Rego policy files directory, applying config files
    -      --custom-headers strings           custom headers in client mode
    -      --db-repository string             OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --dependency-tree                  [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --download-db-only                 download/update vulnerability database but don't run a scan
    -      --download-java-db-only            download/update Java index database but don't run a scan
    -      --enable-modules strings           [EXPERIMENTAL] module names to enable
    -      --exit-code int                    specify exit code when any security issues are found
    -      --exit-on-eol int                  exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings            specify config file patterns
    -  -f, --format string                    format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings                 specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings            specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings          specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings              specify paths to override the Helm values.yaml files
    -  -h, --help                             help for rootfs
    -      --ignore-policy string             specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed                   display only fixed vulnerabilities
    -      --ignored-licenses strings         specify a list of license to ignore
    -      --ignorefile string                specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures             include successes and exceptions, available with '--scanners config'
    -      --java-db-repository string        OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --license-confidence-level float   specify license classifier's confidence level (default 0.9)
    -      --license-full                     eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                    enabling the option will output all packages regardless of vulnerability
    -      --module-dir string                specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                      suppress progress bar
    -      --offline-scan                     do not issue API requests to identify dependencies
    -  -o, --output string                    output file name
    -      --password strings                 password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --policy-namespaces strings        Rego namespaces
    -      --redis-ca string                  redis ca file location, if using redis as cache backend
    -      --redis-cert string                redis certificate file location, if using redis as cache backend
    -      --redis-key string                 redis key file location, if using redis as cache backend
    -      --redis-tls                        enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string            registry token
    -      --rekor-url string                 [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --reset                            remove all caches and database
    -      --sbom-sources strings             [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                 comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
    -      --secret-config string             specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                    server address in client mode
    -  -s, --severity string                  severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update                   skip updating vulnerability database
    -      --skip-dirs strings                specify the directories where the traversal is skipped
    -      --skip-files strings               specify the file paths to skip traversal
    -      --skip-java-db-update              skip updating Java index database
    -      --skip-policy-update               skip fetching rego policy updates
    -      --slow                             scan over time with lower CPU and memory utilization
    -  -t, --template string                  output template
    -      --tf-vars strings                  specify paths to override the Terraform tfvars files
    -      --token string                     for authentication in client/server mode
    -      --token-header string              specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                            enable more verbose trace output for custom queries
    -      --username strings                 username. Comma-separated usernames allowed.
    -      --vuln-type strings                comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_sbom/index.html b/test/docs/references/configuration/cli/trivy_sbom/index.html deleted file mode 100644 index d295b17706dd..000000000000 --- a/test/docs/references/configuration/cli/trivy_sbom/index.html +++ /dev/null @@ -1,3192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    SBOM

    - -

    trivy sbom

    -

    Scan SBOM for vulnerabilities

    -
    trivy sbom [flags] SBOM_PATH
    -
    -

    Examples

    -
      # Scan CycloneDX and show the result in tables
    -  $ trivy sbom /path/to/report.cdx
    -
    -  # Scan CycloneDX and generate a CycloneDX report
    -  $ trivy sbom --format cyclonedx /path/to/report.cdx
    -
    -  # Scan CycloneDX-type attestation and show the result in tables
    -  $ trivy sbom /path/to/report.cdx.intoto.jsonl
    -
    -

    Options

    -
          --cache-backend string        cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration          cache TTL when using redis as cache backend
    -      --clear-cache                 clear image caches without scanning
    -      --compliance string           compliance report to generate
    -      --custom-headers strings      custom headers in client mode
    -      --db-repository string        OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --download-db-only            download/update vulnerability database but don't run a scan
    -      --download-java-db-only       download/update Java index database but don't run a scan
    -      --exit-code int               specify exit code when any security issues are found
    -      --exit-on-eol int             exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings       specify config file patterns
    -  -f, --format string               format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -  -h, --help                        help for sbom
    -      --ignore-policy string        specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed              display only fixed vulnerabilities
    -      --ignorefile string           specify .trivyignore file (default ".trivyignore")
    -      --java-db-repository string   OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --list-all-pkgs               enabling the option will output all packages regardless of vulnerability
    -      --no-progress                 suppress progress bar
    -      --offline-scan                do not issue API requests to identify dependencies
    -  -o, --output string               output file name
    -      --redis-ca string             redis ca file location, if using redis as cache backend
    -      --redis-cert string           redis certificate file location, if using redis as cache backend
    -      --redis-key string            redis key file location, if using redis as cache backend
    -      --redis-tls                   enable redis TLS with public certificates, if using redis as cache backend
    -      --rekor-url string            [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --reset                       remove all caches and database
    -      --sbom-sources strings        [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings            comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
    -      --server string               server address in client mode
    -  -s, --severity string             severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update              skip updating vulnerability database
    -      --skip-dirs strings           specify the directories where the traversal is skipped
    -      --skip-files strings          specify the file paths to skip traversal
    -      --skip-java-db-update         skip updating Java index database
    -      --slow                        scan over time with lower CPU and memory utilization
    -  -t, --template string             output template
    -      --token string                for authentication in client/server mode
    -      --token-header string         specify a header name for token in client/server mode (default "Trivy-Token")
    -      --vex string                  [EXPERIMENTAL] file path to VEX
    -      --vuln-type strings           comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_server/index.html b/test/docs/references/configuration/cli/trivy_server/index.html deleted file mode 100644 index 5d5b37f3fbe6..000000000000 --- a/test/docs/references/configuration/cli/trivy_server/index.html +++ /dev/null @@ -1,3172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Server - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Server

    - -

    trivy server

    -

    Server mode

    -
    trivy server [flags]
    -
    -

    Examples

    -
      # Run a server
    -  $ trivy server
    -
    -  # Listen on 0.0.0.0:10000
    -  $ trivy server --listen 0.0.0.0:10000
    -
    -

    Options

    -
          --cache-backend string        cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration          cache TTL when using redis as cache backend
    -      --clear-cache                 clear image caches without scanning
    -      --db-repository string        OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --download-db-only            download/update vulnerability database but don't run a scan
    -      --download-java-db-only       download/update Java index database but don't run a scan
    -      --enable-modules strings      [EXPERIMENTAL] module names to enable
    -  -h, --help                        help for server
    -      --java-db-repository string   OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --listen string               listen address in server mode (default "localhost:4954")
    -      --module-dir string           specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                 suppress progress bar
    -      --password strings            password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --redis-ca string             redis ca file location, if using redis as cache backend
    -      --redis-cert string           redis certificate file location, if using redis as cache backend
    -      --redis-key string            redis key file location, if using redis as cache backend
    -      --redis-tls                   enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string       registry token
    -      --reset                       remove all caches and database
    -      --skip-db-update              skip updating vulnerability database
    -      --skip-java-db-update         skip updating Java index database
    -      --token string                for authentication in client/server mode
    -      --token-header string         specify a header name for token in client/server mode (default "Trivy-Token")
    -      --username strings            username. Comma-separated usernames allowed.
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_version/index.html b/test/docs/references/configuration/cli/trivy_version/index.html deleted file mode 100644 index 309ed7e456d4..000000000000 --- a/test/docs/references/configuration/cli/trivy_version/index.html +++ /dev/null @@ -1,3129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Version - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Version

    - -

    trivy version

    -

    Print the version

    -
    trivy version [flags]
    -
    -

    Options

    -
      -f, --format string   version format (json)
    -  -h, --help            help for version
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/cli/trivy_vm/index.html b/test/docs/references/configuration/cli/trivy_vm/index.html deleted file mode 100644 index aff7f3533bf7..000000000000 --- a/test/docs/references/configuration/cli/trivy_vm/index.html +++ /dev/null @@ -1,3199 +0,0 @@ - - - - - - - - - - - - - - - - - - - - VM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    VM

    - -

    trivy vm

    -

    [EXPERIMENTAL] Scan a virtual machine image

    -
    trivy vm [flags] VM_IMAGE
    -
    -

    Examples

    -
      # Scan your AWS AMI
    -  $ trivy vm --scanners vuln ami:${your_ami_id}
    -
    -  # Scan your AWS EBS snapshot
    -  $ trivy vm ebs:${your_ebs_snapshot_id}
    -
    -

    Options

    -
          --aws-region string           AWS region to scan
    -      --cache-backend string        cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration          cache TTL when using redis as cache backend
    -      --clear-cache                 clear image caches without scanning
    -      --compliance string           compliance report to generate
    -      --custom-headers strings      custom headers in client mode
    -      --db-repository string        OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
    -      --dependency-tree             [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --download-db-only            download/update vulnerability database but don't run a scan
    -      --download-java-db-only       download/update Java index database but don't run a scan
    -      --enable-modules strings      [EXPERIMENTAL] module names to enable
    -      --exit-code int               specify exit code when any security issues are found
    -      --exit-on-eol int             exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings       specify config file patterns
    -  -f, --format string               format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default "table")
    -      --helm-set strings            specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings       specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings     specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings         specify paths to override the Helm values.yaml files
    -  -h, --help                        help for vm
    -      --ignore-policy string        specify the Rego file path to evaluate each vulnerability
    -      --ignore-unfixed              display only fixed vulnerabilities
    -      --ignorefile string           specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures        include successes and exceptions, available with '--scanners config'
    -      --java-db-repository string   OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db")
    -      --list-all-pkgs               enabling the option will output all packages regardless of vulnerability
    -      --module-dir string           specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                 suppress progress bar
    -      --offline-scan                do not issue API requests to identify dependencies
    -  -o, --output string               output file name
    -      --redis-ca string             redis ca file location, if using redis as cache backend
    -      --redis-cert string           redis certificate file location, if using redis as cache backend
    -      --redis-key string            redis key file location, if using redis as cache backend
    -      --redis-tls                   enable redis TLS with public certificates, if using redis as cache backend
    -      --rekor-url string            [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --reset                       remove all caches and database
    -      --sbom-sources strings        [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings            comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
    -      --secret-config string        specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string               server address in client mode
    -  -s, --severity string             severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
    -      --skip-db-update              skip updating vulnerability database
    -      --skip-dirs strings           specify the directories where the traversal is skipped
    -      --skip-files strings          specify the file paths to skip traversal
    -      --skip-java-db-update         skip updating Java index database
    -      --slow                        scan over time with lower CPU and memory utilization
    -  -t, --template string             output template
    -      --tf-vars strings             specify paths to override the Terraform tfvars files
    -      --token string                for authentication in client/server mode
    -      --token-header string         specify a header name for token in client/server mode (default "Trivy-Token")
    -      --vuln-type strings           comma-separated list of vulnerability types (os,library) (default [os,library])
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/configuration/config-file/index.html b/test/docs/references/configuration/config-file/index.html deleted file mode 100644 index 35245f4feaed..000000000000 --- a/test/docs/references/configuration/config-file/index.html +++ /dev/null @@ -1,3581 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Config file - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Config file

    -

    Trivy can be customized by tweaking a trivy.yaml file. -The config path can be overridden by the --config flag.

    -

    An example is here.

    -

    Global Options

    -
    # Same as '--quiet'
    -# Default is false
    -quiet: false
    -
    -# Same as '--debug'
    -# Default is false
    -debug: false
    -
    -# Same as '--insecure'
    -# Default is false
    -insecure: false
    -
    -# Same as '--timeout'
    -# Default is '5m'
    -timeout: 10m
    -
    -# Same as '--cache-dir'
    -# Default is your system cache dir
    -cache:
    -  dir: $HOME/.cache/trivy
    -
    -

    Report Options

    -
    # Same as '--format'
    -# Default is 'table'
    -format: table
    -
    -# Same as '--report' (available with 'trivy k8s')
    -# Default is all
    -report: all
    -
    -# Same as '--template'
    -# Default is empty
    -template:
    -
    -# Same as '--dependency-tree'
    -# Default is false
    -dependency-tree: false
    -
    -# Same as '--list-all-pkgs'
    -# Default is false
    -list-all-pkgs: false
    -
    -# Same as '--ignorefile'
    -# Default is '.trivyignore'
    -ignorefile: .trivyignore
    -
    -# Same as '--ignore-policy'
    -# Default is empty
    -ignore-policy:
    -
    -# Same as '--exit-code'
    -# Default is 0
    -exit-code: 0
    -
    -# Same as '--exit-on-eol'
    -# Default is 0
    -exit-on-eol: 0
    -
    -# Same as '--output'
    -# Default is empty (stdout)
    -output:
    -
    -# Same as '--severity'
    -# Default is all severities
    -severity:
    -  - UNKNOWN
    -  - LOW
    -  - MEDIUM
    -  - HIGH
    -  - CRITICAL
    -
    -

    Scan Options

    -

    Available in client/server mode

    -
    scan:
    -  # Same as '--file-patterns'
    -  # Default is empty
    -  file-patterns:
    -    -
    -
    -  # Same as '--skip-dirs'
    -  # Default is empty
    -  skip-dirs:
    -    - usr/local/
    -    - etc/
    -
    -  # Same as '--skip-files'
    -  # Default is empty
    -  skip-files:
    -    - package-dev.json
    -
    -  # Same as '--offline-scan'
    -  # Default is false
    -  offline-scan: false
    -
    -  # Same as '--scanners'
    -  # Default depends on subcommand
    -  scanners:
    -    - vuln
    -    - config
    -    - secret
    -
    -

    Cache Options

    -
    cache:
    -  # Same as '--cache-backend'
    -  # Default is 'fs'
    -  backend: 'fs'
    -
    -  # Same as '--cache-ttl'
    -  # Default is 0 (no ttl)
    -  ttl: 0
    -
    -  # Redis options
    -  redis:
    -    # Same as '--redis-ca'
    -    # Default is empty
    -    ca:
    -
    -    # Same as '--redis-cert'
    -    # Default is empty
    -    cert:
    -
    -    # Same as '--redis-key'
    -    # Default is empty
    -    key:
    -
    -

    DB Options

    -
    db:
    -  # Same as '--skip-db-update'
    -  # Default is false
    -  skip-update: false
    -
    -  # Same as '--no-progress'
    -  # Default is false
    -  no-progress: false
    -
    -  # Same as '--db-repository'
    -  # Default is 'ghcr.io/aquasecurity/trivy-db'
    -  repository: ghcr.io/aquasecurity/trivy-db
    -
    -  # Same as '--java-db-repository'
    -  # Default is 'ghcr.io/aquasecurity/trivy-java-db'
    -  java-repository: ghcr.io/aquasecurity/trivy-java-db
    -
    -

    Registry Options

    -
    registry:
    -  # Same as '--username'
    -  # Default is empty
    -  username:
    -
    -  # Same as '--password'
    -  # Default is empty
    -  password:
    -
    -  # Same as '--registry-token'
    -  # Default is empty
    -  registry-token:
    -
    -

    Image Options

    -

    Available with container image scanning

    -
    image:
    -  # Same as '--input' (available with 'trivy image')
    -  # Default is empty
    -  input:
    -
    -  # Same as '--removed-pkgs'
    -  # Default is false
    -  removed-pkgs: false
    -
    -  # Same as '--platform'
    -  # Default is empty
    -  platform: 
    -
    -  docker:
    -    # Same as '--docker-host'
    -    # Default is empty
    -    host: 
    -
    -

    Vulnerability Options

    -

    Available with vulnerability scanning

    -
    vulnerability:
    -  # Same as '--vuln-type'
    -  # Default is 'os,library'
    -  type:
    -    - os
    -    - library
    -
    -  # Same as '--ignore-unfixed'
    -  # Default is false
    -  ignore-unfixed: false
    -
    -

    Secret Options

    -

    Available with secret scanning

    -
    secret:
    -  # Same as '--secret-config'
    -  # Default is 'trivy-secret.yaml'
    -  config: config/trivy/secret.yaml
    -
    -

    Rego Options

    -
    rego
    -  # Same as '--trace'
    -  # Default is false
    -  trace: false
    -
    -  # Same as '--config-policy'
    -  # Default is empty
    -  policy:
    -    - policy/repository
    -    - policy/custom
    -
    -  # Same as '--config-data'
    -  # Default is empty
    -  data:
    -    - data/
    -
    -  # Same as '--policy-namespaces'
    -  # Default is empty
    -  namespaces:
    -    - opa.examples
    -    - users
    -
    -

    Misconfiguration Options

    -

    Available with misconfiguration scanning

    -
    misconfiguration:
    -  # Same as '--include-non-failures'
    -  # Default is false
    -  include-non-failures: false
    -
    -  # helm value override configurations
    -  # set individual values
    -  helm:
    -    set:
    -      - securityContext.runAsUser=10001
    -
    -  # set values with file
    -  helm:
    -    values:
    -      - overrides.yaml
    -
    -  # set specific values from specific files
    -  helm:
    -    set-file:
    -      - image=dev-overrides.yaml
    -
    -  # set as string and preserve type
    -  helm:
    -    set-string:
    -      - name=true
    -
    -  # terraform tfvars overrrides
    -  terraform:
    -    vars:
    -      - dev-terraform.tfvars
    -      - common-terraform.tfvars
    -
    -

    Kubernetes Options

    -

    Available with Kubernetes scanning

    -
    kubernetes:
    -  # Same as '--context'
    -  # Default is empty
    -  context:
    -
    -  # Same as '--namespace'
    -  # Default is empty
    -  namespace:
    -
    -

    Repository Options

    -

    Available with git repository scanning (trivy repo)

    -
    repository:
    -  # Same as '--branch'
    -  # Default is empty
    -  branch:
    -
    -  # Same as '--commit'
    -  # Default is empty
    -  commit:
    -
    -  # Same as '--tag'
    -  # Default is empty
    -  tag:
    -
    -

    Client/Server Options

    -

    Available in client/server mode

    -
    server:
    -  # Same as '--server' (available in client mode)
    -  # Default is empty
    -  addr: http://localhost:4954
    -
    -  # Same as '--token'
    -  # Default is empty
    -  token: "something-secret"
    -
    -  # Same as '--token-header'
    -  # Default is 'Trivy-Token'
    -  token-header: 'My-Token-Header'
    -
    -  # Same as '--custom-headers'
    -  # Default is empty
    -  custom-headers:
    -    - scanner: trivy
    -    - x-api-token: xxx
    -
    -  # Same as '--listen' (available in server mode)
    -  # Default is 'localhost:4954'
    -  listen: 0.0.0.0:10000
    -
    -

    Cloud Options

    -

    Available for cloud scanning (currently only trivy aws)

    -
    cloud:
    -  # whether to force a cache update for every scan
    -  update-cache: false
    -
    -  # how old cached results can be before being invalidated
    -  max-cache-age: 24h
    -
    -  # aws-specific cloud settings
    -  aws:
    -    # the aws region to use
    -    region: us-east-1
    -
    -    # the aws endpoint to use (not required for general use)
    -    endpoint: https://my.custom.aws.endpoint
    -
    -    # the aws account to use (this will be determined from your environment when not set)
    -    account: 123456789012
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/modes/client-server/index.html b/test/docs/references/modes/client-server/index.html deleted file mode 100644 index 126b7cf69cff..000000000000 --- a/test/docs/references/modes/client-server/index.html +++ /dev/null @@ -1,3410 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Client/Server - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    - -
    -
    - - -
    -
    - - - - -

    Client/Server

    -

    Trivy has client/server mode. Trivy server has vulnerability database and Trivy client doesn't have to download vulnerability database. It is useful if you want to scan images or files at multiple locations and do not want to download the database at every location.

    -

    Server

    -

    At first, you need to launch Trivy server. It downloads vulnerability database automatically and continue to fetch the latest DB in the background. -

    $ trivy server --listen localhost:8080
    -2019-12-12T15:17:06.551+0200    INFO    Need to update DB
    -2019-12-12T15:17:56.706+0200    INFO    Reopening DB...
    -2019-12-12T15:17:56.707+0200    INFO    Listening localhost:8080...
    -

    -

    If you want to accept a connection from outside, you have to specify 0.0.0.0 or your ip address, not localhost.

    -
    $ trivy server --listen 0.0.0.0:8080
    -
    -

    Remote image scan

    -

    Then, specify the server address for image command. -

    $ trivy image --server http://localhost:8080 alpine:3.10
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    alpine:3.10 (alpine 3.10.2)
    -===========================
    -Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 2, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |
    -+---------+------------------+----------+-------------------+---------------+
    -| openssl | CVE-2019-1549    | MEDIUM   | 1.1.1c-r0         | 1.1.1d-r0     |
    -+         +------------------+          +                   +               +
    -|         | CVE-2019-1563    |          |                   |               |
    -+         +------------------+----------+                   +               +
    -|         | CVE-2019-1547    | LOW      |                   |               |
    -+---------+------------------+----------+-------------------+---------------+
    -
    -
    - -

    Remote scan of local filesystem

    -

    Also, there is a way to scan local file system: -

    $ trivy fs --server http://localhost:8080 --severity CRITICAL ./integration/testdata/fixtures/fs/pom/
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    pom.xml (pom)
    -=============
    -Total: 24 (CRITICAL: 24)
    -
    -+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+
    -|                   LIBRARY                   | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |         FIXED VERSION          |                 TITLE                 |
    -+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+
    -| com.fasterxml.jackson.core:jackson-databind | CVE-2017-17485   | CRITICAL | 2.9.1             | 2.8.11, 2.9.4                  | jackson-databind: Unsafe              |
    -|                                             |                  |          |                   |                                | deserialization due to                |
    -|                                             |                  |          |                   |                                | incomplete black list (incomplete     |
    -|                                             |                  |          |                   |                                | fix for CVE-2017-15095)...            |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2017-17485 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-11307   |          |                   | 2.7.9.4, 2.8.11.2, 2.9.6       | jackson-databind: Potential           |
    -|                                             |                  |          |                   |                                | information exfiltration with         |
    -|                                             |                  |          |                   |                                | default typing, serialization         |
    -|                                             |                  |          |                   |                                | gadget from MyBatis                   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-11307 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-14718   |          |                   | 2.6.7.2, 2.9.7                 | jackson-databind: arbitrary code      |
    -|                                             |                  |          |                   |                                | execution in slf4j-ext class          |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14718 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-14719   |          |                   |                                | jackson-databind: arbitrary           |
    -|                                             |                  |          |                   |                                | code execution in blaze-ds-opt        |
    -|                                             |                  |          |                   |                                | and blaze-ds-core classes             |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14719 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-14720   |          |                   |                                | jackson-databind: exfiltration/XXE    |
    -|                                             |                  |          |                   |                                | in some JDK classes                   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14720 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-14721   |          |                   |                                | jackson-databind: server-side request |
    -|                                             |                  |          |                   |                                | forgery (SSRF) in axis2-jaxws class   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14721 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-19360   |          |                   | 2.6.7.3, 2.7.9.5, 2.8.11.3,    | jackson-databind: improper            |
    -|                                             |                  |          |                   | 2.9.8                          | polymorphic deserialization           |
    -|                                             |                  |          |                   |                                | in axis2-transport-jms class          |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19360 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-19361   |          |                   |                                | jackson-databind: improper            |
    -|                                             |                  |          |                   |                                | polymorphic deserialization           |
    -|                                             |                  |          |                   |                                | in openjpa class                      |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19361 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-19362   |          |                   |                                | jackson-databind: improper            |
    -|                                             |                  |          |                   |                                | polymorphic deserialization           |
    -|                                             |                  |          |                   |                                | in jboss-common-core class            |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19362 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-7489    |          |                   | 2.7.9.3, 2.8.11.1, 2.9.5       | jackson-databind: incomplete fix      |
    -|                                             |                  |          |                   |                                | for CVE-2017-7525 permits unsafe      |
    -|                                             |                  |          |                   |                                | serialization via c3p0 libraries      |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-7489  |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14379   |          |                   | 2.7.9.6, 2.8.11.4, 2.9.9.2     | jackson-databind: default             |
    -|                                             |                  |          |                   |                                | typing mishandling leading            |
    -|                                             |                  |          |                   |                                | to remote code execution              |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14379 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14540   |          |                   | 2.9.10                         | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | com.zaxxer.hikari.HikariConfig        |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14540 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14892   |          |                   | 2.6.7.3, 2.8.11.5, 2.9.10      | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in classes of the             |
    -|                                             |                  |          |                   |                                | commons-configuration package         |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14892 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14893   |          |                   | 2.8.11.5, 2.9.10               | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | classes of the xalan package          |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14893 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-16335   |          |                   | 2.9.10                         | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | com.zaxxer.hikari.HikariDataSource    |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16335 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-16942   |          |                   | 2.9.10.1                       | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | org.apache.commons.dbcp.datasources.* |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16942 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2019-16943   |          |                   |                                | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | com.p6spy.engine.spy.P6DataSource     |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16943 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-17267   |          |                   | 2.9.10                         | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in classes of                 |
    -|                                             |                  |          |                   |                                | the ehcache package                   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-17267 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-17531   |          |                   | 2.9.10.1                       | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | org.apache.log4j.receivers.db.*       |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-17531 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-20330   |          |                   | 2.8.11.5, 2.9.10.2             | jackson-databind: lacks               |
    -|                                             |                  |          |                   |                                | certain net.sf.ehcache blocking       |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-20330 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2020-8840    |          |                   | 2.7.9.7, 2.8.11.5, 2.9.10.3    | jackson-databind: Lacks certain       |
    -|                                             |                  |          |                   |                                | xbean-reflect/JNDI blocking           |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-8840  |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2020-9546    |          |                   | 2.7.9.7, 2.8.11.6, 2.9.10.4    | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in shaded-hikari-config       |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9546  |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2020-9547    |          |                   |                                | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in ibatis-sqlmap              |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9547  |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2020-9548    |          |                   |                                | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in anteros-core               |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9548  |
    -+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+
    -
    -
    - -

    Remote scan of root filesystem

    -

    Also, there is a way to scan root file system: -

    $ trivy rootfs --server http://localhost:8080 --severity CRITICAL /tmp/rootfs
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    /tmp/rootfs (alpine 3.10.2)
    -
    -Total: 1 (CRITICAL: 1)
    -
    -┌───────────┬────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│  Library  │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├───────────┼────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ apk-tools │ CVE-2021-36159 │ CRITICAL │ 2.10.4-r2         │ 2.10.7-r0     │ libfetch before 2021-07-26, as used in apk-tools, xbps, and │
    -│           │                │          │                   │               │ other products, mishandles...                               │
    -│           │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-36159                  │
    -└───────────┴────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -
    -
    - -

    Remote scan of git repository

    -

    Also, there is a way to scan remote git repository: -

    $ trivy repo https://github.com/knqyf263/trivy-ci-test --server http://localhost:8080 
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    Cargo.lock (cargo)
    -==================
    -Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 0)
    -
    -┌───────────┬─────────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│  Library  │    Vulnerability    │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├───────────┼─────────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ ammonia   │ CVE-2019-15542      │ HIGH     │ 1.9.0             │ 2.1.0         │ Uncontrolled recursion in ammonia                           │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-15542                  │
    -│           ├─────────────────────┼──────────┤                   ├───────────────┼─────────────────────────────────────────────────────────────┤
    -│           │ CVE-2021-38193      │ MEDIUM   │                   │ 2.1.3, 3.1.0  │ An issue was discovered in the ammonia crate before 3.1.0   │
    -│           │                     │          │                   │               │ for Rust....                                                │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-38193                  │
    -├───────────┼─────────────────────┤          ├───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ smallvec  │ CVE-2019-15551      │          │ 0.6.9             │ 0.6.10        │ An issue was discovered in the smallvec crate before 0.6.10 │
    -│           │                     │          │                   │               │ for Rust....                                                │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-15551                  │
    -│           ├─────────────────────┼──────────┤                   ├───────────────┼─────────────────────────────────────────────────────────────┤
    -│           │ CVE-2018-25023      │ HIGH     │                   │ 0.6.13        │ An issue was discovered in the smallvec crate before 0.6.13 │
    -│           │                     │          │                   │               │ for Rust....                                                │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2018-25023                  │
    -│           ├─────────────────────┼──────────┤                   │               ├─────────────────────────────────────────────────────────────┤
    -│           │ GHSA-66p5-j55p-32r9 │ MEDIUM   │                   │               │ smallvec creates uninitialized value of any type            │
    -│           │                     │          │                   │               │ https://github.com/advisories/GHSA-66p5-j55p-32r9           │
    -└───────────┴─────────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -
    -Pipfile.lock (pipenv)
    -=====================
    -Total: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
    -
    -┌─────────────────────┬────────────────┬──────────┬───────────────────┬────────────────────────┬──────────────────────────────────────────────────────────────┐
    -│       Library       │ Vulnerability  │ Severity │ Installed Version │     Fixed Version      │                            Title                             │
    -├─────────────────────┼────────────────┼──────────┼───────────────────┼────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ celery              │ CVE-2021-23727 │ HIGH     │ 4.3.0             │ 5.2.2                  │ celery: stored command injection vulnerability may allow     │
    -│                     │                │          │                   │                        │ privileges escalation                                        │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2021-23727                   │
    -├─────────────────────┼────────────────┤          ├───────────────────┼────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ django              │ CVE-2019-6975  │          │ 2.0.9             │ 1.11.19, 2.0.12, 2.1.7 │ python-django: memory exhaustion in                          │
    -│                     │                │          │                   │                        │ django.utils.numberformat.format()                           │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-6975                    │
    -│                     ├────────────────┼──────────┤                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2019-3498  │ MEDIUM   │                   │ 1.11.18, 2.0.10, 2.1.5 │ python-django: Content spoofing via URL path in default 404  │
    -│                     │                │          │                   │                        │ page                                                         │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-3498                    │
    -│                     ├────────────────┤          │                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2021-33203 │          │                   │ 2.2.24, 3.1.12, 3.2.4  │ django: Potential directory traversal via ``admindocs``      │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2021-33203                   │
    -├─────────────────────┼────────────────┤          ├───────────────────┼────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ urllib3             │ CVE-2019-11324 │          │ 1.24.1            │ 1.24.2                 │ python-urllib3: Certification mishandle when error should be │
    -│                     │                │          │                   │                        │ thrown                                                       │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-11324                   │
    -│                     ├────────────────┤          │                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2021-33503 │          │                   │ 1.26.5                 │ python-urllib3: ReDoS in the parsing of authority part of    │
    -│                     │                │          │                   │                        │ URL                                                          │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2021-33503                   │
    -│                     ├────────────────┼──────────┤                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2019-11236 │ MEDIUM   │                   │ 1.24.3                 │ python-urllib3: CRLF injection due to not encoding the       │
    -│                     │                │          │                   │                        │ '\r\n' sequence leading to...                                │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-11236                   │
    -│                     ├────────────────┤          │                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2020-26137 │          │                   │ 1.25.9                 │ python-urllib3: CRLF injection via HTTP request method       │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2020-26137                   │
    -└─────────────────────┴────────────────┴──────────┴───────────────────┴────────────────────────┴──────────────────────────────────────────────────────────────┘
    -
    -
    - -

    Authentication

    -
    $ trivy server --listen localhost:8080 --token dummy
    -
    -
    $ trivy image --server http://localhost:8080 --token dummy alpine:3.10
    -
    -

    Architecture

    -

    architecture

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/modes/standalone/index.html b/test/docs/references/modes/standalone/index.html deleted file mode 100644 index bea231fc1978..000000000000 --- a/test/docs/references/modes/standalone/index.html +++ /dev/null @@ -1,3091 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Standalone - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Standalone

    -

    trivy image, trivy filesystem, and trivy repo works as standalone mode.

    -

    Image

    -

    standalone

    -

    Filesystem

    -

    fs

    -

    Git Repository

    -

    repo

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/references/troubleshooting/index.html b/test/docs/references/troubleshooting/index.html deleted file mode 100644 index 4e0eff87a176..000000000000 --- a/test/docs/references/troubleshooting/index.html +++ /dev/null @@ -1,3483 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Troubleshooting - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Troubleshooting

    -

    Scan

    -

    Timeout

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -analyze error: timeout: context deadline exceeded
    -
    -
    -

    Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as --timeout 15m.

    -

    Certification

    -
    -

    Error

    -

    Error: x509: certificate signed by unknown authority

    -
    -

    TRIVY_INSECURE can be used to allow insecure connections to a container registry when using SSL.

    -
    $ TRIVY_INSECURE=true trivy image [YOUR_IMAGE]
    -
    -

    GitHub Rate limiting

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -API rate limit exceeded for xxx.xxx.xxx.xxx.
    -
    -
    -

    Specify GITHUB_TOKEN for authentication -https://developer.github.com/v3/#rate-limiting

    -
    $ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10
    -
    -

    Unable to open JAR files

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -failed to analyze file: failed to analyze usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: unable to open usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: failed to open: unable to read the file: stream error: stream ID 9; PROTOCOL_ERROR; received from peer
    -
    -
    -

    Currently, we're investigating this issue. As a temporary mitigation, you may be able to avoid this issue by downloading the Java DB in advance.

    -
    $ trivy image --download-java-db-only
    -2023-02-01T16:57:04.322+0900    INFO    Downloading the Java DB...
    -$ trivy image [YOUR_JAVA_IMAGE]
    -
    -

    Running in parallel takes same time as series run

    -

    When running trivy on multiple images simultaneously, it will take same time as running trivy in series. -This is because of a limitation of boltdb.

    -
    -

    Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.

    -
    -

    Reference : boltdb: Opening a database.

    -

    Multiple Trivy servers

    -
    -

    Error

    -
    $ trivy image --server http://xxx.com:xxxx test-image
    -...
    -- twirp error internal: failed scan, test-image: failed to apply layers: layer cache missing: sha256:*****
    -
    -
    -

    To run multiple Trivy servers, you need to use Redis as the cache backend so that those servers can share the cache. -Follow this instruction to do so.

    -

    Problems with /tmp on remote Git repository scans

    -
    -

    Error

    -

    FATAL repository scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: git clone error: write /tmp/fanal-remote...

    -
    -

    Trivy clones remote Git repositories under the /tmp directory before scanning them. If /tmp doesn't work for you, you can change it by setting the TMPDIR environment variable.

    -

    Try:

    -
    $ TMPDIR=/my/custom/path trivy repo ...
    -
    -

    Running out of space during image scans

    -
    -

    Error

    -
    image scan failed:
    -failed to copy the image:
    -write /tmp/fanal-3323732142: no space left on device
    -
    -
    -

    Trivy uses the /tmp directory during image scan, if the image is large or /tmp is of insufficient size then the scan fails You can set the TMPDIR environment variable to use redirect trivy to use a directory with adequate storage.

    -

    Try:

    -
    $ TMPDIR=/my/custom/path trivy image ...
    -
    -

    DB

    -

    Old DB schema

    -
    -

    Error

    -

    --skip-update cannot be specified with the old DB schema.

    -
    -

    Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow the instruction of air-gapped environment.

    -

    Error downloading vulnerability DB

    -
    -

    Error

    -

    FATAL failed to download vulnerability DB

    -
    -

    If trivy is running behind corporate firewall, you have to add the following urls to your allowlist.

    -
      -
    • ghcr.io
    • -
    • pkg-containers.githubusercontent.com
    • -
    -

    Denied

    -
    -

    Error

    -

    GET https://ghcr.io/token?scope=repository%3Aaquasecurity%2Ftrivy-db%3Apull&service=ghcr.io: DENIED: denied

    -
    -

    Your local GHCR (GitHub Container Registry) token might be expired. -Please remove the token and try downloading the DB again.

    -
    docker logout ghcr.io
    -
    -

    Homebrew

    -

    Scope error

    -
    -

    Error

    -

    Error: Your macOS keychain GitHub credentials do not have sufficient scope!

    -
    -
    $ brew tap aquasecurity/trivy
    -Error: Your macOS keychain GitHub credentials do not have sufficient scope!
    -Scopes they need: none
    -Scopes they have:
    -Create a personal access token:
    -https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew
    -echo 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.zshrc
    -
    -

    Try:

    -
    $ printf "protocol=https\nhost=github.com\n" | git credential-osxkeychain erase
    -
    -

    Already installed

    -
    -

    Error

    -

    Error: aquasecurity/trivy/trivy 64 already installed

    -
    -
    $ brew upgrade
    -...
    -Error: aquasecurity/trivy/trivy 64 already installed
    -
    -

    Try:

    -
    $ brew unlink trivy && brew uninstall trivy
    -($ rm -rf /usr/local/Cellar/trivy/64)
    -$ brew install aquasecurity/trivy/trivy
    -
    -

    Others

    -

    Unknown error

    -

    Try again with --reset option:

    -
    $ trivy image --reset
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/license/index.html b/test/docs/scanner/license/index.html deleted file mode 100644 index 43b329250597..000000000000 --- a/test/docs/scanner/license/index.html +++ /dev/null @@ -1,3528 +0,0 @@ - - - - - - - - - - - - - - - - - - - - License - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    License Scanning

    -

    Trivy scans any container image for license files and offers an opinionated view on the risk associated with the license.

    -

    License are classified using the Google License Classification -

    -
      -
    • Forbidden
    • -
    • Restricted
    • -
    • Reciprocal
    • -
    • Notice
    • -
    • Permissive
    • -
    • Unencumbered
    • -
    • Unknown
    • -
    -
    -

    Tip

    -

    Licenses that Trivy fails to recognize are classified as UNKNOWN. -As those licenses may be in violation, it is recommended to check those unknown licenses as well.

    -
    -

    By default, Trivy scans licenses for packages installed by apk, apt-get, dnf, npm, pip, gem, etc. -To enable extended license scanning, you can use --license-full. -In addition to package licenses, Trivy scans source code files, Markdown documents, text files and LICENSE documents to identify license usage within the image or filesystem.

    -

    By default, Trivy only classifies licenses that are matched with a confidence level of 0.9 or more by the classifer. -To configure the confidence level, you can use --license-confidence-level. This enables us to classify licenses that might be matched with a lower confidence level by the classifer.

    -
    -

    Note

    -

    The full license scanning is expensive. It takes a while.

    -
    -

    Currently, the standard license scanning doesn't support filesystem and repository scanning.

    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    License scanningImageRootfsFilesystemRepository
    Standard--
    Full (--license-full)
    -

    License checking classifies the identified licenses and map the classification to severity.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ClassificationSeverity
    ForbiddenCRITICAL
    RestrictedHIGH
    ReciprocalMEDIUM
    NoticeLOW
    PermissiveLOW
    UnencumberedLOW
    UnknownUNKNOWN
    -

    Quick start

    -

    This section shows how to scan license in container image and filesystem.

    -

    Standard scanning

    -

    Specify an image name with --scanners license.

    -
    $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15
    -2022-07-13T17:28:39.526+0300    INFO    License scanning is enabled
    -
    -OS Packages (license)
    -=====================
    -Total: 6 (UNKNOWN: 0, HIGH: 6, CRITICAL: 0)
    -
    -┌───────────────────┬─────────┬────────────────┬──────────┐
    -│      Package      │ License │ Classification │ Severity │
    -├───────────────────┼─────────┼────────────────┼──────────┤
    -│ alpine-baselayout │ GPL-2.0 │ Restricted     │ HIGH     │
    -├───────────────────┤         │                │          │
    -│ apk-tools         │         │                │          │
    -├───────────────────┤         │                │          │
    -│ busybox           │         │                │          │
    -├───────────────────┤         │                │          │
    -│ musl-utils        │         │                │          │
    -├───────────────────┤         │                │          │
    -│ scanelf           │         │                │          │
    -├───────────────────┤         │                │          │
    -│ ssl_client        │         │                │          │
    -└───────────────────┴─────────┴────────────────┴──────────┘
    -
    -

    Full scanning

    -

    Specify --license-full

    -
    $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana
    -2022-07-13T17:48:40.905+0300    INFO    Full license scanning is enabled
    -
    -OS Packages (license)
    -=====================
    -Total: 20 (UNKNOWN: 9, HIGH: 11, CRITICAL: 0)
    -
    -┌───────────────────┬───────────────────┬────────────────┬──────────┐
    -│      Package      │      License      │ Classification │ Severity │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ alpine-baselayout │ GPL-2.0           │ Restricted     │ HIGH     │
    -├───────────────────┤                   │                │          │
    -│ apk-tools         │                   │                │          │
    -├───────────────────┼───────────────────┤                │          │
    -│ bash              │ GPL-3.0           │                │          │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ keyutils-libs     │ GPL-2.0           │ Restricted     │ HIGH     │
    -│                   ├───────────────────┼────────────────┼──────────┤
    -│                   │ LGPL-2.0-or-later │ Non Standard   │ UNKNOWN  │
    -├───────────────────┼───────────────────┤                │          │
    -│ libaio            │ LGPL-2.1-or-later │                │          │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ libcom_err        │ GPL-2.0           │ Restricted     │ HIGH     │
    -│                   ├───────────────────┼────────────────┼──────────┤
    -│                   │ LGPL-2.0-or-later │ Non Standard   │ UNKNOWN  │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ tzdata            │ Public-Domain     │ Non Standard   │ UNKNOWN  │
    -└───────────────────┴───────────────────┴────────────────┴──────────┘
    -
    -Loose File License(s) (license)
    -===============================
    -Total: 6 (UNKNOWN: 4, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────────┬──────────┬──────────────┬──────────────────────────────────────────────────────────────┐
    -│ Classification │ Severity │   License    │                        File Location                         │
    -├────────────────┼──────────┼──────────────┼──────────────────────────────────────────────────────────────┤
    -│ Forbidden      │ CRITICAL │ AGPL-3.0     │ /usr/share/grafana/LICENSE                                   │
    -│                │          │              │                                                              │
    -│                │          │              │                                                              │
    -├────────────────┼──────────┼──────────────┼──────────────────────────────────────────────────────────────┤
    -│ Non Standard   │ UNKNOWN  │ BSD-0-Clause │ /usr/share/grafana/public/build/5069.d6aae9dd11d49c741a80.j- │
    -│                │          │              │ s.LICENSE.txt                                                │
    -│                │          │              ├──────────────────────────────────────────────────────────────┤
    -│                │          │              │ /usr/share/grafana/public/build/6444.d6aae9dd11d49c741a80.j- │
    -│                │          │              │ s.LICENSE.txt                                                │
    -│                │          │              ├──────────────────────────────────────────────────────────────┤
    -│                │          │              │ /usr/share/grafana/public/build/7889.d6aae9dd11d49c741a80.j- │
    -│                │          │              │ s.LICENSE.txt                                                │
    -│                │          │              ├──────────────────────────────────────────────────────────────┤
    -│                │          │              │ /usr/share/grafana/public/build/canvasPanel.d6aae9dd11d49c7- │
    -│                │          │              │ 41a80.js.LICENSE.txt                                         │
    -└────────────────┴──────────┴──────────────┴──────────────────────────────────────────────────────────────┘
    -
    -

    Configuration

    -

    Trivy has number of configuration flags for use with license scanning;

    -

    Ignored Licenses

    -

    Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the --ignored-licenses flag;

    -
    $ trivy image --scanners license --ignored-licenses MPL-2.0,MIT --severity LOW grafana/grafana:latest
    -2022-07-13T18:15:28.605Z        INFO    License scanning is enabled
    -
    -OS Packages (license)
    -=====================
    -Total: 2 (HIGH: 2, CRITICAL: 0)
    -
    -┌───────────────────┬─────────┬────────────────┬──────────┐
    -│      Package      │ License │ Classification │ Severity │
    -├───────────────────┼─────────┼────────────────┼──────────┤
    -│ alpine-baselayout │ GPL-2.0 │ Restricted     │ HIGH     │
    -├───────────────────┤         │                │          │
    -│ ssl_client        │         │                │          │
    -└───────────────────┴─────────┴────────────────┴──────────┘
    -
    -

    Configuring Classifier Confidence Level

    -

    You can use the --license-confidence-level flag to adjust the confidence level between 0.0 to 1.0 (default 0.9). -For example, when you run the scanner with the default confidence level on SPDX license list data, it is able to detect only 258 licenses.

    -
    $ trivy fs --scanners license --license-full <path/to/spdx/list/data>
    -2023-04-18T10:05:13.601-0700    INFO    Full license scanning is enabled
    -
    -Loose File License(s) (license)
    -===============================
    -Total: 258 (UNKNOWN: 70, LOW: 90, MEDIUM: 18, HIGH: 58, CRITICAL: 22)
    -
    -

    However, by configuring the confidence level to 0.8, the scanner is now able to detect 282 licenses.

    -
    $ trivy fs --scanners license --license-full --license-confidence-level 0.8 <path/to/spdx/list/data>
    -2023-04-18T10:21:39.637-0700    INFO    Full license scanning is enabled
    -
    -Loose File License(s) (license)
    -===============================
    -Total: 282 (UNKNOWN: 81, LOW: 97, MEDIUM: 24, HIGH: 58, CRITICAL: 22)
    -
    -

    Custom Classification

    -

    You can generate the default config by the --generate-default-config flag and customize the license classification. -For example, if you want to forbid only AGPL-3.0, you can leave it under forbidden and move other licenses to another classification.

    -
    $ trivy image --generate-default-config
    -$ vim trivy.yaml
    -license:
    -  forbidden:
    -  - AGPL-3.0
    -
    -  restricted:
    -  - AGPL-1.0
    -  - CC-BY-NC-1.0
    -  - CC-BY-NC-2.0
    -  - CC-BY-NC-2.5
    -  - CC-BY-NC-3.0
    -  - CC-BY-NC-4.0
    -  - CC-BY-NC-ND-1.0
    -  - CC-BY-NC-ND-2.0
    -  - CC-BY-NC-ND-2.5
    -  - CC-BY-NC-ND-3.0
    -  - CC-BY-NC-ND-4.0
    -  - CC-BY-NC-SA-1.0
    -  - CC-BY-NC-SA-2.0
    -  - CC-BY-NC-SA-2.5
    -  - CC-BY-NC-SA-3.0
    -  - CC-BY-NC-SA-4.0
    -  - Commons-Clause
    -  - Facebook-2-Clause
    -  - Facebook-3-Clause
    -  - Facebook-Examples
    -  - WTFPL
    -  - BCL
    -  - CC-BY-ND-1.0
    -  - CC-BY-ND-2.0
    -  - CC-BY-ND-2.5
    -  - CC-BY-ND-3.0
    -  - CC-BY-ND-4.0
    -  - CC-BY-SA-1.0
    -  - CC-BY-SA-2.0
    -  - CC-BY-SA-2.5
    -  - CC-BY-SA-3.0
    -  - CC-BY-SA-4.0
    -  - GPL-1.0
    -  - GPL-2.0
    -  - GPL-2.0-with-autoconf-exception
    -  - GPL-2.0-with-bison-exception
    -  - GPL-2.0-with-classpath-exception
    -  - GPL-2.0-with-font-exception
    -  - GPL-2.0-with-GCC-exception
    -  - GPL-3.0
    -  - GPL-3.0-with-autoconf-exception
    -  - GPL-3.0-with-GCC-exception
    -  - LGPL-2.0
    -  - LGPL-2.1
    -  - LGPL-3.0
    -  - NPL-1.0
    -  - NPL-1.1
    -  - OSL-1.0
    -  - OSL-1.1
    -  - OSL-2.0
    -  - OSL-2.1
    -  - OSL-3.0
    -  - QPL-1.0
    -  - Sleepycat
    -
    -  reciprocal:
    -  - APSL-1.0
    -  - APSL-1.1
    -  - APSL-1.2
    -  - APSL-2.0
    -  - CDDL-1.0
    -  - CDDL-1.1
    -  - CPL-1.0
    -  - EPL-1.0
    -  - EPL-2.0
    -  - FreeImage
    -  - IPL-1.0
    -  - MPL-1.0
    -  - MPL-1.1
    -  - MPL-2.0
    -  - Ruby
    -
    -  notice:
    -  - AFL-1.1
    -  - AFL-1.2
    -  - AFL-2.0
    -  - AFL-2.1
    -  - AFL-3.0
    -  - Apache-1.0
    -  - Apache-1.1
    -  - Apache-2.0
    -  - Artistic-1.0-cl8
    -  - Artistic-1.0-Perl
    -  - Artistic-1.0
    -  - Artistic-2.0
    -  - BSL-1.0
    -  - BSD-2-Clause-FreeBSD
    -  - BSD-2-Clause-NetBSD
    -  - BSD-2-Clause
    -  - BSD-3-Clause-Attribution
    -  - BSD-3-Clause-Clear
    -  - BSD-3-Clause-LBNL
    -  - BSD-3-Clause
    -  - BSD-4-Clause
    -  - BSD-4-Clause-UC
    -  - BSD-Protection
    -  - CC-BY-1.0
    -  - CC-BY-2.0
    -  - CC-BY-2.5
    -  - CC-BY-3.0
    -  - CC-BY-4.0
    -  - FTL
    -  - ISC
    -  - ImageMagick
    -  - Libpng
    -  - Lil-1.0
    -  - Linux-OpenIB
    -  - LPL-1.02
    -  - LPL-1.0
    -  - MS-PL
    -  - MIT
    -  - NCSA
    -  - OpenSSL
    -  - PHP-3.01
    -  - PHP-3.0
    -  - PIL
    -  - Python-2.0
    -  - Python-2.0-complete
    -  - PostgreSQL
    -  - SGI-B-1.0
    -  - SGI-B-1.1
    -  - SGI-B-2.0
    -  - Unicode-DFS-2015
    -  - Unicode-DFS-2016
    -  - Unicode-TOU
    -  - UPL-1.0
    -  - W3C-19980720
    -  - W3C-20150513
    -  - W3C
    -  - X11
    -  - Xnet
    -  - Zend-2.0
    -  - zlib-acknowledgement
    -  - Zlib
    -  - ZPL-1.1
    -  - ZPL-2.0
    -  - ZPL-2.1
    -
    -  unencumbered:
    -  - CC0-1.0
    -  - Unlicense
    -  - 0BSD
    -
    -  permissive: []
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/combine/index.html b/test/docs/scanner/misconfiguration/custom/combine/index.html deleted file mode 100644 index a59c8a8a9bf1..000000000000 --- a/test/docs/scanner/misconfiguration/custom/combine/index.html +++ /dev/null @@ -1,3110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Combine - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Combined input

    -

    Overview

    -

    Trivy usually scans each configuration file individually. -Sometimes it might be useful to compare values from different configuration files simultaneously.

    -

    When combine is set to true, all config files under the specified directory are combined into one input data structure.

    -
    -

    Example

    -
    __rego_input__ := {
    -    "combine": false,
    -}
    -
    -
    -

    In "combine" mode, the input document becomes an array, where each element is an object with two fields:

    -
      -
    • "path": "path/to/file": the relative file path of the respective file
    • -
    • "contents": ...: the parsed content of the respective file
    • -
    -

    Now you can ensure that duplicate values match across the entirety of your configuration files.

    -

    Return value

    -

    In "combine" mode, the deny entrypoint must return an object with two keys

    -
    -
    filepath (required)
    -
    the relative file path of the file being evaluated
    -
    msg (required)
    -
    the message describing an issue
    -
    -
    -

    Example

    -
    deny[res] {
    -    resource := input[i].contents
    -    ... some logic ...
    -
    -    res := {
    -        "filepath": input[i].path,
    -        "msg": "something bad",
    -    }
    -}
    -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/data/index.html b/test/docs/scanner/misconfiguration/custom/data/index.html deleted file mode 100644 index 84b818e26171..000000000000 --- a/test/docs/scanner/misconfiguration/custom/data/index.html +++ /dev/null @@ -1,3035 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Data - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Custom Data

    -

    Custom policies may require additional data in order to determine an answer.

    -

    For example, an allowed list of resources that can be created. -Instead of hardcoding this information inside of your policy, Trivy allows passing paths to data files with the --data flag.

    -

    Given the following yaml file:

    -
    $ cd examples/misconf/custom-data
    -$ cat data/ports.yaml                                                                                                                                                                      [~/src/github.com/aquasecurity/trivy/examples/misconf/custom-data]
    -services:
    -  ports:
    -    - "20"
    -    - "20/tcp"
    -    - "20/udp"
    -    - "23"
    -    - "23/tcp"
    -
    -

    This can be imported into your policy:

    -
    import data.services
    -
    -ports := services.ports
    -
    -

    Then, you need to pass data paths through --data option. -Trivy recursively searches the specified paths for JSON (*.json) and YAML (*.yaml) files.

    -
    $ trivy conf --policy ./policy --data data --namespaces user ./configs
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/debug/index.html b/test/docs/scanner/misconfiguration/custom/debug/index.html deleted file mode 100644 index cfeb18522f7f..000000000000 --- a/test/docs/scanner/misconfiguration/custom/debug/index.html +++ /dev/null @@ -1,3314 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Debugging Policies - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Debugging policies

    -

    When working on more complex queries (or when learning Rego), it's useful to see exactly how the policy is applied. -For this purpose you can use the --trace flag. -This will output a large trace from Open Policy Agent like the following:

    -
    -

    Tip

    -

    Only failed policies show traces. If you want to debug a passed policy, you need to make it fail on purpose.

    -
    -
    $ trivy conf --trace configs/
    -2022-05-16T13:47:58.853+0100    INFO    Detected config files: 1
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 23 (SUCCESSES: 21, FAILURES: 2, EXCEPTIONS: 0)
    -Failures: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 1, CRITICAL: 0)
    -
    -MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.
    -
    -See https://avd.aquasec.com/misconfig/ds001
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - Dockerfile:1
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   1 [ FROM alpine:latest
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -HIGH: Last USER command in Dockerfile should not be 'root'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - Dockerfile:3
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   3 [ USER root
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -ID: DS001
    -File: Dockerfile
    -Namespace: builtin.dockerfile.DS001
    -Query: data.builtin.dockerfile.DS001.deny
    -Message: Specify a tag in the 'FROM' statement for image 'alpine'
    -TRACE  Enter data.builtin.dockerfile.DS001.deny = _
    -TRACE  | Eval data.builtin.dockerfile.DS001.deny = _
    -TRACE  | Index data.builtin.dockerfile.DS001.deny (matched 1 rule)
    -TRACE  | Enter data.builtin.dockerfile.DS001.deny
    -TRACE  | | Eval output = data.builtin.dockerfile.DS001.fail_latest[_]
    -TRACE  | | Index data.builtin.dockerfile.DS001.fail_latest (matched 1 rule)
    -TRACE  | | Enter data.builtin.dockerfile.DS001.fail_latest
    -TRACE  | | | Eval output = data.builtin.dockerfile.DS001.image_tags[_]
    -TRACE  | | | Index data.builtin.dockerfile.DS001.image_tags (matched 2 rules)
    -TRACE  | | | Enter data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | | Eval from = data.lib.docker.from[_]
    -TRACE  | | | | Index data.lib.docker.from (matched 1 rule)
    -TRACE  | | | | Enter data.lib.docker.from
    -TRACE  | | | | | Eval instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "from"
    -TRACE  | | | | | Exit data.lib.docker.from
    -TRACE  | | | | Redo data.lib.docker.from
    -TRACE  | | | | | Redo instruction.Cmd = "from"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "from"
    -TRACE  | | | | | Fail instruction.Cmd = "from"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "from"
    -TRACE  | | | | | Fail instruction.Cmd = "from"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | Eval name = from.Value[0]
    -TRACE  | | | | Eval not startswith(name, "$")
    -TRACE  | | | | Enter startswith(name, "$")
    -TRACE  | | | | | Eval startswith(name, "$")
    -TRACE  | | | | | Fail startswith(name, "$")
    -TRACE  | | | | Eval data.builtin.dockerfile.DS001.parse_tag(name, __local505__)
    -TRACE  | | | | Index data.builtin.dockerfile.DS001.parse_tag (matched 2 rules)
    -TRACE  | | | | Enter data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | | Eval split(name, ":", __local504__)
    -TRACE  | | | | | Eval [img, tag] = __local504__
    -TRACE  | | | | | Exit data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | Eval [img, tag] = __local505__
    -TRACE  | | | | Eval output = {"cmd": from, "img": img, "tag": tag}
    -TRACE  | | | | Exit data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | Redo data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | | Redo output = {"cmd": from, "img": img, "tag": tag}
    -TRACE  | | | | Redo [img, tag] = __local505__
    -TRACE  | | | | Redo data.builtin.dockerfile.DS001.parse_tag(name, __local505__)
    -TRACE  | | | | Redo data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | | Redo [img, tag] = __local504__
    -TRACE  | | | | | Redo split(name, ":", __local504__)
    -TRACE  | | | | Enter data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | | Eval tag = "latest"
    -TRACE  | | | | | Eval not contains(img, ":")
    -TRACE  | | | | | Enter contains(img, ":")
    -TRACE  | | | | | | Eval contains(img, ":")
    -TRACE  | | | | | | Exit contains(img, ":")
    -TRACE  | | | | | Redo contains(img, ":")
    -TRACE  | | | | | | Redo contains(img, ":")
    -TRACE  | | | | | Fail not contains(img, ":")
    -TRACE  | | | | | Redo tag = "latest"
    -TRACE  | | | | Redo name = from.Value[0]
    -TRACE  | | | | Redo from = data.lib.docker.from[_]
    -TRACE  | | | Enter data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | | Eval from = data.lib.docker.from[i]
    -TRACE  | | | | Index data.lib.docker.from (matched 1 rule)
    -TRACE  | | | | Eval name = from.Value[0]
    -TRACE  | | | | Eval cmd_obj = input.stages[j][k]
    -TRACE  | | | | Eval possibilities = {"arg", "env"}
    -TRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Redo possibilities = {"arg", "env"}
    -TRACE  | | | | Redo cmd_obj = input.stages[j][k]
    -TRACE  | | | | Eval possibilities = {"arg", "env"}
    -TRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Redo possibilities = {"arg", "env"}
    -TRACE  | | | | Redo cmd_obj = input.stages[j][k]
    -TRACE  | | | | Eval possibilities = {"arg", "env"}
    -TRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Redo possibilities = {"arg", "env"}
    -TRACE  | | | | Redo cmd_obj = input.stages[j][k]
    -TRACE  | | | | Redo name = from.Value[0]
    -TRACE  | | | | Redo from = data.lib.docker.from[i]
    -TRACE  | | | Eval __local752__ = output.img
    -TRACE  | | | Eval neq(__local752__, "scratch")
    -TRACE  | | | Eval __local753__ = output.img
    -TRACE  | | | Eval not data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | Enter data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | | Eval data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | | Index data.builtin.dockerfile.DS001.is_alias (matched 1 rule, early exit)
    -TRACE  | | | | Enter data.builtin.dockerfile.DS001.is_alias
    -TRACE  | | | | | Eval img = data.builtin.dockerfile.DS001.get_aliases[_]
    -TRACE  | | | | | Index data.builtin.dockerfile.DS001.get_aliases (matched 1 rule)
    -TRACE  | | | | | Enter data.builtin.dockerfile.DS001.get_aliases
    -TRACE  | | | | | | Eval from_cmd = data.lib.docker.from[_]
    -TRACE  | | | | | | Index data.lib.docker.from (matched 1 rule)
    -TRACE  | | | | | | Eval __local749__ = from_cmd.Value
    -TRACE  | | | | | | Eval data.builtin.dockerfile.DS001.get_alias(__local749__, __local503__)
    -TRACE  | | | | | | Index data.builtin.dockerfile.DS001.get_alias (matched 1 rule)
    -TRACE  | | | | | | Enter data.builtin.dockerfile.DS001.get_alias
    -TRACE  | | | | | | | Eval __local748__ = values[i]
    -TRACE  | | | | | | | Eval lower(__local748__, __local501__)
    -TRACE  | | | | | | | Eval "as" = __local501__
    -TRACE  | | | | | | | Fail "as" = __local501__
    -TRACE  | | | | | | | Redo lower(__local748__, __local501__)
    -TRACE  | | | | | | | Redo __local748__ = values[i]
    -TRACE  | | | | | | Fail data.builtin.dockerfile.DS001.get_alias(__local749__, __local503__)
    -TRACE  | | | | | | Redo __local749__ = from_cmd.Value
    -TRACE  | | | | | | Redo from_cmd = data.lib.docker.from[_]
    -TRACE  | | | | | Fail img = data.builtin.dockerfile.DS001.get_aliases[_]
    -TRACE  | | | | Fail data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | Eval output.tag = "latest"
    -TRACE  | | | Exit data.builtin.dockerfile.DS001.fail_latest
    -TRACE  | | Redo data.builtin.dockerfile.DS001.fail_latest
    -TRACE  | | | Redo output.tag = "latest"
    -TRACE  | | | Redo __local753__ = output.img
    -TRACE  | | | Redo neq(__local752__, "scratch")
    -TRACE  | | | Redo __local752__ = output.img
    -TRACE  | | | Redo output = data.builtin.dockerfile.DS001.image_tags[_]
    -TRACE  | | Eval __local754__ = output.img
    -TRACE  | | Eval sprintf("Specify a tag in the 'FROM' statement for image '%s'", [__local754__], __local509__)
    -TRACE  | | Eval msg = __local509__
    -TRACE  | | Eval __local755__ = output.cmd
    -TRACE  | | Eval data.lib.docker.result(msg, __local755__, __local510__)
    -TRACE  | | Index data.lib.docker.result (matched 1 rule)
    -TRACE  | | Enter data.lib.docker.result
    -TRACE  | | | Eval object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | | Eval object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Eval object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Eval result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Exit data.lib.docker.result
    -TRACE  | | Eval res = __local510__
    -TRACE  | | Exit data.builtin.dockerfile.DS001.deny
    -TRACE  | Redo data.builtin.dockerfile.DS001.deny
    -TRACE  | | Redo res = __local510__
    -TRACE  | | Redo data.lib.docker.result(msg, __local755__, __local510__)
    -TRACE  | | Redo data.lib.docker.result
    -TRACE  | | | Redo result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Redo object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Redo object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Redo object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | Redo __local755__ = output.cmd
    -TRACE  | | Redo msg = __local509__
    -TRACE  | | Redo sprintf("Specify a tag in the 'FROM' statement for image '%s'", [__local754__], __local509__)
    -TRACE  | | Redo __local754__ = output.img
    -TRACE  | | Redo output = data.builtin.dockerfile.DS001.fail_latest[_]
    -TRACE  | Exit data.builtin.dockerfile.DS001.deny = _
    -TRACE  Redo data.builtin.dockerfile.DS001.deny = _
    -TRACE  | Redo data.builtin.dockerfile.DS001.deny = _
    -TRACE
    -
    -
    -ID: DS002
    -File: Dockerfile
    -Namespace: builtin.dockerfile.DS002
    -Query: data.builtin.dockerfile.DS002.deny
    -Message: Last USER command in Dockerfile should not be 'root'
    -TRACE  Enter data.builtin.dockerfile.DS002.deny = _
    -TRACE  | Eval data.builtin.dockerfile.DS002.deny = _
    -TRACE  | Index data.builtin.dockerfile.DS002.deny (matched 2 rules)
    -TRACE  | Enter data.builtin.dockerfile.DS002.deny
    -TRACE  | | Eval data.builtin.dockerfile.DS002.fail_user_count
    -TRACE  | | Index data.builtin.dockerfile.DS002.fail_user_count (matched 1 rule, early exit)
    -TRACE  | | Enter data.builtin.dockerfile.DS002.fail_user_count
    -TRACE  | | | Eval __local771__ = data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | Index data.builtin.dockerfile.DS002.get_user (matched 1 rule)
    -TRACE  | | | Enter data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | | Eval user = data.lib.docker.user[_]
    -TRACE  | | | | Index data.lib.docker.user (matched 1 rule)
    -TRACE  | | | | Enter data.lib.docker.user
    -TRACE  | | | | | Eval instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "user"
    -TRACE  | | | | | Fail instruction.Cmd = "user"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "user"
    -TRACE  | | | | | Exit data.lib.docker.user
    -TRACE  | | | | Redo data.lib.docker.user
    -TRACE  | | | | | Redo instruction.Cmd = "user"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "user"
    -TRACE  | | | | | Fail instruction.Cmd = "user"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | Eval username = user.Value[_]
    -TRACE  | | | | Exit data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | Redo data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | | Redo username = user.Value[_]
    -TRACE  | | | | Redo user = data.lib.docker.user[_]
    -TRACE  | | | Eval count(__local771__, __local536__)
    -TRACE  | | | Eval lt(__local536__, 1)
    -TRACE  | | | Fail lt(__local536__, 1)
    -TRACE  | | | Redo count(__local771__, __local536__)
    -TRACE  | | | Redo __local771__ = data.builtin.dockerfile.DS002.get_user
    -TRACE  | | Fail data.builtin.dockerfile.DS002.fail_user_count
    -TRACE  | Enter data.builtin.dockerfile.DS002.deny
    -TRACE  | | Eval cmd = data.builtin.dockerfile.DS002.fail_last_user_root[_]
    -TRACE  | | Index data.builtin.dockerfile.DS002.fail_last_user_root (matched 1 rule)
    -TRACE  | | Enter data.builtin.dockerfile.DS002.fail_last_user_root
    -TRACE  | | | Eval stage_users = data.lib.docker.stage_user[_]
    -TRACE  | | | Index data.lib.docker.stage_user (matched 1 rule)
    -TRACE  | | | Enter data.lib.docker.stage_user
    -TRACE  | | | | Eval stage = input.stages[stage_name]
    -TRACE  | | | | Eval users = [cmd | cmd = stage[_]; cmd.Cmd = "user"]
    -TRACE  | | | | Enter cmd = stage[_]; cmd.Cmd = "user"
    -TRACE  | | | | | Eval cmd = stage[_]
    -TRACE  | | | | | Eval cmd.Cmd = "user"
    -TRACE  | | | | | Fail cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd = stage[_]
    -TRACE  | | | | | Eval cmd.Cmd = "user"
    -TRACE  | | | | | Exit cmd = stage[_]; cmd.Cmd = "user"
    -TRACE  | | | | Redo cmd = stage[_]; cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd = stage[_]
    -TRACE  | | | | | Eval cmd.Cmd = "user"
    -TRACE  | | | | | Fail cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd = stage[_]
    -TRACE  | | | | Exit data.lib.docker.stage_user
    -TRACE  | | | Redo data.lib.docker.stage_user
    -TRACE  | | | | Redo users = [cmd | cmd = stage[_]; cmd.Cmd = "user"]
    -TRACE  | | | | Redo stage = input.stages[stage_name]
    -TRACE  | | | Eval count(stage_users, __local537__)
    -TRACE  | | | Eval len = __local537__
    -TRACE  | | | Eval minus(len, 1, __local538__)
    -TRACE  | | | Eval last = stage_users[__local538__]
    -TRACE  | | | Eval user = last.Value[0]
    -TRACE  | | | Eval user = "root"
    -TRACE  | | | Exit data.builtin.dockerfile.DS002.fail_last_user_root
    -TRACE  | | Redo data.builtin.dockerfile.DS002.fail_last_user_root
    -TRACE  | | | Redo user = "root"
    -TRACE  | | | Redo user = last.Value[0]
    -TRACE  | | | Redo last = stage_users[__local538__]
    -TRACE  | | | Redo minus(len, 1, __local538__)
    -TRACE  | | | Redo len = __local537__
    -TRACE  | | | Redo count(stage_users, __local537__)
    -TRACE  | | | Redo stage_users = data.lib.docker.stage_user[_]
    -TRACE  | | Eval msg = "Last USER command in Dockerfile should not be 'root'"
    -TRACE  | | Eval data.lib.docker.result(msg, cmd, __local540__)
    -TRACE  | | Index data.lib.docker.result (matched 1 rule)
    -TRACE  | | Enter data.lib.docker.result
    -TRACE  | | | Eval object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | | Eval object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Eval object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Eval result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Exit data.lib.docker.result
    -TRACE  | | Eval res = __local540__
    -TRACE  | | Exit data.builtin.dockerfile.DS002.deny
    -TRACE  | Redo data.builtin.dockerfile.DS002.deny
    -TRACE  | | Redo res = __local540__
    -TRACE  | | Redo data.lib.docker.result(msg, cmd, __local540__)
    -TRACE  | | Redo data.lib.docker.result
    -TRACE  | | | Redo result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Redo object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Redo object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Redo object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | Redo msg = "Last USER command in Dockerfile should not be 'root'"
    -TRACE  | | Redo cmd = data.builtin.dockerfile.DS002.fail_last_user_root[_]
    -TRACE  | Exit data.builtin.dockerfile.DS002.deny = _
    -TRACE  Redo data.builtin.dockerfile.DS002.deny = _
    -TRACE  | Redo data.builtin.dockerfile.DS002.deny = _
    -TRACE
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/index.html b/test/docs/scanner/misconfiguration/custom/index.html deleted file mode 100644 index c57a0b030402..000000000000 --- a/test/docs/scanner/misconfiguration/custom/index.html +++ /dev/null @@ -1,3466 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Custom Policies

    -

    Overview

    -

    You can write custom policies in Rego. -Once you finish writing custom policies, you can pass the directory where those policies are stored with --policy option.

    -
    trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir
    -
    -

    As for --namespaces option, the detail is described as below.

    -

    File formats

    -

    If a file name matches the following file patterns, Trivy will parse the file and pass it as input to your Rego policy.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    File formatFile pattern
    JSON*.json
    YAML*.yaml and *.yml
    DockerfileDockerfile, Dockerfile.*, and *.Dockerfile
    ContainerfileContainerfile, Containerfile.*, and *.Containerfile
    Terraform*.tf and *.tf.json
    -

    Configuration languages

    -

    In the above general file formats, Trivy automatically identifies the following types of configuration files:

    -
      -
    • CloudFormation (JSON/YAML)
    • -
    • Kubernetes (JSON/YAML)
    • -
    • Helm (YAML)
    • -
    • Terraform Plan (JSON)
    • -
    -

    This is useful for filtering inputs, as described below.

    -

    Rego format

    -

    A single package must contain only one policy.

    -
    -

    Example

    -
    # METADATA
    -# title: Deployment not allowed
    -# description: Deployments are not allowed because of some reasons.
    -# schemas:
    -#   - input: schema["kubernetes"]
    -# custom:
    -#   id: ID001
    -#   severity: LOW
    -#   input:
    -#     selector: 
    -#     - type: kubernetes
    -package user.kubernetes.ID001
    -
    -deny[res] {
    -    input.kind == "Deployment"
    -    msg := sprintf("Found deployment '%s' but deployments are not allowed", [input.metadata.name])
    -    res := result.new(msg, input.kind)
    -}
    -
    -
    -

    In this example, ID001 "Deployment not allowed" is defined under user.kubernetes.ID001. -If you add a new custom policy, it must be defined under a new package like user.kubernetes.ID002.

    -

    Policy structure

    -
    -
    # METADATA (optional)
    -
    -
      -
    • SHOULD be defined for clarity since these values will be displayed in the scan results
    • -
    • custom.input SHOULD be set to indicate the input type the policy should be applied to. See list of available types
    • -
    -
    -
    package (required)
    -
    -
      -
    • MUST follow the Rego's specification
    • -
    • MUST be unique per policy
    • -
    • SHOULD include policy id for uniqueness
    • -
    • MAY include the group name such as kubernetes for clarity
        -
      • Group name has no effect on policy evaluation
      • -
      -
    • -
    -
    -
    deny (required)
    -
    -
      -
    • SHOULD be deny or start with deny_
        -
      • Although warn, warn_*, violation, violation_ also work for compatibility, deny is recommended as severity can be defined in __rego_metadata__.
      • -
      -
    • -
    • SHOULD return ONE OF:
        -
      • The result of a call to result.new(msg, cause). The msg is a string describing the issue occurrence, and the cause is the property/object where the issue occurred. Providing this allows Trivy to ascertain line numbers and highlight code in the output.
      • -
      • A string denoting the detected issue
          -
        • Although object with msg field is accepted, other fields are dropped and string is recommended if result.new() is not utilised.
        • -
        • e.g. {"msg": "deny message", "details": "something"}
        • -
        -
      • -
      -
    • -
    -
    -
    -

    Package

    -

    A package name must be unique per policy.

    -
    -

    Example

    -
    package user.kubernetes.ID001
    -
    -
    -

    By default, only builtin.* packages will be evaluated. -If you define custom packages, you have to specify the package prefix via --namespaces option.

    -
    trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir
    -
    -

    In this case, user.* will be evaluated. -Any package prefixes such as main and user are allowed.

    -

    Metadata

    -

    Metadata helps enrich Trivy's scan results with useful information.

    -

    The annotation format is described in the OPA documentation.

    -

    Trivy supports extra fields in the custom section as described below.

    -
    -

    Example

    -
    # METADATA
    -# title: Deployment not allowed
    -# description: Deployments are not allowed because of some reasons.
    -# custom:
    -#   id: ID001
    -#   severity: LOW
    -#   input:
    -#     selector:
    -#     - type: kubernetes
    -
    -
    -

    All fields are optional. The schemas field should be used to enable policy validation using a built-in schema. The -schema that will be used is based on the input document type. It is recommended to use this to ensure your policies are -correct and do not reference incorrect properties/values.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Field nameAllowed valuesDefault valueIn tableIn JSON
    titleAny charactersN/A
    descriptionAny characters
    schemas.inputschema["kubernetes"], schema["dockerfile"], schema["cloud"](applied to all input types)
    custom.idAny charactersN/A
    custom.severityLOW, MEDIUM, HIGH, CRITICALUNKNOWN
    custom.recommended_actionsAny characters
    custom.input.selector.typeAny item(s) in this list
    urlAny characters
    -

    Some fields are displayed in scan results.

    -
    k.yaml (kubernetes)
    -───────────────────
    -
    -Tests: 32 (SUCCESSES: 31, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -LOW: Found deployment 'my-deployment' but deployments are not allowed
    -════════════════════════════════════════════════════════════════════════
    -Deployments are not allowed because of some reasons.
    -────────────────────────────────────────────────────────────────────────
    - k.yaml:1-2
    -────────────────────────────────────────────────────────────────────────
    -   1 ┌ apiVersion: v1
    -   2 └ kind: Deployment
    -────────────────────────────────────────────────────────────────────────
    -
    -

    Input

    -

    You can specify input format via the custom.input annotation.

    -
    -

    Example

    -
    # METADATA
    -# custom:
    -#   input:
    -#     combine: false
    -#     selector:
    -#     - type: kubernetes
    -
    -
    -
    -
    combine (boolean)
    -
    The details are here.
    -
    selector (array)
    -
    -

    This option filters the input by file format or configuration language. -In the above example, Trivy passes only Kubernetes files to this policy. -Even if a Dockerfile exists in the specified directory, it will not be passed to the policy as input.

    -

    Possible values for input types are: -- dockerfile (Dockerfile) -- kubernetes (Kubernetes YAML/JSON) -- rbac (Kubernetes RBAC YAML/JSON) -- cloud (Cloud format, as defined by defsec - this is used for Terraform, CloudFormation, and Cloud/AWS scanning) -- yaml (Generic YAML) -- json (Generic JSON) -- toml (Generic TOML)

    -

    When configuration languages such as Kubernetes are not identified, file formats such as JSON will be used as type. -When a configuration language is identified, it will overwrite type.

    -
    -

    Example

    -

    pod.yaml including Kubernetes Pod will be handled as kubernetes, not yaml. -type is overwritten by kubernetes from yaml.

    -
    -

    type accepts kubernetes, dockerfile, cloudformation, terraform, terraformplan, json, or yaml.

    -
    -
    -

    Schemas

    -

    See here for the detail.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/schema/index.html b/test/docs/scanner/misconfiguration/custom/schema/index.html deleted file mode 100644 index 546f9045a10a..000000000000 --- a/test/docs/scanner/misconfiguration/custom/schema/index.html +++ /dev/null @@ -1,3148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Schemas - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Input Schema

    -

    Overview

    -

    Policies can be defined with custom schemas that allow inputs to be verified against them. Adding a policy schema -enables Trivy to show more detailed error messages when an invalid input is encountered.

    -

    In Trivy we have been able to define a schema for a Dockerfile. -Without input schemas, a policy would be as follows:

    -
    -

    Example

    -
    # METADATA
    -package mypackage
    -
    -deny {
    -    input.evil == "foo bar"
    -}
    -
    -
    -

    If this policy is run against offending Dockerfile(s), there will not be any issues as the policy will fail to evaluate. -Although the policy's failure to evaluate is legitimate, this should not result in a positive result for the scan.

    -

    For instance if we have a policy that checks for misconfigurations in a Dockerfile, we could define the -schema as such

    -
    -

    Example

    -
    # METADATA
    -# schemas:
    -# - input: schema["dockerfile"]
    -package mypackage
    -
    -deny {
    -    input.evil == "foo bar"
    -}
    -
    -
    -

    Here input: schema["dockerfile"] points to a schema that expects a valid Dockerfile as input. An example of this -can be found here

    -

    Now if this policy is evaluated against, a more descriptive error will be available to help fix the problem.

    -
    1 error occurred: testpolicy.rego:8: rego_type_error: undefined ref: input.evil
    -        input.evil
    -              ^
    -              have: "evil"
    -              want (one of): ["Stages"]
    -
    -

    Currently, out of the box the following schemas are supported natively:

    -
      -
    1. Docker
    2. -
    3. Kubernetes
    4. -
    5. Cloud
    6. -
    -

    Custom Policies with Custom Schemas

    -

    You can also bring a custom policy that defines one or more custom schema.

    -
    -

    Example

    -
    # METADATA
    -# schemas:
    -# - input: schema["fooschema"]
    -# - input: schema["barschema"]
    -package mypackage
    -
    -deny {
    -    input.evil == "foo bar"
    -}
    -
    -
    -

    The policies can be placed in a structure as follows

    -
    -

    Example

    -
    /Users/user/my-custom-policies
    -├── my_policy.rego
    -└── schemas
    -    └── fooschema.json
    -    └── barschema.json
    -
    -
    -

    To use such a policy with Trivy, use the --config-policy flag that points to the directory where the schemas and policies -are contained.

    -
    $ trivy --config-policy=/Users/user/my-custom-policies <path/to/iac>
    -
    -

    For more details on how to define schemas within Rego policies, please see the OPA guide that describes it in more detail.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/selectors/index.html b/test/docs/scanner/misconfiguration/custom/selectors/index.html deleted file mode 100644 index 6b011908eb11..000000000000 --- a/test/docs/scanner/misconfiguration/custom/selectors/index.html +++ /dev/null @@ -1,3162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Selectors - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Input Selectors

    -

    Overview

    -

    Sometimes you might want to limit a certain policy to only be run on certain resources. This can be -achieved with input selectors.

    -

    Use case

    -

    For instance, if you have a custom policy that you only want to be evaluated if a certain resource type is being scanned. -In such a case you could utilize input selectors to limit its evaluation on only those resources.

    -
    -

    Example

    -
        # METADATA
    -    # title: "RDS Publicly Accessible"
    -    # description: "Ensures RDS instances are not launched into the public cloud."
    -    # custom:
    -    #   input:
    -    #     selector:
    -    #     - type: cloud
    -    #       subtypes:
    -    #         - provider: aws
    -    #           service: rds
    -    package builtin.aws.rds.aws0999
    -
    -    deny[res] {
    -    instance := input.aws.rds.instances[_]
    -    instance.publicaccess.value
    -    res := result.new("Instance has Public Access enabled", instance.publicaccess)
    -
    -
    -

    Observe the following subtypes defined: -

            #       subtypes:
    -        #         - provider: aws
    -        #           service: rds
    -

    -

    They will ensure that the policy is only run when the input to such a policy contains an RDS instance.

    -

    Enabling selectors and subtypes

    -

    Currently, the following are supported:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    SelectorSubtype fields requiredExample
    Cloud (AWS, Azure, etc.)provider, serviceprovider: aws, service: rds
    Kubernetestype: kubernetes
    Dockerfiletype: dockerfile
    -

    Default behaviour

    -

    If no subtypes or selectors are specified, the policy will be evaluated regardless of input.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/custom/testing/index.html b/test/docs/scanner/misconfiguration/custom/testing/index.html deleted file mode 100644 index e3c1e119a2ba..000000000000 --- a/test/docs/scanner/misconfiguration/custom/testing/index.html +++ /dev/null @@ -1,3148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Testing - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Testing

    -

    It is highly recommended to write tests for your custom policies.

    -

    Rego testing

    -

    To help you verify the correctness of your custom policies, OPA gives you a framework that you can use to write tests for your policies. -By writing tests for your custom policies you can speed up the development process of new rules and reduce the amount of time it takes to modify rules as requirements evolve.

    -

    For more details, see Policy Testing.

    -
    -

    Example

    -
    package user.dockerfile.ID002
    -
    -test_add_denied {
    -    r := deny with input as {"stages": {"alpine:3.13": [
    -        {"Cmd": "add", "Value": ["/target/resources.tar.gz", "resources.jar"]},
    -        {"Cmd": "add", "Value": ["/target/app.jar", "app.jar"]},
    -    ]}}
    -
    -    count(r) == 1
    -    r[_] == "Consider using 'COPY /target/app.jar app.jar' command instead of 'ADD /target/app.jar app.jar'"
    -}
    -
    -
    -

    To write tests for custom policies, you can refer to existing tests under defsec.

    -

    Go testing

    -

    Fanal which is a core library of Trivy can be imported as a Go library. -You can scan config files in Go and test your custom policies using Go's testing methods, such as table-driven tests. -This allows you to use the actual configuration file as input, making it easy to prepare test data and ensure that your custom policies work in practice.

    -

    In particular, Dockerfile and HCL need to be converted to structural data as input, which may be different from the expected input format.

    -
    -

    Tip

    -

    We recommend writing OPA and Go tests both since they have different roles, like unit tests and integration tests.

    -
    -

    The following example stores allowed and denied configuration files in a directory. -Successes contains the result of successes, and Failures contains the result of failures.

    -
    {
    -    name:  "disallowed ports",
    -    input: "configs/",
    -    fields: fields{
    -        policyPaths: []string{"policy"},
    -        dataPaths:   []string{"data"},
    -        namespaces:  []string{"user"},
    -    },
    -    want: []types.Misconfiguration{
    -        {
    -            FileType: types.Dockerfile,
    -            FilePath: "Dockerfile.allowed",
    -            Successes: types.MisconfResults{
    -                {
    -                    Namespace: "user.dockerfile.ID002",
    -                    PolicyMetadata: types.PolicyMetadata{
    -                        ID:          "ID002",
    -                        Type:        "Docker Custom Check",
    -                        Title:       "Disallowed ports exposed",
    -                        Severity:    "HIGH",
    -                    },
    -                },
    -            },
    -        },
    -        {
    -            FileType: types.Dockerfile,
    -            FilePath: "Dockerfile.denied",
    -            Failures: types.MisconfResults{
    -                {
    -                    Namespace: "user.dockerfile.ID002",
    -                    Message:   "Port 23 should not be exposed",
    -                    PolicyMetadata: types.PolicyMetadata{
    -                        ID:          "ID002",
    -                        Type:        "Docker Custom Check",
    -                        Title:       "Disallowed ports exposed",
    -                        Severity:    "HIGH",
    -                    },
    -                },
    -            },
    -        },
    -    },
    -},
    -
    -

    Dockerfile.allowed has one successful result in Successes, while Dockerfile.denied has one failure result in Failures.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/index.html b/test/docs/scanner/misconfiguration/index.html deleted file mode 100644 index 965d0d1162e3..000000000000 --- a/test/docs/scanner/misconfiguration/index.html +++ /dev/null @@ -1,3580 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Misconfiguration Scanning

    -

    Trivy provides built-in policies to detect configuration issues in popular Infrastructure as Code files, such as: Docker, Kubernetes, Terraform, CloudFormation, and more. -In addition to built-in policies, you can write your own custom policies, as you can see here.

    -

    Quick start

    -

    Simply specify a directory containing IaC files such as Terraform, CloudFormation, Azure ARM templates, Helm Charts and Dockerfile.

    -
    $ trivy config [YOUR_IaC_DIRECTORY]
    -
    -
    -

    Example

    -
    $ ls build/
    -Dockerfile
    -$ trivy config ./build
    -2022-05-16T13:29:29.952+0100    INFO    Detected config files: 1
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine'
    -══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.
    -
    -See https://avd.aquasec.com/misconfig/ds001
    -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -Dockerfile:1
    -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -1 [ FROM alpine:latest
    -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -

    You can also enable misconfiguration detection in container image, filesystem and git repository scanning via --scanners config.

    -
    $ trivy image --scanners config IMAGE_NAME
    -
    -
    $ trivy fs --scanners config /path/to/dir
    -
    -
    -

    Note

    -

    Misconfiguration detection is not enabled by default in image, fs and repo subcommands.

    -
    -

    Unlike the config subcommand, image, fs and repo subcommands can also scan for vulnerabilities and secrets at the same time. -You can specify --scanners vuln,config,secret to enable vulnerability and secret detection as well as misconfiguration detection.

    -
    -

    Example

    -
    $ ls myapp/
    -Dockerfile Pipfile.lock
    -$ trivy fs --scanners vuln,config,secret --severity HIGH,CRITICAL myapp/
    -2022-05-16T13:42:21.440+0100    INFO    Number of language-specific files: 1
    -2022-05-16T13:42:21.440+0100    INFO    Detecting pipenv vulnerabilities...
    -2022-05-16T13:42:21.440+0100    INFO    Detected config files: 1
    -
    -Pipfile.lock (pipenv)
    -=====================
    -Total: 1 (HIGH: 1, CRITICAL: 0)
    -
    -┌──────────┬────────────────┬──────────┬───────────────────┬───────────────┬───────────────────────────────────────────────────────────┐
    -│ Library  │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                           Title                           │
    -├──────────┼────────────────┼──────────┼───────────────────┼───────────────┼───────────────────────────────────────────────────────────┤
    -│ httplib2 │ CVE-2021-21240 │ HIGH     │ 0.12.1            │ 0.19.0        │ python-httplib2: Regular expression denial of service via │
    -│          │                │          │                   │               │ malicious header                                          │
    -│          │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-21240                │
    -└──────────┴────────────────┴──────────┴───────────────────┴───────────────┴───────────────────────────────────────────────────────────┘
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 17 (SUCCESSES: 16, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Last USER command in Dockerfile should not be 'root'
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -Dockerfile:3
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -3 [ USER root
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -

    In the above example, Trivy detected vulnerabilities of Python dependencies and misconfigurations in Dockerfile.

    -

    Type detection

    -

    The specified directory can contain mixed types of IaC files. -Trivy automatically detects config types and applies relevant policies.

    -

    For example, the following example holds IaC files for Terraform, CloudFormation, Kubernetes, Helm Charts, and Dockerfile in the same directory.

    -
    $ ls iac/
    -Dockerfile  deployment.yaml  main.tf mysql-8.8.26.tar
    -$ trivy conf --severity HIGH,CRITICAL ./iac
    -
    -
    -Result - -
    2022-06-06T11:01:21.142+0100    INFO    Detected config files: 8
    -
    -Dockerfile (dockerfile)
    -
    -Tests: 21 (SUCCESSES: 20, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -deployment.yaml (kubernetes)
    -
    -Tests: 20 (SUCCESSES: 15, FAILURES: 5, EXCEPTIONS: 0)
    -Failures: 5 (MEDIUM: 4, HIGH: 1, CRITICAL: 0)
    -
    -MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.allowPrivilegeEscalation' to false
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.
    -
    -See https://avd.aquasec.com/misconfig/ksv001
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:16-19
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  16 ┌       - name: hello-kubernetes
    -  17 │         image: hello-kubernetes:1.5
    -  18 │         ports:
    -  19 └         - containerPort: 8080
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -HIGH: Deployment 'hello-kubernetes' should not specify '/var/run/docker.socker' in 'spec.template.volumes.hostPath.path'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Mounting docker.sock from the host can give the container full root access to the host.
    -
    -See https://avd.aquasec.com/misconfig/ksv006
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:6-29
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   6 ┌   replicas: 3
    -   7 │   selector:
    -   8 │     matchLabels:
    -   9 │       app: hello-kubernetes
    -  10 │   template:
    -  11 │     metadata:
    -  12 │       labels:
    -  13 │         app: hello-kubernetes
    -  14 └     spec:
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.runAsNonRoot' to true
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.
    -
    -See https://avd.aquasec.com/misconfig/ksv012
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:16-19
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  16 ┌       - name: hello-kubernetes
    -  17 │         image: hello-kubernetes:1.5
    -  18 │         ports:
    -  19 └         - containerPort: 8080
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Deployment 'hello-kubernetes' should not set 'spec.template.volumes.hostPath'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -HostPath volumes must be forbidden.
    -
    -See https://avd.aquasec.com/misconfig/ksv023
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:6-29
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   6 ┌   replicas: 3
    -   7 │   selector:
    -   8 │     matchLabels:
    -   9 │       app: hello-kubernetes
    -  10 │   template:
    -  11 │     metadata:
    -  12 │       labels:
    -  13 │         app: hello-kubernetes
    -  14 └     spec:
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Deployment 'hello-kubernetes' should set 'securityContext.sysctl' to the allowed values
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed 'safe' subset. A sysctl is considered safe if it is namespaced in the container or the Pod, and it is isolated from other Pods or processes on the same Node.
    -
    -See https://avd.aquasec.com/misconfig/ksv026
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:6-29
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   6 ┌   replicas: 3
    -   7 │   selector:
    -   8 │     matchLabels:
    -   9 │       app: hello-kubernetes
    -  10 │   template:
    -  11 │     metadata:
    -  12 │       labels:
    -  13 │         app: hello-kubernetes
    -  14 └     spec:
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -mysql-8.8.26.tar:templates/primary/statefulset.yaml (helm)
    -
    -Tests: 20 (SUCCESSES: 18, FAILURES: 2, EXCEPTIONS: 0)
    -Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0)
    -
    -MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.allowPrivilegeEscalation' to false
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.
    -
    -See https://avd.aquasec.com/misconfig/ksv001
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  56 ┌         - name: mysql
    -  57 │           image: docker.io/bitnami/mysql:8.0.28-debian-10-r23
    -  58 │           imagePullPolicy: "IfNotPresent"
    -  59 │           securityContext:
    -  60 │             runAsUser: 1001
    -  61 │           env:
    -  62 │             - name: BITNAMI_DEBUG
    -  63 │               value: "false"
    -  64 └             - name: MYSQL_ROOT_PASSWORD
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.runAsNonRoot' to true
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.
    -
    -See https://avd.aquasec.com/misconfig/ksv012
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  56 ┌         - name: mysql
    -  57 │           image: docker.io/bitnami/mysql:8.0.28-debian-10-r23
    -  58 │           imagePullPolicy: "IfNotPresent"
    -  59 │           securityContext:
    -  60 │             runAsUser: 1001
    -  61 │           env:
    -  62 │             - name: BITNAMI_DEBUG
    -  63 │               value: "false"
    -  64 └             - name: MYSQL_ROOT_PASSWORD
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    - -
    - -

    You can see the config type next to each file name.

    -
    -

    Example

    -
    -
    Dockerfile (dockerfile)
    -=======================
    -Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
    -Failures: 1 (HIGH: 1, CRITICAL: 0)
    -
    -...
    -
    -deployment.yaml (kubernetes)
    -============================
    -Tests: 28 (SUCCESSES: 15, FAILURES: 13, EXCEPTIONS: 0)
    -Failures: 13 (MEDIUM: 4, HIGH: 1, CRITICAL: 0)
    -
    -...
    -
    -main.tf (terraform)
    -===================
    -Tests: 23 (SUCCESSES: 14, FAILURES: 9, EXCEPTIONS: 0)
    -Failures: 9 (HIGH: 6, CRITICAL: 1)
    -
    -...
    -
    -bucket.yaml (cloudformation)
    -============================
    -Tests: 9 (SUCCESSES: 3, FAILURES: 6, EXCEPTIONS: 0)
    -Failures: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 4, CRITICAL: 0)
    -
    -...
    -
    -mysql-8.8.26.tar:templates/primary/statefulset.yaml (helm)
    -==========================================================
    -Tests: 20 (SUCCESSES: 18, FAILURES: 2, EXCEPTIONS: 0)
    -Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0)
    -
    -

    Configuration

    -

    This section describes misconfiguration-specific configuration. -Other common options are documented here.

    -

    Pass custom policies

    -

    You can pass directories including your custom policies through --policy option. -This can be repeated for specifying multiple directories.

    -
    cd examplex/misconf/
    -trivy conf --policy custom-policy/policy --policy combine/policy --namespaces user misconf/mixed
    -
    -

    For more details, see Custom Policies.

    -
    -

    Tip

    -
    -

    You also need to specify --namespaces option.

    -

    Pass custom data

    -

    You can pass directories including your custom data through --data option. -This can be repeated for specifying multiple directories.

    -
    cd examples/misconf/custom-data
    -trivy conf --policy ./policy --data ./data --namespaces user ./configs
    -
    -

    For more details, see Custom Data.

    -

    Pass namespaces

    -

    By default, Trivy evaluates policies defined in builtin.*. -If you want to evaluate custom policies in other packages, you have to specify package prefixes through --namespaces option. -This can be repeated for specifying multiple packages.

    -
    trivy conf --policy ./policy --namespaces main --namespaces user ./configs
    -
    -

    Terraform value overrides

    -

    You can pass tf-vars files to Trivy to override default values found in the Terraform HCL code.

    -
    trivy conf --tf-vars dev.terraform.tfvars ./infrastructure/tf
    -
    -

    Helm value overrides

    -

    There are a number of options for overriding values in Helm charts. When override values are passed to the Helm scanner, the values will be used during the Manifest rendering process and will become part of the scanned artifact.

    -

    Setting inline value overrides

    -

    Overrides can be set inline on the command line

    -
    trivy conf --helm-set securityContext.runAsUser=0 ./charts/mySql
    -
    -

    Setting value file overrides

    -

    Overrides can be in a file that has the key=value set.

    -
    # Example override file (overrides.yaml)
    -
    -securityContext:
    -  runAsUser: 0
    -
    -
    trivy conf --helm-values overrides.yaml ./charts/mySql
    -
    -

    Setting value as explicit string

    -

    the --helm-set-string is the same as --helm-set but explicitly retains the value as a string

    -
    trivy config --helm-set-string name=false ./infrastructure/tf
    -
    -

    Setting specific values from files

    -

    Specific override values can come from specific files

    -
    trivy conf --helm-set-file environment=dev.values.yaml ./charts/mySql
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/policy/builtin/index.html b/test/docs/scanner/misconfiguration/policy/builtin/index.html deleted file mode 100644 index 5e893191df06..000000000000 --- a/test/docs/scanner/misconfiguration/policy/builtin/index.html +++ /dev/null @@ -1,3132 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Built-in Policies - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Built-in Policies

    -

    Policy Sources

    -

    Built-in policies are mainly written in Rego and Go. -Those policies are managed under defsec repository.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Config typeSource
    Kubernetesdefsec
    Dockerfile, Containerfiledefsec
    Terraformdefsec
    CloudFormationdefsec
    Azure ARM Templatedefsec
    Helm Chartdefsec
    -

    For suggestions or issues regarding policy content, please open an issue under the defsec repository.

    -

    Helm Chart scanning will resolve the chart to Kubernetes manifests then run the kubernetes checks.

    -

    Policy Distribution

    -

    defsec policies are distributed as an OPA bundle on GitHub Container Registry (GHCR). -When misconfiguration detection is enabled, Trivy pulls the OPA bundle from GHCR as an OCI artifact and stores it in the cache. -Those policies are then loaded into Trivy OPA engine and used for detecting misconfigurations. -If Trivy is unable to pull down newer policies, it will use the embedded set of policies as a fallback. This is also the case in air-gap environments where --skip-policy-update might be passed.

    -

    Update Interval

    -

    Trivy checks for updates to OPA bundle on GHCR every 24 hours and pulls it if there are any updates.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/misconfiguration/policy/exceptions/index.html b/test/docs/scanner/misconfiguration/policy/exceptions/index.html deleted file mode 100644 index 22a7e284bb30..000000000000 --- a/test/docs/scanner/misconfiguration/policy/exceptions/index.html +++ /dev/null @@ -1,3150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Exceptions - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Exceptions

    -

    Exceptions let you specify cases where you allow policy violations. -Trivy supports two types of exceptions.

    -
    -

    Info

    -

    Exceptions can be applied to built-in policies as well as custom policies.

    -
    -

    Namespace-based exceptions

    -

    There are some cases where you need to disable built-in policies partially or fully. -Namespace-based exceptions lets you rough choose which individual packages to exempt.

    -

    To use namespace-based exceptions, create a Rego rule with the name exception that returns the package names to exempt. -The exception rule must be defined under namespace.exceptions. -data.namespaces includes all package names.

    -
    -

    Example

    -
    package namespace.exceptions
    -
    -import data.namespaces
    -
    -exception[ns] {
    -    ns := data.namespaces[_]
    -    startswith(ns, "builtin.kubernetes")
    -}
    -
    -
    -

    This example exempts all built-in policies for Kubernetes.

    -

    For more details, see an example.

    -

    Rule-based exceptions

    -

    There are some cases where you need more flexibility and granularity in defining which cases to exempt. -Rule-based exceptions lets you granularly choose which individual rules to exempt, while also declaring under which conditions to exempt them.

    -

    To use rule-based exceptions, create a Rego rule with the name exception that returns the rule name suffixes to exempt, prefixed by deny_ (for example, returning foo will exempt deny_foo). -The rule can make any other assertion, for example, on the input or data documents. -This is useful to specify the exemption for a specific case.

    -

    Note that if you specify the empty string, the exception will match all rules named deny.

    -
    exception[rules] {
    -    # Logic
    -
    -    rules = ["foo","bar"]
    -}
    -
    -

    The above would provide an exception from deny_foo and deny_bar.

    -
    -

    Example

    -
    package user.kubernetes.ID100
    -
    -__rego_metadata := {
    -    "id": "ID100",
    -    "title": "Deployment not allowed",
    -    "severity": "HIGH",
    -    "type": "Kubernetes Custom Check",
    -}
    -
    -deny_deployment[msg] {
    -    input.kind == "Deployment"
    -    msg = sprintf("Found deployment '%s' but deployments are not allowed", [name])
    -}
    -
    -exception[rules] {
    -    input.kind == "Deployment"
    -    input.metadata.name == "allow-deployment"
    -
    -    rules := ["deployment"]
    -}
    -
    -
    -

    If you want to apply rule-based exceptions to built-in policies, you have to define the exception under the same package.

    -
    -

    Example

    -
    package builtin.kubernetes.KSV012
    -
    -exception[rules] {
    -    input.metadata.name == "can-run-as-root"
    -    rules := [""]
    -}
    -
    -
    -

    This exception is applied to KSV012 in defsec. -You can get the package names in the defsec repository or the JSON output from Trivy.

    -

    For more details, see an example.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/secret/index.html b/test/docs/scanner/secret/index.html deleted file mode 100644 index 19bbb4976805..000000000000 --- a/test/docs/scanner/secret/index.html +++ /dev/null @@ -1,3521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Secret - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Secret Scanning

    -

    Trivy scans any container image, filesystem and git repository to detect exposed secrets like passwords, api keys, and tokens. -Secret scanning is enabled by default.

    -

    Trivy will scan every plaintext file, according to builtin rules or configuration. There are plenty of builtin rules:

    -
      -
    • AWS access key
    • -
    • GCP service account
    • -
    • GitHub personal access token
    • -
    • GitLab personal access token
    • -
    • Slack access token
    • -
    • etc.
    • -
    -

    You can see a full list of built-in rules and built-in allow rules.

    -
    -

    Tip

    -

    If your secret is not detected properly, please make sure that your file including the secret is not in the allowed paths. -You can disable allow rules via disable-allow-rules.

    -
    -

    Quick start

    -

    This section shows how to scan secrets in container image and filesystem. Other subcommands should be the same.

    -

    Container image

    -

    Specify an image name.

    -
    $ trivy image myimage:1.0.0
    -2022-04-21T18:56:44.099+0300    INFO    Detected OS: alpine
    -2022-04-21T18:56:44.099+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-04-21T18:56:44.101+0300    INFO    Number of language-specific files: 0
    -
    -myimage:1.0.0 (alpine 3.15.0)
    -=============================
    -Total: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| busybox      | CVE-2022-28391   | CRITICAL | 1.34.1-r3         | 1.34.1-r5     | CVE-2022-28391 affecting              |
    -|              |                  |          |                   |               | package busybox 1.35.0                |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-28391 |
    -+--------------+------------------|          |-------------------+---------------+---------------------------------------+
    -| ssl_client   | CVE-2022-28391   |          | 1.34.1-r3         | 1.34.1-r5     | CVE-2022-28391 affecting              |
    -|              |                  |          |                   |               | package busybox 1.35.0                |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-28391 |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -
    -app/secret.sh (secrets)
    -=======================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
    -
    -+----------+-------------------+----------+---------+--------------------------------+
    -| CATEGORY |    DESCRIPTION    | SEVERITY | LINE NO |             MATCH              |
    -+----------+-------------------+----------+---------+--------------------------------+
    -|   AWS    | AWS Access Key ID | CRITICAL |   10    | export AWS_ACCESS_KEY_ID=***** |
    -+----------+-------------------+----------+---------+--------------------------------+
    -
    -
    -

    Tip

    -

    Trivy tries to detect a base image and skip those layers for secret scanning. -A base image usually contains a lot of files and makes secret scanning much slower. -If a secret is not detected properly, you can see base layers with the --debug flag.

    -
    -

    Filesystem

    -
    $ trivy fs /path/to/your_project
    -...(snip)...
    -
    -certs/key.pem (secrets)
    -========================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -+----------------------+------------------------+----------+---------+---------------------------------+
    -|       CATEGORY       |      DESCRIPTION       | SEVERITY | LINE NO |              MATCH              |
    -+----------------------+------------------------+----------+---------+---------------------------------+
    -| AsymmetricPrivateKey | Asymmetric Private Key |   HIGH   |    1    | -----BEGIN RSA PRIVATE KEY----- |
    -+----------------------+------------------------+----------+---------+---------------------------------+
    -
    -
    -

    Tip

    -

    Your project may have some secrets for testing. You can skip them with --skip-dirs or --skip-files. -We would recommend specifying these options so that the secret scanning can be faster if those files don't need to be scanned. -Also, you can specify paths to be allowed in a configuration file. See the detail here.

    -
    -

    Configuration

    -

    This section describes secret-specific configuration. -Other common options are documented here.

    -

    Trivy has a set of builtin rules for secret scanning, which can be extended or modified by a configuration file. -Trivy tries to load trivy-secret.yaml in the current directory by default. -If the file doesn't exist, only built-in rules are used. -You can customize the config file path via the --secret-config flag.

    -

    Custom Rules

    -

    Trivy allows defining custom rules.

    -
    rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    path: .*\.sh
    -    keywords:
    -      - secret
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -    secret-group-name: secret
    -    allow-rules:
    -      - id: skip-text
    -        description: skip text files
    -        path: .*\.txt
    -
    -
    -
    id (required)
    -
    -
      -
    • Unique identifier for this rule.
    • -
    -
    -
    category (required)
    -
    -
      -
    • String used for metadata and reporting purposes.
    • -
    -
    -
    title (required)
    -
    -
      -
    • Short human-readable title of the rule.
    • -
    -
    -
    severity (required)
    -
    -
      -
    • How critical this rule is.
    • -
    • Allowed values:
    • -
    • CRITICAL
    • -
    • HIGH
    • -
    • MEDIUM
    • -
    • LOW
    • -
    -
    -
    regex (required)
    -
    -
      -
    • Golang regular expression used to detect secrets.
    • -
    -
    -
    path (optional)
    -
    -
      -
    • Golang regular expression used to match paths.
    • -
    -
    -
    keywords (optional, recommended)
    -
    -
      -
    • Keywords are used for pre-regex check filtering.
    • -
    • Rules that contain keywords will perform a quick string compare check to make sure the keyword(s) are in the content being scanned.
    • -
    • Ideally these values should either be part of the identifier or unique strings specific to the rule's regex.
    • -
    • It is recommended to define for better performance.
    • -
    -
    -
    allow-rules (optional)
    -
    -
      -
    • Allow rules for a single rule to reduce false positives with known secrets.
    • -
    • The details are below.
    • -
    -
    -
    -

    Allow Rules

    -

    If the detected secret is matched with the specified regex, then that secret will be skipped and not detected. -The same logic applies for path.

    -

    allow-rules can be defined globally and per each rule. The fields are the same.

    -
    rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -    allow-rules:
    -      - id: skip-text
    -        description: skip text files
    -        path: .*\.txt
    -allow-rules:
    -  - id: social-security-number
    -    description: skip social security number
    -    regex: 219-09-9999
    -
    -
    -
    id (required)
    -
    -
      -
    • Unique identifier for this allow rule.
    • -
    -
    -
    description (optional)
    -
    -
      -
    • Short human-readable description of this allow rule.
    • -
    -
    -
    regex (optional)
    -
    -
      -
    • Golang regular expression used to allow detected secrets.
    • -
    • regex or path must be specified.
    • -
    -
    -
    path (optional)
    -
    -
      -
    • Golang regular expression used to allow matched paths.
    • -
    • regex or path must be specified.
    • -
    -
    -
    -

    Enable Rules

    -

    Trivy provides plenty of out-of-box rules and allow rules, but you may not need all of them. -In that case, enable-builtin-rules will be helpful. -If you just need AWS secret detection, you can enable only relevant rules as shown below. -It specifies AWS-related rule IDs in enable-builtin-rules. -All other rules are disabled, so the scanning will be much faster. -We would strongly recommend using this option if you don't need all rules.

    -

    You can see a full list of built-in rule IDs and built-in allow rule IDs.

    -
    enable-builtin-rules:
    -  - aws-access-key-id
    -  - aws-account-id
    -  - aws-secret-access-key
    -
    -

    Disable Rules

    -

    Trivy offers built-in rules and allow rules, but you may want to disable some of them. -For example, you don't use Slack, so Slack doesn't have to be scanned. -You can specify the Slack rule IDs, slack-access-token and slack-web-hook in disable-rules so that those rules will be disabled for less false positives.

    -

    You should specify either enable-builtin-rules or disable-rules. -If they both are specified, disable-rules takes precedence. -In case github-pat is specified in enable-builtin-rules and disable-rules, it will be disabled.

    -

    In addition, there are some allow rules. -Markdown files are ignored by default, but you may want to scan markdown files as well. -You can disable the allow rule by adding markdown to disable-allow-rules.

    -

    You can see a full list of built-in rule IDs and built-in allow rule IDs.

    -
    disable-rules:
    -  - slack-access-token
    -  - slack-web-hook
    -disable-allow-rules:
    -  - markdown
    -
    -

    Recommendation

    -

    We would recommend specifying --skip-dirs for faster secret scanning. -In container image scanning, Trivy walks the file tree rooted / and scans all the files other than built-in allowed paths. -It will take a while if your image contains a lot of files even though Trivy tries to avoid scanning layers from a base image. -If you want to make scanning faster, --skip-dirs and --skip-files helps so that Trivy will skip scanning those files and directories. -You can see more options here.

    -

    allow-rules is also helpful. See the allow-rules section.

    -

    In addition, all the built-in rules are enabled by default, so it takes some time to scan all of them. -If you don't need all those rules, you can use enable-builtin-rules or disable-rules in the configuration file. -You should use enable-builtin-rules if you need only AWS secret detection, for example. -All rules are disabled except for the ones you specify, so it runs very fast. -On the other hand, you should use disable-rules if you just want to disable some built-in rules. -See the enable-rules and disable-rules sections for the detail.

    -

    If you don't need secret scanning, you can disable it via the --scanners flag.

    -
    $ trivy image --scanners vuln alpine:3.15
    -
    -

    Example

    -

    trivy-secret.yaml in the working directory is loaded by default.

    -
    $ cat trivy-secret.yaml
    -rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -allow-rules:
    -  - id: social-security-number
    -    description: skip social security number
    -    regex: 219-09-9999
    -  - id: log-dir
    -    description: skip log directory
    -    path: ^\/var\/log\/
    -disable-rules:
    -  - slack-access-token
    -  - slack-web-hook
    -disable-allow-rules:
    -  - markdown
    -
    -# The following command automatically loads the above configuration.
    -$ trivy image YOUR_IMAGE
    -
    -

    Also, you can customize the config file path via --secret-config.

    -
    $ cat ./secret-config/trivy.yaml
    -rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -    allow-rules:
    -      - id: skip-text
    -        description: skip text files
    -        path: .*\.txt
    -enable-builtin-rules:
    -  - aws-access-key-id
    -  - aws-account-id
    -  - aws-secret-access-key
    -disable-allow-rules:
    -  - usr-dirs
    -
    -# Pass the above config with `--secret-config`.
    -$ trivy fs --secret-config ./secret-config/trivy.yaml /path/to/your_project
    -
    -

    Credit

    -

    This feature is inspired by gitleaks.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/index.html b/test/docs/scanner/vulnerability/index.html deleted file mode 100644 index 0638e20cd4cb..000000000000 --- a/test/docs/scanner/vulnerability/index.html +++ /dev/null @@ -1,3200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Vulnerability Scanning

    -

    Overview

    -

    This section describes the overview of vulnerability scanning. -Trivy detects known vulnerabilities according to the versions of installed packages.

    -

    The following packages are supported.

    - -

    Trivy downloads the vulnerabillity database every 6 hours.

    -

    Database

    -

    Trivy uses two types of databases for vulnerability detection:

    -
      -
    • Vulnerability Database
    • -
    • Java Index Database
    • -
    -

    This page provides detailed information about these databases.

    -

    Vulnerability Database

    -

    Trivy utilizes a database containing vulnerability information. -This database is built every six hours on GitHub and is distributed via GitHub Container registry (GHCR). -The database is cached and updated as needed. -As Trivy updates the database automatically during execution, users don't need to be concerned about it.

    -

    For CLI flags related to the database, please refer to this page.

    -

    Private Hosting

    -

    If you host the database on your own OCI registry, you can specify a different repository with the --db-repository flag. -The default is ghcr.io/aquasecurity/trivy-db.

    -
    $ trivy image --db-repository YOUR_REPO YOUR_IMAGE
    -
    -

    If authentication is required, it can be configured in the same way as for private images. -Please refer to the documentation for more details.

    -

    Java Index Database

    -

    This database is only downloaded when scanning JAR files so that Trivy can identify the groupId, artifactId, and version of JAR files. -It is built once a day on GitHub and distributed via GitHub Container registry (GHCR). -Like the vulnerability database, it is automatically downloaded and updated when needed, so users don't need to worry about it.

    -

    Private Hosting

    -

    If you host the database on your own OCI registry, you can specify a different repository with the --java-db-repository flag. -The default is ghcr.io/aquasecurity/trivy-java-db.

    -

    If authentication is required, you need to run docker login YOUR_REGISTRY. -Currently, specifying a username and password is not supported.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/golang/index.html b/test/docs/scanner/vulnerability/language/golang/index.html deleted file mode 100644 index 64ac8a54dc47..000000000000 --- a/test/docs/scanner/vulnerability/language/golang/index.html +++ /dev/null @@ -1,3198 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Go - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Go

    -

    Features

    -

    Trivy supports two types of Go scanning, Go Modules and binaries built by Go. -The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactOffline1Dev dependenciesLicenseDependency graph
    ModulesInclude22
    BinariesExclude--
    -
    -

    Note

    -

    Trivy scans only dependencies of the Go project. -Let's say you scan the Docker binary, Trivy doesn't detect vulnerabilities of Docker itself. -Also, when you scan go.mod in Kubernetes, the Kubernetes vulnerabilities will not be found.

    -
    -

    Go Modules

    -

    Depending on Go versions, the required files are different.

    - - - - - - - - - - - - - - - - - - - - -
    VersionRequired filesOffline
    >=1.17go.mod
    <1.17go.mod, go.sum
    -

    In Go 1.17+ projects, Trivy uses go.mod for direct/indirect dependencies. -On the other hand, it uses go.mod for direct dependencies and go.sum for indirect dependencies in Go 1.16 or less.

    -

    Go 1.17+ holds actually needed indirect dependencies in go.mod, and it reduces false detection. -go.sum in Go 1.16 or less contains all indirect dependencies that are even not needed for compiling. -If you want to have better detection, please consider updating the Go version in your project.

    -
    -

    Note

    -

    The Go version doesn't mean your CLI version, but the Go version in your go.mod.

    -
    module github.com/aquasecurity/trivy
    -
    -go 1.18
    -
    -require (
    -        github.com/CycloneDX/cyclonedx-go v0.5.0
    -        ...
    -)
    -
    -

    To update the Go version in your project, you need to run the following command.

    -
    $ go mod tidy -go=1.18
    -
    -
    -

    To identify licenses and dependency relationships, you need to download modules to local cache beforehand, -such as go mod download, go mod tidy, etc. -Trivy traverses $GOPATH/pkg/mod and collects those extra information.

    -

    Go binaries

    -

    Trivy scans binaries built by Go. -If there is a Go binary in your container image, Trivy automatically finds and scans it.

    -

    Also, you can scan your local binaries.

    -
    $ trivy fs ./your_binary
    -
    -
    -
    -
      -
    1. -

      It doesn't require the Internet access. 

      -
    2. -
    3. -

      Need to download modules to local cache beforehand 

      -
    4. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/index.html b/test/docs/scanner/vulnerability/language/index.html deleted file mode 100644 index fe27795d6acf..000000000000 --- a/test/docs/scanner/vulnerability/language/index.html +++ /dev/null @@ -1,3501 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Language-specific Packages

    -

    Trivy automatically detects the following files and scans vulnerabilities in the application dependencies.

    -

    Supported languages

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LanguageFileImage7Rootfs8Filesystem9Repository10Dev dependenciesDependency location11
    RubyGemfile.lock--included-
    gemspec--included-
    PythonPipfile.lock--excluded
    poetry.lock--excluded-
    requirements.txt--included-
    egg package1--excluded-
    wheel package2--excluded-
    PHPcomposer.lockexcluded
    Node.jspackage-lock.json--excluded
    yarn.lock--included
    pnpm-lock.yaml--excluded-
    package.json--excluded-
    .NETpackages.lock.jsonincluded
    packages.configexcluded-
    .deps.jsonexcluded
    JavaJAR/WAR/PAR/EAR3--included-
    pom.xml4--excluded-
    *gradle.lockfile--excluded-
    GoBinaries built by Go5--excluded-
    go.mod6--included-
    RustCargo.lockexcluded
    Binaries built with cargo-auditable--excluded-
    C/C++conan.lock12--excluded-
    Elixirmix.lock12--excluded
    Dartpubspec.lock--included-
    -

    The path of these files does not matter.

    -

    Example: Dockerfile

    -

    Data Sources

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LanguageSourceCommercial UseDelay1
    PHPPHP Security Advisories Database-
    GitHub Advisory Database (Composer)-
    PythonGitHub Advisory Database (pip)-
    Open Source Vulnerabilities (PyPI)-
    RubyRuby Advisory Database-
    GitHub Advisory Database (RubyGems)-
    Node.jsEcosystem Security Working Group-
    GitHub Advisory Database (npm)-
    JavaGitLab Advisories Community1 month
    GitHub Advisory Database (Maven)-
    GoGitLab Advisories Community1 month
    The Go Vulnerability Database-
    RustOpen Source Vulnerabilities (crates.io)-
    .NETGitHub Advisory Database (NuGet)-
    C/C++GitLab Advisories Community1 month
    DartGitHub Advisory Database (Pub)-
    ElixirGitHub Advisory Database (Erlang)
    -
    -
    -
      -
    1. -

      Intentional delay between vulnerability disclosure and registration in the DB 

      -
    2. -
    3. -

      .dist-info/META-DATA 

      -
    4. -
    5. -

      *.jar, *.war, *.par and *.ear 

      -
    6. -
    7. -

      It requires Internet access when the POM doesn't exist in your local repository 

      -
    8. -
    9. -

      UPX-compressed binaries don't work 

      -
    10. -
    11. -

      If smaller than go 1.17, go.sum is also required 

      -
    12. -
    13. -

      ✅ means "enabled" and - means "disabled" in the image scanning 

      -
    14. -
    15. -

      ✅ means "enabled" and - means "disabled" in the rootfs scanning 

      -
    16. -
    17. -

      ✅ means "enabled" and - means "disabled" in the filesystem scanning 

      -
    18. -
    19. -

      ✅ means "enabled" and - means "disabled" in the git repository scanning 

      -
    20. -
    21. -

      ✅ means that Trivy detects line numbers where each dependency is declared in the scanned file. Only supported in json and sarif formats. SARIF uses startline == 1 and endline == 1 for unsupported file types 

      -
    22. -
    23. -

      To scan a filename other than the default filename use file-patterns 

      -
    24. -
    25. -

      When you scan Cargo.lock and Cargo.toml together. See about it here

      -
    26. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/java/index.html b/test/docs/scanner/vulnerability/language/java/index.html deleted file mode 100644 index d5f7b8a4a9a0..000000000000 --- a/test/docs/scanner/vulnerability/language/java/index.html +++ /dev/null @@ -1,3175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Java - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Java

    -

    Trivy supports three types of Java scanning: JAR/WAR/PAR/EAR, pom.xml and *gradle.lockfile files. -The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactInternet accessDev dependencies
    JAR/WAR/PAR/EARTrivy Java DBInclude
    pom.xmlMaven repository 1Exclude
    *gradle.lockfile-Exclude
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    JAR/WAR/PAR/EAR

    -

    To find information about your JAR2 file, Trivy parses pom.properties and MANIFEST.MF files in your JAR2 file and takes required properties3.

    -

    If those files don't exist or don't contain enough information - Trivy will try to find this JAR2 file in trivy-java-db. -The Java DB will be automatically downloaded/updated when any JAR2 file is found. -It is stored in the cache directory.

    -
    -

    EXPERIMENTAL

    -

    Finding JARs in trivy-java-db is an experimental function.

    -
    -

    Base JAR2 may contain inner JARs2 within itself. -To find information about these JARs2, the same logic is used as for the base JAR2.

    -

    table format only contains the name of root JAR2 . To get the full path to inner JARs2 use the json format.

    -

    pom.xml

    -

    Trivy parses your pom.xml file and tries to find files with dependencies from these local locations.

    -
      -
    • project directory4
    • -
    • relativePath field5
    • -
    • local repository directory6.
    • -
    -

    If your machine doesn't have the necessary files - Trivy tries to find the information about these dependencies in the maven repository.

    -
    -

    Note

    -

    Trivy only takes information about packages. We don't take a list of vulnerabilities for packages from the maven repository. -Information about data sources for Java you can see here.

    -
    -

    You can disable connecting to the maven repository with the --offline-scan flag. -The --offline-scan flag does not affect the Trivy database. -The vulnerability database will be downloaded anyway.

    -
    -

    Warning

    -

    Trivy may skip some dependencies (that were not found on your local machine) when the --offline-scan flag is passed.

    -
    -

    Gradle.lock

    -

    gradle.lock files contain all necessary information about used dependencies. -Trivy simply parses the file, extract dependencies, and finds vulnerabilities for them. -It doesn't require the internet access.

    -
    -
    -
      -
    1. -

      Uses maven repository to get information about dependencies. Internet access required. 

      -
    2. -
    3. -

      It means *.jar, *.war, *.par and *.ear file 

      -
    4. -
    5. -

      ArtifactID, GroupID and Version 

      -
    6. -
    7. -

      e.g. when parent pom.xml file has ../pom.xml path 

      -
    8. -
    9. -

      When you use dependency path in relativePath field in pom.xml file 

      -
    10. -
    11. -

      /Users/<username>/.m2/repository (for Linux and Mac) and C:/Users/<username>/.m2/repository (for Windows) by default 

      -
    12. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/nodejs/index.html b/test/docs/scanner/vulnerability/language/nodejs/index.html deleted file mode 100644 index 5cabe4e047ac..000000000000 --- a/test/docs/scanner/vulnerability/language/nodejs/index.html +++ /dev/null @@ -1,3237 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Node.js - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Node.js

    -

    Trivy supports three types of Node.js package managers: npm, Yarn and pnpm. -The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPositionLicense
    npmpackage-lock.jsonExcluded
    Yarnyarn.lockExcluded-
    pnpmpnpm-lock.yamlExcluded--
    -

    In addition, Trivy scans installed packages with package.json.

    - - - - - - - - - - - - - - - - - -
    FileDependency graphPositionLicense
    package.json--
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    Package managers

    -

    Trivy parses your files generated by package managers in filesystem/repository scanning.

    -
    -

    Tip

    -

    Please make sure your lock file is up-to-date after modifying package.json.

    -
    -

    npm

    -

    Trivy parses package-lock.json. -To identify licenses, you need to download dependencies to node_modules beforehand. -Trivy analyzes node_modules for licenses.

    -

    Yarn

    -

    Trivy parses yarn.lock, which doesn't contain information about development dependencies. -To exclude devDependencies, package.json also needs to be present next to yarn.lock.

    -

    pnpm

    -

    Trivy parses pnpm-lock.yaml, then finds production dependencies and builds a tree of dependencies with vulnerabilities.

    -

    Packages

    -

    Trivy parses the manifest files of installed packages in container image scanning and so on.

    -

    package.json

    -

    Trivy searches for package.json files under node_modules and identifies installed packages. -It only extracts package names, versions and licenses for those packages.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/php/index.html b/test/docs/scanner/vulnerability/language/php/index.html deleted file mode 100644 index 9512310cb442..000000000000 --- a/test/docs/scanner/vulnerability/language/php/index.html +++ /dev/null @@ -1,3089 +0,0 @@ - - - - - - - - - - - - - - - - - - - - PHP - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    PHP

    -

    Trivy supports Composer, which is a tool for dependency management in PHP. -The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Package ManagerFileTransitive dependenciesDev dependenciesDependency graphPositionLicense
    Composercomposer.lockExcluded
    -

    Composer

    -

    In order to detect dependencies, Trivy searches for composer.lock.

    -

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. -Since this information is not included in composer.lock, Trivy parses composer.json, which should be located next to composer.lock. -If you want to see the dependency tree, please ensure that composer.json is present.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/python/index.html b/test/docs/scanner/vulnerability/language/python/index.html deleted file mode 100644 index 1a31dfbabde3..000000000000 --- a/test/docs/scanner/vulnerability/language/python/index.html +++ /dev/null @@ -1,3271 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Python - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Python

    -

    Trivy supports three types of Python package managers: pip, Pipenv and Poetry. -The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPositionLicense
    piprequirements.txt-Include---
    PipenvPipfile.lockInclude--
    Poetrypoetry.lockExclude-
    -

    In addition, Trivy supports two formats of Python packages: egg and wheel.

    - - - - - - - - - - - - - - - - - -
    PackagingLicense
    Egg
    Wheel
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    Package managers

    -

    Trivy parses your files generated by package managers in filesystem/repository scanning.

    -

    pip

    -

    requirements.txt files usually contain only the direct dependencies and not contain the transitive dependencies. -Therefore, Trivy scans only for the direct dependencies with requirements.txt.

    -

    To detect transitive dependencies as well, you need to generate requirements.txt with pip freeze.

    -
    $ cat requirements.txt # it will only find `requests@2.28.2`.
    -requests==2.28.2 
    -$ pip install -r requirements.txt
    -...
    -
    -$ pip freeze > requirements.txt   
    -$ cat requirements.txt # it will also find the transitive dependencies of `requests@2.28.2`.
    -certifi==2022.12.7
    -charset-normalizer==3.1.0
    -idna==3.4
    -PyJWT==2.1.0
    -requests==2.28.2
    -urllib3==1.26.15
    -
    -

    pip freeze also helps to resolve extras(optional) dependencies (like package[extras]=0.0.0).

    -

    requirements.txt files don't contain information about dependencies used for development. -Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

    -

    License detection is not supported for pip.

    -

    Pipenv

    -

    Trivy parses Pipfile.lock. -Pipfile.lock files don't contain information about dependencies used for development. -Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

    -

    License detection is not supported for Pipenv.

    -

    Poetry

    -

    Trivy uses poetry.lock to identify dependencies and find vulnerabilities. -To build the correct dependency graph, pyproject.toml also needs to be present next to poetry.lock.

    -

    License detection is not supported for Poetry.

    -

    Packaging

    -

    Trivy parses the manifest files of installed packages in container image scanning and so on. -See here for the detail.

    -

    Egg

    -

    Trivy looks for *.egg-info, *.egg-info/PKG-INFO, *.egg and EGG-INFO/PKG-INFO to identify Python packages.

    -

    Wheel

    -

    Trivy looks for .dist-info/META-DATA to identify Python packages.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/language/rust/index.html b/test/docs/scanner/vulnerability/language/rust/index.html deleted file mode 100644 index ad73a292d015..000000000000 --- a/test/docs/scanner/vulnerability/language/rust/index.html +++ /dev/null @@ -1,3165 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Rust - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Rust

    -

    Features

    -

    Trivy supports Cargo, which is the Rust package manager. -The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesLicenseDependency graphPosition
    CargoCargo.lockExcluded1-
    -

    In addition, it supports binaries built with cargo-auditable.

    - - - - - - - - - - - - - - - - - - - - - -
    ArtifactTransitive dependenciesDev dependenciesLicenseDependency graphPosition
    BinariesExcluded---
    -

    Cargo

    -

    Trivy searches for Cargo.lock to detect dependencies.

    -

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. -Since this information is not included in Cargo.lock, Trivy parses Cargo.toml, which should be located next to Cargo.lock. -If you want to see the dependency tree, please ensure that Cargo.toml is present.

    -

    Scan Cargo.lock and Cargo.toml together also removes developer dependencies.

    -

    Binaries

    -

    Trivy scans binaries built with cargo-auditable. -If such a binary exists, Trivy will identify it as being built with cargo-audit and scan it.

    -
    -
    -
      -
    1. -

      When you scan Cargo.lock and Cargo.toml together. 

      -
    2. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/scanner/vulnerability/os/index.html b/test/docs/scanner/vulnerability/os/index.html deleted file mode 100644 index 8a6841348e77..000000000000 --- a/test/docs/scanner/vulnerability/os/index.html +++ /dev/null @@ -1,3463 +0,0 @@ - - - - - - - - - - - - - - - - - - - - OS Packages - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    OS Packages

    -

    Trivy is capable of automatically detecting installed OS packages when scanning container images, VM images and running hosts. -This page provides an overview of OS packages in the context of Trivy scans.

    -

    Supported OS

    -

    The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution. -To hide unfixed/unfixable vulnerabilities, you can use the --ignore-unfixed flag.

    -

    Trivy doesn't support self-compiled packages/binaries, but official packages provided by vendors such as Red Hat and Debian.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OSSupported VersionsTarget PackagesDetection of unfixed vulnerabilities
    Alpine Linux2.2 - 2.7, 3.0 - 3.18, edgeInstalled by apkNO
    Wolfi Linux(n/a)Installed by apkNO
    Chainguard(n/a)Installed by apkNO
    Red Hat Universal Base Image17, 8, 9Installed by yum/rpmYES
    Red Hat Enterprise Linux6, 7, 8Installed by yum/rpmYES
    CentOS6, 7, 8Installed by yum/rpmYES
    AlmaLinux8, 9Installed by yum/rpmNO
    Rocky Linux8, 9Installed by yum/rpmNO
    Oracle Linux5, 6, 7, 8Installed by yum/rpmNO
    CBL-Mariner1.0, 2.0Installed by yum/rpmYES
    Amazon Linux1, 2, 2023Installed by yum/rpmNO
    openSUSE Leap42, 15Installed by zypper/rpmNO
    SUSE Enterprise Linux11, 12, 15Installed by zypper/rpmNO
    Photon OS1.0, 2.0, 3.0, 4.0Installed by tdnf/yum/rpmNO
    Debian GNU/Linuxwheezy, jessie, stretch, buster, bullseyeInstalled by apt/apt-get/dpkgYES
    UbuntuAll versions supported by CanonicalInstalled by apt/apt-get/dpkgYES
    Distroless2AnyInstalled by apt/apt-get/dpkgYES
    -

    Data Sources

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OSSource
    Arch LinuxVulnerable Issues
    Alpine Linuxsecdb
    Wolfi Linuxsecdb
    Chainguardsecdb
    Amazon LinuxAmazon Linux Security Center
    DebianSecurity Bug Tracker
    OVAL
    UbuntuUbuntu CVE Tracker
    RHEL/CentOSOVAL
    Security Data
    AlmaLinuxAlmaLinux Product Errata
    Rocky LinuxRocky Linux UpdateInfo
    Oracle LinuxOVAL
    CBL-MarinerOVAL
    OpenSUSE/SLESCVRF
    Photon OSPhoton Security Advisory
    -

    Data source selection

    -

    Trivy only consumes security advisories from the sources listed in the above table.

    -

    As for packages installed from OS package managers (dpkg, yum, apk, etc.), Trivy uses the advisory database from the appropriate OS vendor.

    -

    For example: for a python package installed from yum (Amazon linux), Trivy will only get advisories from ALAS. -But for a python package installed from another source (e.g. pip), Trivy will get advisories from the GitLab and GitHub databases.

    -

    This advisory selection is essential to avoid getting false positives because OS vendors usually backport upstream fixes, and the fixed version can be different from the upstream fixed version. -The severity is from the selected data source. -If the data source does not provide severity, it falls back to NVD, and if NVD does not have severity, it will be UNKNOWN.

    -

    Distributions

    -

    CBL-Mariner

    -

    Trivy scans CBL-Mariner.

    -

    Support

    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    VersionContainer imageVirtual machineDistrolessMulti-archUnfixed support
    1.0amd64, arm64
    2.0amd64, arm64
    -

    Examples

    -
    -
    -
    -
    ➜ trivy image mcr.microsoft.com/cbl-mariner/base/core:2.0
    -2022-07-27T14:48:20.355+0600    INFO    Detected OS: cbl-mariner
    -2022-07-27T14:48:20.355+0600    INFO    Detecting CBL-Mariner vulnerabilities...
    -2022-07-27T14:48:20.356+0600    INFO    Number of language-specific files: 0
    -
    -mcr.microsoft.com/cbl-mariner/base/core:2.0 (cbl-mariner 2.0.20220527)
    -
    -Total: 33 (UNKNOWN: 0, LOW: 0, MEDIUM: 15, HIGH: 13, CRITICAL: 5)
    -
    -
    -
    -
    ➜ docker run  -it --rm --entrypoint bin/bash mcr.microsoft.com/cbl-mariner/base/core:2.0
    -root [ / ]# tdnf -y install ca-certificates
    -root [ / ]# # Install the latest Trivy
    -root [ / ]# trivy rootfs /
    -2022-07-27T09:30:06.815Z    INFO    Need to update DB
    -2022-07-27T09:30:06.815Z    INFO    DB Repository: ghcr.io/aquasecurity/trivy-db
    -2022-07-27T09:30:06.815Z    INFO    Downloading DB...
    -33.25 MiB / 33.25 MiB [------------------------------] 100.00% 4.20 MiB p/s 8.1s
    -2022-07-27T09:30:21.756Z    INFO    Vulnerability scanning is enabled
    -2022-07-27T09:30:21.756Z    INFO    Secret scanning is enabled
    -2022-07-27T09:30:21.756Z    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
    -2022-07-27T09:30:21.756Z    INFO    Please see also https://aquasecurity.github.io/trivy/v0.30.4/docs/secret/scanning/#recommendation for faster secret detection
    -2022-07-27T09:30:22.205Z    INFO    Detected OS: cbl-mariner
    -2022-07-27T09:30:22.205Z    INFO    Detecting CBL-Mariner vulnerabilities...
    -2022-07-27T09:30:22.205Z    INFO    Number of language-specific files: 0
    -
    -40ba9a55397c (cbl-mariner 2.0.20220527)
    -=======================================
    -Total: 33 (UNKNOWN: 0, LOW: 0, MEDIUM: 15, HIGH: 13, CRITICAL: 5)
    -
    -
    -
    -
    -
    -
    -
      -
    1. -

      https://developers.redhat.com/products/rhel/ubi 

      -
    2. -
    3. -

      https://github.com/GoogleContainerTools/distroless 

      -
    4. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/supply-chain/attestation/rekor/index.html b/test/docs/supply-chain/attestation/rekor/index.html deleted file mode 100644 index 3f306b4f708a..000000000000 --- a/test/docs/supply-chain/attestation/rekor/index.html +++ /dev/null @@ -1,3276 +0,0 @@ - - - - - - - - - - - - - - - - - - - - SBOM Attestation in Rekor - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Scan SBOM attestation in Rekor

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Container images

    -

    Trivy can retrieve SBOM attestation of the specified container image in the Rekor instance and scan it for vulnerabilities.

    -

    Prerequisites

    -
      -
    1. SBOM attestation stored in Rekor -
    2. -
    -

    Scanning

    -

    You need to pass --sbom-sources rekor so that Trivy will look for SBOM attestation in Rekor.

    -
    -

    Note

    -

    --sbom-sources can be used only with trivy image at the moment.

    -
    -
    $ trivy image --sbom-sources rekor otms61/alpine:3.7.3                                                                            [~/src/github.com/aquasecurity/trivy]
    -2022-09-16T17:37:13.258+0900    INFO    Vulnerability scanning is enabled
    -2022-09-16T17:37:13.258+0900    INFO    Secret scanning is enabled
    -2022-09-16T17:37:13.258+0900    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
    -2022-09-16T17:37:13.258+0900    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection
    -2022-09-16T17:37:14.827+0900    INFO    Detected SBOM format: cyclonedx-json
    -2022-09-16T17:37:14.901+0900    INFO    Found SBOM (cyclonedx) attestation in Rekor
    -2022-09-16T17:37:14.903+0900    INFO    Detected OS: alpine
    -2022-09-16T17:37:14.903+0900    INFO    Detecting Alpine vulnerabilities...
    -2022-09-16T17:37:14.907+0900    INFO    Number of language-specific files: 0
    -2022-09-16T17:37:14.908+0900    WARN    This OS version is no longer supported by the distribution: alpine 3.7.3
    -2022-09-16T17:37:14.908+0900    WARN    The vulnerability detection may be insufficient because security updates are not provided
    -
    -otms61/alpine:3.7.3 (alpine 3.7.3)
    -==================================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────┐
    -│  Library   │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                          Title                           │
    -├────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────┤
    -│ musl       │ CVE-2019-14697 │ CRITICAL │ 1.1.18-r3         │ 1.1.18-r4     │ musl libc through 1.1.23 has an x87 floating-point stack │
    -│            │                │          │                   │               │ adjustment im ......                                     │
    -│            │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-14697               │
    -├────────────┤                │          │                   │               │                                                          │
    -│ musl-utils │                │          │                   │               │                                                          │
    -│            │                │          │                   │               │                                                          │
    -│            │                │          │                   │               │                                                          │
    -└────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────┘
    -
    -

    If you have your own Rekor instance, you can specify the URL via --rekor-url.

    -
    $ trivy image --sbom-sources rekor --rekor-url https://my-rekor.dev otms61/alpine:3.7.3
    -
    -

    Non-packaged binaries

    -

    Trivy can retrieve SBOM attestation of non-packaged binaries in the Rekor instance and scan it for vulnerabilities.

    -

    Prerequisites

    -
      -
    1. SBOM attestation stored in Rekor -
    2. -
    -

    Cosign currently does not support keyless signing for blob attestation, so use our plugin at the moment. -This example uses a cat clone bat written in Rust. -You need to generate SBOM from lock files like Cargo.lock at first.

    -
    $ git clone -b v0.20.0 https://github.com/sharkdp/bat
    -$ trivy fs --format cyclonedx --output bat.cdx ./bat/Cargo.lock
    -
    -

    Then our attestation plugin allows you to store the SBOM attestation linking to a bat binary in the Rekor instance.

    -
    $ wget https://github.com/sharkdp/bat/releases/download/v0.20.0/bat-v0.20.0-x86_64-apple-darwin.tar.gz
    -$ tar xvf bat-v0.20.0-x86_64-apple-darwin.tar.gz
    -$ trivy plugin install github.com/aquasecurity/trivy-plugin-attest
    -$ trivy attest --predicate ./bat.cdx --type cyclonedx ./bat-v0.20.0-x86_64-apple-darwin/bat
    -
    -
    -

    Note

    -

    The public instance of the Rekor maintained by the Sigstore team limits the attestation size. -If you are using the public instance, please make sure that your SBOM is small enough. -To get more detail, please refer to the Rekor project's documentation.

    -
    -

    Scan a non-packaged binary

    -

    Trivy calculates the digest of the bat binary and searches for the SBOM attestation by the digest in Rekor. -If it is found, Trivy uses that for vulnerability scanning.

    -
    $ trivy fs --sbom-sources rekor ./bat-v0.20.0-x86_64-apple-darwin/bat
    -2022-10-25T13:27:25.950+0300    INFO    Found SBOM attestation in Rekor: bat
    -2022-10-25T13:27:25.993+0300    INFO    Number of language-specific files: 1
    -2022-10-25T13:27:25.993+0300    INFO    Detecting cargo vulnerabilities...
    -
    -bat (cargo)
    -===========
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -┌───────────┬───────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│  Library  │   Vulnerability   │ Severity │ Installed Version │ Fixed Version │                           Title                            │
    -├───────────┼───────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ regex     │ CVE-2022-24713    │ HIGH     │ 1.5.4             │ 1.5.5         │ Mozilla: Denial of Service via complex regular expressions │
    -│           │                   │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-24713                 │
    -└───────────┴───────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -

    Also, it is applied to non-packaged binaries even in container images.

    -
    $ trivy image --sbom-sources rekor --scanners vuln alpine-with-bat
    -2022-10-25T13:40:14.920+0300    INFO    Vulnerability scanning is enabled
    -2022-10-25T13:40:18.047+0300    INFO    Found SBOM attestation in Rekor: bat
    -2022-10-25T13:40:18.186+0300    INFO    Detected OS: alpine
    -2022-10-25T13:40:18.186+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-10-25T13:40:18.199+0300    INFO    Number of language-specific files: 1
    -2022-10-25T13:40:18.199+0300    INFO    Detecting cargo vulnerabilities...
    -
    -alpine-with-bat (alpine 3.15.6)
    -===============================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -
    -bat (cargo)
    -===========
    -Total: 4 (UNKNOWN: 3, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -┌───────────┬───────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│  Library  │   Vulnerability   │ Severity │ Installed Version │ Fixed Version │                           Title                            │
    -├───────────┼───────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ regex     │ CVE-2022-24713    │ HIGH     │ 1.5.4             │ 1.5.5         │ Mozilla: Denial of Service via complex regular expressions │
    -│           │                   │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-24713                 │
    -└───────────┴───────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -
    -

    Note

    -

    The --sbom-sources rekor flag slows down the scanning as it queries Rekor on the Internet for all non-packaged binaries.

    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/supply-chain/attestation/sbom/index.html b/test/docs/supply-chain/attestation/sbom/index.html deleted file mode 100644 index 5f9cde733ee6..000000000000 --- a/test/docs/supply-chain/attestation/sbom/index.html +++ /dev/null @@ -1,3146 +0,0 @@ - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    SBOM attestation

    -

    Cosign supports generating and verifying in-toto attestations. This tool enables you to sign and verify SBOM attestation. -And, Trivy can take an SBOM attestation as input and scan for vulnerabilities

    -
    -

    Note

    -

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. -If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    -
    -

    Sign with a local key pair

    -

    Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs.

    -
    $ cosign generate-key-pair
    -
    -

    In the following example, Trivy generates an SBOM in the CycloneDX format, and then Cosign attaches an attestation of the SBOM to a container image with a local key pair.

    -
    # The cyclonedx type is supported in Cosign v1.10.0 or later.
    -$ trivy image --format cyclonedx -o sbom.cdx.json <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type cyclonedx --predicate sbom.cdx.json <IMAGE>
    -
    -

    Then, you can verify attestations on the image.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE>
    -
    -

    You can also create attestations of other formatted SBOM.

    -
    # spdx
    -$ trivy image --format spdx -o sbom.spdx <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx <IMAGE>
    -
    -# spdx-json
    -$ trivy image --format spdx-json -o sbom.spdx.json <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx.json <IMAGE>
    -
    -

    Keyless signing

    -

    You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).

    -
    # The cyclonedx type is supported in Cosign v1.10.0 or later.
    -$ trivy image --format cyclonedx -o sbom.cdx.json <IMAGE>
    -# The following command uploads SBOM attestation to the public Rekor instance.
    -$ COSIGN_EXPERIMENTAL=1 cosign attest --type cyclonedx --predicate sbom.cdx.json <IMAGE>
    -
    -

    You can verify attestations. -

    $ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type cyclonedx <IMAGE>
    -

    -

    Scanning

    -

    Trivy can take an SBOM attestation as input and scan for vulnerabilities. Currently, Trivy supports CycloneDX-type attestation.

    -

    In the following example, Cosign can get an CycloneDX-type attestation and trivy scan it. -You must create CycloneDX-type attestation before trying the example. -To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the Sign with a local key pair section.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE> > sbom.cdx.intoto.jsonl
    -$ trivy sbom ./sbom.cdx.intoto.jsonl
    -
    -sbom.cdx.intoto.jsonl (alpine 3.7.3)
    -=========================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────┐
    -│  Library   │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                          Title                           │
    -├────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────┤
    -│ musl       │ CVE-2019-14697 │ CRITICAL │ 1.1.18-r3         │ 1.1.18-r4     │ musl libc through 1.1.23 has an x87 floating-point stack │
    -│            │                │          │                   │               │ adjustment im ......                                     │
    -│            │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-14697               │
    -├────────────┤                │          │                   │               │                                                          │
    -│ musl-utils │                │          │                   │               │                                                          │
    -│            │                │          │                   │               │                                                          │
    -│            │                │          │                   │               │                                                          │
    -└────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────┘
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/supply-chain/attestation/vuln/index.html b/test/docs/supply-chain/attestation/vuln/index.html deleted file mode 100644 index eee9abded178..000000000000 --- a/test/docs/supply-chain/attestation/vuln/index.html +++ /dev/null @@ -1,3272 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Cosign Vulnerability Scan Record - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Cosign Vulnerability Attestation

    -

    Generate Cosign Vulnerability Scan Record

    -

    Trivy generates reports in the Cosign vulnerability scan record format.

    -

    You can use the regular subcommands (like image, fs and rootfs) and specify cosign-vuln with the --format option.

    -
    $ trivy image --format cosign-vuln --output vuln.json alpine:3.10
    -
    -
    -Result - -
    {
    -  "invocation": {
    -    "parameters": null,
    -    "uri": "",
    -    "event_id": "",
    -    "builder.id": ""
    -  },
    -  "scanner": {
    -    "uri": "pkg:github/aquasecurity/trivy@v0.30.1-8-gf9cb8a28",
    -    "version": "v0.30.1-8-gf9cb8a28",
    -    "db": {
    -      "uri": "",
    -      "version": ""
    -    },
    -    "result": {
    -      "SchemaVersion": 2,
    -      "ArtifactName": "alpine:3.10",
    -      "ArtifactType": "container_image",
    -      "Metadata": {
    -        "OS": {
    -          "Family": "alpine",
    -          "Name": "3.10.9",
    -          "EOSL": true
    -        },
    -        "ImageID": "sha256:e7b300aee9f9bf3433d32bc9305bfdd22183beb59d933b48d77ab56ba53a197a",
    -        "DiffIDs": [
    -          "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
    -        ],
    -        "RepoTags": [
    -          "alpine:3.10"
    -        ],
    -        "RepoDigests": [
    -          "alpine@sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98"
    -        ],
    -        "ImageConfig": {
    -          "architecture": "amd64",
    -          "container": "fdb7e80e3339e8d0599282e606c907aa5881ee4c668a68136119e6dfac6ce3a4",
    -          "created": "2021-04-14T19:20:05.338397761Z",
    -          "docker_version": "19.03.12",
    -          "history": [
    -            {
    -              "created": "2021-04-14T19:20:04.987219124Z",
    -              "created_by": "/bin/sh -c #(nop) ADD file:c5377eaa926bf412dd8d4a08b0a1f2399cfd708743533b0aa03b53d14cb4bb4e in / "
    -            },
    -            {
    -              "created": "2021-04-14T19:20:05.338397761Z",
    -              "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
    -              "empty_layer": true
    -            }
    -          ],
    -          "os": "linux",
    -          "rootfs": {
    -            "type": "layers",
    -            "diff_ids": [
    -              "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
    -            ]
    -          },
    -          "config": {
    -            "Cmd": [
    -              "/bin/sh"
    -            ],
    -            "Env": [
    -              "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    -            ],
    -            "Image": "sha256:eb2080c455e94c22ae35b3aef9e078c492a00795412e026e4d6b41ef64bc7dd8"
    -          }
    -        }
    -      },
    -      "Results": [
    -        {
    -          "Target": "alpine:3.10 (alpine 3.10.9)",
    -          "Class": "os-pkgs",
    -          "Type": "alpine",
    -          "Vulnerabilities": [
    -            {
    -              "VulnerabilityID": "CVE-2021-36159",
    -              "PkgName": "apk-tools",
    -              "InstalledVersion": "2.10.6-r0",
    -              "FixedVersion": "2.10.7-r0",
    -              "Layer": {
    -                "Digest": "sha256:396c31837116ac290458afcb928f68b6cc1c7bdd6963fc72f52f365a2a89c1b5",
    -                "DiffID": "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
    -              },
    -              "SeveritySource": "nvd",
    -              "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-36159",
    -              "DataSource": {
    -                "ID": "alpine",
    -                "Name": "Alpine Secdb",
    -                "URL": "https://secdb.alpinelinux.org/"
    -              },
    -              "Description": "libfetch before 2021-07-26, as used in apk-tools, xbps, and other products, mishandles numeric strings for the FTP and HTTP protocols. The FTP passive mode implementation allows an out-of-bounds read because strtol is used to parse the relevant numbers into address bytes. It does not check if the line ends prematurely. If it does, the for-loop condition checks for the '\\0' terminator one byte too late.",
    -              "Severity": "CRITICAL",
    -              "CweIDs": [
    -                "CWE-125"
    -              ],
    -              "CVSS": {
    -                "nvd": {
    -                  "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:P",
    -                  "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H",
    -                  "V2Score": 6.4,
    -                  "V3Score": 9.1
    -                }
    -              },
    -              "References": [
    -                "https://github.com/freebsd/freebsd-src/commits/main/lib/libfetch",
    -                "https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10749",
    -                "https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cdev.kafka.apache.org%3E",
    -                "https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cusers.kafka.apache.org%3E",
    -                "https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cdev.kafka.apache.org%3E",
    -                "https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cusers.kafka.apache.org%3E"
    -              ],
    -              "PublishedDate": "2021-08-03T14:15:00Z",
    -              "LastModifiedDate": "2021-10-18T12:19:00Z"
    -            }
    -          ]
    -        }
    -      ]
    -    }
    -  },
    -  "metadata": {
    -    "scanStartedOn": "2022-07-24T17:14:04.864682+09:00",
    -    "scanFinishedOn": "2022-07-24T17:14:04.864682+09:00"
    -  }
    -}
    -
    - -
    - -

    Create Cosign Vulnerability Attestation

    -

    Cosign supports generating and verifying in-toto attestations. This tool enables you to sign and verify Cosign vulnerability attestation.

    -
    -

    Note

    -

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. -If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    -
    -

    Sign with a local key pair

    -

    Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs.

    -
    $ cosign generate-key-pair
    -
    -

    In the following example, Trivy generates a cosign vulnerability scan record, and then Cosign attaches an attestation of it to a container image with a local key pair.

    -
    $ trivy image --format cosign-vuln --output vuln.json <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type vuln --predicate vuln.json <IMAGE>
    -
    -

    Then, you can verify attestations on the image.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type vuln <IMAGE>
    -
    -

    Keyless signing

    -

    You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).

    -
    $ trivy image --format cosign-vuln -o vuln.json <IMAGE>
    -$ COSIGN_EXPERIMENTAL=1 cosign attest --type vuln --predicate vuln.json <IMAGE>
    -
    -

    You can verify attestations.

    -
    $ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type vuln <IMAGE>
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/supply-chain/sbom/index.html b/test/docs/supply-chain/sbom/index.html deleted file mode 100644 index f22bf7f527e5..000000000000 --- a/test/docs/supply-chain/sbom/index.html +++ /dev/null @@ -1,3856 +0,0 @@ - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    SBOM generation

    -

    Trivy can generate the following SBOM formats.

    - -

    CLI commands

    -

    To generate SBOM, you can use the --format option for each subcommand such as image, fs and vm.

    -
    $ trivy image --format spdx-json --output result.json alpine:3.15
    -
    -
    $ trivy fs --format cyclonedx --output result.json /app/myproject
    -
    -
    -Result - -
    {
    -  "bomFormat": "CycloneDX",
    -  "specVersion": "1.3",
    -  "serialNumber": "urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace",
    -  "version": 1,
    -  "metadata": {
    -    "timestamp": "2022-02-22T15:11:40.270597Z",
    -    "tools": [
    -      {
    -        "vendor": "aquasecurity",
    -        "name": "trivy",
    -        "version": "dev"
    -      }
    -    ],
    -    "component": {
    -      "bom-ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "type": "container",
    -      "name": "alpine:3.15",
    -      "version": "",
    -      "purl": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SchemaVersion",
    -          "value": "2"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:ImageID",
    -          "value": "sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoDigest",
    -          "value": "alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:DiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoTag",
    -          "value": "alpine:3.15"
    -        }
    -      ]
    -    }
    -  },
    -  "components": [
    -    {
    -      "bom-ref": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "type": "library",
    -      "name": "alpine-baselayout",
    -      "version": "3.2.0-r18",
    -      "licenses": [
    -        {
    -          "expression": "GPL-2.0-only"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "alpine-baselayout"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "3.2.0-r18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    ...(snip)...
    -    {
    -      "bom-ref": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "type": "library",
    -      "name": "zlib",
    -      "version": "1.2.11-r3",
    -      "licenses": [
    -        {
    -          "expression": "Zlib"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "zlib"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "1.2.11-r3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    {
    -      "bom-ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "type": "operating-system",
    -      "name": "alpine",
    -      "version": "3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:Type",
    -          "value": "alpine"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:Class",
    -          "value": "os-pkgs"
    -        }
    -      ]
    -    }
    -  ],
    -  "dependencies": [
    -    {
    -      "ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "dependsOn": [
    -        "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -        "pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0",
    -        "pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0",
    -        "pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0",
    -        "pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0",
    -        "pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0",
    -        "pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0"
    -      ]
    -    },
    -    {
    -      "ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "dependsOn": [
    -        "3da6a469-964d-4b4e-b67d-e94ec7c88d37"
    -      ]
    -    }
    -  ]
    -}
    -
    - -
    - -

    Supported packages

    -

    Trivy supports the following packages.

    - -

    In addition to the above packages, Trivy also supports the following packages for generating SBOM.

    -
    -

    Note

    -

    These packages are not supported for vulnerability scanning.

    -
    - - - - - - - - - - - - - - - - - - - - -
    LanguageFileDependency location1
    Pythonconda package2-
    SwiftPodfile.lock-
    -

    Formats

    -

    CycloneDX

    -

    Trivy can generate SBOM in the CycloneDX format. -Note that XML format is not supported at the moment.

    -

    You can use the regular subcommands (like image, fs and rootfs) and specify cyclonedx with the --format option.

    -

    CycloneDX can represent either or both SBOM or BOV.

    - -

    By default, --format cyclonedx represents SBOM and doesn't include vulnerabilities in the CycloneDX output.

    -
    $ trivy image --format cyclonedx --output result.json alpine:3.15
    -2022-07-19T07:47:27.624Z        INFO    "--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.
    -
    -
    -Result - -
    $ cat result.json | jq .
    -{
    -  "bomFormat": "CycloneDX",
    -  "specVersion": "1.4",
    -  "serialNumber": "urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace",
    -  "version": 1,
    -  "metadata": {
    -    "timestamp": "2022-02-22T15:11:40.270597Z",
    -    "tools": [
    -      {
    -        "vendor": "aquasecurity",
    -        "name": "trivy",
    -        "version": "dev"
    -      }
    -    ],
    -    "component": {
    -      "bom-ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "type": "container",
    -      "name": "alpine:3.15",
    -      "version": "",
    -      "purl": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SchemaVersion",
    -          "value": "2"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:ImageID",
    -          "value": "sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoDigest",
    -          "value": "alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:DiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoTag",
    -          "value": "alpine:3.15"
    -        }
    -      ]
    -    }
    -  },
    -  "components": [
    -    {
    -      "bom-ref": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "type": "library",
    -      "name": "alpine-baselayout",
    -      "version": "3.2.0-r18",
    -      "licenses": [
    -        {
    -          "expression": "GPL-2.0-only"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "alpine-baselayout"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "3.2.0-r18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    ...(snip)...
    -    {
    -      "bom-ref": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "type": "library",
    -      "name": "zlib",
    -      "version": "1.2.11-r3",
    -      "licenses": [
    -        {
    -          "expression": "Zlib"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "zlib"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "1.2.11-r3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    {
    -      "bom-ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "type": "operating-system",
    -      "name": "alpine",
    -      "version": "3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:Type",
    -          "value": "alpine"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:Class",
    -          "value": "os-pkgs"
    -        }
    -      ]
    -    }
    -  ],
    -  "dependencies": [
    -    {
    -      "ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "dependsOn": [
    -        "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -        "pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0",
    -        "pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0",
    -        "pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0",
    -        "pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0",
    -        "pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0",
    -        "pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0"
    -      ]
    -    },
    -    {
    -      "ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "dependsOn": [
    -        "3da6a469-964d-4b4e-b67d-e94ec7c88d37"
    -      ]
    -    }
    -  ],
    -  "vulnerabilities": [
    -    {
    -      "id": "CVE-2021-42386",
    -      "source": {
    -        "name": "alpine",
    -        "url": "https://secdb.alpinelinux.org/"
    -      },
    -      "ratings": [
    -        {
    -          "source": {
    -            "name": "nvd"
    -          },
    -          "score": 7.2,
    -          "severity": "high",
    -          "method": "CVSSv31",
    -          "vector": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H"
    -        },
    -        {
    -          "source": {
    -            "name": "nvd"
    -          },
    -          "score": 6.5,
    -          "severity": "medium",
    -          "method": "CVSSv2",
    -          "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"
    -        },
    -        {
    -          "source": {
    -            "name": "redhat"
    -          },
    -          "score": 6.6,
    -          "severity": "medium",
    -          "method": "CVSSv31",
    -          "vector": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H"
    -        }
    -      ],
    -      "cwes": [
    -        416
    -      ],
    -      "description": "A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the nvalloc function",
    -      "advisories": [
    -        {
    -          "url": "https://access.redhat.com/security/cve/CVE-2021-42386"
    -        },
    -        {
    -          "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42386"
    -        }
    -      ],
    -      "published": "2021-11-15 21:15:00 +0000 UTC",
    -      "updated": "2022-01-04 17:14:00 +0000 UTC",
    -      "affects": [
    -        {
    -          "ref": "pkg:apk/alpine/busybox@1.33.1-r3?distro=3.14.2"
    -        },
    -        {
    -          "ref": "pkg:apk/alpine/ssl_client@1.33.1-r3?distro=3.14.2"
    -        }
    -      ]
    -    }
    -  ]
    -}
    -
    - -
    - -

    If you want to include vulnerabilities, you can enable vulnerability scanning via --scanners vuln.

    -
    $ trivy image --scanners vuln --format cyclonedx --output result.json alpine:3.15
    -
    -

    SPDX

    -

    Trivy can generate SBOM in the SPDX format.

    -

    You can use the regular subcommands (like image, fs and rootfs) and specify spdx with the --format option.

    -
    $ trivy image --format spdx --output result.spdx alpine:3.15
    -
    -
    -Result - -
    $ cat result.spdx
    -SPDXVersion: SPDX-2.2
    -DataLicense: CC0-1.0
    -SPDXID: SPDXRef-DOCUMENT
    -DocumentName: alpine:3.15
    -DocumentNamespace: https://aquasecurity.github.io/trivy/container_image/alpine:3.15-bebf6b19-a94c-4e2c-af44-065f63923f48
    -Creator: Organization: aquasecurity
    -Creator: Tool: trivy-0.38.1
    -Created: 2022-04-28T07:32:57.142806Z
    -
    -##### Package: zlib
    -
    -PackageName: zlib
    -SPDXID: SPDXRef-12bc938ac028a5e1
    -PackageVersion: 1.2.12-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: Zlib
    -PackageLicenseDeclared: Zlib
    -
    -##### Package: apk-tools
    -
    -PackageName: apk-tools
    -SPDXID: SPDXRef-26c274652190d87f
    -PackageVersion: 2.12.7-r3
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: libretls
    -
    -PackageName: libretls
    -SPDXID: SPDXRef-2b021966d19a8211
    -PackageVersion: 3.3.4-r3
    -FilesAnalyzed: false
    -PackageLicenseConcluded: ISC AND (BSD-3-Clause OR MIT)
    -PackageLicenseDeclared: ISC AND (BSD-3-Clause OR MIT)
    -
    -##### Package: busybox
    -
    -PackageName: busybox
    -SPDXID: SPDXRef-317ce3476703f20d
    -PackageVersion: 1.34.1-r5
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: libcrypto1.1
    -
    -PackageName: libcrypto1.1
    -SPDXID: SPDXRef-34f407fb4dbd67f4
    -PackageVersion: 1.1.1n-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: OpenSSL
    -PackageLicenseDeclared: OpenSSL
    -
    -##### Package: libc-utils
    -
    -PackageName: libc-utils
    -SPDXID: SPDXRef-4bbc1cb449d54083
    -PackageVersion: 0.7.2-r3
    -FilesAnalyzed: false
    -PackageLicenseConcluded: BSD-2-Clause AND BSD-3-Clause
    -PackageLicenseDeclared: BSD-2-Clause AND BSD-3-Clause
    -
    -##### Package: alpine-keys
    -
    -PackageName: alpine-keys
    -SPDXID: SPDXRef-a3bdd174be1456b6
    -PackageVersion: 2.4-r1
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MIT
    -PackageLicenseDeclared: MIT
    -
    -##### Package: ca-certificates-bundle
    -
    -PackageName: ca-certificates-bundle
    -SPDXID: SPDXRef-ac6472ba26fb991c
    -PackageVersion: 20211220-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MPL-2.0 AND MIT
    -PackageLicenseDeclared: MPL-2.0 AND MIT
    -
    -##### Package: libssl1.1
    -
    -PackageName: libssl1.1
    -SPDXID: SPDXRef-b2d1b1d70fe90f7d
    -PackageVersion: 1.1.1n-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: OpenSSL
    -PackageLicenseDeclared: OpenSSL
    -
    -##### Package: scanelf
    -
    -PackageName: scanelf
    -SPDXID: SPDXRef-c617077ba6649520
    -PackageVersion: 1.3.3-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: musl
    -
    -PackageName: musl
    -SPDXID: SPDXRef-ca80b810029cde0e
    -PackageVersion: 1.2.2-r7
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MIT
    -PackageLicenseDeclared: MIT
    -
    -##### Package: alpine-baselayout
    -
    -PackageName: alpine-baselayout
    -SPDXID: SPDXRef-d782e64751ba9faa
    -PackageVersion: 3.2.0-r18
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: musl-utils
    -
    -PackageName: musl-utils
    -SPDXID: SPDXRef-e5e8a237f6162e22
    -PackageVersion: 1.2.2-r7
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MIT BSD GPL2+
    -PackageLicenseDeclared: MIT BSD GPL2+
    -
    -##### Package: ssl_client
    -
    -PackageName: ssl_client
    -SPDXID: SPDXRef-fdf0ce84f6337be4
    -PackageVersion: 1.34.1-r5
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    - -
    - -

    SPDX-JSON format is also supported by using spdx-json with the --format option.

    -
    $ trivy image --format spdx-json --output result.spdx.json alpine:3.15
    -
    -
    -Result - -
    $ cat result.spdx.json | jq .
    -{
    -    "SPDXID": "SPDXRef-DOCUMENT",
    -    "creationInfo": {
    -        "created": "2022-04-28T08:16:55.328255Z",
    -        "creators": [
    -            "Tool: trivy-0.38.1",
    -            "Organization: aquasecurity"
    -        ]
    -    },
    -    "dataLicense": "CC0-1.0",
    -    "documentNamespace": "http://aquasecurity.github.io/trivy/container_image/alpine:3.15-d9549e3a-a4c5-4ee3-8bde-8c78d451fbe7",
    -    "name": "alpine:3.15",
    -    "packages": [
    -        {
    -            "SPDXID": "SPDXRef-12bc938ac028a5e1",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "Zlib",
    -            "licenseDeclared": "Zlib",
    -            "name": "zlib",
    -            "versionInfo": "1.2.12-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-26c274652190d87f",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "apk-tools",
    -            "versionInfo": "2.12.7-r3"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-2b021966d19a8211",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "ISC AND (BSD-3-Clause OR MIT)",
    -            "licenseDeclared": "ISC AND (BSD-3-Clause OR MIT)",
    -            "name": "libretls",
    -            "versionInfo": "3.3.4-r3"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-317ce3476703f20d",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "busybox",
    -            "versionInfo": "1.34.1-r5"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-34f407fb4dbd67f4",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "OpenSSL",
    -            "licenseDeclared": "OpenSSL",
    -            "name": "libcrypto1.1",
    -            "versionInfo": "1.1.1n-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-4bbc1cb449d54083",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "BSD-2-Clause AND BSD-3-Clause",
    -            "licenseDeclared": "BSD-2-Clause AND BSD-3-Clause",
    -            "name": "libc-utils",
    -            "versionInfo": "0.7.2-r3"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-a3bdd174be1456b6",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MIT",
    -            "licenseDeclared": "MIT",
    -            "name": "alpine-keys",
    -            "versionInfo": "2.4-r1"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-ac6472ba26fb991c",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MPL-2.0 AND MIT",
    -            "licenseDeclared": "MPL-2.0 AND MIT",
    -            "name": "ca-certificates-bundle",
    -            "versionInfo": "20211220-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-b2d1b1d70fe90f7d",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "OpenSSL",
    -            "licenseDeclared": "OpenSSL",
    -            "name": "libssl1.1",
    -            "versionInfo": "1.1.1n-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-c617077ba6649520",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "scanelf",
    -            "versionInfo": "1.3.3-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-ca80b810029cde0e",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MIT",
    -            "licenseDeclared": "MIT",
    -            "name": "musl",
    -            "versionInfo": "1.2.2-r7"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-d782e64751ba9faa",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "alpine-baselayout",
    -            "versionInfo": "3.2.0-r18"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-e5e8a237f6162e22",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MIT BSD GPL2+",
    -            "licenseDeclared": "MIT BSD GPL2+",
    -            "name": "musl-utils",
    -            "versionInfo": "1.2.2-r7"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-fdf0ce84f6337be4",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "ssl_client",
    -            "versionInfo": "1.34.1-r5"
    -        }
    -    ],
    -    "spdxVersion": "SPDX-2.2"
    -}
    -
    - -
    - -
    -
    -
      -
    1. -

      Use startline == 1 and endline == 1 for unsupported file types 

      -
    2. -
    3. -

      envs/*/conda-meta/*.json 

      -
    4. -
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/supply-chain/vex/index.html b/test/docs/supply-chain/vex/index.html deleted file mode 100644 index 7de34487e18d..000000000000 --- a/test/docs/supply-chain/vex/index.html +++ /dev/null @@ -1,3328 +0,0 @@ - - - - - - - - - - - - - - - - - - - - VEX - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Vulnerability Exploitability Exchange (VEX)

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy supports filtering detected vulnerabilities using the Vulnerability Exploitability Exchange (VEX), a standardized format for sharing and exchanging information about vulnerabilities. -By providing VEX alongside the Software Bill of Materials (SBOM) during scanning, it is possible to filter vulnerabilities based on their status. -Currently, Trivy supports the following two formats:

    - -

    This is still an experimental implementation, with only minimal functionality added.

    -

    CycloneDX

    -

    There are two VEX formats for CycloneDX:

    -
      -
    • Independent BOM and VEX BOM
    • -
    • BOM With Embedded VEX
    • -
    -

    Trivy only supports the Independent BOM and VEX BOM format, so you need to provide a separate VEX file alongside the SBOM. -The input SBOM format must be in CycloneDX format.

    -

    The following steps are required:

    -
      -
    1. Generate a CycloneDX SBOM
    2. -
    3. Create a VEX based on the SBOM generated in step 1
    4. -
    5. Provide the VEX when scanning the CycloneDX SBOM
    6. -
    -

    Generating the SBOM

    -

    You can generate a CycloneDX SBOM with Trivy as follows:

    -
    $ trivy image --format cyclonedx --output debian11.sbom.cdx debian:11
    -
    -

    Create the VEX

    -

    Next, create a VEX based on the generated SBOM. -Multiple vulnerability statuses can be defined under vulnerabilities. -Take a look at the example below.

    -
    $ cat <<EOF > trivy.vex.cdx
    -{
    -  "bomFormat": "CycloneDX",
    -  "specVersion": "1.4",
    -  "version": 1,
    -  "vulnerabilities": [
    -    {
    -      "id": "CVE-2020-8911",
    -      "analysis": {
    -        "state": "not_affected",
    -        "justification": "code_not_reachable",
    -        "response": ["will_not_fix", "update"],
    -        "detail": "The vulnerable function is not called"
    -      },
    -      "affects": [
    -        {
    -          "ref": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#pkg:golang/github.com/aws/aws-sdk-go@1.44.234"
    -        }
    -      ]
    -    }
    -  ]
    -}
    -EOF
    -
    -

    This is a VEX document in the CycloneDX format. -The vulnerability ID, such as a CVE-ID or GHSA-ID, should be placed in vulnerabilities.id. -When the analysis.state is set to not_affected, Trivy will not detect the vulnerability.

    -

    BOM-Links must be placed in affects.ref. -The BOM-Link has the following syntax and consists of three elements:

    -
    urn:cdx:serialNumber/version#bom-ref
    -
    -
      -
    • serialNumber
    • -
    • version
    • -
    • bom-ref
    • -
    -

    These values must be obtained from the CycloneDX SBOM. -Please note that while the serialNumber starts with urn:uuid:, the BOM-Link starts with urn:cdx:.

    -

    The bom-ref must contain the BOM-Ref of the package affected by the vulnerability. -In the example above, since the Go package github.com/aws/aws-sdk-go is affected by CVE-2020-8911, it was necessary to specify the SBOM's BOM-Ref, pkg:golang/github.com/aws/aws-sdk-go@1.44.234.

    -

    For more details on CycloneDX VEX and BOM-Link, please refer to the following links:

    - -

    Scan SBOM with VEX

    -

    Provide the VEX when scanning the CycloneDX SBOM.

    -
    $ trivy sbom trivy.sbom.cdx --vex trivy.vex.cdx
    -...
    -2023-04-13T12:55:44.838+0300    INFO    Filtered out the detected vulnerability {"VEX format": "CycloneDX", "vulnerability-id": "CVE-2020-8911", "status": "not_affected", "justification": "code_not_reachable"}
    -
    -go.mod (gomod)
    -==============
    -Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -┌───────────────────────────┬───────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│          Library          │ Vulnerability │ Severity │ Installed Version │ Fixed Version │                           Title                            │
    -├───────────────────────────┼───────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ github.com/aws/aws-sdk-go │ CVE-2020-8912 │ LOW      │ 1.44.234          │               │ aws-sdk-go: In-band key negotiation issue in AWS S3 Crypto │
    -│                           │               │          │                   │               │ SDK for golang...                                          │
    -│                           │               │          │                   │               │ https://avd.aquasec.com/nvd/cve-2020-8912                  │
    -└───────────────────────────┴───────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -

    CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document.

    -

    OpenVEX

    -

    Trivy also supports OpenVEX that is designed to be minimal, compliant, interoperable, and embeddable. -Since OpenVEX aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy.

    -

    The following steps are required:

    -
      -
    1. Generate a SBOM (CycloneDX or SPDX)
    2. -
    3. Create a VEX based on the SBOM generated in step 1
    4. -
    5. Provide the VEX when scanning the SBOM
    6. -
    -

    Generating the SBOM

    -

    You can generate a CycloneDX or SPDX SBOM with Trivy as follows:

    -
    $ trivy image --format spdx-json --output debian11.spdx.json debian:11
    -
    -

    Create the VEX

    -

    Please see also the example. -The product identifiers differ depending on the SBOM format the VEX references.

    - -
    $ cat <<EOF > trivy.openvex
    -{
    -  "@context": "https://openvex.dev/ns",
    -  "@id": "https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f",
    -  "author": "Aqua Security",
    -  "timestamp": "2023-01-16T19:07:16.853479631-06:00",
    -  "version": "1",
    -  "statements": [
    -    {
    -      "vulnerability": "CVE-2019-8457",
    -      "products": [
    -        "pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8?arch=arm64\u0026distro=debian-11.6"
    -      ],
    -      "status": "not_affected",
    -      "justification": "vulnerable_code_not_in_execute_path"
    -    }
    -  ]
    -}
    -EOF
    -
    -

    In the above example, PURLs, located in packages.externalRefs.referenceLocator are used since the input SBOM format is SPDX.

    -

    As for CycloneDX BOM-Link, please reference the CycloneDX section.

    -

    Scan SBOM with VEX

    -

    Provide the VEX when scanning the SBOM.

    -
    $ trivy sbom debian11.spdx.json --vex trivy.openvex
    -...
    -2023-04-26T17:56:05.358+0300    INFO    Filtered out the detected vulnerability {"VEX format": "OpenVEX", "vulnerability-id": "CVE-2019-8457", "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path"}
    -
    -debian11.spdx.json (debian 11.6)
    -================================
    -Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)
    -
    -

    CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/aws/index.html b/test/docs/target/aws/index.html deleted file mode 100644 index 8b35cef90f7d..000000000000 --- a/test/docs/target/aws/index.html +++ /dev/null @@ -1,3216 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AWS - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Amazon Web Services

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    The Trivy AWS CLI allows you to scan your AWS account for misconfigurations. -You can either run the CLI locally or integrate it into your CI/CD pipeline.

    -

    Whilst you can already scan the infrastructure-as-code that defines your AWS resources with trivy config, you can now scan your live AWS account(s) directly too.

    -

    The included checks cover all of the aspects of the AWS CIS 1.2 automated benchmarks.

    -

    Trivy uses the same authentication methods as the AWS CLI to configure and authenticate your access to the AWS platform.

    -

    You will need permissions configured to read all AWS resources - we recommend using a group/role with the ReadOnlyAccess policy attached.

    -

    Once you've scanned your account, you can run additional commands to filter the results without having to run the entire scan again - infrastructure information is cached locally per AWS account/region.

    -

    Trivy currently supports the following scanning for AWS accounts.

    -
      -
    • Misconfigurations
    • -
    -

    CLI Commands

    -

    Scan a full AWS account (all supported services):

    -
    trivy aws --region us-east-1
    -
    -

    You can allow Trivy to determine the AWS region etc. by using the standard AWS configuration files and environment variables. The --region flag overrides these.

    -

    AWS Summary Report

    -

    The summary view is the default when scanning multiple services.

    -

    Scan a specific service:

    -
    trivy aws --service s3
    -
    -

    Scan multiple services:

    -
    # --service s3,ec2 works too
    -trivy aws --service s3 --service ec2
    -
    -

    Show results for a specific AWS resource:

    -
    trivy aws --service s3 --arn arn:aws:s3:::example-bucket
    -
    -

    All ARNs with detected issues will be displayed when showing results for their associated service.

    -

    Compliance

    -

    This section describes AWS specific compliance reports. -For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    -

    Built in reports

    -

    the following reports are available out of the box:

    - - - - - - - - - - - - - - - - - - - - -
    ComplianceName for commandMore info
    AWS CIS Foundations Benchmark v1.2aws-cis-1.2link
    AWS CIS Foundations Benchmark v1.4aws-cis-1.4link
    -

    Examples

    -

    Scan a cloud account and generate a compliance summary report:

    -
    $ trivy aws --compliance=<compliance_id> --report=summary
    -
    -

    Note : The Issues column represent the total number of failed checks for this control.

    -

    Get all of the detailed output for checks:

    -
    $ trivy aws --compliance=<compliance_id> --report all
    -
    -

    Report result in JSON format:

    -
    $ trivy aws --compliance=<compliance_id> --report all --format json
    -
    -

    Cached Results

    -

    By default, Trivy will cache a representation of each AWS service for 24 hours. -This means you can filter and view results for a service without having to wait for the entire scan to run again. -If you want to force the cache to be refreshed with the latest data, you can use --update-cache. -Or if you'd like to use cached data for a different timeframe, you can specify --max-cache-age (e.g. --max-cache-age 2h.). -Regardless of whether the cache is used or not, rules will be evaluated again with each run of trivy aws.

    -

    Custom Policies

    -

    You can write custom policies for Trivy to evaluate against your AWS account. -These policies are written in Rego, the same language used by Open Policy Agent. -See the Custom Policies page for more information.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/container_image/index.html b/test/docs/target/container_image/index.html deleted file mode 100644 index ec2cd3f42160..000000000000 --- a/test/docs/target/container_image/index.html +++ /dev/null @@ -1,3888 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Container Image - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Container Image

    -

    Trivy supports two targets for container images.

    -
      -
    • Files inside container images
    • -
    • Container image metadata
    • -
    -

    Files inside container images

    -

    Container images consist of files. -For instance, new files will be installed if you install a package.

    -

    Trivy scans the files inside container images for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    -

    Vulnerabilities

    -

    It is enabled by default. -You can simply specify your image name (and a tag). -It detects known vulnerabilities in your container image. -See here for the detail.

    -
    $ trivy image [YOUR_IMAGE_NAME]
    -
    -

    For example:

    -
    $ trivy image python:3.4-alpine
    -
    -
    -Result - -
    2019-05-16T01:20:43.180+0900    INFO    Updating vulnerability database...
    -2019-05-16T01:20:53.029+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |
    -|         |                  |          |                   |               | with long nonces               |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -
    - -
    - -

    To enable only vulnerability scanning, you can specify --scanners vuln.

    -
    $ trivy image --scanners vuln [YOUR_IMAGE_NAME]
    -
    -

    Misconfigurations

    -

    It is supported, but it is not useful in most cases. -As mentioned here, Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. -If your container image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners config.

    -
    $ trivy image --scanners config [YOUR_IMAGE_NAME]
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy image [YOUR_IMAGE_NAME]
    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy image --scanners license [YOUR_IMAGE_NAME]
    -
    -

    Container image metadata

    -

    Container images have configuration. -docker inspect and docker history show the information according to the configuration.

    -

    Trivy scans the configuration of container images for

    -
      -
    • Misconfigurations
    • -
    • Secrets
    • -
    -

    They are disabled by default. -You can enable them with --image-config-scanners.

    -
    -

    Tips

    -

    The configuration can be exported as the JSON file by docker save.

    -
    -

    Misconfigurations

    -

    Trivy detects misconfigurations on the configuration of container images. -The image config is converted into Dockerfile and Trivy handles it as Dockerfile. -See here for the detail of Dockerfile scanning.

    -

    It is disabled by default. -You can enable it with --image-config-scanners config.

    -
    $ trivy image --image-config-scanners config [YOUR_IMAGE_NAME]
    -
    -

    If you just want to scan the image config, you can disable scanners with --scanners none. -For example:

    -
    $ trivy image --scanners none --image-config-scanners config alpine:3.17.0
    -
    -
    -Result - -
    alpine:3.17 (dockerfile)
    -========================
    -Tests: 24 (SUCCESSES: 21, FAILURES: 3, EXCEPTIONS: 0)
    -Failures: 3 (UNKNOWN: 0, LOW: 2, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -LOW: Consider using 'COPY file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' command instead of 'ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /'
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.
    -
    -See https://avd.aquasec.com/misconfig/ds005
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - alpine:3.17:1
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   1 [ ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -LOW: Add HEALTHCHECK instruction in your Dockerfile
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.
    -
    -See https://avd.aquasec.com/misconfig/ds026
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    - -
    -

    Tip

    -

    You can see how each layer is created with docker history.

    -
    -

    Secrets

    -

    Trivy detects secrets on the configuration of container images. -The image config is converted into JSON and Trivy scans the file for secrets. -It is especially useful for environment variables that are likely to have credentials by accident. -See here for the detail.

    -
    $ trivy image --image-config-scanners secret [YOUR_IMAGE_NAME]
    -
    -

    If you just want to scan the image config, you can disable scanners with --scanners none. -For example:

    -
    $ trivy image --scanners none --image-config-scanners secret vuln-image
    -
    -
    -Result - -
    vuln-image (alpine 3.17.1)
    -==========================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -
    -vuln-image (secrets)
    -====================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -CRITICAL: GitHub (github-pat)
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -GitHub Personal Access Token
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - test:16
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  14     {
    -  15     "created": "2023-01-09T17:05:20Z",
    -  16 [   "created_by": "ENV secret=****************************************",
    -  17     "comment": "buildkit.dockerfile.v0",
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -CRITICAL: GitHub (github-pat)
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -GitHub Personal Access Token
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - test:34
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  32     "Env": [
    -  33     "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    -  34 [   "secret=****************************************"
    -  35     ]
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    - -
    - -
    -

    Tip

    -

    You can see environment variables with docker inspect.

    -
    -

    Supported

    -

    Trivy will look for the specified image in a series of locations. By default, it -will first look in the local Docker Engine, then Containerd, Podman, and -finally container registry.

    -

    This behavior can be modified with the --image-src flag. For example, the -command

    -
    trivy image --image-src podman,containerd alpine:3.7.3
    -
    -

    Will first search in Podman. If the image is found there, it will be scanned -and the results returned. If the image is not found in Podman, then Trivy will -search in Containerd. If the image is not found there either, the scan will -fail and no more image sources will be searched.

    -

    Docker Engine

    -

    Trivy tries to looks for the specified image in your local Docker Engine. -It will be skipped if Docker Engine is not running locally.

    -

    If your docker socket is not the default path, you can override it via DOCKER_HOST.

    -

    containerd

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy tries to looks for the specified image in your local containerd. -It will be skipped if containerd is not running locally.

    -

    Specify your image name in containerd running locally.

    -
    $ nerdctl images
    -REPOSITORY        TAG       IMAGE ID        CREATED         PLATFORM       SIZE         BLOB SIZE
    -aquasec/nginx    latest    2bcabc23b454    3 hours ago     linux/amd64    149.1 MiB    54.1 MiB
    -$ trivy image aquasec/nginx
    -
    -

    If your containerd socket is not the default path (//run/containerd/containerd.sock), you can override it via CONTAINERD_ADDRESS.

    -
    $ export CONTAINERD_ADDRESS=/run/k3s/containerd/containerd.sock
    -$ trivy image aquasec/nginx
    -
    -

    If your scan targets are images in a namespace other than containerd's default namespace (default), you can override it via CONTAINERD_NAMESPACE.

    -
    $ export CONTAINERD_NAMESPACE=k8s.io
    -$ trivy image aquasec/nginx
    -
    -

    Podman

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Scan your image in Podman (>=2.0) running locally. The remote Podman is not supported. -Before performing Trivy commands, you must enable the podman.sock systemd service on your machine. -For more details, see here.

    -
    $ systemctl --user enable --now podman.socket
    -
    -

    Then, you can scan your image in Podman.

    -
    $ cat Dockerfile
    -FROM alpine:3.12
    -RUN apk add --no-cache bash
    -$ podman build -t test .
    -$ podman images
    -REPOSITORY                TAG     IMAGE ID      CREATED      SIZE
    -localhost/test            latest  efc372d4e0de  About a minute ago  7.94 MB
    -$ trivy image test
    -
    -

    Container Registry

    -

    Trivy supports registries that comply with the following specifications.

    - -

    You can configure credentials with docker login. -See here for the detail.

    -

    Tar Files

    -

    Trivy supports image tar files generated by the following tools.

    - -
    $ docker pull ruby:3.1-alpine3.15
    -$ docker save ruby:3.1-alpine3.15 -o ruby-3.1.tar
    -$ trivy image --input ruby-3.1.tar
    -
    -
    -Result - -
    2022-02-03T10:08:19.127Z        INFO    Detected OS: alpine
    -2022-02-03T10:08:19.127Z        WARN    This OS version is not on the EOL list: alpine 3.15
    -2022-02-03T10:08:19.127Z        INFO    Detecting Alpine vulnerabilities...
    -2022-02-03T10:08:19.127Z        INFO    Number of language-specific files: 2
    -2022-02-03T10:08:19.127Z        INFO    Detecting gemspec vulnerabilities...
    -2022-02-03T10:08:19.128Z        INFO    Detecting node-pkg vulnerabilities...
    -2022-02-03T10:08:19.128Z        WARN    This OS version is no longer supported by the distribution: alpine 3.15.0
    -2022-02-03T10:08:19.128Z        WARN    The vulnerability detection may be insufficient because security updates are not provided
    -
    -ruby-3.1.tar (alpine 3.15.0)
    -============================
    -Total: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0)
    -
    -+----------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
    -+----------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| gmp      | CVE-2021-43618   | HIGH     | 6.2.1-r0          | 6.2.1-r1      | gmp: Integer overflow and resultant   |
    -|          |                  |          |                   |               | buffer overflow via crafted input     |
    -|          |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-43618 |
    -+----------+                  +          +                   +               +                                       +
    -| gmp-dev  |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -+----------+                  +          +                   +               +                                       +
    -| libgmpxx |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -+----------+------------------+----------+-------------------+---------------+---------------------------------------+
    -
    -Node.js (node-pkg)
    -==================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -
    -Ruby (gemspec)
    -==============
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    - -
    - -

    OCI Layout

    -

    Trivy supports image directories compliant with Open Container Image Layout Specification.

    -

    Buildah:

    -
    $ buildah push docker.io/library/alpine:3.11 oci:/path/to/alpine
    -$ trivy image --input /path/to/alpine
    -
    -

    Skopeo:

    -
    $ skopeo copy docker-daemon:alpine:3.11 oci:/path/to/alpine
    -$ trivy image --input /path/to/alpine
    -
    -

    SBOM

    -

    Trivy supports the generation of Software Bill of Materials (SBOM) for container images and the search for SBOMs during vulnerability scanning.

    -

    Generation

    -

    Trivy can generate SBOM for container images. -See here for the detail.

    -

    Discovery

    -

    Trivy can search for Software Bill of Materials (SBOMs) that reference container images. -If an SBOM is found, the vulnerability scan is performed using the SBOM instead of the container image. -By using the SBOM, you can perform a vulnerability scan more quickly, as it allows you to skip pulling the container image and analyzing its layers.

    -

    To enable this functionality, you need to specify the --sbom-sources flag. -The following two sources are supported:

    -
      -
    • OCI Registry (oci)
    • -
    • Rekor (rekor)
    • -
    -

    Example:

    -
    $ trivy image --sbom-sources oci ghcr.io/knqyf263/oci-referrers
    -2023-03-05T17:36:55.278+0200    INFO    Vulnerability scanning is enabled
    -2023-03-05T17:36:58.103+0200    INFO    Detected SBOM format: cyclonedx-json
    -2023-03-05T17:36:58.129+0200    INFO    Found SBOM (cyclonedx) in the OCI referrers
    -...
    -
    -ghcr.io/knqyf263/oci-referrers (alpine 3.16.2)
    -==============================================
    -Total: 17 (UNKNOWN: 0, LOW: 0, MEDIUM: 5, HIGH: 9, CRITICAL: 3)
    -
    -

    The OCI Registry utilizes the Referrers API. -For more information about Rekor, please refer to its documentation.

    -

    Compliance

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    This section describes container image specific compliance reports. -For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    -

    Built in reports

    -

    The following reports are available out of the box:

    - - - - - - - - - - - - - - - - - -
    ComplianceVersionName for commandMore info
    CIS Docker Community Edition Benchmark1.1.0docker-cisLink
    -

    Examples

    -

    Scan a container image configuration and generate a compliance summary report:

    -
    $ trivy image --compliance docker-cis [YOUR_IMAGE_NAME]
    -
    -
    -

    Note

    -

    The Issues column represent the total number of failed checks for this control.

    -
    -

    Authentication

    -

    Please reference this page.

    -

    Options

    -

    Scan Image on a specific Architecture and OS

    -

    By default, Trivy loads an image on a "linux/amd64" machine. -To customise this, pass a --platform argument in the format OS/Architecture for the image:

    -
    $ trivy image --platform=os/architecture [YOUR_IMAGE_NAME]
    -
    -

    For example:

    -
    $ trivy image --platform=linux/arm alpine:3.16.1
    -
    -
    -Result - -
    2022-10-25T21:00:50.972+0300    INFO    Vulnerability scanning is enabled
    -2022-10-25T21:00:50.972+0300    INFO    Secret scanning is enabled
    -2022-10-25T21:00:50.972+0300    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
    -2022-10-25T21:00:50.972+0300    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection
    -2022-10-25T21:00:56.190+0300    INFO    Detected OS: alpine
    -2022-10-25T21:00:56.190+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-10-25T21:00:56.191+0300    INFO    Number of language-specific files: 0
    -
    -alpine:3.16.1 (alpine 3.16.1)
    -=============================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
    -
    -┌─────────┬────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│ Library │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├─────────┼────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ zlib    │ CVE-2022-37434 │ CRITICAL │ 1.2.12-r1         │ 1.2.12-r2     │ zlib: heap-based buffer over-read and overflow in inflate() │
    -│         │                │          │                   │               │ in inflate.c via a...                                       │
    -│         │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-37434                  │
    -└─────────┴────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -
    - -
    - -

    Configure Docker daemon socket to connect to.

    -

    You can configure Docker daemon socket with DOCKER_HOST or --docker-host.

    -
    $ trivy image --docker-host tcp://127.0.0.1:2375 YOUR_IMAGE
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/filesystem/index.html b/test/docs/target/filesystem/index.html deleted file mode 100644 index 5717ca24db63..000000000000 --- a/test/docs/target/filesystem/index.html +++ /dev/null @@ -1,3208 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Filesystem - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Filesystem

    -

    Scan your local projects for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    -
    $ trivy fs /path/to/project
    -
    -

    It's also possible to scan a single file.

    -
    $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test/Pipfile.lock
    -
    -

    Scanners

    -

    Vulnerabilities

    -

    It is enabled by default. -Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. -See here for the detail.

    -
    $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test
    -
    -
    -Result - -
    2020-06-01T17:06:58.652+0300    WARN    OS is not detected and vulnerabilities in OS packages are not detected.
    -2020-06-01T17:06:58.652+0300    INFO    Detecting pipenv vulnerabilities...
    -2020-06-01T17:06:58.691+0300    INFO    Detecting cargo vulnerabilities...
    -
    -Pipfile.lock
    -============
    -Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
    -
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -|       LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |     FIXED VERSION      |               TITLE                |
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -| django              | CVE-2020-7471    | HIGH     | 2.0.9             | 3.0.3, 2.2.10, 1.11.28 | django: potential                  |
    -|                     |                  |          |                   |                        | SQL injection via                  |
    -|                     |                  |          |                   |                        | StringAgg(delimiter)               |
    -+                     +------------------+----------+                   +------------------------+------------------------------------+
    -|                     | CVE-2019-19844   | MEDIUM   |                   | 3.0.1, 2.2.9, 1.11.27  | Django: crafted email address      |
    -|                     |                  |          |                   |                        | allows account takeover            |
    -+                     +------------------+          +                   +------------------------+------------------------------------+
    -|                     | CVE-2019-3498    |          |                   | 2.1.5, 2.0.10, 1.11.18 | python-django: Content             |
    -|                     |                  |          |                   |                        | spoofing via URL path in           |
    -|                     |                  |          |                   |                        | default 404 page                   |
    -+                     +------------------+          +                   +------------------------+------------------------------------+
    -|                     | CVE-2019-6975    |          |                   | 2.1.6, 2.0.11, 1.11.19 | python-django:                     |
    -|                     |                  |          |                   |                        | memory exhaustion in               |
    -|                     |                  |          |                   |                        | django.utils.numberformat.format() |
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -...
    -
    - -
    - -

    Misconfigurations

    -

    It is disabled by default and can be enabled with --scanners config. -See here for the detail.

    -
    $ trivy fs --scanners config /path/to/project
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy fs /path/to/project
    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy fs --scanners license /path/to/project
    -
    -

    SBOM generation

    -

    Trivy can generate SBOM for local projects. -See here for the detail.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/git-repository/index.html b/test/docs/target/git-repository/index.html deleted file mode 100644 index cde24631c518..000000000000 --- a/test/docs/target/git-repository/index.html +++ /dev/null @@ -1,3418 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Git Repository - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Git Repository

    -

    Scan your remote git repositories for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    -
    $ trivy repo [YOUR_REPO_URL]
    -
    -

    Scanners

    -

    Vulnerabilities

    -

    It is enabled by default. -Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. -See here for the detail.

    -
    $ trivy repo https://github.com/knqyf263/trivy-ci-test
    -
    -
    -Result - -
    2021-03-09T15:04:19.003+0200    INFO    Detecting cargo vulnerabilities...
    -2021-03-09T15:04:19.005+0200    INFO    Detecting pipenv vulnerabilities...
    -
    -Cargo.lock
    -==========
    -Total: 7 (UNKNOWN: 7, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -+----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+
    -| LIBRARY  | VULNERABILITY ID  | SEVERITY | INSTALLED VERSION |        FIXED VERSION         |                    TITLE                    |
    -+----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+
    -| ammonia  | RUSTSEC-2019-0001 | UNKNOWN  | 1.9.0             | >= 2.1.0                     | Uncontrolled recursion leads                |
    -|          |                   |          |                   |                              | to abort in HTML serialization              |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2019-0001 |
    -+----------+-------------------+          +-------------------+------------------------------+---------------------------------------------+
    -| openssl  | RUSTSEC-2016-0001 |          | 0.8.3             | >= 0.9.0                     | SSL/TLS MitM vulnerability                  |
    -|          |                   |          |                   |                              | due to insecure defaults                    |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2016-0001 |
    -+----------+-------------------+          +-------------------+------------------------------+---------------------------------------------+
    -| smallvec | RUSTSEC-2018-0018 |          | 0.6.9             | >= 0.6.13                    | smallvec creates uninitialized              |
    -|          |                   |          |                   |                              | value of any type                           |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2018-0018 |
    -+          +-------------------+          +                   +------------------------------+---------------------------------------------+
    -|          | RUSTSEC-2019-0009 |          |                   | >= 0.6.10                    | Double-free and use-after-free              |
    -|          |                   |          |                   |                              | in SmallVec::grow()                         |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2019-0009 |
    -+          +-------------------+          +                   +                              +---------------------------------------------+
    -|          | RUSTSEC-2019-0012 |          |                   |                              | Memory corruption in SmallVec::grow()       |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2019-0012 |
    -+          +-------------------+          +                   +------------------------------+---------------------------------------------+
    -|          | RUSTSEC-2021-0003 |          |                   | >= 0.6.14, < 1.0.0, >= 1.6.1 | Buffer overflow in SmallVec::insert_many    |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2021-0003 |
    -+----------+-------------------+          +-------------------+------------------------------+---------------------------------------------+
    -| tempdir  | RUSTSEC-2018-0017 |          | 0.3.7             |                              | `tempdir` crate has been                    |
    -|          |                   |          |                   |                              | deprecated; use `tempfile` instead          |
    -|          |                   |          |                   |                              | -->rustsec.org/advisories/RUSTSEC-2018-0017 |
    -+----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+
    -
    -Pipfile.lock
    -============
    -Total: 20 (UNKNOWN: 3, LOW: 0, MEDIUM: 7, HIGH: 5, CRITICAL: 5)
    -
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -|       LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |     FIXED VERSION      |                 TITLE                 |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| django              | CVE-2019-19844   | CRITICAL | 2.0.9             | 3.0.1, 2.2.9, 1.11.27  | Django: crafted email address         |
    -|                     |                  |          |                   |                        | allows account takeover               |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2019-19844 |
    -+                     +------------------+          +                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-7471    |          |                   | 3.0.3, 2.2.10, 1.11.28 | django: potential SQL injection       |
    -|                     |                  |          |                   |                        | via StringAgg(delimiter)              |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-7471  |
    -+                     +------------------+----------+                   +------------------------+---------------------------------------+
    -|                     | CVE-2019-6975    | HIGH     |                   | 2.1.6, 2.0.11, 1.11.19 | python-django: memory exhaustion in   |
    -|                     |                  |          |                   |                        | django.utils.numberformat.format()    |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2019-6975  |
    -+                     +------------------+          +                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-9402    |          |                   | 3.0.4, 2.2.11, 1.11.29 | django: potential SQL injection       |
    -|                     |                  |          |                   |                        | via "tolerance" parameter in          |
    -|                     |                  |          |                   |                        | GIS functions and aggregates...       |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-9402  |
    -+                     +------------------+----------+                   +------------------------+---------------------------------------+
    -|                     | CVE-2019-3498    | MEDIUM   |                   | 2.1.5, 2.0.10, 1.11.18 | python-django: Content spoofing       |
    -|                     |                  |          |                   |                        | via URL path in default 404 page      |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2019-3498  |
    -+                     +------------------+          +                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-13254   |          |                   | 3.0.7, 2.2.13          | django: potential data leakage        |
    -|                     |                  |          |                   |                        | via malformed memcached keys          |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-13254 |
    -+                     +------------------+          +                   +                        +---------------------------------------+
    -|                     | CVE-2020-13596   |          |                   |                        | django: possible XSS via              |
    -|                     |                  |          |                   |                        | admin ForeignKeyRawIdWidget           |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-13596 |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| django-cors-headers | pyup.io-37132    | UNKNOWN  | 2.5.2             | 3.0.0                  | In django-cors-headers                |
    -|                     |                  |          |                   |                        | version 3.0.0,                        |
    -|                     |                  |          |                   |                        | ``CORS_ORIGIN_WHITELIST``             |
    -|                     |                  |          |                   |                        | requires URI schemes, and             |
    -|                     |                  |          |                   |                        | optionally ports. This...             |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| djangorestframework | CVE-2020-25626   | MEDIUM   | 3.9.2             | 3.11.2                 | django-rest-framework: XSS            |
    -|                     |                  |          |                   |                        | Vulnerability in API viewer           |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-25626 |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| httplib2            | CVE-2021-21240   | HIGH     | 0.12.1            | 0.19.0                 | python-httplib2: Regular              |
    -|                     |                  |          |                   |                        | expression denial of                  |
    -|                     |                  |          |                   |                        | service via malicious header          |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2021-21240 |
    -+                     +------------------+----------+                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-11078   | MEDIUM   |                   | 0.18.0                 | python-httplib2: CRLF injection       |
    -|                     |                  |          |                   |                        | via an attacker controlled            |
    -|                     |                  |          |                   |                        | unescaped part of uri for...          |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-11078 |
    -+                     +------------------+----------+                   +                        +---------------------------------------+
    -|                     | pyup.io-38303    | UNKNOWN  |                   |                        | Httplib2 0.18.0 is an                 |
    -|                     |                  |          |                   |                        | important security update to          |
    -|                     |                  |          |                   |                        | patch a CWE-93 CRLF...                |
    -+---------------------+------------------+          +-------------------+------------------------+---------------------------------------+
    -| jinja2              | pyup.io-39525    |          | 2.10.1            | 2.11.3                 | This affects the package              |
    -|                     |                  |          |                   |                        | jinja2 from 0.0.0 and before          |
    -|                     |                  |          |                   |                        | 2.11.3. The ReDOS...                  |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| py                  | CVE-2020-29651   | HIGH     | 1.8.0             |                        | python-py: ReDoS in the py.path.svnwc |
    -|                     |                  |          |                   |                        | component via malicious input         |
    -|                     |                  |          |                   |                        | to blame functionality...             |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-29651 |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| pyyaml              | CVE-2019-20477   | CRITICAL |               5.1 |                        | PyYAML: command execution             |
    -|                     |                  |          |                   |                        | through python/object/apply           |
    -|                     |                  |          |                   |                        | constructor in FullLoader             |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2019-20477 |
    -+                     +------------------+          +                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-14343   |          |                   |                    5.4 | PyYAML: incomplete                    |
    -|                     |                  |          |                   |                        | fix for CVE-2020-1747                 |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-14343 |
    -+                     +------------------+          +                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-1747    |          |                   | 5.3.1                  | PyYAML: arbitrary command             |
    -|                     |                  |          |                   |                        | execution through python/object/new   |
    -|                     |                  |          |                   |                        | when FullLoader is used               |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-1747  |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -| urllib3             | CVE-2019-11324   | HIGH     | 1.24.1            | 1.24.2                 | python-urllib3: Certification         |
    -|                     |                  |          |                   |                        | mishandle when error should be thrown |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2019-11324 |
    -+                     +------------------+----------+                   +------------------------+---------------------------------------+
    -|                     | CVE-2019-11236   | MEDIUM   |                   |                        | python-urllib3: CRLF injection        |
    -|                     |                  |          |                   |                        | due to not encoding the               |
    -|                     |                  |          |                   |                        | '\r\n' sequence leading to...         |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2019-11236 |
    -+                     +------------------+          +                   +------------------------+---------------------------------------+
    -|                     | CVE-2020-26137   |          |                   | 1.25.9                 | python-urllib3: CRLF injection        |
    -|                     |                  |          |                   |                        | via HTTP request method               |
    -|                     |                  |          |                   |                        | -->avd.aquasec.com/nvd/cve-2020-26137 |
    -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+
    -
    - -
    - -

    Misconfigurations

    -

    It is disabled by default and can be enabled with --scanners config. -See here for the detail.

    -
    $ trivy repo --scanners config [YOUR_REPO_URL]
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy repo [YOUR_REPO_URL]
    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy repo --scanners license [YOUR_REPO_URL]
    -
    -

    SBOM generation

    -

    Trivy can generate SBOM for git repositories. -See here for the detail.

    -

    References

    -

    Scanning a Branch

    -

    Pass a --branch argument with a valid branch name on the remote repository provided:

    -
    $ trivy repo --branch <branch-name> <repo-name>
    -
    -

    Scanning upto a Commit

    -

    Pass a --commit argument with a valid commit hash on the remote repository provided:

    -
    $ trivy repo --commit <commit-hash> <repo-name>
    -
    -

    Scanning a Tag

    -

    Pass a --tag argument with a valid tag on the remote repository provided:

    -
    $ trivy repo --tag <tag-name> <repo-name>
    -
    -

    Scanning Private Repositories

    -

    In order to scan private GitHub or GitLab repositories, the environment variable GITHUB_TOKEN or GITLAB_TOKEN must be set, respectively, with a valid token that has access to the private repository being scanned.

    -

    The GITHUB_TOKEN environment variable will take precedence over GITLAB_TOKEN, so if a private GitLab repository will be scanned, then GITHUB_TOKEN must be unset.

    -

    You can find how to generate your GitHub Token in the following GitHub documentation.

    -

    For example:

    -
    $ export GITHUB_TOKEN="your_private_github_token"
    -$ trivy repo <your private GitHub repo URL>
    -$
    -$ # or
    -$ export GITLAB_TOKEN="your_private_gitlab_token"
    -$ trivy repo <your private GitLab repo URL>
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/kubernetes/index.html b/test/docs/target/kubernetes/index.html deleted file mode 100644 index 10f27eb9fc80..000000000000 --- a/test/docs/target/kubernetes/index.html +++ /dev/null @@ -1,3451 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Kubernetes - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Kubernetes

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    CLI

    -

    The Trivy K8s CLI allows you to scan your Kubernetes cluster for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    -

    You can either run the CLI locally or integrate it into your CI/CD pipeline. -The difference to the Trivy CLI is that the Trivy K8s CLI allows you to scan running workloads directly within your cluster.

    -

    If you are looking for continuous cluster audit scanning, have a look at the Trivy K8s operator below.

    -

    Trivy uses your local kubectl configuration to access the API server to list artifacts.

    -

    Commands

    -

    Scan a full cluster and generate a simple summary report:

    -
    $ trivy k8s --report=summary cluster
    -
    -

    k8s Summary Report

    -

    The summary report is the default. To get all of the detail the output contains, use --report all.

    -

    Filter by severity:

    -
    $ trivy k8s --severity=CRITICAL --report=all cluster
    -
    -

    Filter by scanners (Vulnerabilities, Secrets or Misconfigurations):

    -
    $ trivy k8s --scanners=secret --report=summary cluster
    -# or
    -$ trivy k8s --scanners=config --report=summary cluster
    -
    -

    Scan a specific namespace:

    -
    $ trivy k8s -n kube-system --report=summary all
    -
    -

    Use a specific kubeconfig file:

    -
    $ trivy k8s --kubeconfig ~/.kube/config2 -n kube-system --report=summary all
    -
    -

    Scan a specific resource and get all the output:

    -
    $ trivy k8s deployment appname
    -
    -

    Scan all deploys, or deploys and configmaps:

    -
    $ trivy k8s --report=summary deployment
    -$ trivy k8s --report=summary deployment,configmaps
    -
    -

    If you want to pass in flags before scanning specific workloads, you will have to do it before the resource name. -For example, scanning a deployment in the app namespace of your Kubernetes cluster for critical vulnerabilities would be done through the following command:

    -

    $ trivy k8s -n app --severity=CRITICAL deployment/appname
    -
    -This is specific to all Trivy CLI commands.

    -

    The supported formats are table, which is the default, and json. -To get a JSON output on a full cluster scan:

    -
    $ trivy k8s --format json -o results.json cluster
    -
    -
    -Result - -
    {
    -  "ClusterName": "minikube",
    -  "Vulnerabilities": [
    -    {
    -      "Namespace": "default",
    -      "Kind": "Deployment",
    -      "Name": "app",
    -      "Results": [
    -        {
    -          "Target": "ubuntu:latest (ubuntu 22.04)",
    -          "Class": "os-pkgs",
    -          "Type": "ubuntu",
    -          "Vulnerabilities": [
    -            {
    -              "VulnerabilityID": "CVE-2016-2781",
    -              "PkgName": "coreutils",
    -              "InstalledVersion": "8.32-4.1ubuntu1",
    -              "Layer": {
    -                "Digest": "sha256:125a6e411906fe6b0aaa50fc9d600bf6ff9bb11a8651727ce1ed482dc271c24c",
    -                "DiffID": "sha256:e59fc94956120a6c7629f085027578e6357b48061d45714107e79f04a81a6f0c"
    -              },
    -              "SeveritySource": "ubuntu",
    -              "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2016-2781",
    -              "DataSource": {
    -                "ID": "ubuntu",
    -                "Name": "Ubuntu CVE Tracker",
    -                "URL": "https://git.launchpad.net/ubuntu-cve-tracker"
    -              },
    -              "Title": "coreutils: Non-privileged session can escape to the parent session in chroot",
    -              "Description": "chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.",
    -              "Severity": "LOW",
    -              "CweIDs": [
    -                "CWE-20"
    -              ],
    -              "VendorSeverity": {
    -                "cbl-mariner": 2,
    -                "nvd": 2,
    -                "redhat": 2,
    -                "ubuntu": 1
    -              },
    -              "CVSS": {
    -                "nvd": {
    -                  "V2Vector": "AV:L/AC:L/Au:N/C:N/I:P/A:N",
    -                  "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N",
    -                  "V2Score": 2.1,
    -                  "V3Score": 6.5
    -                },
    -                "redhat": {
    -                  "V2Vector": "AV:L/AC:H/Au:N/C:C/I:C/A:C",
    -                  "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
    -                  "V2Score": 6.2,
    -                  "V3Score": 8.6
    -                }
    -              },
    -              "References": [
    -                "http://seclists.org/oss-sec/2016/q1/452",
    -                "http://www.openwall.com/lists/oss-security/2016/02/28/2",
    -                "http://www.openwall.com/lists/oss-security/2016/02/28/3",
    -                "https://access.redhat.com/security/cve/CVE-2016-2781",
    -                "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2781",
    -                "https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E",
    -                "https://lore.kernel.org/patchwork/patch/793178/",
    -                "https://nvd.nist.gov/vuln/detail/CVE-2016-2781"
    -              ],
    -              "PublishedDate": "2017-02-07T15:59:00Z",
    -              "LastModifiedDate": "2021-02-25T17:15:00Z"
    -            }
    -          ]
    -        }
    -      ]
    -    }
    -  ],
    -  "Misconfigurations": [
    -    {
    -      "Namespace": "default",
    -      "Kind": "Deployment",
    -      "Name": "app",
    -      "Results": [
    -        {
    -          "Target": "Deployment/app",
    -          "Class": "config",
    -          "Type": "kubernetes",
    -          "MisconfSummary": {
    -            "Successes": 20,
    -            "Failures": 19,
    -            "Exceptions": 0
    -          },
    -          "Misconfigurations": [
    -            {
    -              "Type": "Kubernetes Security Check",
    -              "ID": "KSV001",
    -              "Title": "Process can elevate its own privileges",
    -              "Description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.",
    -              "Message": "Container 'app' of Deployment 'app' should set 'securityContext.allowPrivilegeEscalation' to false",
    -              "Namespace": "builtin.kubernetes.KSV001",
    -              "Query": "data.builtin.kubernetes.KSV001.deny",
    -              "Resolution": "Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.",
    -              "Severity": "MEDIUM",
    -              "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv001",
    -              "References": [
    -                "https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
    -                "https://avd.aquasec.com/misconfig/ksv001"
    -              ],
    -              "Status": "FAIL",
    -              "Layer": {},
    -              "IacMetadata": {
    -                "Provider": "Kubernetes",
    -                "Service": "general",
    -                "StartLine": 121,
    -                "EndLine": 133
    -              }
    -            },
    -            {
    -              "Type": "Kubernetes Security Check",
    -              "ID": "KSV003",
    -              "Title": "Default capabilities not dropped",
    -              "Description": "The container should drop all default capabilities and add only those that are needed for its execution.",
    -              "Message": "Container 'app' of Deployment 'app' should add 'ALL' to 'securityContext.capabilities.drop'",
    -              "Namespace": "builtin.kubernetes.KSV003",
    -              "Query": "data.builtin.kubernetes.KSV003.deny",
    -              "Resolution": "Add 'ALL' to containers[].securityContext.capabilities.drop.",
    -              "Severity": "LOW",
    -              "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv003",
    -              "References": [
    -                "https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/",
    -                "https://avd.aquasec.com/misconfig/ksv003"
    -              ],
    -              "Status": "FAIL",
    -              "Layer": {},
    -              "IacMetadata": {
    -                "Provider": "Kubernetes",
    -                "Service": "general",
    -                "StartLine": 121,
    -                "EndLine": 133
    -              }
    -            }
    -          ]
    -        }
    -      ]
    -    },
    -    {
    -      "Namespace": "default",
    -      "Kind": "ConfigMap",
    -      "Name": "kube-root-ca.crt"
    -    }
    -  ]
    -}
    -
    - -
    - -

    Infra checks

    -

    Trivy by default scans kubernetes infra components (apiserver, controller-manager, scheduler and etcd) -if they exist under the kube-system namespace. For example, if you run a full cluster scan, or scan all -components under kube-system with commands:

    -
    $ trivy k8s cluster --report summary # full cluster scan
    -$ trivy k8s all -n kube-system --report summary # scan all components under kube-system
    -
    -

    A table will be printed about misconfigurations found on kubernetes core components:

    -
    Summary Report for minikube
    -┌─────────────┬──────────────────────────────────────┬─────────────────────────────┐
    -│  Namespace  │               Resource               │ Kubernetes Infra Assessment │
    -│             │                                      ├────┬────┬────┬─────┬────────┤
    -│             │                                      │ C  │ H  │ M  │ L   │   U    │
    -├─────────────┼──────────────────────────────────────┼────┼────┼────┼─────┼────────┤
    -│ kube-system │ Pod/kube-apiserver-minikube          │    │    │ 1  │ 10  │        │
    -│ kube-system │ Pod/kube-controller-manager-minikube │    │    │    │ 3   │        │
    -│ kube-system │ Pod/kube-scheduler-minikube          │    │    │    │ 1   │        │
    -└─────────────┴──────────────────────────────────────┴────┴────┴────┴─────┴────────┘
    -Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN
    -
    -

    The infra checks are based on CIS Benchmarks recommendations for kubernetes.

    -

    If you want filter only for the infra checks, you can use the flag --components along with the --scanners=config

    -
    $ trivy k8s cluster --report summary --components=infra --scanners=config # scan only infra
    -
    -

    Or, to filter for all other checks besides the infra checks, you can:

    -
    $ trivy k8s cluster --report summary --components=workload --scanners=config # scan all components besides infra
    -
    -

    Compliance

    -

    This section describes Kubernetes specific compliance reports. -For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    -

    Built in reports

    -

    The following reports are available out of the box:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ComplianceName for commandMore info
    NSA, CISA Kubernetes Hardening Guidance v1.2k8s-nsaLink
    CIS Benchmark for Kubernetes v1.23k8s-cisLink
    Pod Security Standards, Baselinek8s-pss-baselineLink
    Pod Security Standards, Restrictedk8s-pss-restrictedLink
    -

    Examples

    -

    Scan a full cluster and generate a compliance summary report:

    -
    $ trivy k8s cluster --compliance=<compliance_id> --report summary
    -
    -

    Note : The Issues column represent the total number of failed checks for this control.

    -

    Get all of the detailed output for checks:

    -
    trivy k8s cluster --compliance=<compliance_id> --report all
    -
    -

    Report result in JSON format:

    -
    trivy k8s cluster --compliance=<compliance_id> --report summary --format json
    -
    -
    trivy k8s cluster --compliance=<compliance_id> --report all --format json
    -
    -

    Operator

    -

    Trivy has a native Kubernetes Operator which continuously scans your Kubernetes cluster for security issues, and generates security reports as Kubernetes Custom Resources. It does it by watching Kubernetes for state changes and automatically triggering scans in response to changes, for example initiating a vulnerability scan when a new Pod is created.

    -
    -

    Kubernetes-native security toolkit. (Documentation).

    -
    -
    -
    Workload reconcilers discover K8s controllers, manage scan jobs, and create VulnerabilityReport and ConfigAuditReport objects.
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/rootfs/index.html b/test/docs/target/rootfs/index.html deleted file mode 100644 index 742ad8e11142..000000000000 --- a/test/docs/target/rootfs/index.html +++ /dev/null @@ -1,3022 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Rootfs - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Rootfs

    -

    Rootfs scanning is for special use cases such as

    - -
    $ trivy rootfs /path/to/rootfs
    -
    -
    -

    Note

    -

    Rootfs scanning works differently from the Filesystem scanning. -You should use trivy fs to scan your local projects in CI/CD. -See here for the differences.

    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/sbom/index.html b/test/docs/target/sbom/index.html deleted file mode 100644 index 9c1105732754..000000000000 --- a/test/docs/target/sbom/index.html +++ /dev/null @@ -1,3183 +0,0 @@ - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    SBOM scanning

    -

    Trivy can take the following SBOM formats as an input and scan for vulnerabilities.

    -
      -
    • CycloneDX
    • -
    • SPDX
    • -
    • SPDX JSON
    • -
    • CycloneDX-type attestation
    • -
    -

    To scan SBOM, you can use the sbom subcommand and pass the path to the SBOM. -The input format is automatically detected.

    -
    $ trivy sbom /path/to/sbom_file
    -
    -
    -

    Note

    -

    Passing SBOMs generated by tool other than Trivy may result in inaccurate detection -because Trivy relies on custom properties in SBOM for accurate scanning.

    -
    -

    CycloneDX

    -

    Trivy supports CycloneDX as an input.

    -
    -

    Note

    -

    CycloneDX XML is not supported at the moment.

    -
    -
    $ trivy sbom /path/to/cyclonedx.json
    -
    -
    -

    Note

    -

    If you want to generate a CycloneDX report from a CycloneDX input, please be aware that the output stores references to your original CycloneDX report and contains only detected vulnerabilities, not components. -The report is called BOV.

    -
    -

    SPDX

    -

    Trivy supports the SPDX SBOM as an input.

    -

    The following SPDX formats are supported:

    -
      -
    • Tag-value (--format spdx)
    • -
    • JSON (--format spdx-json)
    • -
    -
    $ trivy image --format spdx-json --output spdx.json alpine:3.16.0
    -$ trivy sbom spdx.json
    -
    -
    -Result - -
    2022-09-15T21:32:27.168+0300    INFO    Vulnerability scanning is enabled
    -2022-09-15T21:32:27.169+0300    INFO    Detected SBOM format: spdx-json
    -2022-09-15T21:32:27.210+0300    INFO    Detected OS: alpine
    -2022-09-15T21:32:27.210+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-09-15T21:32:27.211+0300    INFO    Number of language-specific files: 0
    -
    -spdx.json (alpine 3.16.0)
    -=========================
    -Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 1)
    -
    -┌──────────────┬────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│   Library    │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                           Title                            │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ busybox      │ CVE-2022-30065 │ HIGH     │ 1.35.0-r13        │ 1.35.0-r15    │ busybox: A use-after-free in Busybox's awk applet leads to │
    -│              │                │          │                   │               │ denial of service...                                       │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-30065                 │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ libcrypto1.1 │ CVE-2022-2097  │ MEDIUM   │ 1.1.1o-r0         │ 1.1.1q-r0     │ openssl: AES OCB fails to encrypt some bytes               │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-2097                  │
    -├──────────────┤                │          │                   │               │                                                            │
    -│ libssl1.1    │                │          │                   │               │                                                            │
    -│              │                │          │                   │               │                                                            │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ ssl_client   │ CVE-2022-30065 │ HIGH     │ 1.35.0-r13        │ 1.35.0-r15    │ busybox: A use-after-free in Busybox's awk applet leads to │
    -│              │                │          │                   │               │ denial of service...                                       │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-30065                 │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ zlib         │ CVE-2022-37434 │ CRITICAL │ 1.2.12-r1         │ 1.2.12-r2     │ zlib: a heap-based buffer over-read or buffer overflow in  │
    -│              │                │          │                   │               │ inflate in inflate.c...                                    │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-37434                 │
    -└──────────────┴────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    - -
    - -

    SBOM attestation

    -

    You can also scan an SBOM attestation. -In the following example, Cosign gets an attestation and Trivy scans it. -You must create CycloneDX-type attestation before trying the example. -To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the SBOM attestation page.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE> > sbom.cdx.intoto.jsonl
    -$ trivy sbom ./sbom.cdx.intoto.jsonl
    -
    -sbom.cdx.intoto.jsonl (alpine 3.7.3)
    -=========================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────┐
    -│  Library   │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                          Title                           │
    -├────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────┤
    -│ musl       │ CVE-2019-14697 │ CRITICAL │ 1.1.18-r3         │ 1.1.18-r4     │ musl libc through 1.1.23 has an x87 floating-point stack │
    -│            │                │          │                   │               │ adjustment im ......                                     │
    -│            │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-14697               │
    -├────────────┤                │          │                   │               │                                                          │
    -│ musl-utils │                │          │                   │               │                                                          │
    -│            │                │          │                   │               │                                                          │
    -│            │                │          │                   │               │                                                          │
    -└────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────┘
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/docs/target/vm/index.html b/test/docs/target/vm/index.html deleted file mode 100644 index 633753a54ca3..000000000000 --- a/test/docs/target/vm/index.html +++ /dev/null @@ -1,3671 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Virtual Machine Image - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Virtual Machine Image

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    To scan virtual machine (VM) images, you can use the vm subcommand.

    -

    Targets

    -

    The following targets are currently supported:

    -
      -
    • Local file
    • -
    • AWS EC2
        -
      • Amazon Machine Image (AMI)
      • -
      • Amazon Elastic Block Store (EBS) Snapshot
      • -
      -
    • -
    -

    Local file

    -

    Pass the path to your local VM image file.

    -
    $ trivy vm --scanners vuln disk.vmdk
    -
    -
    -Result - -
    disk.vmdk (amazon 2 (Karoo))
    -===========================================================================================
    -Total: 802 (UNKNOWN: 0, LOW: 17, MEDIUM: 554, HIGH: 221, CRITICAL: 10)
    -
    -┌────────────────────────────┬────────────────┬──────────┬───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────────────────────────────┐
    -│          Library           │ Vulnerability  │ Severity │       Installed Version       │         Fixed Version         │                            Title                             │
    -├────────────────────────────┼────────────────┼──────────┼───────────────────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ amazon-ssm-agent           │ CVE-2022-24675 │ HIGH     │ 3.0.529.0-1.amzn2             │ 3.1.1575.0-1.amzn2            │ golang: encoding/pem: fix stack overflow in Decode           │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2022-24675                   │
    -├────────────────────────────┼────────────────┤          ├───────────────────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ bind-export-libs           │ CVE-2021-25215 │          │ 32:9.11.4-26.P2.amzn2.4       │ 32:9.11.4-26.P2.amzn2.5       │ bind: An assertion check can fail while answering queries    │
    -│                            │                │          │                               │                               │ for DNAME records...                                         │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25215                   │
    -│                            ├────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                            │ CVE-2021-25214 │ MEDIUM   │                               │ 32:9.11.4-26.P2.amzn2.5.2     │ bind: Broken inbound incremental zone update (IXFR) can      │
    -│                            │                │          │                               │                               │ cause named to terminate...                                  │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25214                   │
    -├────────────────────────────┼────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ bind-libs                  │ CVE-2021-25215 │ HIGH     │                               │ 32:9.11.4-26.P2.amzn2.5       │ bind: An assertion check can fail while answering queries    │
    -│                            │                │          │                               │                               │ for DNAME records...                                         │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25215                   │
    -│                            ├────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                            │ CVE-2021-25214 │ MEDIUM   │                               │ 32:9.11.4-26.P2.amzn2.5.2     │ bind: Broken inbound incremental zone update (IXFR) can      │
    -│                            │                │          │                               │                               │ cause named to terminate...                                  │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25214                   │
    -├────────────────────────────┼────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ bind-libs-lite             │ CVE-2021-25215 │ HIGH     │                               │ 32:9.11.4-26.P2.amzn2.5       │ bind: An assertion check can fail while answering queries    │
    -│                            │                │          │                               │                               │ for DNAME records...                                         │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25215                   │
    -│                            ├────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                            │ CVE-2021-25214 │ MEDIUM   │                               │ 32:9.11.4-26.P2.amzn2.5.2     │ bind: Broken inbound incremental zone update (IXFR) can      │
    -│                            │                │          │                               │                               │ cause named to terminate...                                  │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25214                   │
    -├────────────────────────────┼────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -... 
    -
    - -
    - -

    Amazon Machine Image (AMI)

    -

    You can specify your AMI ID with the ami: prefix.

    -
    $ trivy vm ami:${your_ami_id}
    -
    -
    -

    Note

    -

    AMIs in the marketplace are not supported because the EBS direct APIs don't support that. -See the AWS documentation for the detail.

    -
    -

    Example

    -
    $ trivy vm --scanners vuln ami:ami-0123456789abcdefg
    -
    -

    If you want to scan a AMI of non-default setting region, you can set any region via --aws-region option.

    -
    $ trivy vm --aws-region ap-northeast-1 ami:ami-0123456789abcdefg
    -
    -

    Required Actions

    -

    Some actions on EBS are also necessary since Trivy scans an EBS snapshot tied to the specified AMI under the hood.

    -
      -
    • ec2:DescribeImages
    • -
    • ebs:ListSnapshotBlocks
    • -
    • ebs:GetSnapshotBlock
    • -
    -

    Amazon Elastic Block Store (EBS) Snapshot

    -

    You can specify your EBS snapshot ID with the ebs: prefix.

    -
    $ trivy vm ebs:${your_ebs_snapshot_id}
    -
    -
    -

    Note

    -

    Public snapshots are not supported because the EBS direct APIs don't support that. -See the AWS documentation for the detail.

    -
    -

    Example

    -
    $ trivy vm --scanners vuln ebs:snap-0123456789abcdefg
    -
    -

    If you want to scan an EBS Snapshot of non-default setting region, you can set any region via --aws-region option.

    -
    $ trivy vm --aws-region ap-northeast-1 ebs:ebs-0123456789abcdefg
    -
    -

    The above command takes a while as it calls EBS API and fetches the EBS blocks. -If you want to scan the same snapshot several times, you can download the snapshot locally by using coldsnap maintained by AWS. -Then, Trivy can scan the local VM image file.

    -
    $ coldsnap download snap-0123456789abcdefg disk.img
    -$ trivy vm ./disk.img
    -
    -

    Required Actions

    -
      -
    • ebs:ListSnapshotBlocks
    • -
    • ebs:GetSnapshotBlock
    • -
    -

    Scanners

    -

    Trivy supports VM image scanning for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    Vulnerabilities

    -

    It is enabled by default. -You can simply specify your VM image location. -It detects known vulnerabilities in your VM image. -See here for the detail.

    -
    $ trivy vm [YOUR_VM_IMAGE]
    -
    -

    Misconfigurations

    -

    It is supported, but it is not useful in most cases. -As mentioned here, Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. -If your VM image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners config.

    -
    $ trivy vm --scanners config [YOUR_VM_IMAGE]
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy vm [YOUR_VM_IMAGE]
    -
    -
    -

    Tip

    -

    The scanning could be faster if you enable only vulnerability scanning (--scanners vuln) because Trivy tries to download only necessary blocks for vulnerability detection.

    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy vm --scanners license [YOUR_VM_IMAGE]
    -
    -

    SBOM generation

    -

    Trivy can generate SBOM for VM images. -See here for the detail.

    -

    Supported Architectures

    -

    Virtual machine images

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Image formatSupport
    VMDK
    OVA
    VHD
    VHDX
    QCOW2
    -

    VMDK disk types

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    VMDK disk typeSupport
    streamOptimized
    monolithicSparse
    vmfs
    vmfsSparse
    twoGbMaxExtentSparse
    monolithicFlat
    twoGbMaxExtentFlat
    vmfsRaw
    fullDevice
    partitionedDevice
    vmfsRawDeviceMap
    vmfsPassthroughRawDeviceMap
    -

    Reference: VMware Virtual Disk Format 1.1.pdf

    -

    Disk partitions

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Disk formatSupport
    Master boot record (MBR)
    Extended master boot record
    GUID partition table (GPT)
    Logical volume manager (LVM)
    -

    Filesystems

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Filesystem formatSupport
    XFS
    EXT4
    EXT2/3
    ZFS
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/ecosystem/cicd/index.html b/test/ecosystem/cicd/index.html deleted file mode 100644 index 2c54343e7cff..000000000000 --- a/test/ecosystem/cicd/index.html +++ /dev/null @@ -1,3215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - CI/CD - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    CI/CD Integrations

    -

    GitHub Actions

    -

    GitHub Actions is GitHub's native CI/CD and job orchestration service.

    -

    trivy-action (Official)

    -

    GitHub Action for integrating Trivy into your GitHub pipeline

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-action

    -

    trivy-action (Community)

    -

    GitHub Action to scan vulnerability using Trivy. If vulnerabilities are found by Trivy, it creates a GitHub Issue.

    -

    👉 Get it at: https://github.com/marketplace/actions/trivy-action

    -

    trivy-github-issues (Community)

    -

    In this action, Trivy scans the dependency files such as package-lock.json and go.sum in your repository, then create GitHub issues according to the result.

    -

    👉 Get it at: https://github.com/marketplace/actions/trivy-github-issues

    -

    Azure DevOps (Official)

    -

    Azure Devops is Microsoft Azure cloud native CI/CD service.

    -

    Trivy has a "Azure Devops Pipelines Task" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-azure-pipelines-task

    -

    Semaphore (Community)

    -

    Semaphore is a CI/CD service.

    -

    You can use Trivy in Semaphore for scanning code, containers, infrastructure, and Kubernetes in Semaphore workflow.

    -

    👉 Get it at: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy

    -

    CircleCI (Community)

    -

    CircleCI is a CI/CD service.

    -

    You can use the Trivy Orb for Circle CI to introduce security scanning into your workflow.

    -

    👉 Get it at: https://circleci.com/developer/orbs/orb/fifteen5/trivy-orb -Source: https://github.com/15five/trivy-orb

    -

    Woodpecker CI (Community)

    -

    Example Trivy step in pipeline

    -
    pipeline:
    -  securitycheck:
    -    image: aquasec/trivy:latest
    -    commands:
    -      # use any trivy command, if exit code is 0 woodpecker marks it as passed, else it assumes it failed
    -      - trivy fs --exit-code 1 --skip-dirs web/ --skip-dirs docs/ --severity MEDIUM,HIGH,CRITICAL .
    -
    -

    Woodpecker does use Trivy itself so you can see it in use there.

    -

    Concourse CI (Community)

    -

    Concourse CI is a CI/CD service.

    -

    You can use Trivy Resource in Concourse for scanning containers and introducing security scanning into your workflow. -It has capabilities to fail the pipeline, create issues, alert communication channels (using respective resources) based on Trivy scan output.

    -

    👉 Get it at: https://github.com/Comcast/trivy-resource/

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/ecosystem/ide/index.html b/test/ecosystem/ide/index.html deleted file mode 100644 index 63ffea473e83..000000000000 --- a/test/ecosystem/ide/index.html +++ /dev/null @@ -1,3195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - IDE and Dev tools - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    IDE and developer tools Integrations

    -

    VSCode (Official)

    -

    Visual Studio Code is an open source versatile code editor and development environment.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-vscode-extension

    -

    JetBrains (Official)

    -

    JetBrains makes IDEs such as Goland, Pycharm, IntelliJ, Webstorm, and more.

    -

    The Trivy plugin for JetBrains IDEs lets you use Trivy right from your development environment.

    -

    👉 Get it at: https://plugins.jetbrains.com/plugin/18690-trivy-findings-explorer

    -

    Kubernetes Lens (Official)

    -

    Kubernetes Lens is a management application for Kubernetes clusters.

    -

    Trivy has an extension for Kubernetes Lens that lets you scan Kubernetes workloads and view the results in the Lens UI.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-operator-lens-extension

    -

    Vim (Community)

    -

    Vim is a terminal based text editor.

    -

    Vim plugin for Trivy to install and run Trivy.

    -

    👉 Get it at: https://github.com/aquasecurity/vim-trivy

    -

    Docker Desktop (Community)

    -

    Docker Desktop is an easy way to install Docker container engine on your development machine, and manage it in a GUI .

    -

    Trivy Docker Desktop extension for scanning container images for vulnerabilities and generating SBOMs

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-docker-extension

    -

    Rancher Desktop (Community)

    -

    Rancher Desktop is an easy way to use containers and Kubernetes on your development machine, and mange it in a GUI.

    -

    Trivy is natively integrated with Rancher, no installation is needed. More info in Rancher documentation: https://docs.rancherdesktop.io/getting-started/features#scanning-images

    -

    LazyTrivy (Community)

    -

    A terminal native UI for Trivy

    -

    👉 Get it at: https://github.com/owenrumney/lazytrivy

    -

    Trivy Vulnerability explorer (Community)

    -

    Web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table

    -

    👉 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer

    -

    Trivy pre-commit (Community)

    -

    A trivy pre-commit hook that runs a trivy fs in your git repo before commiting, preventing you from commiting secrets in the first place.

    -

    👉 Get it at: https://github.com/mxab/pre-commit-trivy

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/ecosystem/index.html b/test/ecosystem/index.html deleted file mode 100644 index a32a3b4f2274..000000000000 --- a/test/ecosystem/index.html +++ /dev/null @@ -1,3057 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Ecosystem

    -

    Trivy is integrated into many popular tools and applications, so that you can easily add security to your workflow.

    -

    In this section you will find an aggregation of the different integrations. Integrations are listed as either "official" or "community". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers.

    -

    👈 Please use the side-navigation on the left in order to browse the different topics.

    -

    Add missing integration

    -

    We are happy to showcase community integrations in this section. To suggest an addition simply make a Pull Request to add the missing integration.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/ecosystem/prod/index.html b/test/ecosystem/prod/index.html deleted file mode 100644 index fe777cedf0fd..000000000000 --- a/test/ecosystem/prod/index.html +++ /dev/null @@ -1,3118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Production and Clouds - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Production and cloud Integrations

    -

    Kubernetes

    -

    Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.

    -

    Trivy Operator (Official)

    -

    Using the Trivy Operator you can install Trivy into a Kubernetes cluster so that it automatically and continuously scan your workloads and cluster for security issues.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-operator

    -

    Harbor (Official)

    -

    Harbor is an open source cloud native container and artifact registry.

    -

    Trivy is natively integrated into Harbor, no installation is needed. More info in Harbor documentation: https://goharbor.io/docs/2.6.0/administration/vulnerability-scanning

    -

    Kyverno (Community)

    -

    Kyverno is a policy management tool for Kubernetes.

    -

    You can use Kyverno to ensure and enforce that deployed workloads' images are scanned for vulnerabilities.

    -

    👉 Get it at: https://neonmirrors.net/post/2022-07/attesting-image-scans-kyverno

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/ecosystem/security/index.html b/test/ecosystem/security/index.html deleted file mode 100644 index 0ed59310ca2a..000000000000 --- a/test/ecosystem/security/index.html +++ /dev/null @@ -1,3072 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Security Management - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    - -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/getting-started/faq/index.html b/test/getting-started/faq/index.html deleted file mode 100644 index fdc7d9d440d2..000000000000 --- a/test/getting-started/faq/index.html +++ /dev/null @@ -1,3076 +0,0 @@ - - - - - - - - - - - - - - - - - - - - FAQ - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    FAQ

    - -

    FAQ

    -

    How to pronounce the name "Trivy"?

    -

    tri is pronounced like trigger, vy is pronounced like envy.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/getting-started/installation/index.html b/test/getting-started/installation/index.html deleted file mode 100644 index a41857645e25..000000000000 --- a/test/getting-started/installation/index.html +++ /dev/null @@ -1,3370 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Installation - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Installing Trivy

    -

    In this section you will find an aggregation of the different ways to install Trivy. installations are listed as either "official" or "community". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers.

    -

    Install using Package Manager

    -

    RHEL/CentOS (Official)

    -
    -
    -
    -

    Add repository setting to /etc/yum.repos.d.

    -
    RELEASE_VERSION=$(grep -Po '(?<=VERSION_ID=")[0-9]' /etc/os-release)
    -cat << EOF | sudo tee -a /etc/yum.repos.d/trivy.repo
    -[trivy]
    -name=Trivy repository
    -baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$RELEASE_VERSION/\$basearch/
    -gpgcheck=1
    -enabled=1
    -gpgkey=https://aquasecurity.github.io/trivy-repo/rpm/public.key
    -EOF
    -sudo yum -y update
    -sudo yum -y install trivy
    -
    -
    -
    -
    rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.41.0/trivy_0.41.0_Linux-64bit.rpm
    -
    -
    -
    -
    -

    Debian/Ubuntu (Official)

    -
    -
    -
    -

    Add repository setting to /etc/apt/sources.list.d.

    -
    sudo apt-get install wget apt-transport-https gnupg lsb-release
    -wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
    -echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
    -sudo apt-get update
    -sudo apt-get install trivy
    -
    -
    -
    -
    wget https://github.com/aquasecurity/trivy/releases/download/v0.41.0/trivy_0.41.0_Linux-64bit.deb
    -sudo dpkg -i trivy_0.41.0_Linux-64bit.deb
    -
    -
    -
    -
    -

    Homebrew (Official)

    -

    Homebrew for MacOS and Linux.

    -
    brew install trivy
    -
    -

    Arch Linux (Community)

    -

    Arch Community Package Manager.

    -
    pacman -S trivy
    -
    -

    References: -- https://archlinux.org/packages/community/x86_64/trivy/ -- https://github.com/archlinux/svntogit-community/blob/packages/trivy/trunk/PKGBUILD

    -

    MacPorts (Community)

    -

    MacPorts for MacOS.

    -
    sudo port install trivy
    -
    -

    References: -- https://ports.macports.org/port/trivy/details/

    -

    Nix/NixOS (Community)

    -

    Nix package manager for Linux and MacOS.

    -
    -
    -
    -
    -
    -

    nix-env --install -A nixpkgs.trivy

    -
    -
    -
    -
    -
    -
      # your other config ...
    -  environment.systemPackages = with pkgs; [
    -    # your other packages ...
    -    trivy
    -  ];
    -
    -
    -
    -
    -
    -
    -
      # your other config ...
    -  home.packages = with pkgs; [
    -    # your other packages ...
    -    trivy
    -  ];
    -
    -

    References: -- https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/admin/trivy/default.nix

    -

    Install from GitHub Release (Official)

    -

    Download Binary

    -
      -
    1. Download the file for your operating system/architecture from GitHub Release assets (curl -LO https://url.to/trivy.tar.gz).
    2. -
    3. Unpack the downloaded archive (tar -xzf ./trivy.tar.gz).
    4. -
    5. Put the binary somewhere in your $PATH (e.g mv ./trivy /usr/local/bin/).
    6. -
    7. Make sure the binary has execution bit turned on (chmod +x ./trivy).
    8. -
    -

    Install Script

    -

    The process above can be automated by the following script:

    -
    curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.41.0
    -
    -

    Install from source

    -
    git clone --depth 1 --branch v0.41.0 https://github.com/aquasecurity/trivy
    -cd trivy
    -go install
    -
    -

    Use container image

    -
      -
    1. Pull Trivy image (docker pull aquasec/trivy:0.41.0)
    2. -
    3. It is advisable to mount a consistent cache dir on the host into the Trivy container.
    4. -
    5. For scanning container images with Trivy, mount docker.sock from the host into the Trivy container.
    6. -
    -

    Example:

    -
    docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:0.41.0 image python:3.4-alpine
    -
    -

    Registry | Repository | Link | Supportability -Docker Hub | docker.io/aquasec/trivy | https://hub.docker.com/r/aquasec/trivy | Official -GitHub Container Registry (GHCR) | ghcr.io/aquasecurity/trivy | https://github.com/orgs/aquasecurity/packages/container/package/trivy | Official -AWS Elastic Container Registry (ECR) | public.ecr.aws/aquasecurity/trivy | https://gallery.ecr.aws/aquasecurity/trivy | Official

    -

    Other Tools to use and deploy Trivy

    -

    For additional tools and ways to install and use Trivy in different environments such as in IDE, Kubernetes or CI/CD, see Ecosystem section.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/imgs/Security-Hub.jpeg b/test/imgs/Security-Hub.jpeg deleted file mode 100644 index cece6bcc0c18..000000000000 Binary files a/test/imgs/Security-Hub.jpeg and /dev/null differ diff --git a/test/imgs/argocd-ui.png b/test/imgs/argocd-ui.png deleted file mode 100644 index f9e31a958abb..000000000000 Binary files a/test/imgs/argocd-ui.png and /dev/null differ diff --git a/test/imgs/client-server.png b/test/imgs/client-server.png deleted file mode 100644 index fce67eefdf0b..000000000000 Binary files a/test/imgs/client-server.png and /dev/null differ diff --git a/test/imgs/docker-desktop.png b/test/imgs/docker-desktop.png deleted file mode 100644 index 3eafeb8e8941..000000000000 Binary files a/test/imgs/docker-desktop.png and /dev/null differ diff --git a/test/imgs/excalidraw/client-server.excalidraw b/test/imgs/excalidraw/client-server.excalidraw deleted file mode 100644 index ad67667a9c4a..000000000000 --- a/test/imgs/excalidraw/client-server.excalidraw +++ /dev/null @@ -1,1151 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 458.6370544433594, - "y": 379.5105285644531, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 381, - "versionNonce": 413251305, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "nXkZQsrtjmNqPM6SmPxrc", - "Ljv7RJF8FjyOJX3vZ2ou8", - "o_BKODe9vjtHWQsJ8F3tD", - "zTrormMP-N-W6thSxlTgK", - "fBva4zCGT2vIFPpTWC-oZ" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 427.04335021972656, - "y": 65.240966796875, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 684, - "versionNonce": 78137383, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 511.77996826171875, - "y": 407.1625671386719, - "width": 62, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 253, - "versionNonce": 788328905, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy\nServer", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 488.6784362792969, - "y": 116.34368896484375, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 456, - "versionNonce": 14330695, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 538.7528045696993, - "y": 220.23935960349465, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 1298, - "versionNonce": 267243689, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": -0.03598869040285281, - "gap": 2.911871895302724 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.04563780983822428, - "gap": 5.10864450968802 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 575.9393615722656, - "y": 254.42640686035156, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 629, - "versionNonce": 185838183, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "nXkZQsrtjmNqPM6SmPxrc", - "type": "arrow", - "x": 128.84802246093747, - "y": 395.4753877561888, - "width": 316.63877589590845, - "height": 0.1213064482017785, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2075020231, - "version": 327, - "versionNonce": 1795630503, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 316.63877589590845, - 0.1213064482017785 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "2ZWTQQ2dQDWF8xj1BLdVG", - "focus": 1.483056059007069, - "gap": 12.799499511718778 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.46421771350547186, - "gap": 12.273425031825923 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "OPRFQTrsfmF5a7us-mxkI", - "type": "draw", - "x": -60.78019714355469, - "y": 464.1100280880928, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1541066697, - "version": 569, - "versionNonce": 1115805895, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "QzKnYI7o5Yxg_7szebL6Z", - "type": "draw", - "x": -37.06263732910158, - "y": 508.8429382443428, - "width": 16.976165771484375, - "height": 16.45367431640625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2144447815, - "version": 203, - "versionNonce": 28982057, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 6.905059814453125, - -16.45367431640625 - ], - [ - 16.976165771484375, - -5.1099853515625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "qqbEan2u1uU3loTdTvQ4B", - "type": "text", - "x": -184.67498779296875, - "y": 548.9957397580147, - "width": 230, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1619652615, - "version": 833, - "versionNonce": 981018599, - "isDeleted": false, - "boundElementIds": null, - "text": "6. Analyze pulled layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "GgiFj7vEEZT-VPfKiX6oo", - "type": "rectangle", - "x": -48.80625915527344, - "y": 386.3571411073208, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1005158727, - "version": 500, - "versionNonce": 1358533383, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "nXkZQsrtjmNqPM6SmPxrc", - "2tbWET6O9G38YibdIyLpy", - "FuK6iJ6YprzRoh4wg1UHf", - "o_BKODe9vjtHWQsJ8F3tD", - "fBva4zCGT2vIFPpTWC-oZ" - ] - }, - { - "id": "qQZYQjma-4h8rOrxn5yBo", - "type": "text", - "x": 4.3366546630859375, - "y": 414.00917968153954, - "width": 57, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1918851753, - "version": 381, - "versionNonce": 56771817, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy\nClient", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "vtOTfv319aihVmgTMMbQG", - "type": "ellipse", - "x": -95.58086395263672, - "y": 68.13672637939453, - "width": 249.63902282714844, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1265127495, - "version": 929, - "versionNonce": 1316732873, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "2tbWET6O9G38YibdIyLpy", - "FuK6iJ6YprzRoh4wg1UHf" - ] - }, - { - "id": "bz64cTcmJtjZotVar2MHr", - "type": "text", - "x": -73.4975357055664, - "y": 108.37564849853516, - "width": 202, - "height": 74, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 976812969, - "version": 670, - "versionNonce": 938982727, - "isDeleted": false, - "boundElementIds": null, - "text": "Container Registries\nor\nContainer Engines", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 67 - }, - { - "id": "Z5DzSXSTeTNfyo9GRr57B", - "type": "ellipse", - "x": 871.677619934082, - "y": 347.7999496459961, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#15aabf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1020418857, - "version": 836, - "versionNonce": 845340329, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "Ljv7RJF8FjyOJX3vZ2ou8", - "zTrormMP-N-W6thSxlTgK" - ] - }, - { - "id": "SGILIw_oLMs1yuieBWcoP", - "type": "text", - "x": 898.8127059936523, - "y": 398.90267181396484, - "width": 158, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1953695719, - "version": 653, - "versionNonce": 1086225511, - "isDeleted": false, - "boundElementIds": [ - "zTrormMP-N-W6thSxlTgK" - ], - "text": "Cache Backend\n(Local or Redis)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Ljv7RJF8FjyOJX3vZ2ou8", - "type": "arrow", - "x": 635.243173087202, - "y": 408.1721813855087, - "width": 237.82178502385182, - "height": 0.48828450950475144, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 744746601, - "version": 617, - "versionNonce": 230891913, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 237.82178502385182, - -0.48828450950475144 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.4450219327551968, - "gap": 7.386666739545717 - }, - "endBinding": { - "elementId": "Z5DzSXSTeTNfyo9GRr57B", - "focus": 0.21564885268585596, - "gap": 1.0335001891177882 - }, - "startArrowhead": "arrow", - "endArrowhead": "arrow" - }, - { - "id": "BlRXUB6fETT_zZD6O1fNL", - "type": "text", - "x": -163.05282592773438, - "y": 268.6500244140625, - "width": 124, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 609582183, - "version": 841, - "versionNonce": 2090882951, - "isDeleted": false, - "boundElementIds": null, - "text": "2. Download\n manifest", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "2tbWET6O9G38YibdIyLpy", - "type": "arrow", - "x": -12.186006749219864, - "y": 221.1919311337398, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1740746569, - "version": 1437, - "versionNonce": 1574439017, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "vtOTfv319aihVmgTMMbQG", - "focus": 0.3337009650548285, - "gap": 5.11281200236435 - }, - "endBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": -0.5585687247500966, - "gap": 11.002685522310514 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2ZWTQQ2dQDWF8xj1BLdVG", - "type": "text", - "x": 141.64752197265625, - "y": 364.4148864746094, - "width": 294, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1932287977, - "version": 912, - "versionNonce": 299486887, - "isDeleted": false, - "boundElementIds": [ - "nXkZQsrtjmNqPM6SmPxrc" - ], - "text": "3. Ask missing layers in cache", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "pIwVlwytOx1ZJ4aOCvtRF", - "type": "text", - "x": 636.46630859375, - "y": 352.5987548828125, - "width": 246, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 973317671, - "version": 871, - "versionNonce": 1819087689, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Return existing layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "FuK6iJ6YprzRoh4wg1UHf", - "type": "arrow", - "x": 75.37933138554581, - "y": 220.52838743256788, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1148774855, - "version": 1487, - "versionNonce": 722952647, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "vtOTfv319aihVmgTMMbQG", - "focus": -0.36784928325571326, - "gap": 5.485033392258245 - }, - "endBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": 0.4745035772454494, - "gap": 11.666229223482446 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "jgdyeMn1ZO33kPci2KoGL", - "type": "text", - "x": 94.91287231445312, - "y": 265.060302734375, - "width": 162, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1318802377, - "version": 872, - "versionNonce": 1037943337, - "isDeleted": false, - "boundElementIds": null, - "text": "5. Pull only\n missing layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "o_BKODe9vjtHWQsJ8F3tD", - "type": "arrow", - "x": 128.61206957157697, - "y": 440.13062341766545, - "width": 316.63877589590845, - "height": 0.1213064482017785, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 20958471, - "version": 415, - "versionNonce": 1769312487, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 316.63877589590845, - 0.1213064482017785 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": 0.030966433153118762, - "gap": 8.19887682255353 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.16596748618058757, - "gap": 13.386208975873956 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "6DaFskX4dI8KM57tYJKwz", - "type": "text", - "x": 151.09302660282708, - "y": 409.41115607163283, - "width": 259, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 221555433, - "version": 1091, - "versionNonce": 1058379017, - "isDeleted": false, - "boundElementIds": null, - "text": "7. Send the analysis result", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "zTrormMP-N-W6thSxlTgK", - "type": "arrow", - "x": 639.0015349036082, - "y": 455.7986607407429, - "width": 233.13104569613938, - "height": 0.2533468001336132, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1122927111, - "version": 471, - "versionNonce": 377543687, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 233.13104569613938, - 0.2533468001336132 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.4608119841777207, - "gap": 11.145028555951967 - }, - "endBinding": { - "elementId": "Z5DzSXSTeTNfyo9GRr57B", - "focus": -0.42458037983475105, - "gap": 8.237658674598492 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2sst3d11OgZLJZ3vdmH15", - "type": "text", - "x": 709.851318359375, - "y": 424.4541015625, - "width": 82, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1801175527, - "version": 1132, - "versionNonce": 865078249, - "isDeleted": false, - "boundElementIds": null, - "text": "8. Store", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "QsQ0GcuViNzFPK5QPICis", - "type": "text", - "x": 408.48883056640625, - "y": 561.8040618896484, - "width": 254, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 773954023, - "version": 992, - "versionNonce": 419481159, - "isDeleted": false, - "boundElementIds": null, - "text": "9. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "fBva4zCGT2vIFPpTWC-oZ", - "type": "arrow", - "x": 448.39657694205636, - "y": 484.4299201560043, - "width": 322.1210694778896, - "height": 0.5052042161862573, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 184790569, - "version": 677, - "versionNonce": 151709097, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -322.1210694778896, - -0.5052042161862573 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -1.0131990709910756, - "gap": 10.240477501303019 - }, - "endBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": 0.8669472708483955, - "gap": 5.862314715143327 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "PALQlCWrOXdjqBkRKhS6D", - "type": "draw", - "x": 523.952392578125, - "y": 487.95794677734375, - "width": 72.486083984375, - "height": 62.78338623046875, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#15aabf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 273802089, - "version": 310, - "versionNonce": 230581607, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -23.2962646484375, - 36.8623046875 - ], - [ - -3.4830322265625, - 59.561767578125 - ], - [ - 29.205810546875, - 62.78338623046875 - ], - [ - 49.1898193359375, - 49.74090576171875 - ], - [ - 45.6522216796875, - 21.439453125 - ], - [ - 24.2618408203125, - 1.5714111328125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "vP9i2PUtjapBX142LXX7m", - "type": "draw", - "x": 552.87939453125, - "y": 504.59832763671875, - "width": 16.5072021484375, - "height": 18.1295166015625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#15aabf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 786227753, - "version": 48, - "versionNonce": 2144487561, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.4810791015625, - -18.1295166015625 - ], - [ - 16.5072021484375, - -13.106201171875 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "2XUWMZRUNlhKGsJGNjK9k", - "type": "text", - "x": 154.5665283203125, - "y": 450.849365234375, - "width": 258, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 826013511, - "version": 1180, - "versionNonce": 1404772487, - "isDeleted": false, - "boundElementIds": null, - "text": "10. Return the scan result", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/test/imgs/excalidraw/fs.excalidraw b/test/imgs/excalidraw/fs.excalidraw deleted file mode 100644 index bd97566531aa..000000000000 --- a/test/imgs/excalidraw/fs.excalidraw +++ /dev/null @@ -1,397 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 528.53466796875, - "y": 377.9640197753906, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 274, - "versionNonce": 942385065, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 496.9409637451172, - "y": 63.6944580078125, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 595, - "versionNonce": 1870840679, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 585.4711608886719, - "y": 418.1110534667969, - "width": 48, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 119, - "versionNonce": 1368050313, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 558.5760498046875, - "y": 114.79718017578125, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 368, - "versionNonce": 2034482823, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 608.6504180950899, - "y": 218.69285081443215, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 1069, - "versionNonce": 2093125993, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": -0.035986229233252585, - "gap": 2.9120411440381986 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.04563780983822369, - "gap": 5.10864450968802 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 637.9371185302734, - "y": 248.28482055664062, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 360, - "versionNonce": 326653351, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "zdNQvzJczyD9GSExNdKS1", - "type": "draw", - "x": 513.9153137207031, - "y": 461.14288330078125, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1270145927, - "version": 459, - "versionNonce": 1094761993, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "YK7xYiSKb1RwCCobsRAXm", - "type": "text", - "x": 391.5774230957031, - "y": 541.0142517089844, - "width": 280, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2027931817, - "version": 510, - "versionNonce": 1538345895, - "isDeleted": false, - "boundElementIds": null, - "text": "3. Traverse directories\nand look for necessary files", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Z_DiM_TKY2bBa4Q5VEWgI", - "type": "text", - "x": 684.9671020507812, - "y": 621.1561279296875, - "width": 160, - "height": 25, - "angle": 0, - "strokeColor": "#1864ab", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1365660617, - "version": 564, - "versionNonce": 2113117703, - "isDeleted": false, - "boundElementIds": null, - "text": "Local Filesystem", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "kqEATPhet5tYxzkEOFZng", - "type": "text", - "x": 571.0751342773438, - "y": 494.0994567871094, - "width": 254, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 130557095, - "version": 654, - "versionNonce": 2037434313, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "K0XdIaMYVmUP2kGc8Oe1O", - "type": "rectangle", - "x": 360.9377136230469, - "y": 357.07373046875, - "width": 495.45401000976557, - "height": 297.8450317382812, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1367853545, - "version": 339, - "versionNonce": 314224297, - "isDeleted": false, - "boundElementIds": null - }, - { - "id": "_vOsyHICDRWn01MF3g7rB", - "type": "draw", - "x": 539.7380981445312, - "y": 501.50762939453125, - "width": 16.976165771484375, - "height": 16.45367431640625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1322966281, - "version": 82, - "versionNonce": 244034663, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 6.905059814453125, - -16.45367431640625 - ], - [ - 16.976165771484375, - -5.1099853515625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/test/imgs/excalidraw/image.excalidraw b/test/imgs/excalidraw/image.excalidraw deleted file mode 100644 index 005aa44462a7..000000000000 --- a/test/imgs/excalidraw/image.excalidraw +++ /dev/null @@ -1,504 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 528.53466796875, - "y": 359.7196350097656, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 235, - "versionNonce": 865905065, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 382.4654998779297, - "y": 70.28388977050781, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 442, - "versionNonce": 1305668297, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 585.4711608886719, - "y": 399.8666687011719, - "width": 48, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 82, - "versionNonce": 463601353, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 445.5017395019531, - "y": 121.72871398925781, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 306, - "versionNonce": 1721298503, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 497.981827043938, - "y": 226.98470679602065, - "width": 90.39040277767413, - "height": 127.08286800676547, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 591, - "versionNonce": 1564262983, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 90.39040277767413, - 127.08286800676547 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": 0.41046776258752976, - "gap": 4.7596344319156 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.1341309277800711, - "gap": 5.652060206979513 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 181.22366333007812, - "y": 252.094970703125, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 281, - "versionNonce": 1175555431, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "P3WUTj2Q9se-JE7t3AUeq", - "type": "ellipse", - "x": 635.5376052856445, - "y": 68.77783966064453, - "width": 286.11024475097656, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1633931305, - "version": 684, - "versionNonce": 1011691465, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo" - ] - }, - { - "id": "2q_e-oMWU2gv7ZEClixAx", - "type": "text", - "x": 680.7248458862305, - "y": 102.90502166748047, - "width": 186, - "height": 74, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 866083559, - "version": 676, - "versionNonce": 1669555559, - "isDeleted": false, - "boundElementIds": null, - "text": "Container Registry\nor\nContainer Engine", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 67 - }, - { - "id": "JinTKutXOSTzURP969rwo", - "type": "arrow", - "x": 725.3393330640303, - "y": 216.94283962355922, - "width": 69.9915382406898, - "height": 134.02688987715163, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1348821927, - "version": 938, - "versionNonce": 1580551495, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -69.9915382406898, - 134.02688987715163 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "P3WUTj2Q9se-JE7t3AUeq", - "focus": 0.10510087993199528, - "gap": 1.4587528984692284 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.0931277668871816, - "gap": 8.74990550905477 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "kHnEt-AjbEzMxB61VSDc2", - "type": "text", - "x": 723.4168395996094, - "y": 258.063232421875, - "width": 295, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1080814281, - "version": 613, - "versionNonce": 1064224615, - "isDeleted": false, - "boundElementIds": null, - "text": "2. Pull missing layers in cache", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "zdNQvzJczyD9GSExNdKS1", - "type": "draw", - "x": 524.4000854492188, - "y": 435.25982666015625, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1270145927, - "version": 331, - "versionNonce": 1090245193, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "13A9Y6sL_9DQ1KskiX5Oj", - "type": "draw", - "x": 545.8597412109375, - "y": 483.20318603515625, - "width": 25.76263427734375, - "height": 16.2581787109375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 788909033, - "version": 85, - "versionNonce": 991433415, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 13.24993896484375, - -16.2581787109375 - ], - [ - 25.76263427734375, - -5.01812744140625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "YK7xYiSKb1RwCCobsRAXm", - "type": "text", - "x": 261.88555908203125, - "y": 379.65887451171875, - "width": 249, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2027931817, - "version": 255, - "versionNonce": 809279785, - "isDeleted": false, - "boundElementIds": null, - "text": "3. Analyze layers &\nStore informatin in cache", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Z_DiM_TKY2bBa4Q5VEWgI", - "type": "text", - "x": 404.58673095703125, - "y": 522.828125, - "width": 144, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1365660617, - "version": 327, - "versionNonce": 2016944615, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Apply layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "kqEATPhet5tYxzkEOFZng", - "type": "text", - "x": 598.8711547851562, - "y": 480.22222900390625, - "width": 257, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 130557095, - "version": 539, - "versionNonce": 562048487, - "isDeleted": false, - "boundElementIds": null, - "text": "5. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/test/imgs/excalidraw/overview.excalidraw b/test/imgs/excalidraw/overview.excalidraw deleted file mode 100644 index 2762654df7f2..000000000000 --- a/test/imgs/excalidraw/overview.excalidraw +++ /dev/null @@ -1,466 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "type": "rectangle", - "version": 788, - "versionNonce": 555477386, - "isDeleted": false, - "id": "BkXuq_6BxgqZGZWc8oCtu", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 599.653076171875, - "y": 734.7542114257812, - "strokeColor": "#000000", - "backgroundColor": "#fd7e14", - "width": 1227.452155219184, - "height": 151.39703369140625, - "seed": 1632394695, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177570112, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 713, - "versionNonce": 44400470, - "isDeleted": false, - "id": "YQURTHNPSe05RPSlYRcok", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1118.2101508246528, - "y": 763.5906914605034, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 88, - "height": 45, - "seed": 891391049, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177702292, - "link": null, - "locked": false, - "fontSize": 36, - "fontFamily": 1, - "text": "Trivy", - "baseline": 32, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "Trivy" - }, - { - "type": "text", - "version": 1191, - "versionNonce": 1166344150, - "isDeleted": false, - "id": "6dpF2EyZBtYgO6MrvGj0-", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 875.3033447265625, - "y": 820.7327100965712, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 612, - "height": 36, - "seed": 687997545, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177705177, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Vulnerability/Misconfiguration/Secret Scanner", - "baseline": 25, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "Vulnerability/Misconfiguration/Secret Scanner" - }, - { - "type": "rectangle", - "version": 858, - "versionNonce": 1118008458, - "isDeleted": false, - "id": "cpnTMy7L2AUg9IDJppF4H", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 600.9835205078125, - "y": 635.5783640543619, - "strokeColor": "#000000", - "backgroundColor": "#fab005", - "width": 335.3091227213542, - "height": 82.36856587727866, - "seed": 77164935, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1077, - "versionNonce": 1122201878, - "isDeleted": false, - "id": "9-blmNVtLesthMSY_f60t", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 649.8531494140625, - "y": 660.223378499349, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 224, - "height": 36, - "seed": 860091815, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Container Image", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "top", - "containerId": null, - "originalText": "Container Image" - }, - { - "type": "rectangle", - "version": 1118, - "versionNonce": 1679315786, - "isDeleted": false, - "id": "gugZxhi7ThlcjWY_MFO7q", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 954.3485412597656, - "y": 635.849225362142, - "strokeColor": "#000000", - "backgroundColor": "#be4bdb", - "width": 409.35879516601574, - "height": 82.97188822428383, - "seed": 1232790121, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1300, - "versionNonce": 1187044950, - "isDeleted": false, - "id": "K48gtpesBxIGJxLTnI2CB", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1084.4311319986978, - "y": 660.9795074462891, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 139, - "height": 36, - "seed": 449264361, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Filesystem", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "top", - "containerId": null, - "originalText": "Filesystem" - }, - { - "type": "rectangle", - "version": 1204, - "versionNonce": 688085514, - "isDeleted": false, - "id": "La6f87LDZ0uEIZB947bXo", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1375.0136108398438, - "y": 636.5654322306316, - "strokeColor": "#000000", - "backgroundColor": "#12b886", - "width": 452.76554361979186, - "height": 80.08313496907543, - "seed": 2005637801, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1432, - "versionNonce": 1593746326, - "isDeleted": false, - "id": "aOgRPVQ81jhOfkvzjWTMF", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1498.8465237087673, - "y": 658.0244835747612, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 201, - "height": 36, - "seed": 1284472935, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Git Repository", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "top", - "containerId": null, - "originalText": "Git Repository" - }, - { - "type": "rectangle", - "version": 2792, - "versionNonce": 183831882, - "isDeleted": false, - "id": "10WjipxoLx2zzSI91pXbR", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 599.7894943723566, - "y": 905.6027750791251, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "width": 344.482180700969, - "height": 83.67398764683533, - "seed": 1813731484, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177825759, - "link": null, - "locked": false - }, - { - "type": "rectangle", - "version": 2771, - "versionNonce": 617525398, - "isDeleted": false, - "id": "M7Cngti6H0_kawKRN8yJ6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 963.2554264391833, - "y": 904.2447769132434, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 402.42137951281796, - "height": 86.03696372105414, - "seed": 1260603804, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177777585, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1057, - "versionNonce": 405881110, - "isDeleted": false, - "id": "Iq57wFRtO1a8AU0rT6lRD", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1046.152429428344, - "y": 930.8676815998951, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 218, - "height": 36, - "seed": 1329695396, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177655817, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Misconfiguration", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": null, - "originalText": "Misconfiguration" - }, - { - "type": "text", - "version": 883, - "versionNonce": 969949898, - "isDeleted": false, - "id": "_cm6xpfcL9Yv2XBK5MBZF", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 681.3134368986982, - "y": 931.5212932384402, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 161, - "height": 36, - "seed": 807441828, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177624726, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Vulnerability", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": null, - "originalText": "Vulnerability" - }, - { - "type": "rectangle", - "version": 2874, - "versionNonce": 1934391254, - "isDeleted": false, - "id": "Fq7meULupm1A9leboPlko", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1389.3043677318824, - "y": 903.8533384764222, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "width": 437.15079032010976, - "height": 84.42746665074158, - "seed": 230693534, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177785481, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1121, - "versionNonce": 110517002, - "isDeleted": false, - "id": "OUGk8nZzvgcKUHhKUcQov", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1556.0451356485157, - "y": 930.8040952304675, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 91, - "height": 36, - "seed": 2044527454, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177636085, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Secret", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": null, - "originalText": "Secret" - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - }, - "files": {} -} \ No newline at end of file diff --git a/test/imgs/excalidraw/repo.excalidraw b/test/imgs/excalidraw/repo.excalidraw deleted file mode 100644 index 72fcf1b47905..000000000000 --- a/test/imgs/excalidraw/repo.excalidraw +++ /dev/null @@ -1,631 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 458.6370544433594, - "y": 379.5105285644531, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 360, - "versionNonce": 899087049, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "nXkZQsrtjmNqPM6SmPxrc" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 427.04335021972656, - "y": 65.240966796875, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 679, - "versionNonce": 1333899847, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 515.5735473632812, - "y": 419.6575622558594, - "width": 48, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 202, - "versionNonce": 677296553, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 488.6784362792969, - "y": 116.34368896484375, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 451, - "versionNonce": 490852711, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 538.7528045696993, - "y": 220.23935960349465, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 1292, - "versionNonce": 764124297, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": -0.03598869040285281, - "gap": 2.911871895302724 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.04563780983822428, - "gap": 5.10864450968802 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 190.61294555664062, - "y": 255.17030334472656, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 569, - "versionNonce": 2012286087, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "YK7xYiSKb1RwCCobsRAXm", - "type": "text", - "x": 588.7474975585938, - "y": 488.1255798339844, - "width": 280, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2027931817, - "version": 628, - "versionNonce": 30461609, - "isDeleted": false, - "boundElementIds": null, - "text": "3. Traverse directories\nand look for necessary files", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Z_DiM_TKY2bBa4Q5VEWgI", - "type": "text", - "x": 877.162353515625, - "y": 618.5094604492188, - "width": 160, - "height": 25, - "angle": 0, - "strokeColor": "#1864ab", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1365660617, - "version": 647, - "versionNonce": 760156423, - "isDeleted": false, - "boundElementIds": null, - "text": "Local Filesystem", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "K0XdIaMYVmUP2kGc8Oe1O", - "type": "rectangle", - "x": 360.9377136230469, - "y": 357.07373046875, - "width": 695.5669860839844, - "height": 297.8450317382812, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1367853545, - "version": 417, - "versionNonce": 1598611913, - "isDeleted": false, - "boundElementIds": null - }, - { - "id": "9cBakj4Z-FKXwYYdweyW1", - "type": "ellipse", - "x": 774.155647277832, - "y": 56.2083175778389, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1010956009, - "version": 673, - "versionNonce": 825999529, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "vGa683rpZ9AztfvrVvEyD" - ] - }, - { - "id": "5y2AKGYkXhCldwQOecwl6", - "type": "text", - "x": 806.7732543945312, - "y": 106.18511658906937, - "width": 147, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1289267591, - "version": 83, - "versionNonce": 1127203721, - "isDeleted": false, - "boundElementIds": null, - "text": "Remote\nGit Repository", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "vGa683rpZ9AztfvrVvEyD", - "type": "arrow", - "x": 884.4609964246083, - "y": 220.86864013003574, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1762737031, - "version": 1200, - "versionNonce": 457627015, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "9cBakj4Z-FKXwYYdweyW1", - "focus": -0.022674122391029432, - "gap": 12.541597764893623 - }, - "endBinding": { - "elementId": "4_okkFmweGK_2DBTmRp4i", - "focus": 0.047202684587572305, - "gap": 3.295263653270979 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "4_okkFmweGK_2DBTmRp4i", - "type": "rectangle", - "x": 796.4703521728516, - "y": 378.3264282345772, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 853231143, - "version": 387, - "versionNonce": 1096837737, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "vGa683rpZ9AztfvrVvEyD", - "nXkZQsrtjmNqPM6SmPxrc" - ] - }, - { - "id": "zvgwnUmSms_XcbMDespIP", - "type": "text", - "x": 847.181640625, - "y": 404.5675476193428, - "width": 72, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1769283399, - "version": 307, - "versionNonce": 1392544935, - "isDeleted": false, - "boundElementIds": null, - "text": "Git\nProject", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "f0kayc0oXZazxPJKizaM1", - "type": "text", - "x": 916.8968811035156, - "y": 253.85886842012405, - "width": 258, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 49135625, - "version": 649, - "versionNonce": 1150891337, - "isDeleted": false, - "boundElementIds": null, - "text": "2. Clone Git Repository\n to local temp directory", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "nXkZQsrtjmNqPM6SmPxrc", - "type": "arrow", - "x": 640.9059448242188, - "y": 429.34260255098343, - "width": 146.4581298828125, - "height": 0.93572998046875, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2075020231, - "version": 93, - "versionNonce": 1421238215, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 146.4581298828125, - -0.93572998046875 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.031650787945314215, - "gap": 13.0494384765625 - }, - "endBinding": { - "elementId": "4_okkFmweGK_2DBTmRp4i", - "focus": 0.050151997400131744, - "gap": 9.106277465820312 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "OPRFQTrsfmF5a7us-mxkI", - "type": "draw", - "x": 446.98912048339844, - "y": 467.28928834199905, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1541066697, - "version": 504, - "versionNonce": 1115999975, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "QzKnYI7o5Yxg_7szebL6Z", - "type": "draw", - "x": 472.81190490722656, - "y": 507.65403443574905, - "width": 16.976165771484375, - "height": 16.45367431640625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2144447815, - "version": 127, - "versionNonce": 807483145, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 6.905059814453125, - -16.45367431640625 - ], - [ - 16.976165771484375, - -5.1099853515625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "qqbEan2u1uU3loTdTvQ4B", - "type": "text", - "x": 376.983642578125, - "y": 561.5254028439522, - "width": 254, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1619652615, - "version": 718, - "versionNonce": 1190681095, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/test/imgs/fs.png b/test/imgs/fs.png deleted file mode 100644 index 2a6acb83d058..000000000000 Binary files a/test/imgs/fs.png and /dev/null differ diff --git a/test/imgs/gitlab-codequality.png b/test/imgs/gitlab-codequality.png deleted file mode 100644 index b7069b8af7c1..000000000000 Binary files a/test/imgs/gitlab-codequality.png and /dev/null differ diff --git a/test/imgs/image.png b/test/imgs/image.png deleted file mode 100644 index e014f0c7b653..000000000000 Binary files a/test/imgs/image.png and /dev/null differ diff --git a/test/imgs/logo-horizontal.svg b/test/imgs/logo-horizontal.svg deleted file mode 100644 index fb169f58c8b8..000000000000 --- a/test/imgs/logo-horizontal.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/imgs/logo-white.svg b/test/imgs/logo-white.svg deleted file mode 100644 index 4aa8d97280ad..000000000000 --- a/test/imgs/logo-white.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/imgs/logo.png b/test/imgs/logo.png deleted file mode 100644 index 3048e8ce67f2..000000000000 Binary files a/test/imgs/logo.png and /dev/null differ diff --git a/test/imgs/overview.png b/test/imgs/overview.png deleted file mode 100644 index 777c32d939d2..000000000000 Binary files a/test/imgs/overview.png and /dev/null differ diff --git a/test/imgs/repo.png b/test/imgs/repo.png deleted file mode 100644 index 80b80689d02f..000000000000 Binary files a/test/imgs/repo.png and /dev/null differ diff --git a/test/imgs/secret-demo.gif b/test/imgs/secret-demo.gif deleted file mode 100644 index 085606ccb563..000000000000 Binary files a/test/imgs/secret-demo.gif and /dev/null differ diff --git a/test/imgs/trivy-aws.png b/test/imgs/trivy-aws.png deleted file mode 100644 index 5e748fea5757..000000000000 Binary files a/test/imgs/trivy-aws.png and /dev/null differ diff --git a/test/imgs/trivy-k8s.png b/test/imgs/trivy-k8s.png deleted file mode 100644 index e959d50c7039..000000000000 Binary files a/test/imgs/trivy-k8s.png and /dev/null differ diff --git a/test/index.html b/test/index.html deleted file mode 100644 index 19e9dad7e246..000000000000 --- a/test/index.html +++ /dev/null @@ -1,3087 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - - - -
    -
    - - - - -

    logo

    -

    Trivy Documentation

    -

    👋 Welcome to Trivy Documentation! To help you get around, please notice the different sections at the top global menu:

    -
      -
    • You are currently in the Getting Started section where you can find general information and help with first steps.
    • -
    • In the Tutorials section you can find step-by-step guides that help you accomplish specific tasks.
    • -
    • In the Docs section you can find the complete reference documentation for all of the different features and settings that Trivy has to offer.
    • -
    • In the Ecosystem section you can find how Trivy works together with other tools and applications that you might already use.
    • -
    • In the Contributing section you can find technical developer documentation and contribution guidelines.
    • -
    -

    About Trivy

    -

    Trivy (pronunciation) is a comprehensive and versatile security scanner. Trivy has scanners that look for security issues, and targets where it can find those issues.

    -

    Targets (what Trivy can scan):

    -
      -
    • Container Image
    • -
    • Filesystem
    • -
    • Git Repository (remote)
    • -
    • Virtual Machine Image
    • -
    • Kubernetes
    • -
    • AWS
    • -
    -

    Scanners (what Trivy can find there):

    -
      -
    • OS packages and software dependencies in use (SBOM)
    • -
    • Known vulnerabilities (CVEs)
    • -
    • IaC issues and misconfigurations
    • -
    • Sensitive information and secrets
    • -
    • Software licenses
    • -
    -

    To learn more, go to the Trivy homepage for feature highlights, or to the Documentation site for detailed information.

    -

    Quick Start

    -

    Get Trivy

    -

    Trivy is available in most common distribution channels. The complete list of installation options is available in the Installation page. Here are a few popular examples:

    - -

    Trivy is integrated with many popular platforms and applications. The complete list of integrations is available in the Ecosystem page. Here are a few popular options examples:

    - -

    General usage

    -
    trivy <target> [--scanners <scanner1,scanner2>] <subject>
    -
    -

    Examples:

    -
    trivy image python:3.4-alpine
    -
    -
    -Result - -
    - -
    Demo: Vulnerability Detection
    -
    - -
    - -
    trivy fs --scanners vuln,secret,config myproject/
    -
    -
    -Result - -
    - -
    Demo: Misconfiguration Detection
    -
    - -
    - -
    trivy k8s --report summary cluster
    -
    -
    -Result - -
    - -
    Demo: Secret Detection
    -
    - -
    -
    -

    Trivy is an Aqua Security open source project.
    -Learn about our open source work and portfolio here.
    -Contact us about any matter by opening a GitHub Discussion here

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/overrides/main.html b/test/overrides/main.html deleted file mode 100644 index f3bc7637878b..000000000000 --- a/test/overrides/main.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "base.html" %} - -{% block outdated %} -You're not viewing the latest version. - - Click here to go to latest. - -{% endblock %} \ No newline at end of file diff --git a/test/search/search_index.json b/test/search/search_index.json deleted file mode 100644 index abd4ef1adec1..000000000000 --- a/test/search/search_index.json +++ /dev/null @@ -1 +0,0 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Trivy Documentation \ud83d\udc4b Welcome to Trivy Documentation! To help you get around, please notice the different sections at the top global menu: You are currently in the Getting Started section where you can find general information and help with first steps. In the Tutorials section you can find step-by-step guides that help you accomplish specific tasks. In the Docs section you can find the complete reference documentation for all of the different features and settings that Trivy has to offer. In the Ecosystem section you can find how Trivy works together with other tools and applications that you might already use. In the Contributing section you can find technical developer documentation and contribution guidelines. About Trivy Trivy ( pronunciation ) is a comprehensive and versatile security scanner. Trivy has scanners that look for security issues, and targets where it can find those issues. Targets (what Trivy can scan): Container Image Filesystem Git Repository (remote) Virtual Machine Image Kubernetes AWS Scanners (what Trivy can find there): OS packages and software dependencies in use (SBOM) Known vulnerabilities (CVEs) IaC issues and misconfigurations Sensitive information and secrets Software licenses To learn more, go to the Trivy homepage for feature highlights, or to the Documentation site for detailed information. Quick Start Get Trivy Trivy is available in most common distribution channels. The complete list of installation options is available in the Installation page. Here are a few popular examples: brew install trivy docker run aquasec/trivy Download binary from https://github.com/aquasecurity/trivy/releases/latest/ See Installation for more Trivy is integrated with many popular platforms and applications. The complete list of integrations is available in the Ecosystem page. Here are a few popular options examples: GitHub Actions Kubernetes operator VS Code plugin See Ecosystem for more General usage trivy [ --scanners ] Examples: trivy image python:3.4-alpine Result Demo: Vulnerability Detection trivy fs --scanners vuln,secret,config myproject/ Result Demo: Misconfiguration Detection trivy k8s --report summary cluster Result Demo: Secret Detection Trivy is an Aqua Security open source project. Learn about our open source work and portfolio here . Contact us about any matter by opening a GitHub Discussion here","title":"Overview"},{"location":"#trivy-documentation","text":"\ud83d\udc4b Welcome to Trivy Documentation! To help you get around, please notice the different sections at the top global menu: You are currently in the Getting Started section where you can find general information and help with first steps. In the Tutorials section you can find step-by-step guides that help you accomplish specific tasks. In the Docs section you can find the complete reference documentation for all of the different features and settings that Trivy has to offer. In the Ecosystem section you can find how Trivy works together with other tools and applications that you might already use. In the Contributing section you can find technical developer documentation and contribution guidelines.","title":"Trivy Documentation"},{"location":"#about-trivy","text":"Trivy ( pronunciation ) is a comprehensive and versatile security scanner. Trivy has scanners that look for security issues, and targets where it can find those issues. Targets (what Trivy can scan): Container Image Filesystem Git Repository (remote) Virtual Machine Image Kubernetes AWS Scanners (what Trivy can find there): OS packages and software dependencies in use (SBOM) Known vulnerabilities (CVEs) IaC issues and misconfigurations Sensitive information and secrets Software licenses To learn more, go to the Trivy homepage for feature highlights, or to the Documentation site for detailed information.","title":"About Trivy"},{"location":"#quick-start","text":"","title":"Quick Start"},{"location":"#get-trivy","text":"Trivy is available in most common distribution channels. The complete list of installation options is available in the Installation page. Here are a few popular examples: brew install trivy docker run aquasec/trivy Download binary from https://github.com/aquasecurity/trivy/releases/latest/ See Installation for more Trivy is integrated with many popular platforms and applications. The complete list of integrations is available in the Ecosystem page. Here are a few popular options examples: GitHub Actions Kubernetes operator VS Code plugin See Ecosystem for more","title":"Get Trivy"},{"location":"#general-usage","text":"trivy [ --scanners ] Examples: trivy image python:3.4-alpine Result Demo: Vulnerability Detection trivy fs --scanners vuln,secret,config myproject/ Result Demo: Misconfiguration Detection trivy k8s --report summary cluster Result Demo: Secret Detection Trivy is an Aqua Security open source project. Learn about our open source work and portfolio here . Contact us about any matter by opening a GitHub Discussion here","title":"General usage"},{"location":"community/contribute/discussion/","text":"Discussions Thank you for taking interest in contributing to Trivy! Trivy uses GitHub Discussion for bug reports, feature requests, and questions. If maintainers decide to accept a new feature or confirm that it is a bug, they will close the discussion and create a GitHub Issue associated with that discussion. Feel free to open discussions for any reason. When you open a new discussion, you'll have to select a discussion category as described below. Please spend a small amount of time giving due diligence to the issue/discussion tracker. Your discussion might be a duplicate. If it is, please add your comment to the existing issue/discussion. Remember that users might search for your issue/discussion in the future, so please give it a meaningful title to help others. The issue should clearly explain the reason for opening, the proposal if you have any, and any relevant technical information. There are 4 categories: \ud83d\udca1 Ideas Share ideas for new features \ud83d\udd0e False Detection Report false positives/negatives \ud83d\udc1b Bugs Report something that is not working as expected \ud83d\ude4f Q&A Ask the community for help Note If you find any false positives or false negatives, please make sure to report them under the \"False Detection\" category, not \"Bugs\". False detection Trivy depends on multiple data sources . Sometime these databases contain mistakes. If Trivy can't detect any CVE-IDs or shows false positive result, at first please follow the next steps: Run Trivy with -f json that shows data sources. According to the shown data source, make sure that the security advisory in the data source is correct. If the data source is correct and Trivy shows wrong results, please raise an issue on Trivy. GitHub Advisory Database Visit here and search CVE-ID. If you find a problem, it'll be nice to fix it: How to contribute to a GitHub security advisory GitLab Advisory Database Visit here and search CVE-ID. If you find a problem, it'll be nice to fix it: Create an issue to GitLab Advisory Database Red Hat CVE Database Visit here and search CVE-ID.","title":"Discussions"},{"location":"community/contribute/discussion/#discussions","text":"Thank you for taking interest in contributing to Trivy! Trivy uses GitHub Discussion for bug reports, feature requests, and questions. If maintainers decide to accept a new feature or confirm that it is a bug, they will close the discussion and create a GitHub Issue associated with that discussion. Feel free to open discussions for any reason. When you open a new discussion, you'll have to select a discussion category as described below. Please spend a small amount of time giving due diligence to the issue/discussion tracker. Your discussion might be a duplicate. If it is, please add your comment to the existing issue/discussion. Remember that users might search for your issue/discussion in the future, so please give it a meaningful title to help others. The issue should clearly explain the reason for opening, the proposal if you have any, and any relevant technical information. There are 4 categories: \ud83d\udca1 Ideas Share ideas for new features \ud83d\udd0e False Detection Report false positives/negatives \ud83d\udc1b Bugs Report something that is not working as expected \ud83d\ude4f Q&A Ask the community for help Note If you find any false positives or false negatives, please make sure to report them under the \"False Detection\" category, not \"Bugs\".","title":"Discussions"},{"location":"community/contribute/discussion/#false-detection","text":"Trivy depends on multiple data sources . Sometime these databases contain mistakes. If Trivy can't detect any CVE-IDs or shows false positive result, at first please follow the next steps: Run Trivy with -f json that shows data sources. According to the shown data source, make sure that the security advisory in the data source is correct. If the data source is correct and Trivy shows wrong results, please raise an issue on Trivy.","title":"False detection"},{"location":"community/contribute/discussion/#github-advisory-database","text":"Visit here and search CVE-ID. If you find a problem, it'll be nice to fix it: How to contribute to a GitHub security advisory","title":"GitHub Advisory Database"},{"location":"community/contribute/discussion/#gitlab-advisory-database","text":"Visit here and search CVE-ID. If you find a problem, it'll be nice to fix it: Create an issue to GitLab Advisory Database","title":"GitLab Advisory Database"},{"location":"community/contribute/discussion/#red-hat-cve-database","text":"Visit here and search CVE-ID.","title":"Red Hat CVE Database"},{"location":"community/contribute/issue/","text":"Issues Thank you for taking interest in contributing to Trivy! Trivy uses GitHub Discussion for bug reports, feature requests, and questions.","title":"Issues"},{"location":"community/contribute/issue/#issues","text":"Thank you for taking interest in contributing to Trivy! Trivy uses GitHub Discussion for bug reports, feature requests, and questions.","title":"Issues"},{"location":"community/contribute/pr/","text":"Thank you for taking interest in contributing to Trivy! Every Pull Request should have an associated bug or feature issue unless you are fixing a trivial documentation issue. Please add the associated Issue link in the PR description. Your PR is more likely to be accepted if it focuses on just one change. There's no need to add or tag reviewers. If a reviewer commented on your code or asked for changes, please remember to respond with comment. Do not mark discussion as resolved. It's up to reviewer to mark it resolved (in case if suggested fix addresses problem properly). PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side). Please include a comment with the results before and after your change. Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!). If your PR affects the user experience in some way, please update the README.md and the CLI help accordingly. Development Install the necessary tools for development by following their respective installation instructions. Go Mage Build After making changes to the Go source code, build the project with the following command: $ mage build $ ./trivy -h Lint You must pass the linter checks: $ mage lint Additionally, you need to have run go mod tidy , so execute the following command as well: $ mage tidy Unit tests Your PR must pass all the unit tests. You can test it as below. $ mage test:unit Integration tests Your PR must pass all the integration tests. You can test it as below. $ mage test:integration Documentation If you update CLI flags, you need to generate the CLI references. The test will fail if they are not up-to-date. $ mage docs:generate You can build the documents as below and view it at http://localhost:8000. $ mage docs:serve Title It is not that strict, but we use the title conventions in this repository. Each commit message doesn't have to follow the conventions as long as it is clear and descriptive since it will be squashed and merged. Format of the title (): The type and scope should always be lowercase as shown below. Allowed values: feat for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version. fix for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version. perf for performance improvements. Such commit will trigger a release bumping a PATCH version. docs for changes to the documentation. style for formatting changes, missing semicolons, etc. refactor for refactoring production code, e.g. renaming a variable. test for adding missing tests, refactoring tests; no production code change. build for updating build configuration, development tools or other changes irrelevant to the user. chore for updates that do not apply to the above, such as dependency updates. ci for changes to CI configuration files and scripts revert for revert to a previous commit Allowed values: checks: vuln misconf secret license mode: image fs repo sbom k8s server aws vm os: alpine redhat alma rocky mariner oracle debian ubuntu amazon suse photon distroless language: ruby php python nodejs rust dotnet java go elixir dart vuln: os lang config: kubernetes dockerfile terraform cloudformation container docker podman containerd oci cli: cli flag SBOM: cyclonedx spdx purl others: helm report db deps The can be empty (e.g. if the change is a global or difficult to assign to a single component), in which case the parentheses are omitted. Example titles feat(alma): add support for AlmaLinux fix(oracle): handle advisories with ksplice versions docs(misconf): add comparison with Conftest and TFsec chore(deps): bump go.uber.org/zap from 1.19.1 to 1.20.0 NOTE : please do not use chore(deps): update fanal and something like that if you add new features or fix bugs in Trivy-related projects. The PR title should describe what the PR adds or fixes even though it just updates the dependency in Trivy. Commits Understand where your pull request belongs Trivy is composed of several repositories that work together: Trivy is the client-side, user-facing, command line tool. vuln-list is a vulnerability database, aggregated from different sources, and normalized for easy consumption. Think of this as the \"server\" side of the trivy command line tool. There should be no pull requests to this repo vuln-list-update is the code that maintains the vuln-list database. trivy-db maintains the vulnerability database pulled by Trivy CLI. go-dep-parser is a library for parsing lock files such as package-lock.json and Gemfile.lock.","title":"Pull Requests"},{"location":"community/contribute/pr/#development","text":"Install the necessary tools for development by following their respective installation instructions. Go Mage","title":"Development"},{"location":"community/contribute/pr/#build","text":"After making changes to the Go source code, build the project with the following command: $ mage build $ ./trivy -h","title":"Build"},{"location":"community/contribute/pr/#lint","text":"You must pass the linter checks: $ mage lint Additionally, you need to have run go mod tidy , so execute the following command as well: $ mage tidy","title":"Lint"},{"location":"community/contribute/pr/#unit-tests","text":"Your PR must pass all the unit tests. You can test it as below. $ mage test:unit","title":"Unit tests"},{"location":"community/contribute/pr/#integration-tests","text":"Your PR must pass all the integration tests. You can test it as below. $ mage test:integration","title":"Integration tests"},{"location":"community/contribute/pr/#documentation","text":"If you update CLI flags, you need to generate the CLI references. The test will fail if they are not up-to-date. $ mage docs:generate You can build the documents as below and view it at http://localhost:8000. $ mage docs:serve","title":"Documentation"},{"location":"community/contribute/pr/#title","text":"It is not that strict, but we use the title conventions in this repository. Each commit message doesn't have to follow the conventions as long as it is clear and descriptive since it will be squashed and merged.","title":"Title"},{"location":"community/contribute/pr/#format-of-the-title","text":"(): The type and scope should always be lowercase as shown below. Allowed values: feat for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version. fix for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version. perf for performance improvements. Such commit will trigger a release bumping a PATCH version. docs for changes to the documentation. style for formatting changes, missing semicolons, etc. refactor for refactoring production code, e.g. renaming a variable. test for adding missing tests, refactoring tests; no production code change. build for updating build configuration, development tools or other changes irrelevant to the user. chore for updates that do not apply to the above, such as dependency updates. ci for changes to CI configuration files and scripts revert for revert to a previous commit Allowed values: checks: vuln misconf secret license mode: image fs repo sbom k8s server aws vm os: alpine redhat alma rocky mariner oracle debian ubuntu amazon suse photon distroless language: ruby php python nodejs rust dotnet java go elixir dart vuln: os lang config: kubernetes dockerfile terraform cloudformation container docker podman containerd oci cli: cli flag SBOM: cyclonedx spdx purl others: helm report db deps The can be empty (e.g. if the change is a global or difficult to assign to a single component), in which case the parentheses are omitted.","title":"Format of the title"},{"location":"community/contribute/pr/#example-titles","text":"feat(alma): add support for AlmaLinux fix(oracle): handle advisories with ksplice versions docs(misconf): add comparison with Conftest and TFsec chore(deps): bump go.uber.org/zap from 1.19.1 to 1.20.0 NOTE : please do not use chore(deps): update fanal and something like that if you add new features or fix bugs in Trivy-related projects. The PR title should describe what the PR adds or fixes even though it just updates the dependency in Trivy.","title":"Example titles"},{"location":"community/contribute/pr/#commits","text":"","title":"Commits"},{"location":"community/contribute/pr/#understand-where-your-pull-request-belongs","text":"Trivy is composed of several repositories that work together: Trivy is the client-side, user-facing, command line tool. vuln-list is a vulnerability database, aggregated from different sources, and normalized for easy consumption. Think of this as the \"server\" side of the trivy command line tool. There should be no pull requests to this repo vuln-list-update is the code that maintains the vuln-list database. trivy-db maintains the vulnerability database pulled by Trivy CLI. go-dep-parser is a library for parsing lock files such as package-lock.json and Gemfile.lock.","title":"Understand where your pull request belongs"},{"location":"community/maintainer/help-wanted/","text":"Overview We use two labels help wanted and good first issue to identify issues that have been specially groomed for new contributors. The good first issue label is a subset of help wanted label, indicating that members have committed to providing extra assistance for new contributors. All good first issue items also have the help wanted label. Help Wanted Items marked with the help wanted label need to ensure that they are: Low Barrier to Entry It should be tractable for new contributors. Documentation on how that type of change should be made should already exist. Clear Task The task is agreed upon and does not require further discussions in the community. Call out if that area of code is untested and requires new fixtures. API / CLI behavior is decided and included in the OP issue, for example: \"The new command syntax is trivy --format yaml IMAGE_NAME \"_ with expected validations called out. Goldilocks priority Not too high that a core contributor should do it, but not too low that it isn't useful enough for a core contributor to spend time to review it, answer questions, help get it into a release, etc. Up-To-Date Often these issues become obsolete and have already been done, are no longer desired, no longer make sense, have changed priority or difficulty , etc. Good First Issue Items marked with the good first issue label are intended for first-time contributors . It indicates that members will keep an eye out for these pull requests and shepherd it through our processes. These items need to ensure that they follow the guidelines for help wanted labels (above) in addition to meeting the following criteria: No Barrier to Entry The task is something that a new contributor can tackle without advanced setup, or domain knowledge. Solution Explained The recommended solution is clearly described in the issue. Provides Context If background knowledge is required, this should be explicitly mentioned and a list of suggested readings included. Gives Examples Link to examples of similar implementations so new contributors have a reference guide for their changes. Identifies Relevant Code The relevant code and tests to be changed should be linked in the issue. Ready to Test There should be existing tests that can be modified, or existing test cases fit to be copied. If the area of code doesn't have tests, before labeling the issue, add a test fixture. This prep often makes a great help wanted task!","title":"Help Wanted"},{"location":"community/maintainer/help-wanted/#overview","text":"We use two labels help wanted and good first issue to identify issues that have been specially groomed for new contributors. The good first issue label is a subset of help wanted label, indicating that members have committed to providing extra assistance for new contributors. All good first issue items also have the help wanted label.","title":"Overview"},{"location":"community/maintainer/help-wanted/#help-wanted","text":"Items marked with the help wanted label need to ensure that they are: Low Barrier to Entry It should be tractable for new contributors. Documentation on how that type of change should be made should already exist. Clear Task The task is agreed upon and does not require further discussions in the community. Call out if that area of code is untested and requires new fixtures. API / CLI behavior is decided and included in the OP issue, for example: \"The new command syntax is trivy --format yaml IMAGE_NAME \"_ with expected validations called out. Goldilocks priority Not too high that a core contributor should do it, but not too low that it isn't useful enough for a core contributor to spend time to review it, answer questions, help get it into a release, etc. Up-To-Date Often these issues become obsolete and have already been done, are no longer desired, no longer make sense, have changed priority or difficulty , etc.","title":"Help Wanted"},{"location":"community/maintainer/help-wanted/#good-first-issue","text":"Items marked with the good first issue label are intended for first-time contributors . It indicates that members will keep an eye out for these pull requests and shepherd it through our processes. These items need to ensure that they follow the guidelines for help wanted labels (above) in addition to meeting the following criteria: No Barrier to Entry The task is something that a new contributor can tackle without advanced setup, or domain knowledge. Solution Explained The recommended solution is clearly described in the issue. Provides Context If background knowledge is required, this should be explicitly mentioned and a list of suggested readings included. Gives Examples Link to examples of similar implementations so new contributors have a reference guide for their changes. Identifies Relevant Code The relevant code and tests to be changed should be linked in the issue. Ready to Test There should be existing tests that can be modified, or existing test cases fit to be copied. If the area of code doesn't have tests, before labeling the issue, add a test fixture. This prep often makes a great help wanted task!","title":"Good First Issue"},{"location":"community/maintainer/triage/","text":"Triage Triage is an important part of maintaining the health of the trivy repo. A well organized repo allows maintainers to prioritize feature requests, fix bugs, and respond to users facing difficulty with the tool as quickly as possible. Triage includes: Labeling issues Responding to issues Closing issues Daily Triage Daily triage has two goals: Responsiveness for new issues Responsiveness when explicitly requested information was provided It covers: Issues without a kind/ or triage/ label Issues without a priority/ label triage/needs-information issues which the user has followed up on, and now require a response. Categorization The most important level of categorizing the issue is defining what type it is. We typically want at least one of the following labels on every issue, and some issues may fall into multiple categories: triage/support - The default for most incoming issues kind/bug - When it\u2019s a bug or we aren\u2019t delivering the best user experience Other possibilities: - kind/feature - Identify new feature requests - kind/testing - Update or fix unit/integration tests - kind/cleanup - Cleaning up/refactoring the codebase - kind/documentation - Updates or additions to trivy documentation If the issue is specific to a driver for OS packages or libraries: co/[driver for OS packages] co/alpine co/amazon co/debian co/oracle co/photon co/redhat co/suse co/ubuntu co/[driver for libraries of programming languages] co/bundler co/cargo co/composer co/npm co/yarn co/pipenv co/poetry Help wanted? Good First Issue - bug has a proposed solution, can be implemented w/o further discussion. Help wanted - if the bug could use help from a contributor Prioritization If the issue is not triage/support , it needs a priority label. priority/critical-urgent - someones top priority ASAP, such as security issue, user-visible bug, or build breakage. Rarely used. priority/important-soon : in time for the next two releases. It should be attached to a milestone. priority/important-longterm : 2-4 releases from now priority/backlog : agreed that this would be good to have, but no one is available at the moment. Consider tagging as help wanted priority/awaiting-more-evidence : may be useful, but there is not yet enough support. Weekly Triage Weekly triage has three goals: Catching up on unresponded issues Reviewing and closing PR\u2019s Closing stale issues Post-Release Triage Post-release triage occurs after a major release (around every 4-6 weeks). It focuses on: Closing bugs that have been resolved by the release Reprioritizing bugs that have not been resolved by the release Letting users know if we believe that there is still an issue This includes reviewing: Every issue that hasn\u2019t been touched in the last 2 days Re-evaluation of long-term issues Re-evaluation of short-term issues Responding to Issues Needs More Information A sample response to ask for more info: I don\u2019t yet have a clear way to replicate this issue. Do you mind adding some additional details. Here is additional information that would be helpful: * The exact trivy command line used * The exact image you want to scan * The full output of the trivy command, preferably with --debug for extra logging. Thank you for sharing your experience! Then: Label with triage/needs-information . Issue might be resolved If you think a release may have resolved an issue, ask the author to see if their issue has been resolved: Could you please check to see if trivy addresses this issue? We've made some changes with how this is handled, and improved the trivy logs output to help us debug tricky cases like this. Then: Label with triage/needs-information . Closing with Care Issues typically need to be closed for the following reasons: The issue has been addressed The issue is a duplicate of an existing issue There has been a lack of information over a long period of time In any of these situations, we aim to be kind when closing the issue, and offer the author action items should they need to reopen their issue or still require a solution. Samples responses for these situations include: Issue has been addressed @author: I believe this issue is now addressed by trivy v1.0.0, as it . If you still see this issue with trivy v1.0 or higher, please reopen this issue. Thank you for reporting this issue! Then: Close the issue Duplicate Issue This issue appears to be a duplicate of #X, do you mind if we move the conversation there? This way we can centralize the content relating to the issue. If you feel that this issue is not in fact a duplicate, please re-open it. If you have additional information to share, please add it to the new issue. Thank you for reporting this! Then: Label with triage/duplicate and close the issue. Lack of Information If an issue hasn't been active for more than four weeks, and the author has been pinged at least once, then the issue can be closed. Hey @author -- hopefully it's OK if I close this - there wasn't enough information to make it actionable, and some time has already passed. If you are able to provide additional details, you may reopen it at any point. Here is additional information that may be helpful to us: * Whether the issue occurs with the latest trivy release * The exact trivy command line used * The exact image you want to scan * The full output of the trivy command, preferably with --debug for extra logging. Thank you for sharing your experience! Then: Close the issue. Help Wanted issues We use two labels help wanted and good first issue to identify issues that have been specially groomed for new contributors. We have specific guidelines for how to use these labels. If you see an issue that satisfies these guidelines, you can add the help wanted label and the good first issue label. Please note that adding the good first issue label must also add the help wanted label. If an issue has these labels but does not satisfy the guidelines, please ask for more details to be added to the issue or remove the labels.","title":"Triage"},{"location":"community/maintainer/triage/#triage","text":"Triage is an important part of maintaining the health of the trivy repo. A well organized repo allows maintainers to prioritize feature requests, fix bugs, and respond to users facing difficulty with the tool as quickly as possible. Triage includes: Labeling issues Responding to issues Closing issues","title":"Triage"},{"location":"community/maintainer/triage/#daily-triage","text":"Daily triage has two goals: Responsiveness for new issues Responsiveness when explicitly requested information was provided It covers: Issues without a kind/ or triage/ label Issues without a priority/ label triage/needs-information issues which the user has followed up on, and now require a response.","title":"Daily Triage"},{"location":"community/maintainer/triage/#categorization","text":"The most important level of categorizing the issue is defining what type it is. We typically want at least one of the following labels on every issue, and some issues may fall into multiple categories: triage/support - The default for most incoming issues kind/bug - When it\u2019s a bug or we aren\u2019t delivering the best user experience Other possibilities: - kind/feature - Identify new feature requests - kind/testing - Update or fix unit/integration tests - kind/cleanup - Cleaning up/refactoring the codebase - kind/documentation - Updates or additions to trivy documentation If the issue is specific to a driver for OS packages or libraries: co/[driver for OS packages] co/alpine co/amazon co/debian co/oracle co/photon co/redhat co/suse co/ubuntu co/[driver for libraries of programming languages] co/bundler co/cargo co/composer co/npm co/yarn co/pipenv co/poetry Help wanted? Good First Issue - bug has a proposed solution, can be implemented w/o further discussion. Help wanted - if the bug could use help from a contributor","title":"Categorization"},{"location":"community/maintainer/triage/#prioritization","text":"If the issue is not triage/support , it needs a priority label. priority/critical-urgent - someones top priority ASAP, such as security issue, user-visible bug, or build breakage. Rarely used. priority/important-soon : in time for the next two releases. It should be attached to a milestone. priority/important-longterm : 2-4 releases from now priority/backlog : agreed that this would be good to have, but no one is available at the moment. Consider tagging as help wanted priority/awaiting-more-evidence : may be useful, but there is not yet enough support.","title":"Prioritization"},{"location":"community/maintainer/triage/#weekly-triage","text":"Weekly triage has three goals: Catching up on unresponded issues Reviewing and closing PR\u2019s Closing stale issues","title":"Weekly Triage"},{"location":"community/maintainer/triage/#post-release-triage","text":"Post-release triage occurs after a major release (around every 4-6 weeks). It focuses on: Closing bugs that have been resolved by the release Reprioritizing bugs that have not been resolved by the release Letting users know if we believe that there is still an issue This includes reviewing: Every issue that hasn\u2019t been touched in the last 2 days Re-evaluation of long-term issues Re-evaluation of short-term issues","title":"Post-Release Triage"},{"location":"community/maintainer/triage/#responding-to-issues","text":"","title":"Responding to Issues"},{"location":"community/maintainer/triage/#needs-more-information","text":"A sample response to ask for more info: I don\u2019t yet have a clear way to replicate this issue. Do you mind adding some additional details. Here is additional information that would be helpful: * The exact trivy command line used * The exact image you want to scan * The full output of the trivy command, preferably with --debug for extra logging. Thank you for sharing your experience! Then: Label with triage/needs-information .","title":"Needs More Information"},{"location":"community/maintainer/triage/#issue-might-be-resolved","text":"If you think a release may have resolved an issue, ask the author to see if their issue has been resolved: Could you please check to see if trivy addresses this issue? We've made some changes with how this is handled, and improved the trivy logs output to help us debug tricky cases like this. Then: Label with triage/needs-information .","title":"Issue might be resolved"},{"location":"community/maintainer/triage/#closing-with-care","text":"Issues typically need to be closed for the following reasons: The issue has been addressed The issue is a duplicate of an existing issue There has been a lack of information over a long period of time In any of these situations, we aim to be kind when closing the issue, and offer the author action items should they need to reopen their issue or still require a solution. Samples responses for these situations include:","title":"Closing with Care"},{"location":"community/maintainer/triage/#issue-has-been-addressed","text":"@author: I believe this issue is now addressed by trivy v1.0.0, as it . If you still see this issue with trivy v1.0 or higher, please reopen this issue. Thank you for reporting this issue! Then: Close the issue","title":"Issue has been addressed"},{"location":"community/maintainer/triage/#duplicate-issue","text":"This issue appears to be a duplicate of #X, do you mind if we move the conversation there? This way we can centralize the content relating to the issue. If you feel that this issue is not in fact a duplicate, please re-open it. If you have additional information to share, please add it to the new issue. Thank you for reporting this! Then: Label with triage/duplicate and close the issue.","title":"Duplicate Issue"},{"location":"community/maintainer/triage/#lack-of-information","text":"If an issue hasn't been active for more than four weeks, and the author has been pinged at least once, then the issue can be closed. Hey @author -- hopefully it's OK if I close this - there wasn't enough information to make it actionable, and some time has already passed. If you are able to provide additional details, you may reopen it at any point. Here is additional information that may be helpful to us: * Whether the issue occurs with the latest trivy release * The exact trivy command line used * The exact image you want to scan * The full output of the trivy command, preferably with --debug for extra logging. Thank you for sharing your experience! Then: Close the issue.","title":"Lack of Information"},{"location":"community/maintainer/triage/#help-wanted-issues","text":"We use two labels help wanted and good first issue to identify issues that have been specially groomed for new contributors. We have specific guidelines for how to use these labels. If you see an issue that satisfies these guidelines, you can add the help wanted label and the good first issue label. Please note that adding the good first issue label must also add the help wanted label. If an issue has these labels but does not satisfy the guidelines, please ask for more details to be added to the issue or remove the labels.","title":"Help Wanted issues"},{"location":"docs/","text":"Docs In this section you can find the complete reference documentation for all of the different features and settings that Trivy has to offer. \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics.","title":"Overview"},{"location":"docs/#docs","text":"In this section you can find the complete reference documentation for all of the different features and settings that Trivy has to offer. \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics.","title":"Docs"},{"location":"docs/advanced/air-gap/","text":"Air-Gapped Environment Trivy can be used in air-gapped environments. Note that an allowlist is here . Air-Gapped Environment for vulnerabilities Download the vulnerability database At first, you need to download the vulnerability database for use in air-gapped environments. Trivy oras >= v0.13.0 oras < v0.13.0 TRIVY_TEMP_DIR=$(mktemp -d) trivy --cache-dir $TRIVY_TEMP_DIR image --download-db-only tar -cf ./db.tar.gz -C $TRIVY_TEMP_DIR/db metadata.json trivy.db rm -rf $TRIVY_TEMP_DIR Please follow oras installation instruction . Download db.tar.gz : $ oras pull ghcr.io/aquasecurity/trivy-db:2 Please follow oras installation instruction . Download db.tar.gz : $ oras pull -a ghcr.io/aquasecurity/trivy-db:2 Download the Java index database 1 Java users also need to download the Java index database for use in air-gapped environments. Note You container image may contain JAR files even though you don't use Java directly. In that case, you also need to download the Java index database. Trivy oras >= v0.13.0 oras < v0.13.0 TRIVY_TEMP_DIR=$(mktemp -d) trivy --cache-dir $TRIVY_TEMP_DIR image --download-java-db-only tar -cf ./javadb.tar.gz -C $TRIVY_TEMP_DIR/java-db metadata.json trivy-java.db rm -rf $TRIVY_TEMP_DIR Please follow oras installation instruction . Download javadb.tar.gz : $ oras pull ghcr.io/aquasecurity/trivy-java-db:1 Please follow oras installation instruction . Download javadb.tar.gz : $ oras pull -a ghcr.io/aquasecurity/trivy-java-db:1 Transfer the DB files into the air-gapped environment The way of transfer depends on the environment. Vulnerability db Java index db 1 $ rsync -av -e ssh /path/to/db.tar.gz [user]@[host]:dst $ rsync -av -e ssh /path/to/javadb.tar.gz [user]@[host]:dst Put the DB files in Trivy's cache directory You have to know where to put the DB files. The following command shows the default cache directory. $ ssh user@host $ trivy -h | grep cache --cache-dir value cache directory (default: \"/home/myuser/.cache/trivy\") [$TRIVY_CACHE_DIR] Vulnerability db Java index db 1 Put the DB file in the cache directory + /db . $ mkdir -p /home/myuser/.cache/trivy/db $ cd /home/myuser/.cache/trivy/db $ tar xvf /path/to/db.tar.gz -C /home/myuser/.cache/trivy/db x trivy.db x metadata.json $ rm /path/to/db.tar.gz Put the DB file in the cache directory + /java-db . $ mkdir -p /home/myuser/.cache/trivy/java-db $ cd /home/myuser/.cache/trivy/java-db $ tar xvf /path/to/javadb.tar.gz -C /home/myuser/.cache/trivy/java-db x trivy-java.db x metadata.json $ rm /path/to/javadb.tar.gz In an air-gapped environment it is your responsibility to update the Trivy databases on a regular basis, so that the scanner can detect recently-identified vulnerabilities. Run Trivy with the specific flags. In an air-gapped environment, you have to specify --skip-db-update and --skip-java-db-update 1 so that Trivy doesn't attempt to download the latest database files. In addition, if you want to scan pom.xml dependencies, you need to specify --offline-scan since Trivy tries to issue API requests for scanning Java applications by default. $ trivy image --skip-db-update --skip-java-db-update --offline-scan alpine:3.12 Air-Gapped Environment for misconfigurations No special measures are required to detect misconfigurations in an air-gapped environment. Run Trivy with --skip-policy-update option In an air-gapped environment, specify --skip-policy-update so that Trivy doesn't attempt to download the latest misconfiguration policies. $ trivy conf --skip-policy-update /path/to/conf This is only required to scan jar files. More information about Java index db here \u21a9 \u21a9 \u21a9 \u21a9","title":"Air-Gapped Environment"},{"location":"docs/advanced/air-gap/#air-gapped-environment","text":"Trivy can be used in air-gapped environments. Note that an allowlist is here .","title":"Air-Gapped Environment"},{"location":"docs/advanced/air-gap/#air-gapped-environment-for-vulnerabilities","text":"","title":"Air-Gapped Environment for vulnerabilities"},{"location":"docs/advanced/air-gap/#download-the-vulnerability-database","text":"At first, you need to download the vulnerability database for use in air-gapped environments. Trivy oras >= v0.13.0 oras < v0.13.0 TRIVY_TEMP_DIR=$(mktemp -d) trivy --cache-dir $TRIVY_TEMP_DIR image --download-db-only tar -cf ./db.tar.gz -C $TRIVY_TEMP_DIR/db metadata.json trivy.db rm -rf $TRIVY_TEMP_DIR Please follow oras installation instruction . Download db.tar.gz : $ oras pull ghcr.io/aquasecurity/trivy-db:2 Please follow oras installation instruction . Download db.tar.gz : $ oras pull -a ghcr.io/aquasecurity/trivy-db:2","title":"Download the vulnerability database"},{"location":"docs/advanced/air-gap/#download-the-java-index-database1","text":"Java users also need to download the Java index database for use in air-gapped environments. Note You container image may contain JAR files even though you don't use Java directly. In that case, you also need to download the Java index database. Trivy oras >= v0.13.0 oras < v0.13.0 TRIVY_TEMP_DIR=$(mktemp -d) trivy --cache-dir $TRIVY_TEMP_DIR image --download-java-db-only tar -cf ./javadb.tar.gz -C $TRIVY_TEMP_DIR/java-db metadata.json trivy-java.db rm -rf $TRIVY_TEMP_DIR Please follow oras installation instruction . Download javadb.tar.gz : $ oras pull ghcr.io/aquasecurity/trivy-java-db:1 Please follow oras installation instruction . Download javadb.tar.gz : $ oras pull -a ghcr.io/aquasecurity/trivy-java-db:1","title":"Download the Java index database1"},{"location":"docs/advanced/air-gap/#transfer-the-db-files-into-the-air-gapped-environment","text":"The way of transfer depends on the environment. Vulnerability db Java index db 1 $ rsync -av -e ssh /path/to/db.tar.gz [user]@[host]:dst $ rsync -av -e ssh /path/to/javadb.tar.gz [user]@[host]:dst","title":"Transfer the DB files into the air-gapped environment"},{"location":"docs/advanced/air-gap/#put-the-db-files-in-trivys-cache-directory","text":"You have to know where to put the DB files. The following command shows the default cache directory. $ ssh user@host $ trivy -h | grep cache --cache-dir value cache directory (default: \"/home/myuser/.cache/trivy\") [$TRIVY_CACHE_DIR] Vulnerability db Java index db 1 Put the DB file in the cache directory + /db . $ mkdir -p /home/myuser/.cache/trivy/db $ cd /home/myuser/.cache/trivy/db $ tar xvf /path/to/db.tar.gz -C /home/myuser/.cache/trivy/db x trivy.db x metadata.json $ rm /path/to/db.tar.gz Put the DB file in the cache directory + /java-db . $ mkdir -p /home/myuser/.cache/trivy/java-db $ cd /home/myuser/.cache/trivy/java-db $ tar xvf /path/to/javadb.tar.gz -C /home/myuser/.cache/trivy/java-db x trivy-java.db x metadata.json $ rm /path/to/javadb.tar.gz In an air-gapped environment it is your responsibility to update the Trivy databases on a regular basis, so that the scanner can detect recently-identified vulnerabilities.","title":"Put the DB files in Trivy's cache directory"},{"location":"docs/advanced/air-gap/#run-trivy-with-the-specific-flags","text":"In an air-gapped environment, you have to specify --skip-db-update and --skip-java-db-update 1 so that Trivy doesn't attempt to download the latest database files. In addition, if you want to scan pom.xml dependencies, you need to specify --offline-scan since Trivy tries to issue API requests for scanning Java applications by default. $ trivy image --skip-db-update --skip-java-db-update --offline-scan alpine:3.12","title":"Run Trivy with the specific flags."},{"location":"docs/advanced/air-gap/#air-gapped-environment-for-misconfigurations","text":"No special measures are required to detect misconfigurations in an air-gapped environment.","title":"Air-Gapped Environment for misconfigurations"},{"location":"docs/advanced/air-gap/#run-trivy-with-skip-policy-update-option","text":"In an air-gapped environment, specify --skip-policy-update so that Trivy doesn't attempt to download the latest misconfiguration policies. $ trivy conf --skip-policy-update /path/to/conf This is only required to scan jar files. More information about Java index db here \u21a9 \u21a9 \u21a9 \u21a9","title":"Run Trivy with --skip-policy-update option"},{"location":"docs/advanced/modules/","text":"Modules EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy provides a module feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. It changes the behavior during scanning by WebAssembly. Overview Trivy modules are add-on tools that integrate seamlessly with Trivy. They provide a way to extend the core feature set of Trivy, but without updating the Trivy binary. They can be added and removed from a Trivy installation without impacting the core Trivy tool. They can be written in any programming language supporting WebAssembly. It supports only TinyGo at the moment. You can write your own detection logic. Evaluate complex vulnerability conditions like Spring4Shell Detect a shell script communicating with malicious domains Detect malicious python install script (setup.py) Even detect misconfigurations in WordPress setting etc. Then, you can update the scan result however you want. Change a severity Remove a vulnerability Add a new vulnerability etc. Modules should be distributed in OCI registries like GitHub Container Registry. Warning WebAssembly doesn't allow file access and network access by default. Modules can read required files only, but cannot overwrite them. WebAssembly is sandboxed and secure by design, but Trivy modules available in public are not audited for security. You should install and run third-party modules at your own risk even though Under the hood Trivy leverages wazero to run WebAssembly modules without CGO. Installing a Module A module can be installed using the trivy module install command. This command takes an url. It will download the module and install it in the module cache. Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy will now search XDG_DATA_HOME for the location of the Trivy modules cache. The preference order is as follows: XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir $HOME/.trivy/plugins For example, to download the WebAssembly module, you can execute the following command: $ trivy module install ghcr.io/aquasecurity/trivy-module-spring4shell Using Modules Once the module is installed, Trivy will load all available modules in the cache on the start of the next Trivy execution. The modules may inject custom logic into scanning and change the result. You can run Trivy as usual and modules are loaded automatically. You will see the log messages about WASM modules. $ trivy image ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8 2022 -06-12T12:57:13.210+0300 INFO Loading ghcr.io/aquasecurity/trivy-module-spring4shell/spring4shell.wasm... 2022 -06-12T12:57:13.596+0300 INFO Registering WASM module: spring4shell@v1 ... 2022 -06-12T12:57:14.865+0300 INFO Module spring4shell: Java Version: 8 , Tomcat Version: 8 .5.77 2022 -06-12T12:57:14.865+0300 INFO Module spring4shell: change CVE-2022-22965 severity from CRITICAL to LOW Java ( jar ) Total: 9 ( UNKNOWN: 1 , LOW: 3 , MEDIUM: 2 , HIGH: 3 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 org.springframework.boot:spring-boot ( helloworld.war ) \u2502 CVE-2022-22965 \u2502 LOW \u2502 2 .6.3 \u2502 2 .5.12, 2 .6.6 \u2502 spring-framework: RCE via Data Binding on JDK 9 + \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-22965 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 ... ( snip ) ... In the above example, the Spring4Shell module changed the severity from CRITICAL to LOW because the application doesn't satisfy one of conditions. Uninstalling Modules Specify a module repository with trivy module uninstall command. $ trivy module uninstall ghcr.io/aquasecurity/trivy-module-spring4shell Building Modules It supports TinyGo only at the moment. TinyGo Trivy provides Go SDK including three interfaces. Your own module needs to implement either or both Analyzer and PostScanner in addition to Module . type Module interface { Version () int Name () string } type Analyzer interface { RequiredFiles () [] string Analyze ( filePath string ) ( * serialize . AnalysisResult , error ) } type PostScanner interface { PostScanSpec () serialize . PostScanSpec PostScan ( serialize . Results ) ( serialize . Results , error ) } In the following tutorial, it creates a WordPress module that detects a WordPress version and a critical vulnerability accordingly. Tips You can use logging functions such as Debug and Info for debugging. See examples for the detail. Initialize your module Replace the repository name with yours. $ go mod init github.com/aquasecurity/trivy-module-wordpress Module interface Version() returns your module version and should be incremented after updates. Name() returns your module name. package main const ( version = 1 name = \"wordpress-module\" ) type WordpressModule struct { // Cannot define fields as modules can't keep state. } func ( WordpressModule ) Version () int { return version } func ( WordpressModule ) Name () string { return name } Info A struct cannot have any fields. Each method invocation is performed in different states. Analyzer interface If you implement the Analyzer interface, Analyze method is called when the file path is matched to file patterns returned by RequiredFiles() . A file pattern must be a regular expression. The syntax detail is here . Analyze takes the matched file path, then the file can be opened by os.Open() . const typeWPVersion = \"wordpress-version\" func ( WordpressModule ) RequiredFiles () [] string { return [] string { `wp-includes\\/version.php` , } } func ( WordpressModule ) Analyze ( filePath string ) ( * serialize . AnalysisResult , error ) { f , err := os . Open ( filePath ) // e.g. filePath: /usr/src/wordpress/wp-includes/version.php if err != nil { return nil , err } defer f . Close () var wpVersion string scanner := bufio . NewScanner ( f ) for scanner . Scan () { line := scanner . Text () if ! strings . HasPrefix ( line , \"$wp_version=\" ) { continue } ss := strings . Split ( line , \"=\" ) if len ( ss ) != 2 { return nil , fmt . Errorf ( \"invalid wordpress version: %s\" , line ) } // NOTE: it is an example; you actually need to handle comments, etc ss [ 1 ] = strings . TrimSpace ( ss [ 1 ]) wpVersion = strings . Trim ( ss [ 1 ], `\";` ) } if err = scanner . Err (); err != nil { return nil , err } return & serialize . AnalysisResult { CustomResources : [] serialize . CustomResource { { Type : typeWPVersion , FilePath : filePath , Data : wpVersion , }, }, }, nil } Tips Trivy caches analysis results according to the module version. We'd recommend cleaning the cache or changing the module version every time you update Analyzer . PostScanner interface PostScan is called after scanning and takes the scan result as an argument from Trivy. In post scanning, your module can perform one of three actions: Insert Add a new security finding e.g. Add a new vulnerability and misconfiguration Update Update the detected vulnerability and misconfiguration e.g. Change a severity Delete Delete the detected vulnerability and misconfiguration e.g. Remove Spring4Shell because it is not actually affected. PostScanSpec() returns which action the module does. If it is Update or Delete , it also needs to return IDs such as CVE-ID and misconfiguration ID, which your module wants to update or delete. serialize.Results contains the filtered results matching IDs you specified. Also, it includes CustomResources with the values your Analyze returns, so you can modify the scan result according to the custom resources. func ( WordpressModule ) PostScanSpec () serialize . PostScanSpec { return serialize . PostScanSpec { Action : api . ActionInsert , // Add new vulnerabilities } } func ( WordpressModule ) PostScan ( results serialize . Results ) ( serialize . Results , error ) { // e.g. results // [ // { // \"Target\": \"\", // \"Class\": \"custom\", // \"CustomResources\": [ // { // \"Type\": \"wordpress-version\", // \"FilePath\": \"/usr/src/wordpress/wp-includes/version.php\", // \"Layer\": { // \"DiffID\": \"sha256:057649e61046e02c975b84557c03c6cca095b8c9accd3bd20eb4e432f7aec887\" // }, // \"Data\": \"5.7.1\" // } // ] // } // ] var wpVersion int for _ , result := range results { if result . Class != types . ClassCustom { continue } for _ , c := range result . CustomResources { if c . Type != typeWPVersion { continue } wpVersion = c . Data .( string ) wasm . Info ( fmt . Sprintf ( \"WordPress Version: %s\" , wpVersion )) ... snip ... if affectedVersion . Check ( ver ) { vulnerable = true } break } } if vulnerable { // Add CVE-2020-36326 results = append ( results , serialize . Result { Target : wpPath , Class : types . ClassLangPkg , Type : \"wordpress\" , Vulnerabilities : [] types . DetectedVulnerability { { VulnerabilityID : \"CVE-2020-36326\" , PkgName : \"wordpress\" , InstalledVersion : wpVersion , FixedVersion : \"5.7.2\" , Vulnerability : dbTypes . Vulnerability { Title : \"PHPMailer 6.1.8 through 6.4.0 allows object injection through Phar Deserialization via addAttachment with a UNC pathname.\" , Severity : \"CRITICAL\" , }, }, }, }) } return results , nil } The new vulnerability will be added to the scan results. This example shows how the module inserts a new finding. If you are interested in Update , you can see an example of Spring4Shell . In the Delete action, PostScan needs to return results you want to delete. If PostScan returns an empty, Trivy will not delete anything. Build Follow the install guide and install TinyGo. $ tinygo build -o wordpress.wasm -scheduler = none -target = wasi --no-debug wordpress.go Put the built binary to the module directory that is under the home directory by default. $ mkdir -p ~/.trivy/modules $ cp spring4shell.wasm ~/.trivy/modules Distribute Your Module You can distribute your own module in OCI registries. Please follow the oras installation instruction . oras push ghcr.io/aquasecurity/trivy-module-wordpress:latest wordpress.wasm:application/vnd.module.wasm.content.layer.v1+wasm Uploading 3daa3dac086b wordpress.wasm Pushed ghcr.io/aquasecurity/trivy-module-wordpress:latest Digest: sha256:6416d0199d66ce52ced19f01d75454b22692ff3aa7737e45f7a189880840424f Examples Spring4Shell WordPress","title":"Modules"},{"location":"docs/advanced/modules/#modules","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy provides a module feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. It changes the behavior during scanning by WebAssembly.","title":"Modules"},{"location":"docs/advanced/modules/#overview","text":"Trivy modules are add-on tools that integrate seamlessly with Trivy. They provide a way to extend the core feature set of Trivy, but without updating the Trivy binary. They can be added and removed from a Trivy installation without impacting the core Trivy tool. They can be written in any programming language supporting WebAssembly. It supports only TinyGo at the moment. You can write your own detection logic. Evaluate complex vulnerability conditions like Spring4Shell Detect a shell script communicating with malicious domains Detect malicious python install script (setup.py) Even detect misconfigurations in WordPress setting etc. Then, you can update the scan result however you want. Change a severity Remove a vulnerability Add a new vulnerability etc. Modules should be distributed in OCI registries like GitHub Container Registry. Warning WebAssembly doesn't allow file access and network access by default. Modules can read required files only, but cannot overwrite them. WebAssembly is sandboxed and secure by design, but Trivy modules available in public are not audited for security. You should install and run third-party modules at your own risk even though Under the hood Trivy leverages wazero to run WebAssembly modules without CGO.","title":"Overview"},{"location":"docs/advanced/modules/#installing-a-module","text":"A module can be installed using the trivy module install command. This command takes an url. It will download the module and install it in the module cache. Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy will now search XDG_DATA_HOME for the location of the Trivy modules cache. The preference order is as follows: XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir $HOME/.trivy/plugins For example, to download the WebAssembly module, you can execute the following command: $ trivy module install ghcr.io/aquasecurity/trivy-module-spring4shell","title":"Installing a Module"},{"location":"docs/advanced/modules/#using-modules","text":"Once the module is installed, Trivy will load all available modules in the cache on the start of the next Trivy execution. The modules may inject custom logic into scanning and change the result. You can run Trivy as usual and modules are loaded automatically. You will see the log messages about WASM modules. $ trivy image ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8 2022 -06-12T12:57:13.210+0300 INFO Loading ghcr.io/aquasecurity/trivy-module-spring4shell/spring4shell.wasm... 2022 -06-12T12:57:13.596+0300 INFO Registering WASM module: spring4shell@v1 ... 2022 -06-12T12:57:14.865+0300 INFO Module spring4shell: Java Version: 8 , Tomcat Version: 8 .5.77 2022 -06-12T12:57:14.865+0300 INFO Module spring4shell: change CVE-2022-22965 severity from CRITICAL to LOW Java ( jar ) Total: 9 ( UNKNOWN: 1 , LOW: 3 , MEDIUM: 2 , HIGH: 3 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 org.springframework.boot:spring-boot ( helloworld.war ) \u2502 CVE-2022-22965 \u2502 LOW \u2502 2 .6.3 \u2502 2 .5.12, 2 .6.6 \u2502 spring-framework: RCE via Data Binding on JDK 9 + \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-22965 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 ... ( snip ) ... In the above example, the Spring4Shell module changed the severity from CRITICAL to LOW because the application doesn't satisfy one of conditions.","title":"Using Modules"},{"location":"docs/advanced/modules/#uninstalling-modules","text":"Specify a module repository with trivy module uninstall command. $ trivy module uninstall ghcr.io/aquasecurity/trivy-module-spring4shell","title":"Uninstalling Modules"},{"location":"docs/advanced/modules/#building-modules","text":"It supports TinyGo only at the moment.","title":"Building Modules"},{"location":"docs/advanced/modules/#tinygo","text":"Trivy provides Go SDK including three interfaces. Your own module needs to implement either or both Analyzer and PostScanner in addition to Module . type Module interface { Version () int Name () string } type Analyzer interface { RequiredFiles () [] string Analyze ( filePath string ) ( * serialize . AnalysisResult , error ) } type PostScanner interface { PostScanSpec () serialize . PostScanSpec PostScan ( serialize . Results ) ( serialize . Results , error ) } In the following tutorial, it creates a WordPress module that detects a WordPress version and a critical vulnerability accordingly. Tips You can use logging functions such as Debug and Info for debugging. See examples for the detail.","title":"TinyGo"},{"location":"docs/advanced/modules/#initialize-your-module","text":"Replace the repository name with yours. $ go mod init github.com/aquasecurity/trivy-module-wordpress","title":"Initialize your module"},{"location":"docs/advanced/modules/#module-interface","text":"Version() returns your module version and should be incremented after updates. Name() returns your module name. package main const ( version = 1 name = \"wordpress-module\" ) type WordpressModule struct { // Cannot define fields as modules can't keep state. } func ( WordpressModule ) Version () int { return version } func ( WordpressModule ) Name () string { return name } Info A struct cannot have any fields. Each method invocation is performed in different states.","title":"Module interface"},{"location":"docs/advanced/modules/#analyzer-interface","text":"If you implement the Analyzer interface, Analyze method is called when the file path is matched to file patterns returned by RequiredFiles() . A file pattern must be a regular expression. The syntax detail is here . Analyze takes the matched file path, then the file can be opened by os.Open() . const typeWPVersion = \"wordpress-version\" func ( WordpressModule ) RequiredFiles () [] string { return [] string { `wp-includes\\/version.php` , } } func ( WordpressModule ) Analyze ( filePath string ) ( * serialize . AnalysisResult , error ) { f , err := os . Open ( filePath ) // e.g. filePath: /usr/src/wordpress/wp-includes/version.php if err != nil { return nil , err } defer f . Close () var wpVersion string scanner := bufio . NewScanner ( f ) for scanner . Scan () { line := scanner . Text () if ! strings . HasPrefix ( line , \"$wp_version=\" ) { continue } ss := strings . Split ( line , \"=\" ) if len ( ss ) != 2 { return nil , fmt . Errorf ( \"invalid wordpress version: %s\" , line ) } // NOTE: it is an example; you actually need to handle comments, etc ss [ 1 ] = strings . TrimSpace ( ss [ 1 ]) wpVersion = strings . Trim ( ss [ 1 ], `\";` ) } if err = scanner . Err (); err != nil { return nil , err } return & serialize . AnalysisResult { CustomResources : [] serialize . CustomResource { { Type : typeWPVersion , FilePath : filePath , Data : wpVersion , }, }, }, nil } Tips Trivy caches analysis results according to the module version. We'd recommend cleaning the cache or changing the module version every time you update Analyzer .","title":"Analyzer interface"},{"location":"docs/advanced/modules/#postscanner-interface","text":"PostScan is called after scanning and takes the scan result as an argument from Trivy. In post scanning, your module can perform one of three actions: Insert Add a new security finding e.g. Add a new vulnerability and misconfiguration Update Update the detected vulnerability and misconfiguration e.g. Change a severity Delete Delete the detected vulnerability and misconfiguration e.g. Remove Spring4Shell because it is not actually affected. PostScanSpec() returns which action the module does. If it is Update or Delete , it also needs to return IDs such as CVE-ID and misconfiguration ID, which your module wants to update or delete. serialize.Results contains the filtered results matching IDs you specified. Also, it includes CustomResources with the values your Analyze returns, so you can modify the scan result according to the custom resources. func ( WordpressModule ) PostScanSpec () serialize . PostScanSpec { return serialize . PostScanSpec { Action : api . ActionInsert , // Add new vulnerabilities } } func ( WordpressModule ) PostScan ( results serialize . Results ) ( serialize . Results , error ) { // e.g. results // [ // { // \"Target\": \"\", // \"Class\": \"custom\", // \"CustomResources\": [ // { // \"Type\": \"wordpress-version\", // \"FilePath\": \"/usr/src/wordpress/wp-includes/version.php\", // \"Layer\": { // \"DiffID\": \"sha256:057649e61046e02c975b84557c03c6cca095b8c9accd3bd20eb4e432f7aec887\" // }, // \"Data\": \"5.7.1\" // } // ] // } // ] var wpVersion int for _ , result := range results { if result . Class != types . ClassCustom { continue } for _ , c := range result . CustomResources { if c . Type != typeWPVersion { continue } wpVersion = c . Data .( string ) wasm . Info ( fmt . Sprintf ( \"WordPress Version: %s\" , wpVersion )) ... snip ... if affectedVersion . Check ( ver ) { vulnerable = true } break } } if vulnerable { // Add CVE-2020-36326 results = append ( results , serialize . Result { Target : wpPath , Class : types . ClassLangPkg , Type : \"wordpress\" , Vulnerabilities : [] types . DetectedVulnerability { { VulnerabilityID : \"CVE-2020-36326\" , PkgName : \"wordpress\" , InstalledVersion : wpVersion , FixedVersion : \"5.7.2\" , Vulnerability : dbTypes . Vulnerability { Title : \"PHPMailer 6.1.8 through 6.4.0 allows object injection through Phar Deserialization via addAttachment with a UNC pathname.\" , Severity : \"CRITICAL\" , }, }, }, }) } return results , nil } The new vulnerability will be added to the scan results. This example shows how the module inserts a new finding. If you are interested in Update , you can see an example of Spring4Shell . In the Delete action, PostScan needs to return results you want to delete. If PostScan returns an empty, Trivy will not delete anything.","title":"PostScanner interface"},{"location":"docs/advanced/modules/#build","text":"Follow the install guide and install TinyGo. $ tinygo build -o wordpress.wasm -scheduler = none -target = wasi --no-debug wordpress.go Put the built binary to the module directory that is under the home directory by default. $ mkdir -p ~/.trivy/modules $ cp spring4shell.wasm ~/.trivy/modules","title":"Build"},{"location":"docs/advanced/modules/#distribute-your-module","text":"You can distribute your own module in OCI registries. Please follow the oras installation instruction . oras push ghcr.io/aquasecurity/trivy-module-wordpress:latest wordpress.wasm:application/vnd.module.wasm.content.layer.v1+wasm Uploading 3daa3dac086b wordpress.wasm Pushed ghcr.io/aquasecurity/trivy-module-wordpress:latest Digest: sha256:6416d0199d66ce52ced19f01d75454b22692ff3aa7737e45f7a189880840424f","title":"Distribute Your Module"},{"location":"docs/advanced/modules/#examples","text":"Spring4Shell WordPress","title":"Examples"},{"location":"docs/advanced/plugins/","text":"Plugins Trivy provides a plugin feature to allow others to extend the Trivy CLI without the need to change the Trivycode base. This plugin system was inspired by the plugin system used in kubectl , Helm , and Conftest . Overview Trivy plugins are add-on tools that integrate seamlessly with Trivy. They provide a way to extend the core feature set of Trivy, but without requiring every new feature to be written in Go and added to the core tool. They can be added and removed from a Trivy installation without impacting the core Trivy tool. They can be written in any programming language. They integrate with Trivy, and will show up in Trivy help and subcommands. Warning Trivy plugins available in public are not audited for security. You should install and run third-party plugins at your own risk, since they are arbitrary programs running on your machine. Installing a Plugin A plugin can be installed using the trivy plugin install command. This command takes a url and will download the plugin and install it in the plugin cache. Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache. The preference order is as follows: XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir ~/.trivy/plugins Under the hood Trivy leverages go-getter to download plugins. This means the following protocols are supported for downloading plugins: OCI Registries Local Files Git HTTP/HTTPS Mercurial Amazon S3 Google Cloud Storage For example, to download the Kubernetes Trivy plugin you can execute the following command: $ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl Also, Trivy plugin can be installed from a local archive: $ trivy plugin install myplugin.tar.gz Using Plugins Once the plugin is installed, Trivy will load all available plugins in the cache on the start of the next Trivy execution. A plugin will be made in the Trivy CLI based on the plugin name. To display all plugins, you can list them by trivy --help $ trivy --help NAME: trivy - A simple and comprehensive vulnerability scanner for containers USAGE: trivy [ global options ] command [ command options ] target VERSION: dev COMMANDS: image, i scan an image filesystem, fs scan local filesystem repository, repo scan remote repository client, c client mode server, s server mode plugin, p manage plugins kubectl scan kubectl resources help, h Shows a list of commands or help for one command As shown above, kubectl subcommand exists in the COMMANDS section. To call the kubectl plugin and scan existing Kubernetes deployments, you can execute the following command: $ trivy kubectl deployment -- --ignore-unfixed --severity CRITICAL Internally the kubectl plugin calls the kubectl binary to fetch information about that deployment and passes the using images to Trivy. You can see the detail here . If you want to omit even the subcommand, you can use TRIVY_RUN_AS_PLUGIN environment variable. $ TRIVY_RUN_AS_PLUGIN = kubectl trivy job your-job -- --format json Installing and Running Plugins on the fly trivy plugin run installs a plugin and runs it on the fly. If the plugin is already present in the cache, the installation is skipped. trivy plugin run github.com/aquasecurity/trivy-plugin-kubectl pod your-pod -- --exit-code 1 Uninstalling Plugins Specify a plugin name with trivy plugin uninstall command. $ trivy plugin uninstall kubectl Building Plugins Each plugin has a top-level directory, and then a plugin.yaml file. your-plugin/ | | - plugin.yaml | - your-plugin.sh In the example above, the plugin is contained inside of a directory named your-plugin . It has two files: plugin.yaml (required) and an executable script, your-plugin.sh (optional). The core of a plugin is a simple YAML file named plugin.yaml. Here is an example YAML of trivy-plugin-kubectl plugin that adds support for Kubernetes scanning. name : \"kubectl\" repository : github.com/aquasecurity/trivy-plugin-kubectl version : \"0.1.0\" usage : scan kubectl resources description : |- A Trivy plugin that scans the images of a kubernetes resource. Usage: trivy kubectl TYPE[.VERSION][.GROUP] NAME platforms : - selector : # optional os : darwin arch : amd64 uri : ./trivy-kubectl # where the execution file is (local file, http, git, etc.) bin : ./trivy-kubectl # path to the execution file - selector : # optional os : linux arch : amd64 uri : https://github.com/aquasecurity/trivy-plugin-kubectl/releases/download/v0.1.0/trivy-kubectl.tar.gz bin : ./trivy-kubectl The plugin.yaml field should contain the following information: name: The name of the plugin. This also determines how the plugin will be made available in the Trivy CLI. For example, if the plugin is named kubectl, you can call the plugin with trivy kubectl . (required) version: The version of the plugin. (required) usage: A short usage description. (required) description: A long description of the plugin. This is where you could provide a helpful documentation of your plugin. (required) platforms: (required) selector: The OS/Architecture specific variations of a execution file. (optional) os: OS information based on GOOS (linux, darwin, etc.) (optional) arch: The architecture information based on GOARCH (amd64, arm64, etc.) (optional) uri: Where the executable file is. Relative path from the root directory of the plugin or remote URL such as HTTP and S3. (required) bin: Which file to call when the plugin is executed. Relative path from the root directory of the plugin. (required) The following rules will apply in deciding which platform to select: If both os and arch under selector match the current platform, search will stop and the platform will be used. If selector is not present, the platform will be used. If os matches and there is no more specific arch match, the platform will be used. If no platform match is found, Trivy will exit with an error. After determining platform, Trivy will download the execution file from uri and store it in the plugin cache. When the plugin is called via Trivy CLI, bin command will be executed. The plugin is responsible for handling flags and arguments. Any arguments are passed to the plugin from the trivy command. A plugin should be archived *.tar.gz . $ tar -czvf myplugin.tar.gz plugin.yaml script.py plugin.yaml script.py $ trivy plugin install myplugin.tar.gz 2023 -03-03T19:04:42.026+0600 INFO Installing the plugin from myplugin.tar.gz... 2023 -03-03T19:04:42.026+0600 INFO Loading the plugin metadata... $ trivy myplugin Hello from Trivy demo plugin! Example https://github.com/aquasecurity/trivy-plugin-kubectl","title":"Plugins"},{"location":"docs/advanced/plugins/#plugins","text":"Trivy provides a plugin feature to allow others to extend the Trivy CLI without the need to change the Trivycode base. This plugin system was inspired by the plugin system used in kubectl , Helm , and Conftest .","title":"Plugins"},{"location":"docs/advanced/plugins/#overview","text":"Trivy plugins are add-on tools that integrate seamlessly with Trivy. They provide a way to extend the core feature set of Trivy, but without requiring every new feature to be written in Go and added to the core tool. They can be added and removed from a Trivy installation without impacting the core Trivy tool. They can be written in any programming language. They integrate with Trivy, and will show up in Trivy help and subcommands. Warning Trivy plugins available in public are not audited for security. You should install and run third-party plugins at your own risk, since they are arbitrary programs running on your machine.","title":"Overview"},{"location":"docs/advanced/plugins/#installing-a-plugin","text":"A plugin can be installed using the trivy plugin install command. This command takes a url and will download the plugin and install it in the plugin cache. Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache. The preference order is as follows: XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir ~/.trivy/plugins Under the hood Trivy leverages go-getter to download plugins. This means the following protocols are supported for downloading plugins: OCI Registries Local Files Git HTTP/HTTPS Mercurial Amazon S3 Google Cloud Storage For example, to download the Kubernetes Trivy plugin you can execute the following command: $ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl Also, Trivy plugin can be installed from a local archive: $ trivy plugin install myplugin.tar.gz","title":"Installing a Plugin"},{"location":"docs/advanced/plugins/#using-plugins","text":"Once the plugin is installed, Trivy will load all available plugins in the cache on the start of the next Trivy execution. A plugin will be made in the Trivy CLI based on the plugin name. To display all plugins, you can list them by trivy --help $ trivy --help NAME: trivy - A simple and comprehensive vulnerability scanner for containers USAGE: trivy [ global options ] command [ command options ] target VERSION: dev COMMANDS: image, i scan an image filesystem, fs scan local filesystem repository, repo scan remote repository client, c client mode server, s server mode plugin, p manage plugins kubectl scan kubectl resources help, h Shows a list of commands or help for one command As shown above, kubectl subcommand exists in the COMMANDS section. To call the kubectl plugin and scan existing Kubernetes deployments, you can execute the following command: $ trivy kubectl deployment -- --ignore-unfixed --severity CRITICAL Internally the kubectl plugin calls the kubectl binary to fetch information about that deployment and passes the using images to Trivy. You can see the detail here . If you want to omit even the subcommand, you can use TRIVY_RUN_AS_PLUGIN environment variable. $ TRIVY_RUN_AS_PLUGIN = kubectl trivy job your-job -- --format json","title":"Using Plugins"},{"location":"docs/advanced/plugins/#installing-and-running-plugins-on-the-fly","text":"trivy plugin run installs a plugin and runs it on the fly. If the plugin is already present in the cache, the installation is skipped. trivy plugin run github.com/aquasecurity/trivy-plugin-kubectl pod your-pod -- --exit-code 1","title":"Installing and Running Plugins on the fly"},{"location":"docs/advanced/plugins/#uninstalling-plugins","text":"Specify a plugin name with trivy plugin uninstall command. $ trivy plugin uninstall kubectl","title":"Uninstalling Plugins"},{"location":"docs/advanced/plugins/#building-plugins","text":"Each plugin has a top-level directory, and then a plugin.yaml file. your-plugin/ | | - plugin.yaml | - your-plugin.sh In the example above, the plugin is contained inside of a directory named your-plugin . It has two files: plugin.yaml (required) and an executable script, your-plugin.sh (optional). The core of a plugin is a simple YAML file named plugin.yaml. Here is an example YAML of trivy-plugin-kubectl plugin that adds support for Kubernetes scanning. name : \"kubectl\" repository : github.com/aquasecurity/trivy-plugin-kubectl version : \"0.1.0\" usage : scan kubectl resources description : |- A Trivy plugin that scans the images of a kubernetes resource. Usage: trivy kubectl TYPE[.VERSION][.GROUP] NAME platforms : - selector : # optional os : darwin arch : amd64 uri : ./trivy-kubectl # where the execution file is (local file, http, git, etc.) bin : ./trivy-kubectl # path to the execution file - selector : # optional os : linux arch : amd64 uri : https://github.com/aquasecurity/trivy-plugin-kubectl/releases/download/v0.1.0/trivy-kubectl.tar.gz bin : ./trivy-kubectl The plugin.yaml field should contain the following information: name: The name of the plugin. This also determines how the plugin will be made available in the Trivy CLI. For example, if the plugin is named kubectl, you can call the plugin with trivy kubectl . (required) version: The version of the plugin. (required) usage: A short usage description. (required) description: A long description of the plugin. This is where you could provide a helpful documentation of your plugin. (required) platforms: (required) selector: The OS/Architecture specific variations of a execution file. (optional) os: OS information based on GOOS (linux, darwin, etc.) (optional) arch: The architecture information based on GOARCH (amd64, arm64, etc.) (optional) uri: Where the executable file is. Relative path from the root directory of the plugin or remote URL such as HTTP and S3. (required) bin: Which file to call when the plugin is executed. Relative path from the root directory of the plugin. (required) The following rules will apply in deciding which platform to select: If both os and arch under selector match the current platform, search will stop and the platform will be used. If selector is not present, the platform will be used. If os matches and there is no more specific arch match, the platform will be used. If no platform match is found, Trivy will exit with an error. After determining platform, Trivy will download the execution file from uri and store it in the plugin cache. When the plugin is called via Trivy CLI, bin command will be executed. The plugin is responsible for handling flags and arguments. Any arguments are passed to the plugin from the trivy command. A plugin should be archived *.tar.gz . $ tar -czvf myplugin.tar.gz plugin.yaml script.py plugin.yaml script.py $ trivy plugin install myplugin.tar.gz 2023 -03-03T19:04:42.026+0600 INFO Installing the plugin from myplugin.tar.gz... 2023 -03-03T19:04:42.026+0600 INFO Loading the plugin metadata... $ trivy myplugin Hello from Trivy demo plugin!","title":"Building Plugins"},{"location":"docs/advanced/plugins/#example","text":"https://github.com/aquasecurity/trivy-plugin-kubectl","title":"Example"},{"location":"docs/advanced/container/embed-in-dockerfile/","text":"Embed in Dockerfile Scan your image as part of the build process by embedding Trivy in the Dockerfile. This approach can be used to update Dockerfiles currently using Aqua\u2019s Microscanner . $ cat Dockerfile FROM alpine:3.7 RUN apk add curl \\ && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \\ && trivy rootfs --exit-code 1 --no-progress / $ docker build -t vulnerable-image . Alternatively you can use Trivy in a multistage build. Thus avoiding the insecure curl | sh . Also the image is not changed. [ ... ] # Run vulnerability scan on build image FROM build AS vulnscan COPY --from = aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy RUN trivy rootfs --exit-code 1 --no-progress / [ ... ]","title":"Embed in Dockerfile"},{"location":"docs/advanced/container/embed-in-dockerfile/#embed-in-dockerfile","text":"Scan your image as part of the build process by embedding Trivy in the Dockerfile. This approach can be used to update Dockerfiles currently using Aqua\u2019s Microscanner . $ cat Dockerfile FROM alpine:3.7 RUN apk add curl \\ && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \\ && trivy rootfs --exit-code 1 --no-progress / $ docker build -t vulnerable-image . Alternatively you can use Trivy in a multistage build. Thus avoiding the insecure curl | sh . Also the image is not changed. [ ... ] # Run vulnerability scan on build image FROM build AS vulnscan COPY --from = aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy RUN trivy rootfs --exit-code 1 --no-progress / [ ... ]","title":"Embed in Dockerfile"},{"location":"docs/advanced/container/unpacked-filesystem/","text":"Unpacked Filesystem Scan an unpacked container image filesystem. In this case, Trivy works the same way when scanning containers $ docker export $( docker create alpine:3.10.2 ) | tar -C /tmp/rootfs -xvf - $ trivy rootfs /tmp/rootfs Result 2021 -03-08T05:22:26.378Z INFO Need to update DB 2021 -03-08T05:22:26.380Z INFO Downloading DB... 20 .37 MiB / 20 .37 MiB [ ------------------------------------------------------------------------------------------------------------------------------------- ] 100 .00% 8 .24 MiB p/s 2s 2021 -03-08T05:22:30.134Z INFO Detecting Alpine vulnerabilities... /tmp/rootfs ( alpine 3 .10.2 ) =========================== Total: 20 ( UNKNOWN: 0 , LOW: 2 , MEDIUM: 10 , HIGH: 8 , CRITICAL: 0 ) +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | libcrypto1.1 | CVE-2020-1967 | HIGH | 1 .1.1c-r0 | 1 .1.1g-r0 | openssl: Segmentation | | | | | | | fault in SSL_check_chain | | | | | | | causes denial of service | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1967 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2021-23839 | | | 1 .1.1j-r0 | openssl: incorrect SSLv2 | | | | | | | rollback protection | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23840 | | | | openssl: integer | | | | | | | overflow in CipherUpdate | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23841 | | | | openssl: NULL pointer dereference | | | | | | | in X509_issuer_and_serial_hash () | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1547 | MEDIUM | | 1 .1.1d-r0 | openssl: side-channel weak | | | | | | | encryption vulnerability | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1547 | + +------------------+ + + +---------------------------------------+ | | CVE-2019-1549 | | | | openssl: information | | | | | | | disclosure in fork () | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1549 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2019-1551 | | | 1 .1.1d-r2 | openssl: Integer overflow in RSAZ | | | | | | | modular exponentiation on x86_64 | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1551 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2020-1971 | | | 1 .1.1i-r0 | openssl: EDIPARTYNAME | | | | | | | NULL pointer de-reference | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1563 | LOW | | 1 .1.1d-r0 | openssl: information | | | | | | | disclosure in PKCS7_dataDecode | | | | | | | and CMS_decrypt_set1_pkey | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1563 | +--------------+------------------+----------+ +---------------+---------------------------------------+ | libssl1.1 | CVE-2020-1967 | HIGH | | 1 .1.1g-r0 | openssl: Segmentation | | | | | | | fault in SSL_check_chain | | | | | | | causes denial of service | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1967 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2021-23839 | | | 1 .1.1j-r0 | openssl: incorrect SSLv2 | | | | | | | rollback protection | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23840 | | | | openssl: integer | | | | | | | overflow in CipherUpdate | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23841 | | | | openssl: NULL pointer dereference | | | | | | | in X509_issuer_and_serial_hash () | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1547 | MEDIUM | | 1 .1.1d-r0 | openssl: side-channel weak | | | | | | | encryption vulnerability | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1547 | + +------------------+ + + +---------------------------------------+ | | CVE-2019-1549 | | | | openssl: information | | | | | | | disclosure in fork () | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1549 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2019-1551 | | | 1 .1.1d-r2 | openssl: Integer overflow in RSAZ | | | | | | | modular exponentiation on x86_64 | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1551 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2020-1971 | | | 1 .1.1i-r0 | openssl: EDIPARTYNAME | | | | | | | NULL pointer de-reference | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1563 | LOW | | 1 .1.1d-r0 | openssl: information | | | | | | | disclosure in PKCS7_dataDecode | | | | | | | and CMS_decrypt_set1_pkey | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1563 | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | musl | CVE-2020-28928 | MEDIUM | 1 .1.22-r3 | 1 .1.22-r4 | In musl libc through 1 .2.1, | | | | | | | wcsnrtombs mishandles particular | | | | | | | combinations of destination buffer... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-28928 | +--------------+ + + + + + | musl-utils | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+","title":"Unpacked container image filesystem"},{"location":"docs/advanced/container/unpacked-filesystem/#unpacked-filesystem","text":"Scan an unpacked container image filesystem. In this case, Trivy works the same way when scanning containers $ docker export $( docker create alpine:3.10.2 ) | tar -C /tmp/rootfs -xvf - $ trivy rootfs /tmp/rootfs Result 2021 -03-08T05:22:26.378Z INFO Need to update DB 2021 -03-08T05:22:26.380Z INFO Downloading DB... 20 .37 MiB / 20 .37 MiB [ ------------------------------------------------------------------------------------------------------------------------------------- ] 100 .00% 8 .24 MiB p/s 2s 2021 -03-08T05:22:30.134Z INFO Detecting Alpine vulnerabilities... /tmp/rootfs ( alpine 3 .10.2 ) =========================== Total: 20 ( UNKNOWN: 0 , LOW: 2 , MEDIUM: 10 , HIGH: 8 , CRITICAL: 0 ) +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | libcrypto1.1 | CVE-2020-1967 | HIGH | 1 .1.1c-r0 | 1 .1.1g-r0 | openssl: Segmentation | | | | | | | fault in SSL_check_chain | | | | | | | causes denial of service | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1967 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2021-23839 | | | 1 .1.1j-r0 | openssl: incorrect SSLv2 | | | | | | | rollback protection | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23840 | | | | openssl: integer | | | | | | | overflow in CipherUpdate | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23841 | | | | openssl: NULL pointer dereference | | | | | | | in X509_issuer_and_serial_hash () | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1547 | MEDIUM | | 1 .1.1d-r0 | openssl: side-channel weak | | | | | | | encryption vulnerability | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1547 | + +------------------+ + + +---------------------------------------+ | | CVE-2019-1549 | | | | openssl: information | | | | | | | disclosure in fork () | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1549 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2019-1551 | | | 1 .1.1d-r2 | openssl: Integer overflow in RSAZ | | | | | | | modular exponentiation on x86_64 | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1551 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2020-1971 | | | 1 .1.1i-r0 | openssl: EDIPARTYNAME | | | | | | | NULL pointer de-reference | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1563 | LOW | | 1 .1.1d-r0 | openssl: information | | | | | | | disclosure in PKCS7_dataDecode | | | | | | | and CMS_decrypt_set1_pkey | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1563 | +--------------+------------------+----------+ +---------------+---------------------------------------+ | libssl1.1 | CVE-2020-1967 | HIGH | | 1 .1.1g-r0 | openssl: Segmentation | | | | | | | fault in SSL_check_chain | | | | | | | causes denial of service | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1967 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2021-23839 | | | 1 .1.1j-r0 | openssl: incorrect SSLv2 | | | | | | | rollback protection | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23840 | | | | openssl: integer | | | | | | | overflow in CipherUpdate | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 | + +------------------+ + + +---------------------------------------+ | | CVE-2021-23841 | | | | openssl: NULL pointer dereference | | | | | | | in X509_issuer_and_serial_hash () | | | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1547 | MEDIUM | | 1 .1.1d-r0 | openssl: side-channel weak | | | | | | | encryption vulnerability | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1547 | + +------------------+ + + +---------------------------------------+ | | CVE-2019-1549 | | | | openssl: information | | | | | | | disclosure in fork () | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1549 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2019-1551 | | | 1 .1.1d-r2 | openssl: Integer overflow in RSAZ | | | | | | | modular exponentiation on x86_64 | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1551 | + +------------------+ + +---------------+---------------------------------------+ | | CVE-2020-1971 | | | 1 .1.1i-r0 | openssl: EDIPARTYNAME | | | | | | | NULL pointer de-reference | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | + +------------------+----------+ +---------------+---------------------------------------+ | | CVE-2019-1563 | LOW | | 1 .1.1d-r0 | openssl: information | | | | | | | disclosure in PKCS7_dataDecode | | | | | | | and CMS_decrypt_set1_pkey | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1563 | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | musl | CVE-2020-28928 | MEDIUM | 1 .1.22-r3 | 1 .1.22-r4 | In musl libc through 1 .2.1, | | | | | | | wcsnrtombs mishandles particular | | | | | | | combinations of destination buffer... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-28928 | +--------------+ + + + + + | musl-utils | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+","title":"Unpacked Filesystem"},{"location":"docs/advanced/private-registries/","text":"Trivy can download images from a private registry without the need for installing Docker or any other 3rd party tools. This makes it easy to run within a CI process. Credential To use Trivy with private images, simply install it and provide your credentials: $ TRIVY_USERNAME = YOUR_USERNAME TRIVY_PASSWORD = YOUR_PASSWORD trivy image YOUR_PRIVATE_IMAGE Trivy also supports providing credentials through CLI flags: $ TRIVY_PASSWORD = YOUR_PASSWORD trivy image --username YOUR_USERNAME YOUR_PRIVATE_IMAGE Warning The CLI flag --password is available, but its use is not recommended for security reasons. You can also store your credentials in trivy.yaml . For more information, please refer to the documentation . It can handle multiple sets of credentials as well: $ export TRIVY_USERNAME = USERNAME1,USERNAME2 $ export TRIVY_PASSWORD = PASSWORD1,PASSWORD2 $ trivy image YOUR_PRIVATE_IMAGE In the example above, Trivy attempts to use two pairs of credentials: USERNAME1/PASSWORD1 USERNAME2/PASSWORD2 Please note that the number of usernames and passwords must be the same. docker login If you have Docker configured locally and have set up the credentials, Trivy can access them. $ docker login ghcr.io Username: Password: $ trivy image ghcr.io/your/private_image Note docker login can be used with any container runtime, such as Podman.","title":"Overview"},{"location":"docs/advanced/private-registries/#credential","text":"To use Trivy with private images, simply install it and provide your credentials: $ TRIVY_USERNAME = YOUR_USERNAME TRIVY_PASSWORD = YOUR_PASSWORD trivy image YOUR_PRIVATE_IMAGE Trivy also supports providing credentials through CLI flags: $ TRIVY_PASSWORD = YOUR_PASSWORD trivy image --username YOUR_USERNAME YOUR_PRIVATE_IMAGE Warning The CLI flag --password is available, but its use is not recommended for security reasons. You can also store your credentials in trivy.yaml . For more information, please refer to the documentation . It can handle multiple sets of credentials as well: $ export TRIVY_USERNAME = USERNAME1,USERNAME2 $ export TRIVY_PASSWORD = PASSWORD1,PASSWORD2 $ trivy image YOUR_PRIVATE_IMAGE In the example above, Trivy attempts to use two pairs of credentials: USERNAME1/PASSWORD1 USERNAME2/PASSWORD2 Please note that the number of usernames and passwords must be the same.","title":"Credential"},{"location":"docs/advanced/private-registries/#docker-login","text":"If you have Docker configured locally and have set up the credentials, Trivy can access them. $ docker login ghcr.io Username: Password: $ trivy image ghcr.io/your/private_image Note docker login can be used with any container runtime, such as Podman.","title":"docker login"},{"location":"docs/advanced/private-registries/acr/","text":"Requirements None, Trivy uses Azure SDK for Go. You don't need to install az command. Privileges Service principal must have the AcrPull permissions. Creation of a service principal export SP_DATA = $( az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope \"/subscriptions//resourceGroups//providers/Microsoft.ContainerRegistry/registries/\" ) Usage # must set TRIVY_USERNAME empty char export AZURE_CLIENT_ID $( echo $SP_DATA | jq -r .appId ) export AZURE_CLIENT_SECRET $( echo $SP_DATA | jq -r .password ) export AZURE_TENANT_ID $( echo $SP_DATA | jq -r .tenant ) Testing You can test credentials in the following manner. docker run -it --rm -v /tmp:/tmp \\ -e AZURE_CLIENT_ID = ${ AZURE_CLIENT_ID } -e AZURE_CLIENT_SECRET = ${ AZURE_CLIENT_SECRET } \\ -e AZURE_TENANT_ID = ${ AZURE_TENANT_ID } aquasec/trivy image your_special_project.azurecr.io/your_special_image:your_special_tag","title":"ACR (Azure Container Registry)"},{"location":"docs/advanced/private-registries/acr/#requirements","text":"None, Trivy uses Azure SDK for Go. You don't need to install az command.","title":"Requirements"},{"location":"docs/advanced/private-registries/acr/#privileges","text":"Service principal must have the AcrPull permissions.","title":"Privileges"},{"location":"docs/advanced/private-registries/acr/#creation-of-a-service-principal","text":"export SP_DATA = $( az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope \"/subscriptions//resourceGroups//providers/Microsoft.ContainerRegistry/registries/\" )","title":"Creation of a service principal"},{"location":"docs/advanced/private-registries/acr/#usage","text":"# must set TRIVY_USERNAME empty char export AZURE_CLIENT_ID $( echo $SP_DATA | jq -r .appId ) export AZURE_CLIENT_SECRET $( echo $SP_DATA | jq -r .password ) export AZURE_TENANT_ID $( echo $SP_DATA | jq -r .tenant )","title":"Usage"},{"location":"docs/advanced/private-registries/acr/#testing","text":"You can test credentials in the following manner. docker run -it --rm -v /tmp:/tmp \\ -e AZURE_CLIENT_ID = ${ AZURE_CLIENT_ID } -e AZURE_CLIENT_SECRET = ${ AZURE_CLIENT_SECRET } \\ -e AZURE_TENANT_ID = ${ AZURE_TENANT_ID } aquasec/trivy image your_special_project.azurecr.io/your_special_image:your_special_tag","title":"Testing"},{"location":"docs/advanced/private-registries/docker-hub/","text":"See here for the detail. You don't need to provide a credential when download from public repository.","title":"Docker Hub"},{"location":"docs/advanced/private-registries/ecr/","text":"Trivy uses AWS SDK. You don't need to install aws CLI tool. You can use AWS CLI's ENV Vars . AWS private registry permissions You may need to grant permissions to allow Trivy to pull images from private ECR. It depends on how you want to provide AWS Role to trivy. IAM Role Service account Kube2iam or Kiam IAM Role Service account Add the AWS role in trivy's service account annotations: trivy : serviceAccount : annotations : {} # eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME Kube2iam or Kiam Add the AWS role to pod's annotations: podAnnotations : {} ## kube2iam/kiam annotation # iam.amazonaws.com/role: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME","title":"AWS ECR (Elastic Container Registry)"},{"location":"docs/advanced/private-registries/ecr/#aws-private-registry-permissions","text":"You may need to grant permissions to allow Trivy to pull images from private ECR. It depends on how you want to provide AWS Role to trivy. IAM Role Service account Kube2iam or Kiam","title":"AWS private registry permissions"},{"location":"docs/advanced/private-registries/ecr/#iam-role-service-account","text":"Add the AWS role in trivy's service account annotations: trivy : serviceAccount : annotations : {} # eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME","title":"IAM Role Service account"},{"location":"docs/advanced/private-registries/ecr/#kube2iam-or-kiam","text":"Add the AWS role to pod's annotations: podAnnotations : {} ## kube2iam/kiam annotation # iam.amazonaws.com/role: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME","title":"Kube2iam or Kiam"},{"location":"docs/advanced/private-registries/gcr/","text":"Requirements None, Trivy uses Google Cloud SDK. You don't need to install gcloud command. Privileges Credential file must have the roles/storage.objectViewer permissions. More information can be found in Google's documentation JSON File Format The JSON file specified should have the following format provided by google's service account mechanisms: { \"type\" : \"service_account\" , \"project_id\" : \"your_special_project\" , \"private_key_id\" : \"XXXXXXXXXXXXXXXXXXXXxx\" , \"private_key\" : \"-----BEGIN PRIVATE KEY-----\\nNONONONO\\n-----END PRIVATE KEY-----\\n\" , \"client_email\" : \"somedude@your_special_project.iam.gserviceaccount.com\" , \"client_id\" : \"1234567890\" , \"auth_uri\" : \"https://accounts.google.com/o/oauth2/auth\" , \"token_uri\" : \"https://oauth2.googleapis.com/token\" , \"auth_provider_x509_cert_url\" : \"https://www.googleapis.com/oauth2/v1/certs\" , \"client_x509_cert_url\" : \"https://www.googleapis.com/robot/v1/metadata/x509/somedude%40your_special_project.iam.gserviceaccount.com\" } Usage If you want to use target project's repository, you can set them via GOOGLE_APPLICATION_CREDENTIALS . # must set TRIVY_USERNAME empty char export GOOGLE_APPLICATION_CREDENTIALS = /path/to/credential.json Testing You can test credentials in the following manner (assuming they are in /tmp on host machine). docker run -it --rm -v /tmp:/tmp \\ -e GOOGLE_APPLICATION_CREDENTIALS = /tmp/service_account.json \\ aquasec/trivy image gcr.io/your_special_project/your_special_image:your_special_tag","title":"GCR (Google Container Registry)"},{"location":"docs/advanced/private-registries/gcr/#requirements","text":"None, Trivy uses Google Cloud SDK. You don't need to install gcloud command.","title":"Requirements"},{"location":"docs/advanced/private-registries/gcr/#privileges","text":"Credential file must have the roles/storage.objectViewer permissions. More information can be found in Google's documentation","title":"Privileges"},{"location":"docs/advanced/private-registries/gcr/#json-file-format","text":"The JSON file specified should have the following format provided by google's service account mechanisms: { \"type\" : \"service_account\" , \"project_id\" : \"your_special_project\" , \"private_key_id\" : \"XXXXXXXXXXXXXXXXXXXXxx\" , \"private_key\" : \"-----BEGIN PRIVATE KEY-----\\nNONONONO\\n-----END PRIVATE KEY-----\\n\" , \"client_email\" : \"somedude@your_special_project.iam.gserviceaccount.com\" , \"client_id\" : \"1234567890\" , \"auth_uri\" : \"https://accounts.google.com/o/oauth2/auth\" , \"token_uri\" : \"https://oauth2.googleapis.com/token\" , \"auth_provider_x509_cert_url\" : \"https://www.googleapis.com/oauth2/v1/certs\" , \"client_x509_cert_url\" : \"https://www.googleapis.com/robot/v1/metadata/x509/somedude%40your_special_project.iam.gserviceaccount.com\" }","title":"JSON File Format"},{"location":"docs/advanced/private-registries/gcr/#usage","text":"If you want to use target project's repository, you can set them via GOOGLE_APPLICATION_CREDENTIALS . # must set TRIVY_USERNAME empty char export GOOGLE_APPLICATION_CREDENTIALS = /path/to/credential.json","title":"Usage"},{"location":"docs/advanced/private-registries/gcr/#testing","text":"You can test credentials in the following manner (assuming they are in /tmp on host machine). docker run -it --rm -v /tmp:/tmp \\ -e GOOGLE_APPLICATION_CREDENTIALS = /tmp/service_account.json \\ aquasec/trivy image gcr.io/your_special_project/your_special_image:your_special_tag","title":"Testing"},{"location":"docs/advanced/private-registries/self/","text":"BasicAuth server needs TRIVY_USERNAME and TRIVY_PASSWORD . export TRIVY_USERNAME ={ USERNAME } export TRIVY_PASSWORD ={ PASSWORD } # if you want to use 80 port, use NonSSL export TRIVY_NON_SSL = true","title":"Self-Hosted"},{"location":"docs/compliance/compliance/","text":"Compliance Reports EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy\u2019s compliance flag lets you curate a specific set of checks into a report. In a typical Trivy scan, there are hundreds of different checks for many different components and configurations, but sometimes you already know which specific checks you are interested in. Often this would be an industry accepted set of checks such as CIS, or some vendor specific guideline, or your own organization policy that you want to comply with. These are all possible using the flexible compliance infrastructure that's built into Trivy. Compliance reports are defined as simple YAML documents that select checks to include in the report. Usage Compliance report is currently supported in the following targets (trivy sub-commands): trivy image trivy aws trivy k8s Add the --compliance flag to the command line, and set it's value to desired report. For example: trivy k8s cluster --compliance k8s-nsa (see below for built-in and custom reports) Options The following flags are compatible with --compliance flag and allows customizing it's output: flag effect --report summary shows a summary of the results. for every control shows the number of failed checks. --report all shows fully detailed results. for every control shows where it failed and why. --format table shows results in textual table format (good for human readability). --format json shows results in json format (good for machine readability). Built-in compliance Trivy has a number of built-in compliance reports that you can asses right out of the box. to specify a built-in compliance report, select it by ID like trivy --compliance . For the list of built-in compliance reports, please see the relevant section: Docker compliance Kubernetes compliance AWS compliance Custom compliance You can create your own custom compliance report. A compliance report is a simple YAML document in the following format: spec : id : \"k8s-myreport\" # report unique identifier. this should not container spaces. title : \"My custom Kubernetes report\" # report title. Any one-line title. description : \"Describe your report\" # description of the report. Any text. relatedResources : - https://some.url # useful references. URLs only. version : \"1.0\" # spec version (string) controls : - name : \"Non-root containers\" # Name for the control (appears in the report as is). Any one-line name. description : 'Check that container is not running as root' # Description (appears in the report as is). Any text. id : \"1.0\" # control identifier (string) checks : # list of existing Trivy checks that define the control - id : AVD-KSV-0012 # check ID. Must start with `AVD-` or `CVE-` severity : \"MEDIUM\" # Severity for the control (note that checks severity isn't used) - name : \"Immutable container file systems\" description : 'Check that container root file system is immutable' id : \"1.1\" checks : - id : AVD-KSV-0014 severity : \"LOW\" The check id field ( controls[].checks[].id ) is referring to existing check by it's \"AVD ID\". This AVD ID is easily located in the check's source code metadata header, or by browsing Aqua vulnerability DB , specifically in the Misconfigurations and Vulnerabilities sections. Once you have a compliance spec, you can select it by file path: trivy --compliance @ (note the @ indicating file path instead of report id).","title":"Reports"},{"location":"docs/compliance/compliance/#compliance-reports","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy\u2019s compliance flag lets you curate a specific set of checks into a report. In a typical Trivy scan, there are hundreds of different checks for many different components and configurations, but sometimes you already know which specific checks you are interested in. Often this would be an industry accepted set of checks such as CIS, or some vendor specific guideline, or your own organization policy that you want to comply with. These are all possible using the flexible compliance infrastructure that's built into Trivy. Compliance reports are defined as simple YAML documents that select checks to include in the report.","title":"Compliance Reports"},{"location":"docs/compliance/compliance/#usage","text":"Compliance report is currently supported in the following targets (trivy sub-commands): trivy image trivy aws trivy k8s Add the --compliance flag to the command line, and set it's value to desired report. For example: trivy k8s cluster --compliance k8s-nsa (see below for built-in and custom reports)","title":"Usage"},{"location":"docs/compliance/compliance/#options","text":"The following flags are compatible with --compliance flag and allows customizing it's output: flag effect --report summary shows a summary of the results. for every control shows the number of failed checks. --report all shows fully detailed results. for every control shows where it failed and why. --format table shows results in textual table format (good for human readability). --format json shows results in json format (good for machine readability).","title":"Options"},{"location":"docs/compliance/compliance/#built-in-compliance","text":"Trivy has a number of built-in compliance reports that you can asses right out of the box. to specify a built-in compliance report, select it by ID like trivy --compliance . For the list of built-in compliance reports, please see the relevant section: Docker compliance Kubernetes compliance AWS compliance","title":"Built-in compliance"},{"location":"docs/compliance/compliance/#custom-compliance","text":"You can create your own custom compliance report. A compliance report is a simple YAML document in the following format: spec : id : \"k8s-myreport\" # report unique identifier. this should not container spaces. title : \"My custom Kubernetes report\" # report title. Any one-line title. description : \"Describe your report\" # description of the report. Any text. relatedResources : - https://some.url # useful references. URLs only. version : \"1.0\" # spec version (string) controls : - name : \"Non-root containers\" # Name for the control (appears in the report as is). Any one-line name. description : 'Check that container is not running as root' # Description (appears in the report as is). Any text. id : \"1.0\" # control identifier (string) checks : # list of existing Trivy checks that define the control - id : AVD-KSV-0012 # check ID. Must start with `AVD-` or `CVE-` severity : \"MEDIUM\" # Severity for the control (note that checks severity isn't used) - name : \"Immutable container file systems\" description : 'Check that container root file system is immutable' id : \"1.1\" checks : - id : AVD-KSV-0014 severity : \"LOW\" The check id field ( controls[].checks[].id ) is referring to existing check by it's \"AVD ID\". This AVD ID is easily located in the check's source code metadata header, or by browsing Aqua vulnerability DB , specifically in the Misconfigurations and Vulnerabilities sections. Once you have a compliance spec, you can select it by file path: trivy --compliance @ (note the @ indicating file path instead of report id).","title":"Custom compliance"},{"location":"docs/configuration/","text":"Configuration Trivy can be configured using the following ways. Each item takes precedence over the item below it: CLI flags Environment variables Configuration file CLI Flags You can view the list of available flags using the --help option. For more details, please refer to the CLI reference . Environment Variables Trivy can be customized by environment variables. The environment variable key is the flag name converted by the following procedure. Add TRIVY_ prefix Make it all uppercase Replace - with _ For example, --debug => TRIVY_DEBUG --cache-dir => TRIVY_CACHE_DIR $ TRIVY_DEBUG=true TRIVY_SEVERITY=CRITICAL trivy image alpine:3.15 Configuration File By default, Trivy reads the trivy.yaml file. For more details, please refer to the page .","title":"Overview"},{"location":"docs/configuration/#configuration","text":"Trivy can be configured using the following ways. Each item takes precedence over the item below it: CLI flags Environment variables Configuration file","title":"Configuration"},{"location":"docs/configuration/#cli-flags","text":"You can view the list of available flags using the --help option. For more details, please refer to the CLI reference .","title":"CLI Flags"},{"location":"docs/configuration/#environment-variables","text":"Trivy can be customized by environment variables. The environment variable key is the flag name converted by the following procedure. Add TRIVY_ prefix Make it all uppercase Replace - with _ For example, --debug => TRIVY_DEBUG --cache-dir => TRIVY_CACHE_DIR $ TRIVY_DEBUG=true TRIVY_SEVERITY=CRITICAL trivy image alpine:3.15","title":"Environment Variables"},{"location":"docs/configuration/#configuration-file","text":"By default, Trivy reads the trivy.yaml file. For more details, please refer to the page .","title":"Configuration File"},{"location":"docs/configuration/cache/","text":"Cache The cache directory includes Vulnerability Database 1 Java Index Database 2 Misconfiguration Policies 3 Cache of previous scans. The cache option is common to all scanners. Clear Caches The --clear-cache option removes caches. The scan is not performed. $ trivy image --clear-cache Result 2019-11-15T15:13:26.209+0200 INFO Reopening vulnerability DB 2019-11-15T15:13:26.209+0200 INFO Removing image caches... Cache Directory Specify where the cache is stored with --cache-dir . $ trivy --cache-dir /tmp/trivy/ image python:3.4-alpine3.9 Cache Backend EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy supports local filesystem and Redis as the cache backend. This option is useful especially for client/server mode. Two options: fs the cache path can be specified by --cache-dir redis:// redis://[HOST]:[PORT] TTL can be configured via --cache-ttl $ trivy server --cache-backend redis://localhost:6379 If you want to use TLS with Redis, you can enable it by specifying the --redis-tls flag. $ trivy server --cache-backend redis://localhost:6379 --redis-tls Trivy also supports for connecting to Redis with your certificates. You need to specify --redis-ca , --redis-cert , and --redis-key options. $ trivy server --cache-backend redis://localhost:6379 \\ --redis-ca /path/to/ca-cert.pem \\ --redis-cert /path/to/cert.pem \\ --redis-key /path/to/key.pem Downloaded when scanning for vulnerabilities \u21a9 Downloaded when scanning jar/war/par/ear files \u21a9 Downloaded when scanning for misconfigurations \u21a9","title":"Cache"},{"location":"docs/configuration/cache/#cache","text":"The cache directory includes Vulnerability Database 1 Java Index Database 2 Misconfiguration Policies 3 Cache of previous scans. The cache option is common to all scanners.","title":"Cache"},{"location":"docs/configuration/cache/#clear-caches","text":"The --clear-cache option removes caches. The scan is not performed. $ trivy image --clear-cache Result 2019-11-15T15:13:26.209+0200 INFO Reopening vulnerability DB 2019-11-15T15:13:26.209+0200 INFO Removing image caches...","title":"Clear Caches"},{"location":"docs/configuration/cache/#cache-directory","text":"Specify where the cache is stored with --cache-dir . $ trivy --cache-dir /tmp/trivy/ image python:3.4-alpine3.9","title":"Cache Directory"},{"location":"docs/configuration/cache/#cache-backend","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy supports local filesystem and Redis as the cache backend. This option is useful especially for client/server mode. Two options: fs the cache path can be specified by --cache-dir redis:// redis://[HOST]:[PORT] TTL can be configured via --cache-ttl $ trivy server --cache-backend redis://localhost:6379 If you want to use TLS with Redis, you can enable it by specifying the --redis-tls flag. $ trivy server --cache-backend redis://localhost:6379 --redis-tls Trivy also supports for connecting to Redis with your certificates. You need to specify --redis-ca , --redis-cert , and --redis-key options. $ trivy server --cache-backend redis://localhost:6379 \\ --redis-ca /path/to/ca-cert.pem \\ --redis-cert /path/to/cert.pem \\ --redis-key /path/to/key.pem Downloaded when scanning for vulnerabilities \u21a9 Downloaded when scanning jar/war/par/ear files \u21a9 Downloaded when scanning for misconfigurations \u21a9","title":"Cache Backend"},{"location":"docs/configuration/db/","text":"DB Scanner Supported Vulnerability \u2713 Misconfiguration Secret License The vulnerability database and the Java index database are needed only for vulnerability scanning. See here for the detail. Vulnerability Database Skip update of vulnerability DB If you want to skip downloading the vulnerability database, use the --skip-db-update option. $ trivy image --skip-db-update python:3.4-alpine3.9 Result 2019-05-16T12:48:08.703+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 (alpine 3.9.2) =================================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+--------------------------------+ | openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 | | | | | | | with long nonces | +---------+------------------+----------+-------------------+---------------+--------------------------------+ Only download vulnerability database You can also ask Trivy to simply retrieve the vulnerability database. This is useful to initialize workers in Continuous Integration systems. $ trivy image --download-db-only DB Repository Trivy could also download the vulnerability database from an external OCI registry by using --db-repository option. $ trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db Java Index Database The same options are also available for the Java index DB, which is used for scanning Java applications. Skipping an update can be done by using the --skip-java-db-update option, while --download-java-db-only can be used to only download the Java index DB. Downloading the Java index DB from an external OCI registry can be done by using the --java-db-repository option. $ trivy image --java-db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-java-db --download-java-db-only Remove DBs The --reset flag removes all caches and databases. $ trivy image --reset","title":"DB"},{"location":"docs/configuration/db/#db","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License The vulnerability database and the Java index database are needed only for vulnerability scanning. See here for the detail.","title":"DB"},{"location":"docs/configuration/db/#vulnerability-database","text":"","title":"Vulnerability Database"},{"location":"docs/configuration/db/#skip-update-of-vulnerability-db","text":"If you want to skip downloading the vulnerability database, use the --skip-db-update option. $ trivy image --skip-db-update python:3.4-alpine3.9 Result 2019-05-16T12:48:08.703+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 (alpine 3.9.2) =================================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+--------------------------------+ | openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 | | | | | | | with long nonces | +---------+------------------+----------+-------------------+---------------+--------------------------------+","title":"Skip update of vulnerability DB"},{"location":"docs/configuration/db/#only-download-vulnerability-database","text":"You can also ask Trivy to simply retrieve the vulnerability database. This is useful to initialize workers in Continuous Integration systems. $ trivy image --download-db-only","title":"Only download vulnerability database"},{"location":"docs/configuration/db/#db-repository","text":"Trivy could also download the vulnerability database from an external OCI registry by using --db-repository option. $ trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db","title":"DB Repository"},{"location":"docs/configuration/db/#java-index-database","text":"The same options are also available for the Java index DB, which is used for scanning Java applications. Skipping an update can be done by using the --skip-java-db-update option, while --download-java-db-only can be used to only download the Java index DB. Downloading the Java index DB from an external OCI registry can be done by using the --java-db-repository option. $ trivy image --java-db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-java-db --download-java-db-only","title":"Java Index Database"},{"location":"docs/configuration/db/#remove-dbs","text":"The --reset flag removes all caches and databases. $ trivy image --reset","title":"Remove DBs"},{"location":"docs/configuration/filtering/","text":"Filtering Trivy provides various methods for filtering the results. Hide Unfixed Vulnerabilities Scanner Supported Vulnerability \u2713 Misconfiguration Secret License By default, Trivy also detects unpatched/unfixed vulnerabilities. This means you can't fix these vulnerabilities even if you update all packages. If you would like to ignore them, use the --ignore-unfixed option. $ trivy image --ignore-unfixed ruby:2.4.0 Result 2019-05-16T12:49:52.656+0900 INFO Updating vulnerability database... 2019-05-16T12:50:14.786+0900 INFO Detecting Debian vulnerabilities... ruby:2.4.0 (debian 8.7) ======================= Total: 4730 (UNKNOWN: 1, LOW: 145, MEDIUM: 3487, HIGH: 1014, CRITICAL: 83) +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ | apt | CVE-2019-3462 | CRITICAL | 1.0.9.8.3 | 1.0.9.8.5 | Incorrect sanitation of the | | | | | | | 302 redirect field in HTTP | | | | | | | transport method of... | + +------------------+----------+ +----------------------------------+-----------------------------------------------------+ | | CVE-2016-1252 | MEDIUM | | 1.0.9.8.4 | The apt package in Debian | | | | | | | jessie before 1.0.9.8.4, in | | | | | | | Debian unstable before... | +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ | bash | CVE-2019-9924 | HIGH | 4.3-11 | 4.3-11+deb8u2 | bash: BASH_CMD is writable in | | | | | | | restricted bash shells | + +------------------+ + +----------------------------------+-----------------------------------------------------+ | | CVE-2016-7543 | | | 4.3-11+deb8u1 | bash: Specially crafted | | | | | | | SHELLOPTS+PS4 variables allows | | | | | | | command substitution | + +------------------+----------+ + +-----------------------------------------------------+ | | CVE-2016-0634 | MEDIUM | | | bash: Arbitrary code execution | | | | | | | via malicious hostname | + +------------------+----------+ +----------------------------------+-----------------------------------------------------+ | | CVE-2016-9401 | LOW | | 4.3-11+deb8u2 | bash: popd controlled free | +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ ... By Severity Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 Use --severity option. $ trivy image --severity HIGH,CRITICAL ruby:2.4.0 Result 2019 -05-16T01:51:46.255+0900 INFO Updating vulnerability database... 2019 -05-16T01:51:49.213+0900 INFO Detecting Debian vulnerabilities... ruby:2.4.0 ( debian 8 .7 ) ======================= Total: 1785 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 1680 , CRITICAL: 105 ) +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ | apt | CVE-2019-3462 | CRITICAL | 1 .0.9.8.3 | 1 .0.9.8.5 | Incorrect sanitation of the | | | | | | | 302 redirect field in HTTP | | | | | | | transport method of... | +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ | bash | CVE-2019-9924 | HIGH | 4 .3-11 | 4 .3-11+deb8u2 | bash: BASH_CMD is writable in | | | | | | | restricted bash shells | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2016-7543 | | | 4 .3-11+deb8u1 | bash: Specially crafted | | | | | | | SHELLOPTS+PS4 variables allows | | | | | | | command substitution | +-----------------------------+------------------+ +---------------------------+----------------------------------+-------------------------------------------------+ | binutils | CVE-2017-8421 | | 2 .25-5 | | binutils: Memory exhaustion in | | | | | | | objdump via a crafted PE file | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2017-14930 | | | | binutils: Memory leak in | | | | | | | decode_line_info | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2017-7614 | | | | binutils: NULL | | | | | | | pointer dereference in | | | | | | | bfd_elf_final_link function | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2014-9939 | | | | binutils: buffer overflow in | | | | | | | ihex.c | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2017-13716 | | | | binutils: Memory leak with the | | | | | | | C++ symbol demangler routine | | | | | | | in libiberty | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2018-12699 | | | | binutils: heap-based buffer | | | | | | | overflow in finish_stab in | | | | | | | stabs.c | +-----------------------------+------------------+ +---------------------------+----------------------------------+-------------------------------------------------+ | bsdutils | CVE-2015-5224 | | 2 .25.2-6 | | util-linux: File name | | | | | | | collision due to incorrect | | | | | | | mkstemp use | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2016-2779 | | | | util-linux: runuser tty hijack | | | | | | | via TIOCSTI ioctl | +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ trivy conf --severity HIGH,CRITICAL examples/misconf/mixed Result 2022 -05-16T13:50:42.718+0100 INFO Detected config files: 3 Dockerfile ( dockerfile ) ======================= Tests: 17 ( SUCCESSES: 16 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 1 , CRITICAL: 0 ) HIGH: Last USER command in Dockerfile should not be 'root' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3 [ USER root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml ( kubernetes ) ============================ Tests: 8 ( SUCCESSES: 8 , FAILURES: 0 , EXCEPTIONS: 0 ) Failures: 0 ( HIGH: 0 , CRITICAL: 0 ) main.tf ( terraform ) =================== Tests: 1 ( SUCCESSES: 0 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 0 , CRITICAL: 1 ) CRITICAL: Classic resources should not be used. \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 AWS Classic resources run in a shared environment with infrastructure owned by other AWS customers. You should run resources in a VPC instead. See https://avd.aquasec.com/misconfig/avd-aws-0081 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 main.tf:2-4 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 2 \u250c resource \"aws_db_security_group\" \"sg\" { 3 \u2502 4 \u2514 } \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 By Finding IDs Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License Use .trivyignore . $ cat .trivyignore # Accept the risk CVE-2018-14618 # Accept the risk until 2023-01-01 CVE-2019-14697 exp:2023-01-01 # No impact in our settings CVE-2019-1543 # Ignore misconfigurations AVD-DS-0002 # Ignore secrets generic-unwanted-rule aws-account-id $ trivy image python:3.4-alpine3.9 Result 2019 -05-16T12:53:10.076+0900 INFO Updating vulnerability database... 2019 -05-16T12:53:28.134+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 ( alpine 3 .9.2 ) =================================== Total: 0 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 0 ) By Vulnerability Target Scanner Supported Vulnerability \u2713 Misconfiguration Secret License Use --vuln-type option. $ trivy image --vuln-type os ruby:2.4.0 Available values: library os Result 2019 -05-22T19:36:50.530+0200 \u001b [ 34mINFO\u001b [ 0m Updating vulnerability database... 2019 -05-22T19:36:51.681+0200 \u001b [ 34mINFO\u001b [ 0m Detecting Alpine vulnerabilities... 2019 -05-22T19:36:51.685+0200 \u001b [ 34mINFO\u001b [ 0m Updating npm Security DB... 2019 -05-22T19:36:52.389+0200 \u001b [ 34mINFO\u001b [ 0m Detecting npm vulnerabilities... 2019 -05-22T19:36:52.390+0200 \u001b [ 34mINFO\u001b [ 0m Updating pipenv Security DB... 2019 -05-22T19:36:53.406+0200 \u001b [ 34mINFO\u001b [ 0m Detecting pipenv vulnerabilities... ruby:2.4.0 ( debian 8 .7 ) ======================= Total: 7 ( UNKNOWN: 0 , LOW: 1 , MEDIUM: 1 , HIGH: 3 , CRITICAL: 2 ) +---------+------------------+----------+-------------------+---------------+----------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | curl | CVE-2018-14618 | CRITICAL | 7 .61.0-r0 | 7 .61.1-r0 | curl: NTLM password overflow | | | | | | | via integer overflow | + +------------------+----------+ +---------------+----------------------------------+ | | CVE-2018-16839 | HIGH | | 7 .61.1-r1 | curl: Integer overflow leading | | | | | | | to heap-based buffer overflow in | | | | | | | Curl_sasl_create_plain_message () | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | git | CVE-2018-17456 | HIGH | 2 .15.2-r0 | 2 .15.3-r0 | git: arbitrary code execution | | | | | | | via .gitmodules | + +------------------+ + + +----------------------------------+ | | CVE-2018-19486 | | | | git: Improper handling of | | | | | | | PATH allows for commands to be | | | | | | | executed from... | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | libssh2 | CVE-2019-3855 | CRITICAL | 1 .8.0-r2 | 1 .8.1-r0 | libssh2: Integer overflow in | | | | | | | transport read resulting in | | | | | | | out of bounds write... | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | sqlite | CVE-2018-20346 | MEDIUM | 3 .21.0-r1 | 3 .25.3-r0 | CVE-2018-20505 CVE-2018-20506 | | | | | | | sqlite: Multiple flaws in | | | | | | | sqlite which can be triggered | | | | | | | via... | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | tar | CVE-2018-20482 | LOW | 1 .29-r1 | 1 .31-r0 | tar: Infinite read loop in | | | | | | | sparse_dump_region function in | | | | | | | sparse.c | +---------+------------------+----------+-------------------+---------------+----------------------------------+ By Open Policy Agent Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy supports Open Policy Agent (OPA) to filter vulnerabilities. You can specify a Rego file with --ignore-policy option. The Rego package name must be trivy and it must include a rule called ignore which determines if each individual vulnerability should be excluded (ignore=true) or not (ignore=false). In the policy, each vulnerability will be available for inspection as the input variable. The structure of each vulnerability input is the same as for the Trivy JSON output. There is a built-in Rego library with helper functions that you can import into your policy using: import data.lib.trivy . For more info about the helper functions, look at the library here To get started, see the example policy . $ trivy image --ignore-policy contrib/example_policy/basic.rego centos:7 Result centos:7 ( centos 7 .9.2009 ) ========================== Total: 9 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 4 , CRITICAL: 5 ) +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | glib2 | CVE-2015-8385 | HIGH | 2 .56.1-7.el7 | | pcre: buffer overflow caused | | | | | | | by named forward reference | | | | | | | to duplicate group number... | | | | | | | -->avd.aquasec.com/nvd/cve-2015-8385 | + +------------------+ + +-------------------+-----------------------------------------+ | | CVE-2016-3191 | | | | pcre: workspace overflow for | | | | | | | ( *ACCEPT ) with deeply nested | | | | | | | parentheses ( 8 .39/13, 10 .22/12 ) | | | | | | | -->avd.aquasec.com/nvd/cve-2016-3191 | + +------------------+ + +-------------------+-----------------------------------------+ | | CVE-2021-27219 | | | 2 .56.1-9.el7_9 | glib: integer overflow in | | | | | | | g_bytes_new function on | | | | | | | 64 -bit platforms due to an... | | | | | | | -->avd.aquasec.com/nvd/cve-2021-27219 | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | glibc | CVE-2019-1010022 | CRITICAL | 2 .17-317.el7 | | glibc: stack guard protection bypass | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1010022 | +--------------+ + + +-------------------+ + | glibc-common | | | | | | | | | | | | | +--------------+------------------+ +-------------------+-------------------+-----------------------------------------+ | nss | CVE-2021-43527 | | 3 .53.1-3.el7_9 | 3 .67.0-4.el7_9 | nss: Memory corruption in | | | | | | | decodeECorDsaSignature with | | | | | | | DSA signatures ( and RSA-PSS ) | | | | | | | -->avd.aquasec.com/nvd/cve-2021-43527 | +--------------+ + + + + + | nss-sysinit | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+ + + + + + | nss-tools | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | openssl-libs | CVE-2020-1971 | HIGH | 1 :1.0.2k-19.el7 | 1 :1.0.2k-21.el7_9 | openssl: EDIPARTYNAME | | | | | | | NULL pointer de-reference | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ By Inline Comments Scanner Supported Vulnerability Misconfiguration \u2713 Secret License Some configuration file formats (e.g. Terraform) support inline comments. In cases where trivy can detect comments of a specific format immediately adjacent to resource definitions, it is possible to filter/ignore findings from a single point of resource definition (in contrast to .trivyignore , which has a directory-wide scope on all of the files scanned). The format for these comments is trivy:ignore: immediately following the format-specific line-comment token. For example, to filter a Vulnerability ID \"AVD-GCP-0051\" in a Terraform HCL file: #trivy:ignore:AVD-GCP-0051 resource \"google_container_cluster\" \"one_off_test\" { name = var.cluster_name location = var.region }","title":"Filtering"},{"location":"docs/configuration/filtering/#filtering","text":"Trivy provides various methods for filtering the results.","title":"Filtering"},{"location":"docs/configuration/filtering/#hide-unfixed-vulnerabilities","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License By default, Trivy also detects unpatched/unfixed vulnerabilities. This means you can't fix these vulnerabilities even if you update all packages. If you would like to ignore them, use the --ignore-unfixed option. $ trivy image --ignore-unfixed ruby:2.4.0 Result 2019-05-16T12:49:52.656+0900 INFO Updating vulnerability database... 2019-05-16T12:50:14.786+0900 INFO Detecting Debian vulnerabilities... ruby:2.4.0 (debian 8.7) ======================= Total: 4730 (UNKNOWN: 1, LOW: 145, MEDIUM: 3487, HIGH: 1014, CRITICAL: 83) +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ | apt | CVE-2019-3462 | CRITICAL | 1.0.9.8.3 | 1.0.9.8.5 | Incorrect sanitation of the | | | | | | | 302 redirect field in HTTP | | | | | | | transport method of... | + +------------------+----------+ +----------------------------------+-----------------------------------------------------+ | | CVE-2016-1252 | MEDIUM | | 1.0.9.8.4 | The apt package in Debian | | | | | | | jessie before 1.0.9.8.4, in | | | | | | | Debian unstable before... | +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ | bash | CVE-2019-9924 | HIGH | 4.3-11 | 4.3-11+deb8u2 | bash: BASH_CMD is writable in | | | | | | | restricted bash shells | + +------------------+ + +----------------------------------+-----------------------------------------------------+ | | CVE-2016-7543 | | | 4.3-11+deb8u1 | bash: Specially crafted | | | | | | | SHELLOPTS+PS4 variables allows | | | | | | | command substitution | + +------------------+----------+ + +-----------------------------------------------------+ | | CVE-2016-0634 | MEDIUM | | | bash: Arbitrary code execution | | | | | | | via malicious hostname | + +------------------+----------+ +----------------------------------+-----------------------------------------------------+ | | CVE-2016-9401 | LOW | | 4.3-11+deb8u2 | bash: popd controlled free | +------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+ ...","title":"Hide Unfixed Vulnerabilities"},{"location":"docs/configuration/filtering/#by-severity","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 Use --severity option. $ trivy image --severity HIGH,CRITICAL ruby:2.4.0 Result 2019 -05-16T01:51:46.255+0900 INFO Updating vulnerability database... 2019 -05-16T01:51:49.213+0900 INFO Detecting Debian vulnerabilities... ruby:2.4.0 ( debian 8 .7 ) ======================= Total: 1785 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 1680 , CRITICAL: 105 ) +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ | apt | CVE-2019-3462 | CRITICAL | 1 .0.9.8.3 | 1 .0.9.8.5 | Incorrect sanitation of the | | | | | | | 302 redirect field in HTTP | | | | | | | transport method of... | +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ | bash | CVE-2019-9924 | HIGH | 4 .3-11 | 4 .3-11+deb8u2 | bash: BASH_CMD is writable in | | | | | | | restricted bash shells | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2016-7543 | | | 4 .3-11+deb8u1 | bash: Specially crafted | | | | | | | SHELLOPTS+PS4 variables allows | | | | | | | command substitution | +-----------------------------+------------------+ +---------------------------+----------------------------------+-------------------------------------------------+ | binutils | CVE-2017-8421 | | 2 .25-5 | | binutils: Memory exhaustion in | | | | | | | objdump via a crafted PE file | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2017-14930 | | | | binutils: Memory leak in | | | | | | | decode_line_info | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2017-7614 | | | | binutils: NULL | | | | | | | pointer dereference in | | | | | | | bfd_elf_final_link function | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2014-9939 | | | | binutils: buffer overflow in | | | | | | | ihex.c | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2017-13716 | | | | binutils: Memory leak with the | | | | | | | C++ symbol demangler routine | | | | | | | in libiberty | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2018-12699 | | | | binutils: heap-based buffer | | | | | | | overflow in finish_stab in | | | | | | | stabs.c | +-----------------------------+------------------+ +---------------------------+----------------------------------+-------------------------------------------------+ | bsdutils | CVE-2015-5224 | | 2 .25.2-6 | | util-linux: File name | | | | | | | collision due to incorrect | | | | | | | mkstemp use | + +------------------+ + +----------------------------------+-------------------------------------------------+ | | CVE-2016-2779 | | | | util-linux: runuser tty hijack | | | | | | | via TIOCSTI ioctl | +-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+ trivy conf --severity HIGH,CRITICAL examples/misconf/mixed Result 2022 -05-16T13:50:42.718+0100 INFO Detected config files: 3 Dockerfile ( dockerfile ) ======================= Tests: 17 ( SUCCESSES: 16 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 1 , CRITICAL: 0 ) HIGH: Last USER command in Dockerfile should not be 'root' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3 [ USER root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml ( kubernetes ) ============================ Tests: 8 ( SUCCESSES: 8 , FAILURES: 0 , EXCEPTIONS: 0 ) Failures: 0 ( HIGH: 0 , CRITICAL: 0 ) main.tf ( terraform ) =================== Tests: 1 ( SUCCESSES: 0 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 0 , CRITICAL: 1 ) CRITICAL: Classic resources should not be used. \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 AWS Classic resources run in a shared environment with infrastructure owned by other AWS customers. You should run resources in a VPC instead. See https://avd.aquasec.com/misconfig/avd-aws-0081 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 main.tf:2-4 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 2 \u250c resource \"aws_db_security_group\" \"sg\" { 3 \u2502 4 \u2514 } \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500","title":"By Severity"},{"location":"docs/configuration/filtering/#by-finding-ids","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License Use .trivyignore . $ cat .trivyignore # Accept the risk CVE-2018-14618 # Accept the risk until 2023-01-01 CVE-2019-14697 exp:2023-01-01 # No impact in our settings CVE-2019-1543 # Ignore misconfigurations AVD-DS-0002 # Ignore secrets generic-unwanted-rule aws-account-id $ trivy image python:3.4-alpine3.9 Result 2019 -05-16T12:53:10.076+0900 INFO Updating vulnerability database... 2019 -05-16T12:53:28.134+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 ( alpine 3 .9.2 ) =================================== Total: 0 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 0 )","title":"By Finding IDs"},{"location":"docs/configuration/filtering/#by-vulnerability-target","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License Use --vuln-type option. $ trivy image --vuln-type os ruby:2.4.0 Available values: library os Result 2019 -05-22T19:36:50.530+0200 \u001b [ 34mINFO\u001b [ 0m Updating vulnerability database... 2019 -05-22T19:36:51.681+0200 \u001b [ 34mINFO\u001b [ 0m Detecting Alpine vulnerabilities... 2019 -05-22T19:36:51.685+0200 \u001b [ 34mINFO\u001b [ 0m Updating npm Security DB... 2019 -05-22T19:36:52.389+0200 \u001b [ 34mINFO\u001b [ 0m Detecting npm vulnerabilities... 2019 -05-22T19:36:52.390+0200 \u001b [ 34mINFO\u001b [ 0m Updating pipenv Security DB... 2019 -05-22T19:36:53.406+0200 \u001b [ 34mINFO\u001b [ 0m Detecting pipenv vulnerabilities... ruby:2.4.0 ( debian 8 .7 ) ======================= Total: 7 ( UNKNOWN: 0 , LOW: 1 , MEDIUM: 1 , HIGH: 3 , CRITICAL: 2 ) +---------+------------------+----------+-------------------+---------------+----------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | curl | CVE-2018-14618 | CRITICAL | 7 .61.0-r0 | 7 .61.1-r0 | curl: NTLM password overflow | | | | | | | via integer overflow | + +------------------+----------+ +---------------+----------------------------------+ | | CVE-2018-16839 | HIGH | | 7 .61.1-r1 | curl: Integer overflow leading | | | | | | | to heap-based buffer overflow in | | | | | | | Curl_sasl_create_plain_message () | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | git | CVE-2018-17456 | HIGH | 2 .15.2-r0 | 2 .15.3-r0 | git: arbitrary code execution | | | | | | | via .gitmodules | + +------------------+ + + +----------------------------------+ | | CVE-2018-19486 | | | | git: Improper handling of | | | | | | | PATH allows for commands to be | | | | | | | executed from... | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | libssh2 | CVE-2019-3855 | CRITICAL | 1 .8.0-r2 | 1 .8.1-r0 | libssh2: Integer overflow in | | | | | | | transport read resulting in | | | | | | | out of bounds write... | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | sqlite | CVE-2018-20346 | MEDIUM | 3 .21.0-r1 | 3 .25.3-r0 | CVE-2018-20505 CVE-2018-20506 | | | | | | | sqlite: Multiple flaws in | | | | | | | sqlite which can be triggered | | | | | | | via... | +---------+------------------+----------+-------------------+---------------+----------------------------------+ | tar | CVE-2018-20482 | LOW | 1 .29-r1 | 1 .31-r0 | tar: Infinite read loop in | | | | | | | sparse_dump_region function in | | | | | | | sparse.c | +---------+------------------+----------+-------------------+---------------+----------------------------------+","title":"By Vulnerability Target"},{"location":"docs/configuration/filtering/#by-open-policy-agent","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy supports Open Policy Agent (OPA) to filter vulnerabilities. You can specify a Rego file with --ignore-policy option. The Rego package name must be trivy and it must include a rule called ignore which determines if each individual vulnerability should be excluded (ignore=true) or not (ignore=false). In the policy, each vulnerability will be available for inspection as the input variable. The structure of each vulnerability input is the same as for the Trivy JSON output. There is a built-in Rego library with helper functions that you can import into your policy using: import data.lib.trivy . For more info about the helper functions, look at the library here To get started, see the example policy . $ trivy image --ignore-policy contrib/example_policy/basic.rego centos:7 Result centos:7 ( centos 7 .9.2009 ) ========================== Total: 9 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 4 , CRITICAL: 5 ) +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | glib2 | CVE-2015-8385 | HIGH | 2 .56.1-7.el7 | | pcre: buffer overflow caused | | | | | | | by named forward reference | | | | | | | to duplicate group number... | | | | | | | -->avd.aquasec.com/nvd/cve-2015-8385 | + +------------------+ + +-------------------+-----------------------------------------+ | | CVE-2016-3191 | | | | pcre: workspace overflow for | | | | | | | ( *ACCEPT ) with deeply nested | | | | | | | parentheses ( 8 .39/13, 10 .22/12 ) | | | | | | | -->avd.aquasec.com/nvd/cve-2016-3191 | + +------------------+ + +-------------------+-----------------------------------------+ | | CVE-2021-27219 | | | 2 .56.1-9.el7_9 | glib: integer overflow in | | | | | | | g_bytes_new function on | | | | | | | 64 -bit platforms due to an... | | | | | | | -->avd.aquasec.com/nvd/cve-2021-27219 | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | glibc | CVE-2019-1010022 | CRITICAL | 2 .17-317.el7 | | glibc: stack guard protection bypass | | | | | | | -->avd.aquasec.com/nvd/cve-2019-1010022 | +--------------+ + + +-------------------+ + | glibc-common | | | | | | | | | | | | | +--------------+------------------+ +-------------------+-------------------+-----------------------------------------+ | nss | CVE-2021-43527 | | 3 .53.1-3.el7_9 | 3 .67.0-4.el7_9 | nss: Memory corruption in | | | | | | | decodeECorDsaSignature with | | | | | | | DSA signatures ( and RSA-PSS ) | | | | | | | -->avd.aquasec.com/nvd/cve-2021-43527 | +--------------+ + + + + + | nss-sysinit | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+ + + + + + | nss-tools | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ | openssl-libs | CVE-2020-1971 | HIGH | 1 :1.0.2k-19.el7 | 1 :1.0.2k-21.el7_9 | openssl: EDIPARTYNAME | | | | | | | NULL pointer de-reference | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | +--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+","title":"By Open Policy Agent"},{"location":"docs/configuration/filtering/#by-inline-comments","text":"Scanner Supported Vulnerability Misconfiguration \u2713 Secret License Some configuration file formats (e.g. Terraform) support inline comments. In cases where trivy can detect comments of a specific format immediately adjacent to resource definitions, it is possible to filter/ignore findings from a single point of resource definition (in contrast to .trivyignore , which has a directory-wide scope on all of the files scanned). The format for these comments is trivy:ignore: immediately following the format-specific line-comment token. For example, to filter a Vulnerability ID \"AVD-GCP-0051\" in a Terraform HCL file: #trivy:ignore:AVD-GCP-0051 resource \"google_container_cluster\" \"one_off_test\" { name = var.cluster_name location = var.region }","title":"By Inline Comments"},{"location":"docs/configuration/others/","text":"Others Enable/Disable Scanners You can enable/disable scanners with the --scanners flag. Supported values: vuln config secret license For example, container image scanning enables vulnerability and secret scanners by default. If you don't need secret scanning, it can be disabled. $ trivy image --scanners vuln alpine:3.15 Exit Code Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 By default, Trivy exits with code 0 even when security issues are detected. Use the --exit-code option if you want to exit with a non-zero exit code. $ trivy image --exit-code 1 python:3.4-alpine3.9 Result 2019-05-16T12:51:43.500+0900 INFO Updating vulnerability database... 2019-05-16T12:52:00.387+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 (alpine 3.9.2) =================================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+--------------------------------+ | openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 | | | | | | | with long nonces | +---------+------------------+----------+-------------------+---------------+--------------------------------+ This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found. $ trivy image --exit-code 0 --severity MEDIUM,HIGH ruby:2.4.0 $ trivy image --exit-code 1 --severity CRITICAL ruby:2.4.0 Exit on EOL Scanner Supported Vulnerability \u2713 Misconfiguration Secret License Sometimes you may surprisingly get 0 vulnerabilities in an old image: Enabling --ignore-unfixed option while all packages have no fixed versions. Scanning a rather outdated OS (e.g. Ubuntu 10.04). An OS at the end of service/life (EOL) usually gets into this situation, which is definitely full of vulnerabilities. --exit-on-eol can fail scanning on EOL OS with a non-zero code. This flag is available with the following targets. Container images ( trivy image ) Virtual machine images ( trivy vm ) SBOM ( trivy sbom ) Root filesystem ( trivy rootfs ) $ trivy image --exit-on-eol 1 alpine:3.10 Result 2023-03-01T11:07:15.455+0200 INFO Vulnerability scanning is enabled ... 2023-03-01T11:07:17.938+0200 WARN This OS version is no longer supported by the distribution: alpine 3.10.9 2023-03-01T11:07:17.938+0200 WARN The vulnerability detection may be insufficient because security updates are not provided alpine:3.10 (alpine 3.10.9) =========================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 apk-tools \u2502 CVE-2021-36159 \u2502 CRITICAL \u2502 2.10.6-r0 \u2502 2.10.7-r0 \u2502 libfetch before 2021-07-26, as used in apk-tools, xbps, and \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 other products, mishandles... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-36159 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 2023-03-01T11:07:17.941+0200 ERROR Detected EOL OS: alpine 3.10.9 This option is useful for CI/CD. The following example will fail when a critical vulnerability is found or the OS is EOSL: $ trivy image --exit-code 1 --exit-on-eol 1 --severity CRITICAL alpine:3.16.3","title":"Others"},{"location":"docs/configuration/others/#others","text":"","title":"Others"},{"location":"docs/configuration/others/#enabledisable-scanners","text":"You can enable/disable scanners with the --scanners flag. Supported values: vuln config secret license For example, container image scanning enables vulnerability and secret scanners by default. If you don't need secret scanning, it can be disabled. $ trivy image --scanners vuln alpine:3.15","title":"Enable/Disable Scanners"},{"location":"docs/configuration/others/#exit-code","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 By default, Trivy exits with code 0 even when security issues are detected. Use the --exit-code option if you want to exit with a non-zero exit code. $ trivy image --exit-code 1 python:3.4-alpine3.9 Result 2019-05-16T12:51:43.500+0900 INFO Updating vulnerability database... 2019-05-16T12:52:00.387+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 (alpine 3.9.2) =================================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+--------------------------------+ | openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 | | | | | | | with long nonces | +---------+------------------+----------+-------------------+---------------+--------------------------------+ This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found. $ trivy image --exit-code 0 --severity MEDIUM,HIGH ruby:2.4.0 $ trivy image --exit-code 1 --severity CRITICAL ruby:2.4.0","title":"Exit Code"},{"location":"docs/configuration/others/#exit-on-eol","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License Sometimes you may surprisingly get 0 vulnerabilities in an old image: Enabling --ignore-unfixed option while all packages have no fixed versions. Scanning a rather outdated OS (e.g. Ubuntu 10.04). An OS at the end of service/life (EOL) usually gets into this situation, which is definitely full of vulnerabilities. --exit-on-eol can fail scanning on EOL OS with a non-zero code. This flag is available with the following targets. Container images ( trivy image ) Virtual machine images ( trivy vm ) SBOM ( trivy sbom ) Root filesystem ( trivy rootfs ) $ trivy image --exit-on-eol 1 alpine:3.10 Result 2023-03-01T11:07:15.455+0200 INFO Vulnerability scanning is enabled ... 2023-03-01T11:07:17.938+0200 WARN This OS version is no longer supported by the distribution: alpine 3.10.9 2023-03-01T11:07:17.938+0200 WARN The vulnerability detection may be insufficient because security updates are not provided alpine:3.10 (alpine 3.10.9) =========================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 apk-tools \u2502 CVE-2021-36159 \u2502 CRITICAL \u2502 2.10.6-r0 \u2502 2.10.7-r0 \u2502 libfetch before 2021-07-26, as used in apk-tools, xbps, and \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 other products, mishandles... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-36159 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 2023-03-01T11:07:17.941+0200 ERROR Detected EOL OS: alpine 3.10.9 This option is useful for CI/CD. The following example will fail when a critical vulnerability is found or the OS is EOSL: $ trivy image --exit-code 1 --exit-on-eol 1 --severity CRITICAL alpine:3.16.3","title":"Exit on EOL"},{"location":"docs/configuration/reporting/","text":"Reporting Trivy supports the following formats: Table JSON SARIF Template SBOM Table (Default) Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 $ trivy image -f table golang:1.12-alpine Show origins of vulnerable dependencies Scanner Supported Vulnerability \u2713 Misconfiguration Secret License EXPERIMENTAL This feature might change without preserving backwards compatibility. Modern software development relies on the use of third-party libraries. Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph. In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree. To make this task simpler Trivy can show a dependency origin tree with the --dependency-tree flag. This flag is only available with the --format table flag. The following packages/languages are currently supported: OS packages apk dpkg rpm Node.js npm: package-lock.json pnpm: pnpm-lock.yaml yarn: yarn.lock .NET NuGet: packages.lock.json Python Poetry: poetry.lock Ruby Bundler: Gemfile.lock Rust Binaries built with cargo-auditable Go Modules: go.mod PHP Composer This tree is the reverse of the npm list command. However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update. In table output, it looks like: $ trivy fs --severity HIGH,CRITICAL --dependency-tree /path/to/your_node_project package-lock.json ( npm ) ======================= Total: 2 ( HIGH: 1 , CRITICAL: 1 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 follow-redirects \u2502 CVE-2022-0155 \u2502 HIGH \u2502 1 .14.6 \u2502 1 .14.7 \u2502 follow-redirects: Exposure of Private Personal Information \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 to an Unauthorized Actor \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-0155 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 glob-parent \u2502 CVE-2020-28469 \u2502 CRITICAL \u2502 3 .1.0 \u2502 5 .1.2 \u2502 nodejs-glob-parent: Regular expression denial of service \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2020-28469 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Dependency Origin Tree ( Reversed ) ================================= package-lock.json \u251c\u2500\u2500 follow-redirects@1.14.6, ( HIGH: 1 , CRITICAL: 0 ) \u2502 \u2514\u2500\u2500 axios@0.21.4 \u2514\u2500\u2500 glob-parent@3.1.0, ( HIGH: 0 , CRITICAL: 1 ) \u2514\u2500\u2500 chokidar@2.1.8 \u2514\u2500\u2500 watchpack-chokidar2@2.0.1 \u2514\u2500\u2500 watchpack@1.7.5 \u2514\u2500\u2500 webpack@4.46.0 \u2514\u2500\u2500 cra-append-sw@2.7.0 Vulnerable dependencies are shown in the top level of the tree. Lower levels show how those vulnerabilities are introduced. In the example above axios@0.21.4 included in the project directly depends on the vulnerable follow-redirects@1.14.6 . Also, glob-parent@3.1.0 with some vulnerabilities is included through chain of dependencies that is added by cra-append-sw@2.7.0 . Then, you can try to update axios@0.21.4 and cra-append-sw@2.7.0 to resolve vulnerabilities in follow-redirects@1.14.6 and glob-parent@3.1.0 . JSON Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 $ trivy image -f json -o results.json golang:1.12-alpine Result 2019-05-16T01:46:31.777+0900 INFO Updating vulnerability database... 2019-05-16T01:47:03.007+0900 INFO Detecting Alpine vulnerabilities... JSON [ { \"Target\": \"php-app/composer.lock\", \"Vulnerabilities\": null }, { \"Target\": \"node-app/package-lock.json\", \"Vulnerabilities\": [ { \"VulnerabilityID\": \"CVE-2018-16487\", \"PkgName\": \"lodash\", \"InstalledVersion\": \"4.17.4\", \"FixedVersion\": \"\\u003e=4.17.11\", \"Title\": \"lodash: Prototype pollution in utilities function\", \"Description\": \"A prototype pollution vulnerability was found in lodash \\u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.\", \"Severity\": \"HIGH\", \"References\": [ \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487\", ] } ] }, { \"Target\": \"trivy-ci-test (alpine 3.7.1)\", \"Vulnerabilities\": [ { \"VulnerabilityID\": \"CVE-2018-16840\", \"PkgName\": \"curl\", \"InstalledVersion\": \"7.61.0-r0\", \"FixedVersion\": \"7.61.1-r1\", \"Title\": \"curl: Use-after-free when closing \\\"easy\\\" handle in Curl_close()\", \"Description\": \"A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. \", \"Severity\": \"HIGH\", \"References\": [ \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840\", ] }, { \"VulnerabilityID\": \"CVE-2019-3822\", \"PkgName\": \"curl\", \"InstalledVersion\": \"7.61.0-r0\", \"FixedVersion\": \"7.61.1-r2\", \"Title\": \"curl: NTLMv2 type-3 header stack buffer overflow\", \"Description\": \"libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. \", \"Severity\": \"HIGH\", \"References\": [ \"https://curl.haxx.se/docs/CVE-2019-3822.html\", \"https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E\" ] }, { \"VulnerabilityID\": \"CVE-2018-16839\", \"PkgName\": \"curl\", \"InstalledVersion\": \"7.61.0-r0\", \"FixedVersion\": \"7.61.1-r1\", \"Title\": \"curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()\", \"Description\": \"Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.\", \"Severity\": \"HIGH\", \"References\": [ \"https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5\", ] }, { \"VulnerabilityID\": \"CVE-2018-19486\", \"PkgName\": \"git\", \"InstalledVersion\": \"2.15.2-r0\", \"FixedVersion\": \"2.15.3-r0\", \"Title\": \"git: Improper handling of PATH allows for commands to be executed from the current directory\", \"Description\": \"Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.\", \"Severity\": \"HIGH\", \"References\": [ \"https://usn.ubuntu.com/3829-1/\", ] }, { \"VulnerabilityID\": \"CVE-2018-17456\", \"PkgName\": \"git\", \"InstalledVersion\": \"2.15.2-r0\", \"FixedVersion\": \"2.15.3-r0\", \"Title\": \"git: arbitrary code execution via .gitmodules\", \"Description\": \"Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \\\"git clone\\\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.\", \"Severity\": \"HIGH\", \"References\": [ \"http://www.securitytracker.com/id/1041811\", ] } ] }, { \"Target\": \"python-app/Pipfile.lock\", \"Vulnerabilities\": null }, { \"Target\": \"ruby-app/Gemfile.lock\", \"Vulnerabilities\": null }, { \"Target\": \"rust-app/Cargo.lock\", \"Vulnerabilities\": null } ] VulnerabilityID , PkgName , InstalledVersion , and Severity in Vulnerabilities are always filled with values, but other fields might be empty. SARIF Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License SARIF can be generated with the --format sarif flag. $ trivy image --format sarif -o report.sarif golang:1.12-alpine This SARIF file can be uploaded to GitHub code scanning results, and there is a Trivy GitHub Action for automating this process. Template Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 Custom Template $ trivy image --format template --template \"{{ range . }} {{ .Target }} {{ end }}\" golang:1.12-alpine Result 2020-01-02T18:02:32.856+0100 INFO Detecting Alpine vulnerabilities... golang:1.12-alpine (alpine 3.10.2) You can compute different figures within the template using sprig functions. As an example you can summarize the different classes of issues: $ trivy image --format template --template '{{- $critical := 0 }}{{- $high := 0 }}{{- range . }}{{- range .Vulnerabilities }}{{- if eq .Severity \"CRITICAL\" }}{{- $critical = add $critical 1 }}{{- end }}{{- if eq .Severity \"HIGH\" }}{{- $high = add $high 1 }}{{- end }}{{- end }}{{- end }}Critical: {{ $critical }}, High: {{ $high }}' golang:1.12-alpine Result Critical: 0, High: 2 For other features of sprig, see the official sprig documentation. Load templates from a file You can load templates from a file prefixing the template path with an @. $ trivy image --format template --template \"@/path/to/template\" golang:1.12-alpine Default Templates If Trivy is installed using rpm then default templates can be found at /usr/local/share/trivy/templates . JUnit Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License In the following example using the template junit.tpl XML can be generated. $ trivy image --format template --template \"@contrib/junit.tpl\" -o junit-report.xml golang:1.12-alpine ASFF Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License Trivy also supports an ASFF template for reporting findings to AWS Security Hub HTML Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License $ trivy image --format template --template \"@contrib/html.tpl\" -o report.html golang:1.12-alpine The following example shows use of default HTML template when Trivy is installed using rpm. $ trivy image --format template --template \"@/usr/local/share/trivy/templates/html.tpl\" -o report.html golang:1.12-alpine SBOM See here for details.","title":"Reporting"},{"location":"docs/configuration/reporting/#reporting","text":"Trivy supports the following formats: Table JSON SARIF Template SBOM","title":"Reporting"},{"location":"docs/configuration/reporting/#table-default","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 $ trivy image -f table golang:1.12-alpine","title":"Table (Default)"},{"location":"docs/configuration/reporting/#show-origins-of-vulnerable-dependencies","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License EXPERIMENTAL This feature might change without preserving backwards compatibility. Modern software development relies on the use of third-party libraries. Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph. In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree. To make this task simpler Trivy can show a dependency origin tree with the --dependency-tree flag. This flag is only available with the --format table flag. The following packages/languages are currently supported: OS packages apk dpkg rpm Node.js npm: package-lock.json pnpm: pnpm-lock.yaml yarn: yarn.lock .NET NuGet: packages.lock.json Python Poetry: poetry.lock Ruby Bundler: Gemfile.lock Rust Binaries built with cargo-auditable Go Modules: go.mod PHP Composer This tree is the reverse of the npm list command. However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update. In table output, it looks like: $ trivy fs --severity HIGH,CRITICAL --dependency-tree /path/to/your_node_project package-lock.json ( npm ) ======================= Total: 2 ( HIGH: 1 , CRITICAL: 1 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 follow-redirects \u2502 CVE-2022-0155 \u2502 HIGH \u2502 1 .14.6 \u2502 1 .14.7 \u2502 follow-redirects: Exposure of Private Personal Information \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 to an Unauthorized Actor \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-0155 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 glob-parent \u2502 CVE-2020-28469 \u2502 CRITICAL \u2502 3 .1.0 \u2502 5 .1.2 \u2502 nodejs-glob-parent: Regular expression denial of service \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2020-28469 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Dependency Origin Tree ( Reversed ) ================================= package-lock.json \u251c\u2500\u2500 follow-redirects@1.14.6, ( HIGH: 1 , CRITICAL: 0 ) \u2502 \u2514\u2500\u2500 axios@0.21.4 \u2514\u2500\u2500 glob-parent@3.1.0, ( HIGH: 0 , CRITICAL: 1 ) \u2514\u2500\u2500 chokidar@2.1.8 \u2514\u2500\u2500 watchpack-chokidar2@2.0.1 \u2514\u2500\u2500 watchpack@1.7.5 \u2514\u2500\u2500 webpack@4.46.0 \u2514\u2500\u2500 cra-append-sw@2.7.0 Vulnerable dependencies are shown in the top level of the tree. Lower levels show how those vulnerabilities are introduced. In the example above axios@0.21.4 included in the project directly depends on the vulnerable follow-redirects@1.14.6 . Also, glob-parent@3.1.0 with some vulnerabilities is included through chain of dependencies that is added by cra-append-sw@2.7.0 . Then, you can try to update axios@0.21.4 and cra-append-sw@2.7.0 to resolve vulnerabilities in follow-redirects@1.14.6 and glob-parent@3.1.0 .","title":"Show origins of vulnerable dependencies"},{"location":"docs/configuration/reporting/#json","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 $ trivy image -f json -o results.json golang:1.12-alpine Result 2019-05-16T01:46:31.777+0900 INFO Updating vulnerability database... 2019-05-16T01:47:03.007+0900 INFO Detecting Alpine vulnerabilities... JSON [ { \"Target\": \"php-app/composer.lock\", \"Vulnerabilities\": null }, { \"Target\": \"node-app/package-lock.json\", \"Vulnerabilities\": [ { \"VulnerabilityID\": \"CVE-2018-16487\", \"PkgName\": \"lodash\", \"InstalledVersion\": \"4.17.4\", \"FixedVersion\": \"\\u003e=4.17.11\", \"Title\": \"lodash: Prototype pollution in utilities function\", \"Description\": \"A prototype pollution vulnerability was found in lodash \\u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.\", \"Severity\": \"HIGH\", \"References\": [ \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487\", ] } ] }, { \"Target\": \"trivy-ci-test (alpine 3.7.1)\", \"Vulnerabilities\": [ { \"VulnerabilityID\": \"CVE-2018-16840\", \"PkgName\": \"curl\", \"InstalledVersion\": \"7.61.0-r0\", \"FixedVersion\": \"7.61.1-r1\", \"Title\": \"curl: Use-after-free when closing \\\"easy\\\" handle in Curl_close()\", \"Description\": \"A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. \", \"Severity\": \"HIGH\", \"References\": [ \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840\", ] }, { \"VulnerabilityID\": \"CVE-2019-3822\", \"PkgName\": \"curl\", \"InstalledVersion\": \"7.61.0-r0\", \"FixedVersion\": \"7.61.1-r2\", \"Title\": \"curl: NTLMv2 type-3 header stack buffer overflow\", \"Description\": \"libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. \", \"Severity\": \"HIGH\", \"References\": [ \"https://curl.haxx.se/docs/CVE-2019-3822.html\", \"https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E\" ] }, { \"VulnerabilityID\": \"CVE-2018-16839\", \"PkgName\": \"curl\", \"InstalledVersion\": \"7.61.0-r0\", \"FixedVersion\": \"7.61.1-r1\", \"Title\": \"curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()\", \"Description\": \"Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.\", \"Severity\": \"HIGH\", \"References\": [ \"https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5\", ] }, { \"VulnerabilityID\": \"CVE-2018-19486\", \"PkgName\": \"git\", \"InstalledVersion\": \"2.15.2-r0\", \"FixedVersion\": \"2.15.3-r0\", \"Title\": \"git: Improper handling of PATH allows for commands to be executed from the current directory\", \"Description\": \"Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.\", \"Severity\": \"HIGH\", \"References\": [ \"https://usn.ubuntu.com/3829-1/\", ] }, { \"VulnerabilityID\": \"CVE-2018-17456\", \"PkgName\": \"git\", \"InstalledVersion\": \"2.15.2-r0\", \"FixedVersion\": \"2.15.3-r0\", \"Title\": \"git: arbitrary code execution via .gitmodules\", \"Description\": \"Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \\\"git clone\\\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.\", \"Severity\": \"HIGH\", \"References\": [ \"http://www.securitytracker.com/id/1041811\", ] } ] }, { \"Target\": \"python-app/Pipfile.lock\", \"Vulnerabilities\": null }, { \"Target\": \"ruby-app/Gemfile.lock\", \"Vulnerabilities\": null }, { \"Target\": \"rust-app/Cargo.lock\", \"Vulnerabilities\": null } ] VulnerabilityID , PkgName , InstalledVersion , and Severity in Vulnerabilities are always filled with values, but other fields might be empty.","title":"JSON"},{"location":"docs/configuration/reporting/#sarif","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License SARIF can be generated with the --format sarif flag. $ trivy image --format sarif -o report.sarif golang:1.12-alpine This SARIF file can be uploaded to GitHub code scanning results, and there is a Trivy GitHub Action for automating this process.","title":"SARIF"},{"location":"docs/configuration/reporting/#template","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713","title":"Template"},{"location":"docs/configuration/reporting/#custom-template","text":"$ trivy image --format template --template \"{{ range . }} {{ .Target }} {{ end }}\" golang:1.12-alpine Result 2020-01-02T18:02:32.856+0100 INFO Detecting Alpine vulnerabilities... golang:1.12-alpine (alpine 3.10.2) You can compute different figures within the template using sprig functions. As an example you can summarize the different classes of issues: $ trivy image --format template --template '{{- $critical := 0 }}{{- $high := 0 }}{{- range . }}{{- range .Vulnerabilities }}{{- if eq .Severity \"CRITICAL\" }}{{- $critical = add $critical 1 }}{{- end }}{{- if eq .Severity \"HIGH\" }}{{- $high = add $high 1 }}{{- end }}{{- end }}{{- end }}Critical: {{ $critical }}, High: {{ $high }}' golang:1.12-alpine Result Critical: 0, High: 2 For other features of sprig, see the official sprig documentation.","title":"Custom Template"},{"location":"docs/configuration/reporting/#load-templates-from-a-file","text":"You can load templates from a file prefixing the template path with an @. $ trivy image --format template --template \"@/path/to/template\" golang:1.12-alpine","title":"Load templates from a file"},{"location":"docs/configuration/reporting/#default-templates","text":"If Trivy is installed using rpm then default templates can be found at /usr/local/share/trivy/templates .","title":"Default Templates"},{"location":"docs/configuration/reporting/#junit","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License In the following example using the template junit.tpl XML can be generated. $ trivy image --format template --template \"@contrib/junit.tpl\" -o junit-report.xml golang:1.12-alpine","title":"JUnit"},{"location":"docs/configuration/reporting/#asff","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License Trivy also supports an ASFF template for reporting findings to AWS Security Hub","title":"ASFF"},{"location":"docs/configuration/reporting/#html","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License $ trivy image --format template --template \"@contrib/html.tpl\" -o report.html golang:1.12-alpine The following example shows use of default HTML template when Trivy is installed using rpm. $ trivy image --format template --template \"@/usr/local/share/trivy/templates/html.tpl\" -o report.html golang:1.12-alpine","title":"HTML"},{"location":"docs/configuration/reporting/#sbom","text":"See here for details.","title":"SBOM"},{"location":"docs/configuration/skipping/","text":"Skipping Files and Directories This section details ways to specify the files and directories that Trivy should not scan. Skip Files Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 By default, Trivy traverses directories and searches for all necessary files for scanning. You can skip files that you don't maintain using the --skip-files flag. $ trivy image --skip-files \"/Gemfile.lock\" --skip-files \"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock\" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 It's possible to specify globs as part of the value. $ trivy image --skip-files \"./testdata/*/bar\" . Will skip any file named bar in the subdirectories of testdata. Skip Directories Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 By default, Trivy traverses directories and searches for all necessary files for scanning. You can skip directories that you don't maintain using the --skip-dirs flag. $ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs \"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0\" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 It's possible to specify globs as part of the value. $ trivy image --skip-dirs \"./testdata/*\" . Will skip all subdirectories of the testdata directory. Tip Glob patterns work with any trivy subcommand (image, config, etc.) and can be specified to skip both directories (with --skip-dirs ) and files (with --skip-files ). Advanced globbing Trivy also supports the globstar pattern matching. $ trivy image --skip-files \"**/foo\" image:tag Will skip the file foo that happens to be nested under any parent(s). File patterns Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License When a directory is given as an input, Trivy will recursively look for and test all files based on file patterns. The default file patterns are here . In addition to the default file patterns, the --file-patterns option takes regexp patterns to look for your files. For example, it may be useful when your file name of Dockerfile doesn't match the default patterns. This can be repeated for specifying multiple file patterns. A file pattern contains the analyzer it is used for, and the pattern itself, joined by a semicolon. For example: --file-patterns \"dockerfile:.*.docker\" --file-patterns \"yaml:deployment\" --file-patterns \"pip:requirements-.*\\.txt\" The prefixes are listed here","title":"Skipping Files"},{"location":"docs/configuration/skipping/#skipping-files-and-directories","text":"This section details ways to specify the files and directories that Trivy should not scan.","title":"Skipping Files and Directories"},{"location":"docs/configuration/skipping/#skip-files","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 By default, Trivy traverses directories and searches for all necessary files for scanning. You can skip files that you don't maintain using the --skip-files flag. $ trivy image --skip-files \"/Gemfile.lock\" --skip-files \"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock\" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 It's possible to specify globs as part of the value. $ trivy image --skip-files \"./testdata/*/bar\" . Will skip any file named bar in the subdirectories of testdata.","title":"Skip Files"},{"location":"docs/configuration/skipping/#skip-directories","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713 By default, Trivy traverses directories and searches for all necessary files for scanning. You can skip directories that you don't maintain using the --skip-dirs flag. $ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs \"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0\" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 It's possible to specify globs as part of the value. $ trivy image --skip-dirs \"./testdata/*\" . Will skip all subdirectories of the testdata directory. Tip Glob patterns work with any trivy subcommand (image, config, etc.) and can be specified to skip both directories (with --skip-dirs ) and files (with --skip-files ).","title":"Skip Directories"},{"location":"docs/configuration/skipping/#advanced-globbing","text":"Trivy also supports the globstar pattern matching. $ trivy image --skip-files \"**/foo\" image:tag Will skip the file foo that happens to be nested under any parent(s).","title":"Advanced globbing"},{"location":"docs/configuration/skipping/#file-patterns","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License When a directory is given as an input, Trivy will recursively look for and test all files based on file patterns. The default file patterns are here . In addition to the default file patterns, the --file-patterns option takes regexp patterns to look for your files. For example, it may be useful when your file name of Dockerfile doesn't match the default patterns. This can be repeated for specifying multiple file patterns. A file pattern contains the analyzer it is used for, and the pattern itself, joined by a semicolon. For example: --file-patterns \"dockerfile:.*.docker\" --file-patterns \"yaml:deployment\" --file-patterns \"pip:requirements-.*\\.txt\" The prefixes are listed here","title":"File patterns"},{"location":"docs/references/troubleshooting/","text":"Troubleshooting Scan Timeout Error $ trivy image ... ... analyze error: timeout: context deadline exceeded Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as --timeout 15m . Certification Error Error: x509: certificate signed by unknown authority TRIVY_INSECURE can be used to allow insecure connections to a container registry when using SSL. $ TRIVY_INSECURE=true trivy image [YOUR_IMAGE] GitHub Rate limiting Error $ trivy image ... ... API rate limit exceeded for xxx.xxx.xxx.xxx. Specify GITHUB_TOKEN for authentication https://developer.github.com/v3/#rate-limiting $ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10 Unable to open JAR files Error $ trivy image ... ... failed to analyze file: failed to analyze usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: unable to open usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: failed to open: unable to read the file: stream error: stream ID 9 ; PROTOCOL_ERROR ; received from peer Currently, we're investigating this issue. As a temporary mitigation, you may be able to avoid this issue by downloading the Java DB in advance. $ trivy image --download-java-db-only 2023 -02-01T16:57:04.322+0900 INFO Downloading the Java DB... $ trivy image [ YOUR_JAVA_IMAGE ] Running in parallel takes same time as series run When running trivy on multiple images simultaneously, it will take same time as running trivy in series. This is because of a limitation of boltdb. Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it. Reference : boltdb: Opening a database . Multiple Trivy servers Error $ trivy image --server http://xxx.com:xxxx test-image ... - twirp error internal: failed scan, test-image: failed to apply layers: layer cache missing: sha256:***** To run multiple Trivy servers, you need to use Redis as the cache backend so that those servers can share the cache. Follow this instruction to do so. Problems with /tmp on remote Git repository scans Error FATAL repository scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: git clone error: write /tmp/fanal-remote... Trivy clones remote Git repositories under the /tmp directory before scanning them. If /tmp doesn't work for you, you can change it by setting the TMPDIR environment variable. Try: $ TMPDIR=/my/custom/path trivy repo ... Running out of space during image scans Error image scan failed: failed to copy the image: write /tmp/fanal-3323732142: no space left on device Trivy uses the /tmp directory during image scan, if the image is large or /tmp is of insufficient size then the scan fails You can set the TMPDIR environment variable to use redirect trivy to use a directory with adequate storage. Try: $ TMPDIR=/my/custom/path trivy image ... DB Old DB schema Error --skip-update cannot be specified with the old DB schema. Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow the instruction of air-gapped environment . Error downloading vulnerability DB Error FATAL failed to download vulnerability DB If trivy is running behind corporate firewall, you have to add the following urls to your allowlist. ghcr.io pkg-containers.githubusercontent.com Denied Error GET https://ghcr.io/token?scope=repository%3Aaquasecurity%2Ftrivy-db%3Apull&service=ghcr.io: DENIED: denied Your local GHCR (GitHub Container Registry) token might be expired. Please remove the token and try downloading the DB again. docker logout ghcr.io Homebrew Scope error Error Error: Your macOS keychain GitHub credentials do not have sufficient scope! $ brew tap aquasecurity/trivy Error: Your macOS keychain GitHub credentials do not have sufficient scope! Scopes they need: none Scopes they have: Create a personal access token: https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew echo 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.zshrc Try: $ printf \"protocol=https\\nhost=github.com\\n\" | git credential-osxkeychain erase Already installed Error Error: aquasecurity/trivy/trivy 64 already installed $ brew upgrade ... Error: aquasecurity/trivy/trivy 64 already installed Try: $ brew unlink trivy && brew uninstall trivy ($ rm -rf /usr/local/Cellar/trivy/64) $ brew install aquasecurity/trivy/trivy Others Unknown error Try again with --reset option: $ trivy image --reset","title":"Troubleshooting"},{"location":"docs/references/troubleshooting/#troubleshooting","text":"","title":"Troubleshooting"},{"location":"docs/references/troubleshooting/#scan","text":"","title":"Scan"},{"location":"docs/references/troubleshooting/#timeout","text":"Error $ trivy image ... ... analyze error: timeout: context deadline exceeded Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as --timeout 15m .","title":"Timeout"},{"location":"docs/references/troubleshooting/#certification","text":"Error Error: x509: certificate signed by unknown authority TRIVY_INSECURE can be used to allow insecure connections to a container registry when using SSL. $ TRIVY_INSECURE=true trivy image [YOUR_IMAGE]","title":"Certification"},{"location":"docs/references/troubleshooting/#github-rate-limiting","text":"Error $ trivy image ... ... API rate limit exceeded for xxx.xxx.xxx.xxx. Specify GITHUB_TOKEN for authentication https://developer.github.com/v3/#rate-limiting $ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10","title":"GitHub Rate limiting"},{"location":"docs/references/troubleshooting/#unable-to-open-jar-files","text":"Error $ trivy image ... ... failed to analyze file: failed to analyze usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: unable to open usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: failed to open: unable to read the file: stream error: stream ID 9 ; PROTOCOL_ERROR ; received from peer Currently, we're investigating this issue. As a temporary mitigation, you may be able to avoid this issue by downloading the Java DB in advance. $ trivy image --download-java-db-only 2023 -02-01T16:57:04.322+0900 INFO Downloading the Java DB... $ trivy image [ YOUR_JAVA_IMAGE ]","title":"Unable to open JAR files"},{"location":"docs/references/troubleshooting/#running-in-parallel-takes-same-time-as-series-run","text":"When running trivy on multiple images simultaneously, it will take same time as running trivy in series. This is because of a limitation of boltdb. Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it. Reference : boltdb: Opening a database .","title":"Running in parallel takes same time as series run"},{"location":"docs/references/troubleshooting/#multiple-trivy-servers","text":"Error $ trivy image --server http://xxx.com:xxxx test-image ... - twirp error internal: failed scan, test-image: failed to apply layers: layer cache missing: sha256:***** To run multiple Trivy servers, you need to use Redis as the cache backend so that those servers can share the cache. Follow this instruction to do so.","title":"Multiple Trivy servers"},{"location":"docs/references/troubleshooting/#problems-with-tmp-on-remote-git-repository-scans","text":"Error FATAL repository scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: git clone error: write /tmp/fanal-remote... Trivy clones remote Git repositories under the /tmp directory before scanning them. If /tmp doesn't work for you, you can change it by setting the TMPDIR environment variable. Try: $ TMPDIR=/my/custom/path trivy repo ...","title":"Problems with /tmp on remote Git repository scans"},{"location":"docs/references/troubleshooting/#running-out-of-space-during-image-scans","text":"Error image scan failed: failed to copy the image: write /tmp/fanal-3323732142: no space left on device Trivy uses the /tmp directory during image scan, if the image is large or /tmp is of insufficient size then the scan fails You can set the TMPDIR environment variable to use redirect trivy to use a directory with adequate storage. Try: $ TMPDIR=/my/custom/path trivy image ...","title":"Running out of space during image scans"},{"location":"docs/references/troubleshooting/#db","text":"","title":"DB"},{"location":"docs/references/troubleshooting/#old-db-schema","text":"Error --skip-update cannot be specified with the old DB schema. Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow the instruction of air-gapped environment .","title":"Old DB schema"},{"location":"docs/references/troubleshooting/#error-downloading-vulnerability-db","text":"Error FATAL failed to download vulnerability DB If trivy is running behind corporate firewall, you have to add the following urls to your allowlist. ghcr.io pkg-containers.githubusercontent.com","title":"Error downloading vulnerability DB"},{"location":"docs/references/troubleshooting/#denied","text":"Error GET https://ghcr.io/token?scope=repository%3Aaquasecurity%2Ftrivy-db%3Apull&service=ghcr.io: DENIED: denied Your local GHCR (GitHub Container Registry) token might be expired. Please remove the token and try downloading the DB again. docker logout ghcr.io","title":"Denied"},{"location":"docs/references/troubleshooting/#homebrew","text":"","title":"Homebrew"},{"location":"docs/references/troubleshooting/#scope-error","text":"Error Error: Your macOS keychain GitHub credentials do not have sufficient scope! $ brew tap aquasecurity/trivy Error: Your macOS keychain GitHub credentials do not have sufficient scope! Scopes they need: none Scopes they have: Create a personal access token: https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew echo 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.zshrc Try: $ printf \"protocol=https\\nhost=github.com\\n\" | git credential-osxkeychain erase","title":"Scope error"},{"location":"docs/references/troubleshooting/#already-installed","text":"Error Error: aquasecurity/trivy/trivy 64 already installed $ brew upgrade ... Error: aquasecurity/trivy/trivy 64 already installed Try: $ brew unlink trivy && brew uninstall trivy ($ rm -rf /usr/local/Cellar/trivy/64) $ brew install aquasecurity/trivy/trivy","title":"Already installed"},{"location":"docs/references/troubleshooting/#others","text":"","title":"Others"},{"location":"docs/references/troubleshooting/#unknown-error","text":"Try again with --reset option: $ trivy image --reset","title":"Unknown error"},{"location":"docs/references/configuration/config-file/","text":"Config file Trivy can be customized by tweaking a trivy.yaml file. The config path can be overridden by the --config flag. An example is here . Global Options # Same as '--quiet' # Default is false quiet : false # Same as '--debug' # Default is false debug : false # Same as '--insecure' # Default is false insecure : false # Same as '--timeout' # Default is '5m' timeout : 10m # Same as '--cache-dir' # Default is your system cache dir cache : dir : $HOME/.cache/trivy Report Options # Same as '--format' # Default is 'table' format : table # Same as '--report' (available with 'trivy k8s') # Default is all report : all # Same as '--template' # Default is empty template : # Same as '--dependency-tree' # Default is false dependency-tree : false # Same as '--list-all-pkgs' # Default is false list-all-pkgs : false # Same as '--ignorefile' # Default is '.trivyignore' ignorefile : .trivyignore # Same as '--ignore-policy' # Default is empty ignore-policy : # Same as '--exit-code' # Default is 0 exit-code : 0 # Same as '--exit-on-eol' # Default is 0 exit-on-eol : 0 # Same as '--output' # Default is empty (stdout) output : # Same as '--severity' # Default is all severities severity : - UNKNOWN - LOW - MEDIUM - HIGH - CRITICAL Scan Options Available in client/server mode scan : # Same as '--file-patterns' # Default is empty file-patterns : - # Same as '--skip-dirs' # Default is empty skip-dirs : - usr/local/ - etc/ # Same as '--skip-files' # Default is empty skip-files : - package-dev.json # Same as '--offline-scan' # Default is false offline-scan : false # Same as '--scanners' # Default depends on subcommand scanners : - vuln - config - secret Cache Options cache : # Same as '--cache-backend' # Default is 'fs' backend : 'fs' # Same as '--cache-ttl' # Default is 0 (no ttl) ttl : 0 # Redis options redis : # Same as '--redis-ca' # Default is empty ca : # Same as '--redis-cert' # Default is empty cert : # Same as '--redis-key' # Default is empty key : DB Options db : # Same as '--skip-db-update' # Default is false skip-update : false # Same as '--no-progress' # Default is false no-progress : false # Same as '--db-repository' # Default is 'ghcr.io/aquasecurity/trivy-db' repository : ghcr.io/aquasecurity/trivy-db # Same as '--java-db-repository' # Default is 'ghcr.io/aquasecurity/trivy-java-db' java-repository : ghcr.io/aquasecurity/trivy-java-db Registry Options registry : # Same as '--username' # Default is empty username : # Same as '--password' # Default is empty password : # Same as '--registry-token' # Default is empty registry-token : Image Options Available with container image scanning image : # Same as '--input' (available with 'trivy image') # Default is empty input : # Same as '--removed-pkgs' # Default is false removed-pkgs : false # Same as '--platform' # Default is empty platform : docker : # Same as '--docker-host' # Default is empty host : Vulnerability Options Available with vulnerability scanning vulnerability : # Same as '--vuln-type' # Default is 'os,library' type : - os - library # Same as '--ignore-unfixed' # Default is false ignore-unfixed : false Secret Options Available with secret scanning secret : # Same as '--secret-config' # Default is 'trivy-secret.yaml' config : config/trivy/secret.yaml Rego Options rego # Same as '--trace' # Default is false trace : false # Same as '--config-policy' # Default is empty policy : - policy/repository - policy/custom # Same as '--config-data' # Default is empty data : - data/ # Same as '--policy-namespaces' # Default is empty namespaces : - opa.examples - users Misconfiguration Options Available with misconfiguration scanning misconfiguration : # Same as '--include-non-failures' # Default is false include-non-failures : false # helm value override configurations # set individual values helm : set : - securityContext.runAsUser=10001 # set values with file helm : values : - overrides.yaml # set specific values from specific files helm : set-file : - image=dev-overrides.yaml # set as string and preserve type helm : set-string : - name=true # terraform tfvars overrrides terraform : vars : - dev-terraform.tfvars - common-terraform.tfvars Kubernetes Options Available with Kubernetes scanning kubernetes : # Same as '--context' # Default is empty context : # Same as '--namespace' # Default is empty namespace : Repository Options Available with git repository scanning ( trivy repo ) repository : # Same as '--branch' # Default is empty branch : # Same as '--commit' # Default is empty commit : # Same as '--tag' # Default is empty tag : Client/Server Options Available in client/server mode server : # Same as '--server' (available in client mode) # Default is empty addr : http://localhost:4954 # Same as '--token' # Default is empty token : \"something-secret\" # Same as '--token-header' # Default is 'Trivy-Token' token-header : 'My-Token-Header' # Same as '--custom-headers' # Default is empty custom-headers : - scanner : trivy - x-api-token : xxx # Same as '--listen' (available in server mode) # Default is 'localhost:4954' listen : 0.0.0.0:10000 Cloud Options Available for cloud scanning (currently only trivy aws ) cloud : # whether to force a cache update for every scan update-cache : false # how old cached results can be before being invalidated max-cache-age : 24h # aws-specific cloud settings aws : # the aws region to use region : us-east-1 # the aws endpoint to use (not required for general use) endpoint : https://my.custom.aws.endpoint # the aws account to use (this will be determined from your environment when not set) account : 123456789012","title":"Config file"},{"location":"docs/references/configuration/config-file/#config-file","text":"Trivy can be customized by tweaking a trivy.yaml file. The config path can be overridden by the --config flag. An example is here .","title":"Config file"},{"location":"docs/references/configuration/config-file/#global-options","text":"# Same as '--quiet' # Default is false quiet : false # Same as '--debug' # Default is false debug : false # Same as '--insecure' # Default is false insecure : false # Same as '--timeout' # Default is '5m' timeout : 10m # Same as '--cache-dir' # Default is your system cache dir cache : dir : $HOME/.cache/trivy","title":"Global Options"},{"location":"docs/references/configuration/config-file/#report-options","text":"# Same as '--format' # Default is 'table' format : table # Same as '--report' (available with 'trivy k8s') # Default is all report : all # Same as '--template' # Default is empty template : # Same as '--dependency-tree' # Default is false dependency-tree : false # Same as '--list-all-pkgs' # Default is false list-all-pkgs : false # Same as '--ignorefile' # Default is '.trivyignore' ignorefile : .trivyignore # Same as '--ignore-policy' # Default is empty ignore-policy : # Same as '--exit-code' # Default is 0 exit-code : 0 # Same as '--exit-on-eol' # Default is 0 exit-on-eol : 0 # Same as '--output' # Default is empty (stdout) output : # Same as '--severity' # Default is all severities severity : - UNKNOWN - LOW - MEDIUM - HIGH - CRITICAL","title":"Report Options"},{"location":"docs/references/configuration/config-file/#scan-options","text":"Available in client/server mode scan : # Same as '--file-patterns' # Default is empty file-patterns : - # Same as '--skip-dirs' # Default is empty skip-dirs : - usr/local/ - etc/ # Same as '--skip-files' # Default is empty skip-files : - package-dev.json # Same as '--offline-scan' # Default is false offline-scan : false # Same as '--scanners' # Default depends on subcommand scanners : - vuln - config - secret","title":"Scan Options"},{"location":"docs/references/configuration/config-file/#cache-options","text":"cache : # Same as '--cache-backend' # Default is 'fs' backend : 'fs' # Same as '--cache-ttl' # Default is 0 (no ttl) ttl : 0 # Redis options redis : # Same as '--redis-ca' # Default is empty ca : # Same as '--redis-cert' # Default is empty cert : # Same as '--redis-key' # Default is empty key :","title":"Cache Options"},{"location":"docs/references/configuration/config-file/#db-options","text":"db : # Same as '--skip-db-update' # Default is false skip-update : false # Same as '--no-progress' # Default is false no-progress : false # Same as '--db-repository' # Default is 'ghcr.io/aquasecurity/trivy-db' repository : ghcr.io/aquasecurity/trivy-db # Same as '--java-db-repository' # Default is 'ghcr.io/aquasecurity/trivy-java-db' java-repository : ghcr.io/aquasecurity/trivy-java-db","title":"DB Options"},{"location":"docs/references/configuration/config-file/#registry-options","text":"registry : # Same as '--username' # Default is empty username : # Same as '--password' # Default is empty password : # Same as '--registry-token' # Default is empty registry-token :","title":"Registry Options"},{"location":"docs/references/configuration/config-file/#image-options","text":"Available with container image scanning image : # Same as '--input' (available with 'trivy image') # Default is empty input : # Same as '--removed-pkgs' # Default is false removed-pkgs : false # Same as '--platform' # Default is empty platform : docker : # Same as '--docker-host' # Default is empty host :","title":"Image Options"},{"location":"docs/references/configuration/config-file/#vulnerability-options","text":"Available with vulnerability scanning vulnerability : # Same as '--vuln-type' # Default is 'os,library' type : - os - library # Same as '--ignore-unfixed' # Default is false ignore-unfixed : false","title":"Vulnerability Options"},{"location":"docs/references/configuration/config-file/#secret-options","text":"Available with secret scanning secret : # Same as '--secret-config' # Default is 'trivy-secret.yaml' config : config/trivy/secret.yaml","title":"Secret Options"},{"location":"docs/references/configuration/config-file/#rego-options","text":"rego # Same as '--trace' # Default is false trace : false # Same as '--config-policy' # Default is empty policy : - policy/repository - policy/custom # Same as '--config-data' # Default is empty data : - data/ # Same as '--policy-namespaces' # Default is empty namespaces : - opa.examples - users","title":"Rego Options"},{"location":"docs/references/configuration/config-file/#misconfiguration-options","text":"Available with misconfiguration scanning misconfiguration : # Same as '--include-non-failures' # Default is false include-non-failures : false # helm value override configurations # set individual values helm : set : - securityContext.runAsUser=10001 # set values with file helm : values : - overrides.yaml # set specific values from specific files helm : set-file : - image=dev-overrides.yaml # set as string and preserve type helm : set-string : - name=true # terraform tfvars overrrides terraform : vars : - dev-terraform.tfvars - common-terraform.tfvars","title":"Misconfiguration Options"},{"location":"docs/references/configuration/config-file/#kubernetes-options","text":"Available with Kubernetes scanning kubernetes : # Same as '--context' # Default is empty context : # Same as '--namespace' # Default is empty namespace :","title":"Kubernetes Options"},{"location":"docs/references/configuration/config-file/#repository-options","text":"Available with git repository scanning ( trivy repo ) repository : # Same as '--branch' # Default is empty branch : # Same as '--commit' # Default is empty commit : # Same as '--tag' # Default is empty tag :","title":"Repository Options"},{"location":"docs/references/configuration/config-file/#clientserver-options","text":"Available in client/server mode server : # Same as '--server' (available in client mode) # Default is empty addr : http://localhost:4954 # Same as '--token' # Default is empty token : \"something-secret\" # Same as '--token-header' # Default is 'Trivy-Token' token-header : 'My-Token-Header' # Same as '--custom-headers' # Default is empty custom-headers : - scanner : trivy - x-api-token : xxx # Same as '--listen' (available in server mode) # Default is 'localhost:4954' listen : 0.0.0.0:10000","title":"Client/Server Options"},{"location":"docs/references/configuration/config-file/#cloud-options","text":"Available for cloud scanning (currently only trivy aws ) cloud : # whether to force a cache update for every scan update-cache : false # how old cached results can be before being invalidated max-cache-age : 24h # aws-specific cloud settings aws : # the aws region to use region : us-east-1 # the aws endpoint to use (not required for general use) endpoint : https://my.custom.aws.endpoint # the aws account to use (this will be determined from your environment when not set) account : 123456789012","title":"Cloud Options"},{"location":"docs/references/configuration/cli/trivy/","text":"trivy Unified security scanner Synopsis Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets trivy [global flags] command [flags] target Examples # Scan a container image $ trivy image python:3.4-alpine # Scan a container image from a tar archive $ trivy image --input ruby-3.1.tar # Scan local filesystem $ trivy fs . # Run in server mode $ trivy server Options --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode -f, --format string version format (json) --generate-default-config write the default config to trivy-default.yaml -h, --help help for trivy --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy aws - [EXPERIMENTAL] Scan AWS account trivy config - Scan config files for misconfigurations trivy filesystem - Scan local filesystem trivy image - Scan a container image trivy kubernetes - [EXPERIMENTAL] Scan kubernetes cluster trivy module - Manage modules trivy plugin - Manage plugins trivy repository - Scan a remote repository trivy rootfs - Scan rootfs trivy sbom - Scan SBOM for vulnerabilities trivy server - Server mode trivy version - Print the version trivy vm - [EXPERIMENTAL] Scan a virtual machine image","title":"Overview"},{"location":"docs/references/configuration/cli/trivy/#trivy","text":"Unified security scanner","title":"trivy"},{"location":"docs/references/configuration/cli/trivy/#synopsis","text":"Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets trivy [global flags] command [flags] target","title":"Synopsis"},{"location":"docs/references/configuration/cli/trivy/#examples","text":"# Scan a container image $ trivy image python:3.4-alpine # Scan a container image from a tar archive $ trivy image --input ruby-3.1.tar # Scan local filesystem $ trivy fs . # Run in server mode $ trivy server","title":"Examples"},{"location":"docs/references/configuration/cli/trivy/#options","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode -f, --format string version format (json) --generate-default-config write the default config to trivy-default.yaml -h, --help help for trivy --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options"},{"location":"docs/references/configuration/cli/trivy/#see-also","text":"trivy aws - [EXPERIMENTAL] Scan AWS account trivy config - Scan config files for misconfigurations trivy filesystem - Scan local filesystem trivy image - Scan a container image trivy kubernetes - [EXPERIMENTAL] Scan kubernetes cluster trivy module - Manage modules trivy plugin - Manage plugins trivy repository - Scan a remote repository trivy rootfs - Scan rootfs trivy sbom - Scan SBOM for vulnerabilities trivy server - Server mode trivy version - Print the version trivy vm - [EXPERIMENTAL] Scan a virtual machine image","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_aws/","text":"trivy aws [EXPERIMENTAL] Scan AWS account Synopsis Scan an AWS account for misconfigurations. Trivy uses the same authentication methods as the AWS CLI. See https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html The following services are supported: - accessanalyzer - api-gateway - athena - cloudfront - cloudtrail - cloudwatch - codebuild - documentdb - dynamodb - ec2 - ecr - ecs - efs - eks - elasticache - elasticsearch - elb - emr - iam - kinesis - kms - lambda - mq - msk - neptune - rds - redshift - s3 - sns - sqs - ssm - workspaces trivy aws [flags] Examples # basic scanning $ trivy aws --region us-east-1 # limit scan to a single service: $ trivy aws --region us-east-1 --service s3 # limit scan to multiple services: $ trivy aws --region us-east-1 --service s3 --service ec2 # force refresh of cache for fresh results $ trivy aws --region us-east-1 --update-cache Options --account string The AWS account to scan. It's useful to specify this when reviewing cached results for multiple accounts. --arn string The AWS ARN to show results for. Useful to filter results once a scan is cached. --compliance string compliance report to generate (aws-cis-1.2, aws-cis-1.4) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --endpoint string AWS Endpoint override --exit-code int specify exit code when any security issues are found -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for aws --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --list-all-pkgs enabling the option will output all packages regardless of vulnerability --max-cache-age duration The maximum age of the cloud cache. Cached data will be requeried from the cloud provider if it is older than this. (default 24h0m0s) -o, --output string output file name --policy-namespaces strings Rego namespaces --region string AWS Region to scan --report string specify a report format for the output. (all,summary) (default \"all\") --service strings Only scan AWS Service(s) specified with this flag. Can specify multiple services using --service A --service B etc. -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-policy-update skip fetching rego policy updates -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --trace enable more verbose trace output for custom queries --update-cache Update the cache for the applicable cloud provider instead of using cached results. Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"AWS"},{"location":"docs/references/configuration/cli/trivy_aws/#trivy-aws","text":"[EXPERIMENTAL] Scan AWS account","title":"trivy aws"},{"location":"docs/references/configuration/cli/trivy_aws/#synopsis","text":"Scan an AWS account for misconfigurations. Trivy uses the same authentication methods as the AWS CLI. See https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html The following services are supported: - accessanalyzer - api-gateway - athena - cloudfront - cloudtrail - cloudwatch - codebuild - documentdb - dynamodb - ec2 - ecr - ecs - efs - eks - elasticache - elasticsearch - elb - emr - iam - kinesis - kms - lambda - mq - msk - neptune - rds - redshift - s3 - sns - sqs - ssm - workspaces trivy aws [flags]","title":"Synopsis"},{"location":"docs/references/configuration/cli/trivy_aws/#examples","text":"# basic scanning $ trivy aws --region us-east-1 # limit scan to a single service: $ trivy aws --region us-east-1 --service s3 # limit scan to multiple services: $ trivy aws --region us-east-1 --service s3 --service ec2 # force refresh of cache for fresh results $ trivy aws --region us-east-1 --update-cache","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_aws/#options","text":"--account string The AWS account to scan. It's useful to specify this when reviewing cached results for multiple accounts. --arn string The AWS ARN to show results for. Useful to filter results once a scan is cached. --compliance string compliance report to generate (aws-cis-1.2, aws-cis-1.4) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --endpoint string AWS Endpoint override --exit-code int specify exit code when any security issues are found -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for aws --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --list-all-pkgs enabling the option will output all packages regardless of vulnerability --max-cache-age duration The maximum age of the cloud cache. Cached data will be requeried from the cloud provider if it is older than this. (default 24h0m0s) -o, --output string output file name --policy-namespaces strings Rego namespaces --region string AWS Region to scan --report string specify a report format for the output. (all,summary) (default \"all\") --service strings Only scan AWS Service(s) specified with this flag. Can specify multiple services using --service A --service B etc. -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-policy-update skip fetching rego policy updates -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --trace enable more verbose trace output for custom queries --update-cache Update the cache for the applicable cloud provider instead of using cached results.","title":"Options"},{"location":"docs/references/configuration/cli/trivy_aws/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_aws/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_config/","text":"trivy config Scan config files for misconfigurations trivy config [flags] DIR Options --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for config --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0) --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --report string specify a compliance report format for the output. (all,summary) (default \"all\") -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-policy-update skip fetching rego policy updates -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Config"},{"location":"docs/references/configuration/cli/trivy_config/#trivy-config","text":"Scan config files for misconfigurations trivy config [flags] DIR","title":"trivy config"},{"location":"docs/references/configuration/cli/trivy_config/#options","text":"--cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for config --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0) --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --report string specify a compliance report format for the output. (all,summary) (default \"all\") -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-policy-update skip fetching rego policy updates -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed.","title":"Options"},{"location":"docs/references/configuration/cli/trivy_config/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_config/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_filesystem/","text":"trivy filesystem Scan local filesystem trivy filesystem [flags] PATH Examples # Scan a local project including language-specific files $ trivy fs /path/to/your_project # Scan a single file $ trivy fs ./trivy-ci-test/Pipfile.lock Options --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for filesystem --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --report string specify a compliance report format for the output. (all,summary) (default \"all\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Filesystem"},{"location":"docs/references/configuration/cli/trivy_filesystem/#trivy-filesystem","text":"Scan local filesystem trivy filesystem [flags] PATH","title":"trivy filesystem"},{"location":"docs/references/configuration/cli/trivy_filesystem/#examples","text":"# Scan a local project including language-specific files $ trivy fs /path/to/your_project # Scan a single file $ trivy fs ./trivy-ci-test/Pipfile.lock","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_filesystem/#options","text":"--cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for filesystem --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --report string specify a compliance report format for the output. (all,summary) (default \"all\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_filesystem/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_filesystem/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_image/","text":"trivy image Scan a container image trivy image [flags] IMAGE_NAME Examples # Scan a container image $ trivy image python:3.4-alpine # Scan a container image from a tar archive $ trivy image --input ruby-3.1.tar # Filter by severities $ trivy image --severity HIGH,CRITICAL alpine:3.15 # Ignore unfixed/unpatched vulnerabilities $ trivy image --ignore-unfixed alpine:3.15 # Scan a container image in client mode $ trivy image --server http://127.0.0.1:4954 alpine:latest # Generate json result $ trivy image --format json --output result.json alpine:3.15 # Generate a report in the CycloneDX format $ trivy image --format cyclonedx --output result.cdx alpine:3.15 Options --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate (docker-cis) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --docker-host string unix domain socket path to use for docker scanning --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for image --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --image-config-scanners string comma-separated list of what security issues to detect on container image configurations (config,secret) --image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote]) --include-non-failures include successes and exceptions, available with '--scanners config' --input string input file path instead of image name --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --platform string set platform in the form os/arch if image is multi-platform capable --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --removed-pkgs detect vulnerabilities of removed packages (only for Alpine) --report string specify a format for the compliance report. (default \"summary\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Image"},{"location":"docs/references/configuration/cli/trivy_image/#trivy-image","text":"Scan a container image trivy image [flags] IMAGE_NAME","title":"trivy image"},{"location":"docs/references/configuration/cli/trivy_image/#examples","text":"# Scan a container image $ trivy image python:3.4-alpine # Scan a container image from a tar archive $ trivy image --input ruby-3.1.tar # Filter by severities $ trivy image --severity HIGH,CRITICAL alpine:3.15 # Ignore unfixed/unpatched vulnerabilities $ trivy image --ignore-unfixed alpine:3.15 # Scan a container image in client mode $ trivy image --server http://127.0.0.1:4954 alpine:latest # Generate json result $ trivy image --format json --output result.json alpine:3.15 # Generate a report in the CycloneDX format $ trivy image --format cyclonedx --output result.cdx alpine:3.15","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_image/#options","text":"--cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate (docker-cis) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --docker-host string unix domain socket path to use for docker scanning --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for image --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --image-config-scanners string comma-separated list of what security issues to detect on container image configurations (config,secret) --image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote]) --include-non-failures include successes and exceptions, available with '--scanners config' --input string input file path instead of image name --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --platform string set platform in the form os/arch if image is multi-platform capable --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --removed-pkgs detect vulnerabilities of removed packages (only for Alpine) --report string specify a format for the compliance report. (default \"summary\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_image/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_image/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_kubernetes/","text":"trivy kubernetes [EXPERIMENTAL] Scan kubernetes cluster trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: pods, pod/NAME } Examples # cluster scanning $ trivy k8s --report summary cluster # namespace scanning: $ trivy k8s -n kube-system --report summary all # resources scanning: $ trivy k8s --report=summary deploy $ trivy k8s --namespace=kube-system --report=summary deploy,configmaps # resource scanning: $ trivy k8s deployment/orion Options -A, --all-namespaces fetch resources from all cluster namespaces --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate (k8s-nsa,k8s-cis, k8s-pss-baseline, k8s-pss-restricted) --components strings specify which components to scan (default [workload,infra]) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --context string specify a context to scan --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for kubernetes --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0) --kubeconfig string specify the kubeconfig file path to use --list-all-pkgs enabling the option will output all packages regardless of vulnerability -n, --namespace string specify a namespace to scan --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --parallel int number (between 1-20) of goroutines enabled for parallel scanning (default 5) --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --report string specify a report format for the output. (all,summary) (default \"all\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners string comma-separated list of what security issues to detect (vuln,config,secret,license) (default \"vuln,config,secret,rbac\") --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --tolerations strings specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule) --trace enable more verbose trace output for custom queries --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Kubernetes"},{"location":"docs/references/configuration/cli/trivy_kubernetes/#trivy-kubernetes","text":"[EXPERIMENTAL] Scan kubernetes cluster trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: pods, pod/NAME }","title":"trivy kubernetes"},{"location":"docs/references/configuration/cli/trivy_kubernetes/#examples","text":"# cluster scanning $ trivy k8s --report summary cluster # namespace scanning: $ trivy k8s -n kube-system --report summary all # resources scanning: $ trivy k8s --report=summary deploy $ trivy k8s --namespace=kube-system --report=summary deploy,configmaps # resource scanning: $ trivy k8s deployment/orion","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_kubernetes/#options","text":"-A, --all-namespaces fetch resources from all cluster namespaces --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate (k8s-nsa,k8s-cis, k8s-pss-baseline, k8s-pss-restricted) --components strings specify which components to scan (default [workload,infra]) --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --context string specify a context to scan --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for kubernetes --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0) --kubeconfig string specify the kubeconfig file path to use --list-all-pkgs enabling the option will output all packages regardless of vulnerability -n, --namespace string specify a namespace to scan --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --parallel int number (between 1-20) of goroutines enabled for parallel scanning (default 5) --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --report string specify a report format for the output. (all,summary) (default \"all\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners string comma-separated list of what security issues to detect (vuln,config,secret,license) (default \"vuln,config,secret,rbac\") --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --tolerations strings specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule) --trace enable more verbose trace output for custom queries --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_kubernetes/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_kubernetes/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_module/","text":"trivy module Manage modules Options --enable-modules strings [EXPERIMENTAL] module names to enable -h, --help help for module --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner trivy module install - Install a module trivy module uninstall - Uninstall a module","title":"Module"},{"location":"docs/references/configuration/cli/trivy_module/#trivy-module","text":"Manage modules","title":"trivy module"},{"location":"docs/references/configuration/cli/trivy_module/#options","text":"--enable-modules strings [EXPERIMENTAL] module names to enable -h, --help help for module --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")","title":"Options"},{"location":"docs/references/configuration/cli/trivy_module/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_module/#see-also","text":"trivy - Unified security scanner trivy module install - Install a module trivy module uninstall - Uninstall a module","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_module_install/","text":"trivy module install Install a module trivy module install [flags] REPOSITORY Options -h, --help help for install Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --enable-modules strings [EXPERIMENTAL] module names to enable --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy module - Manage modules","title":"Module Install"},{"location":"docs/references/configuration/cli/trivy_module_install/#trivy-module-install","text":"Install a module trivy module install [flags] REPOSITORY","title":"trivy module install"},{"location":"docs/references/configuration/cli/trivy_module_install/#options","text":"-h, --help help for install","title":"Options"},{"location":"docs/references/configuration/cli/trivy_module_install/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --enable-modules strings [EXPERIMENTAL] module names to enable --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_module_install/#see-also","text":"trivy module - Manage modules","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_module_uninstall/","text":"trivy module uninstall Uninstall a module trivy module uninstall [flags] REPOSITORY Options -h, --help help for uninstall Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --enable-modules strings [EXPERIMENTAL] module names to enable --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy module - Manage modules","title":"Module Uninstall"},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#trivy-module-uninstall","text":"Uninstall a module trivy module uninstall [flags] REPOSITORY","title":"trivy module uninstall"},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#options","text":"-h, --help help for uninstall","title":"Options"},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --enable-modules strings [EXPERIMENTAL] module names to enable --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#see-also","text":"trivy module - Manage modules","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin/","text":"trivy plugin Manage plugins Options -h, --help help for plugin Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner trivy plugin info - Show information about the specified plugin trivy plugin install - Install a plugin trivy plugin list - List installed plugin trivy plugin run - Run a plugin on the fly trivy plugin uninstall - Uninstall a plugin trivy plugin update - Update an existing plugin","title":"Plugin"},{"location":"docs/references/configuration/cli/trivy_plugin/#trivy-plugin","text":"Manage plugins","title":"trivy plugin"},{"location":"docs/references/configuration/cli/trivy_plugin/#options","text":"-h, --help help for plugin","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin/#see-also","text":"trivy - Unified security scanner trivy plugin info - Show information about the specified plugin trivy plugin install - Install a plugin trivy plugin list - List installed plugin trivy plugin run - Run a plugin on the fly trivy plugin uninstall - Uninstall a plugin trivy plugin update - Update an existing plugin","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin_info/","text":"trivy plugin info Show information about the specified plugin trivy plugin info PLUGIN_NAME Options -h, --help help for info Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy plugin - Manage plugins","title":"Plugin Info"},{"location":"docs/references/configuration/cli/trivy_plugin_info/#trivy-plugin-info","text":"Show information about the specified plugin trivy plugin info PLUGIN_NAME","title":"trivy plugin info"},{"location":"docs/references/configuration/cli/trivy_plugin_info/#options","text":"-h, --help help for info","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin_info/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin_info/#see-also","text":"trivy plugin - Manage plugins","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin_install/","text":"trivy plugin install Install a plugin trivy plugin install URL | FILE_PATH Options -h, --help help for install Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy plugin - Manage plugins","title":"Plugin Install"},{"location":"docs/references/configuration/cli/trivy_plugin_install/#trivy-plugin-install","text":"Install a plugin trivy plugin install URL | FILE_PATH","title":"trivy plugin install"},{"location":"docs/references/configuration/cli/trivy_plugin_install/#options","text":"-h, --help help for install","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin_install/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin_install/#see-also","text":"trivy plugin - Manage plugins","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin_list/","text":"trivy plugin list List installed plugin trivy plugin list Options -h, --help help for list Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy plugin - Manage plugins","title":"Plugin List"},{"location":"docs/references/configuration/cli/trivy_plugin_list/#trivy-plugin-list","text":"List installed plugin trivy plugin list","title":"trivy plugin list"},{"location":"docs/references/configuration/cli/trivy_plugin_list/#options","text":"-h, --help help for list","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin_list/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin_list/#see-also","text":"trivy plugin - Manage plugins","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin_run/","text":"trivy plugin run Run a plugin on the fly trivy plugin run URL | FILE_PATH Options -h, --help help for run Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy plugin - Manage plugins","title":"Plugin Run"},{"location":"docs/references/configuration/cli/trivy_plugin_run/#trivy-plugin-run","text":"Run a plugin on the fly trivy plugin run URL | FILE_PATH","title":"trivy plugin run"},{"location":"docs/references/configuration/cli/trivy_plugin_run/#options","text":"-h, --help help for run","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin_run/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin_run/#see-also","text":"trivy plugin - Manage plugins","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/","text":"trivy plugin uninstall Uninstall a plugin trivy plugin uninstall PLUGIN_NAME Options -h, --help help for uninstall Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy plugin - Manage plugins","title":"Plugin Uninstall"},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#trivy-plugin-uninstall","text":"Uninstall a plugin trivy plugin uninstall PLUGIN_NAME","title":"trivy plugin uninstall"},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#options","text":"-h, --help help for uninstall","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#see-also","text":"trivy plugin - Manage plugins","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_plugin_update/","text":"trivy plugin update Update an existing plugin trivy plugin update PLUGIN_NAME Options -h, --help help for update Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy plugin - Manage plugins","title":"Plugin Update"},{"location":"docs/references/configuration/cli/trivy_plugin_update/#trivy-plugin-update","text":"Update an existing plugin trivy plugin update PLUGIN_NAME","title":"trivy plugin update"},{"location":"docs/references/configuration/cli/trivy_plugin_update/#options","text":"-h, --help help for update","title":"Options"},{"location":"docs/references/configuration/cli/trivy_plugin_update/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_plugin_update/#see-also","text":"trivy plugin - Manage plugins","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_repository/","text":"trivy repository Scan a remote repository trivy repository [flags] REPO_URL Examples # Scan your remote git repository $ trivy repo https://github.com/knqyf263/trivy-ci-test Options --branch string pass the branch name to be scanned --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --commit string pass the commit hash to be scanned --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for repository --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization --tag string pass the tag name to be scanned -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Repository"},{"location":"docs/references/configuration/cli/trivy_repository/#trivy-repository","text":"Scan a remote repository trivy repository [flags] REPO_URL","title":"trivy repository"},{"location":"docs/references/configuration/cli/trivy_repository/#examples","text":"# Scan your remote git repository $ trivy repo https://github.com/knqyf263/trivy-ci-test","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_repository/#options","text":"--branch string pass the branch name to be scanned --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --commit string pass the commit hash to be scanned --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for repository --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization --tag string pass the tag name to be scanned -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_repository/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_repository/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_rootfs/","text":"trivy rootfs Scan rootfs trivy rootfs [flags] ROOTDIR Examples # Scan unpacked filesystem $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf - $ trivy rootfs /tmp/rootfs # Scan from inside a container $ docker run --rm -it alpine:3.11 / # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin / # trivy rootfs / Options --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for rootfs --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Rootfs"},{"location":"docs/references/configuration/cli/trivy_rootfs/#trivy-rootfs","text":"Scan rootfs trivy rootfs [flags] ROOTDIR","title":"trivy rootfs"},{"location":"docs/references/configuration/cli/trivy_rootfs/#examples","text":"# Scan unpacked filesystem $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf - $ trivy rootfs /tmp/rootfs # Scan from inside a container $ docker run --rm -it alpine:3.11 / # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin / # trivy rootfs /","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_rootfs/#options","text":"--cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --config-data strings specify paths from which data for the Rego policies will be recursively loaded --config-policy strings specify paths to the Rego policy files directory, applying config files --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for rootfs --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignored-licenses strings specify a list of license to ignore --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-namespaces strings Rego namespaces --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --skip-policy-update skip fetching rego policy updates --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_rootfs/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_rootfs/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_sbom/","text":"trivy sbom Scan SBOM for vulnerabilities trivy sbom [flags] SBOM_PATH Examples # Scan CycloneDX and show the result in tables $ trivy sbom /path/to/report.cdx # Scan CycloneDX and generate a CycloneDX report $ trivy sbom --format cyclonedx /path/to/report.cdx # Scan CycloneDX-type attestation and show the result in tables $ trivy sbom /path/to/report.cdx.intoto.jsonl Options --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") -h, --help help for sbom --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignorefile string specify .trivyignore file (default \".trivyignore\") --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --list-all-pkgs enabling the option will output all packages regardless of vulnerability --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --slow scan over time with lower CPU and memory utilization -t, --template string output template --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"SBOM"},{"location":"docs/references/configuration/cli/trivy_sbom/#trivy-sbom","text":"Scan SBOM for vulnerabilities trivy sbom [flags] SBOM_PATH","title":"trivy sbom"},{"location":"docs/references/configuration/cli/trivy_sbom/#examples","text":"# Scan CycloneDX and show the result in tables $ trivy sbom /path/to/report.cdx # Scan CycloneDX and generate a CycloneDX report $ trivy sbom --format cyclonedx /path/to/report.cdx # Scan CycloneDX-type attestation and show the result in tables $ trivy sbom /path/to/report.cdx.intoto.jsonl","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_sbom/#options","text":"--cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") -h, --help help for sbom --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignorefile string specify .trivyignore file (default \".trivyignore\") --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --list-all-pkgs enabling the option will output all packages regardless of vulnerability --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --slow scan over time with lower CPU and memory utilization -t, --template string output template --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_sbom/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_sbom/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_server/","text":"trivy server Server mode trivy server [flags] Examples # Run a server $ trivy server # Listen on 0.0.0.0:10000 $ trivy server --listen 0.0.0.0:10000 Options --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable -h, --help help for server --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --listen string listen address in server mode (default \"localhost:4954\") --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --reset remove all caches and database --skip-db-update skip updating vulnerability database --skip-java-db-update skip updating Java index database --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --username strings username. Comma-separated usernames allowed. Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Server"},{"location":"docs/references/configuration/cli/trivy_server/#trivy-server","text":"Server mode trivy server [flags]","title":"trivy server"},{"location":"docs/references/configuration/cli/trivy_server/#examples","text":"# Run a server $ trivy server # Listen on 0.0.0.0:10000 $ trivy server --listen 0.0.0.0:10000","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_server/#options","text":"--cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable -h, --help help for server --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --listen string listen address in server mode (default \"localhost:4954\") --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --registry-token string registry token --reset remove all caches and database --skip-db-update skip updating vulnerability database --skip-java-db-update skip updating Java index database --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --username strings username. Comma-separated usernames allowed.","title":"Options"},{"location":"docs/references/configuration/cli/trivy_server/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_server/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_version/","text":"trivy version Print the version trivy version [flags] Options -f, --format string version format (json) -h, --help help for version Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"Version"},{"location":"docs/references/configuration/cli/trivy_version/#trivy-version","text":"Print the version trivy version [flags]","title":"trivy version"},{"location":"docs/references/configuration/cli/trivy_version/#options","text":"-f, --format string version format (json) -h, --help help for version","title":"Options"},{"location":"docs/references/configuration/cli/trivy_version/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_version/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/configuration/cli/trivy_vm/","text":"trivy vm [EXPERIMENTAL] Scan a virtual machine image trivy vm [flags] VM_IMAGE Examples # Scan your AWS AMI $ trivy vm --scanners vuln ami:${your_ami_id} # Scan your AWS EBS snapshot $ trivy vm ebs:${your_ebs_snapshot_id} Options --aws-region string AWS region to scan --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for vm --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) Options inherited from parent commands --cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version SEE ALSO trivy - Unified security scanner","title":"VM"},{"location":"docs/references/configuration/cli/trivy_vm/#trivy-vm","text":"[EXPERIMENTAL] Scan a virtual machine image trivy vm [flags] VM_IMAGE","title":"trivy vm"},{"location":"docs/references/configuration/cli/trivy_vm/#examples","text":"# Scan your AWS AMI $ trivy vm --scanners vuln ami:${your_ami_id} # Scan your AWS EBS snapshot $ trivy vm ebs:${your_ebs_snapshot_id}","title":"Examples"},{"location":"docs/references/configuration/cli/trivy_vm/#options","text":"--aws-region string AWS region to scan --cache-backend string cache backend (e.g. redis://localhost:6379) (default \"fs\") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning --compliance string compliance report to generate --custom-headers strings custom headers in client mode --db-repository string OCI repository to retrieve trivy-db from (default \"ghcr.io/aquasecurity/trivy-db\") --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages --download-db-only download/update vulnerability database but don't run a scan --download-java-db-only download/update Java index database but don't run a scan --enable-modules strings [EXPERIMENTAL] module names to enable --exit-code int specify exit code when any security issues are found --exit-on-eol int exit with the specified code when the OS reaches end of service/life --file-patterns strings specify config file patterns -f, --format string format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln) (default \"table\") --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files -h, --help help for vm --ignore-policy string specify the Rego file path to evaluate each vulnerability --ignore-unfixed display only fixed vulnerabilities --ignorefile string specify .trivyignore file (default \".trivyignore\") --include-non-failures include successes and exceptions, available with '--scanners config' --java-db-repository string OCI repository to retrieve trivy-java-db from (default \"ghcr.io/aquasecurity/trivy-java-db\") --list-all-pkgs enabling the option will output all packages regardless of vulnerability --module-dir string specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend --redis-tls enable redis TLS with public certificates, if using redis as cache backend --rekor-url string [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\") --reset remove all caches and database --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) --scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret]) --secret-config string specify a path to config file for secret scanning (default \"trivy-secret.yaml\") --server string server address in client mode -s, --severity string severities of security issues to be displayed (comma separated) (default \"UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL\") --skip-db-update skip updating vulnerability database --skip-dirs strings specify the directories where the traversal is skipped --skip-files strings specify the file paths to skip traversal --skip-java-db-update skip updating Java index database --slow scan over time with lower CPU and memory utilization -t, --template string output template --tf-vars strings specify paths to override the Terraform tfvars files --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default \"Trivy-Token\") --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])","title":"Options"},{"location":"docs/references/configuration/cli/trivy_vm/#options-inherited-from-parent-commands","text":"--cache-dir string cache directory (default \"/path/to/cache\") -c, --config string config path (default \"trivy.yaml\") -d, --debug debug mode --generate-default-config write the default config to trivy-default.yaml --insecure allow insecure server connections -q, --quiet suppress progress bar and log output --timeout duration timeout (default 5m0s) -v, --version show version","title":"Options inherited from parent commands"},{"location":"docs/references/configuration/cli/trivy_vm/#see-also","text":"trivy - Unified security scanner","title":"SEE ALSO"},{"location":"docs/references/modes/client-server/","text":"Client/Server Trivy has client/server mode. Trivy server has vulnerability database and Trivy client doesn't have to download vulnerability database. It is useful if you want to scan images or files at multiple locations and do not want to download the database at every location. Server At first, you need to launch Trivy server. It downloads vulnerability database automatically and continue to fetch the latest DB in the background. $ trivy server --listen localhost:8080 2019-12-12T15:17:06.551+0200 INFO Need to update DB 2019-12-12T15:17:56.706+0200 INFO Reopening DB... 2019-12-12T15:17:56.707+0200 INFO Listening localhost:8080... If you want to accept a connection from outside, you have to specify 0.0.0.0 or your ip address, not localhost . $ trivy server --listen 0.0.0.0:8080 Remote image scan Then, specify the server address for image command. $ trivy image --server http://localhost:8080 alpine:3.10 Note : It's important to specify the protocol (http or https). Result alpine:3.10 (alpine 3.10.2) =========================== Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 2, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | +---------+------------------+----------+-------------------+---------------+ | openssl | CVE-2019-1549 | MEDIUM | 1.1.1c-r0 | 1.1.1d-r0 | + +------------------+ + + + | | CVE-2019-1563 | | | | + +------------------+----------+ + + | | CVE-2019-1547 | LOW | | | +---------+------------------+----------+-------------------+---------------+ Remote scan of local filesystem Also, there is a way to scan local file system: $ trivy fs --server http://localhost:8080 --severity CRITICAL ./integration/testdata/fixtures/fs/pom/ Note : It's important to specify the protocol (http or https). Result pom.xml (pom) ============= Total: 24 (CRITICAL: 24) +---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+ | com.fasterxml.jackson.core:jackson-databind | CVE-2017-17485 | CRITICAL | 2.9.1 | 2.8.11, 2.9.4 | jackson-databind: Unsafe | | | | | | | deserialization due to | | | | | | | incomplete black list (incomplete | | | | | | | fix for CVE-2017-15095)... | | | | | | | -->avd.aquasec.com/nvd/cve-2017-17485 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-11307 | | | 2.7.9.4, 2.8.11.2, 2.9.6 | jackson-databind: Potential | | | | | | | information exfiltration with | | | | | | | default typing, serialization | | | | | | | gadget from MyBatis | | | | | | | -->avd.aquasec.com/nvd/cve-2018-11307 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-14718 | | | 2.6.7.2, 2.9.7 | jackson-databind: arbitrary code | | | | | | | execution in slf4j-ext class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14718 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-14719 | | | | jackson-databind: arbitrary | | | | | | | code execution in blaze-ds-opt | | | | | | | and blaze-ds-core classes | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14719 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-14720 | | | | jackson-databind: exfiltration/XXE | | | | | | | in some JDK classes | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14720 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-14721 | | | | jackson-databind: server-side request | | | | | | | forgery (SSRF) in axis2-jaxws class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14721 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-19360 | | | 2.6.7.3, 2.7.9.5, 2.8.11.3, | jackson-databind: improper | | | | | | 2.9.8 | polymorphic deserialization | | | | | | | in axis2-transport-jms class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-19360 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-19361 | | | | jackson-databind: improper | | | | | | | polymorphic deserialization | | | | | | | in openjpa class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-19361 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-19362 | | | | jackson-databind: improper | | | | | | | polymorphic deserialization | | | | | | | in jboss-common-core class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-19362 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-7489 | | | 2.7.9.3, 2.8.11.1, 2.9.5 | jackson-databind: incomplete fix | | | | | | | for CVE-2017-7525 permits unsafe | | | | | | | serialization via c3p0 libraries | | | | | | | -->avd.aquasec.com/nvd/cve-2018-7489 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14379 | | | 2.7.9.6, 2.8.11.4, 2.9.9.2 | jackson-databind: default | | | | | | | typing mishandling leading | | | | | | | to remote code execution | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14379 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14540 | | | 2.9.10 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | com.zaxxer.hikari.HikariConfig | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14540 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14892 | | | 2.6.7.3, 2.8.11.5, 2.9.10 | jackson-databind: Serialization | | | | | | | gadgets in classes of the | | | | | | | commons-configuration package | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14892 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14893 | | | 2.8.11.5, 2.9.10 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | classes of the xalan package | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14893 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-16335 | | | 2.9.10 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | com.zaxxer.hikari.HikariDataSource | | | | | | | -->avd.aquasec.com/nvd/cve-2019-16335 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-16942 | | | 2.9.10.1 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | org.apache.commons.dbcp.datasources.* | | | | | | | -->avd.aquasec.com/nvd/cve-2019-16942 | + +------------------+ + + +---------------------------------------+ | | CVE-2019-16943 | | | | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | com.p6spy.engine.spy.P6DataSource | | | | | | | -->avd.aquasec.com/nvd/cve-2019-16943 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-17267 | | | 2.9.10 | jackson-databind: Serialization | | | | | | | gadgets in classes of | | | | | | | the ehcache package | | | | | | | -->avd.aquasec.com/nvd/cve-2019-17267 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-17531 | | | 2.9.10.1 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | org.apache.log4j.receivers.db.* | | | | | | | -->avd.aquasec.com/nvd/cve-2019-17531 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-20330 | | | 2.8.11.5, 2.9.10.2 | jackson-databind: lacks | | | | | | | certain net.sf.ehcache blocking | | | | | | | -->avd.aquasec.com/nvd/cve-2019-20330 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2020-8840 | | | 2.7.9.7, 2.8.11.5, 2.9.10.3 | jackson-databind: Lacks certain | | | | | | | xbean-reflect/JNDI blocking | | | | | | | -->avd.aquasec.com/nvd/cve-2020-8840 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2020-9546 | | | 2.7.9.7, 2.8.11.6, 2.9.10.4 | jackson-databind: Serialization | | | | | | | gadgets in shaded-hikari-config | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9546 | + +------------------+ + + +---------------------------------------+ | | CVE-2020-9547 | | | | jackson-databind: Serialization | | | | | | | gadgets in ibatis-sqlmap | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9547 | + +------------------+ + + +---------------------------------------+ | | CVE-2020-9548 | | | | jackson-databind: Serialization | | | | | | | gadgets in anteros-core | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9548 | +---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+ Remote scan of root filesystem Also, there is a way to scan root file system: $ trivy rootfs --server http://localhost:8080 --severity CRITICAL /tmp/rootfs Note : It's important to specify the protocol (http or https). Result /tmp/rootfs (alpine 3.10.2) Total: 1 (CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 apk-tools \u2502 CVE-2021-36159 \u2502 CRITICAL \u2502 2.10.4-r2 \u2502 2.10.7-r0 \u2502 libfetch before 2021-07-26, as used in apk-tools, xbps, and \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 other products, mishandles... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-36159 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Remote scan of git repository Also, there is a way to scan remote git repository: $ trivy repo https://github.com/knqyf263/trivy-ci-test --server http://localhost:8080 Note : It's important to specify the protocol (http or https). Result Cargo.lock (cargo) ================== Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 0) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 ammonia \u2502 CVE-2019-15542 \u2502 HIGH \u2502 1.9.0 \u2502 2.1.0 \u2502 Uncontrolled recursion in ammonia \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-15542 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-38193 \u2502 MEDIUM \u2502 \u2502 2.1.3, 3.1.0 \u2502 An issue was discovered in the ammonia crate before 3.1.0 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for Rust.... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-38193 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 smallvec \u2502 CVE-2019-15551 \u2502 \u2502 0.6.9 \u2502 0.6.10 \u2502 An issue was discovered in the smallvec crate before 0.6.10 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for Rust.... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-15551 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2018-25023 \u2502 HIGH \u2502 \u2502 0.6.13 \u2502 An issue was discovered in the smallvec crate before 0.6.13 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for Rust.... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2018-25023 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 GHSA-66p5-j55p-32r9 \u2502 MEDIUM \u2502 \u2502 \u2502 smallvec creates uninitialized value of any type \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://github.com/advisories/GHSA-66p5-j55p-32r9 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Pipfile.lock (pipenv) ===================== Total: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 celery \u2502 CVE-2021-23727 \u2502 HIGH \u2502 4.3.0 \u2502 5.2.2 \u2502 celery: stored command injection vulnerability may allow \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 privileges escalation \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-23727 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 django \u2502 CVE-2019-6975 \u2502 \u2502 2.0.9 \u2502 1.11.19, 2.0.12, 2.1.7 \u2502 python-django: memory exhaustion in \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 django.utils.numberformat.format() \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-6975 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2019-3498 \u2502 MEDIUM \u2502 \u2502 1.11.18, 2.0.10, 2.1.5 \u2502 python-django: Content spoofing via URL path in default 404 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 page \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-3498 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-33203 \u2502 \u2502 \u2502 2.2.24, 3.1.12, 3.2.4 \u2502 django: Potential directory traversal via ``admindocs`` \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-33203 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 urllib3 \u2502 CVE-2019-11324 \u2502 \u2502 1.24.1 \u2502 1.24.2 \u2502 python-urllib3: Certification mishandle when error should be \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 thrown \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-11324 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-33503 \u2502 \u2502 \u2502 1.26.5 \u2502 python-urllib3: ReDoS in the parsing of authority part of \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 URL \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-33503 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2019-11236 \u2502 MEDIUM \u2502 \u2502 1.24.3 \u2502 python-urllib3: CRLF injection due to not encoding the \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 '\\r\\n' sequence leading to... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-11236 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2020-26137 \u2502 \u2502 \u2502 1.25.9 \u2502 python-urllib3: CRLF injection via HTTP request method \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2020-26137 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Authentication $ trivy server --listen localhost:8080 --token dummy $ trivy image --server http://localhost:8080 --token dummy alpine:3.10 Architecture","title":"Client/Server"},{"location":"docs/references/modes/client-server/#clientserver","text":"Trivy has client/server mode. Trivy server has vulnerability database and Trivy client doesn't have to download vulnerability database. It is useful if you want to scan images or files at multiple locations and do not want to download the database at every location.","title":"Client/Server"},{"location":"docs/references/modes/client-server/#server","text":"At first, you need to launch Trivy server. It downloads vulnerability database automatically and continue to fetch the latest DB in the background. $ trivy server --listen localhost:8080 2019-12-12T15:17:06.551+0200 INFO Need to update DB 2019-12-12T15:17:56.706+0200 INFO Reopening DB... 2019-12-12T15:17:56.707+0200 INFO Listening localhost:8080... If you want to accept a connection from outside, you have to specify 0.0.0.0 or your ip address, not localhost . $ trivy server --listen 0.0.0.0:8080","title":"Server"},{"location":"docs/references/modes/client-server/#remote-image-scan","text":"Then, specify the server address for image command. $ trivy image --server http://localhost:8080 alpine:3.10 Note : It's important to specify the protocol (http or https). Result alpine:3.10 (alpine 3.10.2) =========================== Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 2, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | +---------+------------------+----------+-------------------+---------------+ | openssl | CVE-2019-1549 | MEDIUM | 1.1.1c-r0 | 1.1.1d-r0 | + +------------------+ + + + | | CVE-2019-1563 | | | | + +------------------+----------+ + + | | CVE-2019-1547 | LOW | | | +---------+------------------+----------+-------------------+---------------+","title":"Remote image scan"},{"location":"docs/references/modes/client-server/#remote-scan-of-local-filesystem","text":"Also, there is a way to scan local file system: $ trivy fs --server http://localhost:8080 --severity CRITICAL ./integration/testdata/fixtures/fs/pom/ Note : It's important to specify the protocol (http or https). Result pom.xml (pom) ============= Total: 24 (CRITICAL: 24) +---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+ | com.fasterxml.jackson.core:jackson-databind | CVE-2017-17485 | CRITICAL | 2.9.1 | 2.8.11, 2.9.4 | jackson-databind: Unsafe | | | | | | | deserialization due to | | | | | | | incomplete black list (incomplete | | | | | | | fix for CVE-2017-15095)... | | | | | | | -->avd.aquasec.com/nvd/cve-2017-17485 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-11307 | | | 2.7.9.4, 2.8.11.2, 2.9.6 | jackson-databind: Potential | | | | | | | information exfiltration with | | | | | | | default typing, serialization | | | | | | | gadget from MyBatis | | | | | | | -->avd.aquasec.com/nvd/cve-2018-11307 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-14718 | | | 2.6.7.2, 2.9.7 | jackson-databind: arbitrary code | | | | | | | execution in slf4j-ext class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14718 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-14719 | | | | jackson-databind: arbitrary | | | | | | | code execution in blaze-ds-opt | | | | | | | and blaze-ds-core classes | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14719 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-14720 | | | | jackson-databind: exfiltration/XXE | | | | | | | in some JDK classes | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14720 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-14721 | | | | jackson-databind: server-side request | | | | | | | forgery (SSRF) in axis2-jaxws class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-14721 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-19360 | | | 2.6.7.3, 2.7.9.5, 2.8.11.3, | jackson-databind: improper | | | | | | 2.9.8 | polymorphic deserialization | | | | | | | in axis2-transport-jms class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-19360 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-19361 | | | | jackson-databind: improper | | | | | | | polymorphic deserialization | | | | | | | in openjpa class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-19361 | + +------------------+ + + +---------------------------------------+ | | CVE-2018-19362 | | | | jackson-databind: improper | | | | | | | polymorphic deserialization | | | | | | | in jboss-common-core class | | | | | | | -->avd.aquasec.com/nvd/cve-2018-19362 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2018-7489 | | | 2.7.9.3, 2.8.11.1, 2.9.5 | jackson-databind: incomplete fix | | | | | | | for CVE-2017-7525 permits unsafe | | | | | | | serialization via c3p0 libraries | | | | | | | -->avd.aquasec.com/nvd/cve-2018-7489 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14379 | | | 2.7.9.6, 2.8.11.4, 2.9.9.2 | jackson-databind: default | | | | | | | typing mishandling leading | | | | | | | to remote code execution | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14379 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14540 | | | 2.9.10 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | com.zaxxer.hikari.HikariConfig | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14540 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14892 | | | 2.6.7.3, 2.8.11.5, 2.9.10 | jackson-databind: Serialization | | | | | | | gadgets in classes of the | | | | | | | commons-configuration package | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14892 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-14893 | | | 2.8.11.5, 2.9.10 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | classes of the xalan package | | | | | | | -->avd.aquasec.com/nvd/cve-2019-14893 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-16335 | | | 2.9.10 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | com.zaxxer.hikari.HikariDataSource | | | | | | | -->avd.aquasec.com/nvd/cve-2019-16335 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-16942 | | | 2.9.10.1 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | org.apache.commons.dbcp.datasources.* | | | | | | | -->avd.aquasec.com/nvd/cve-2019-16942 | + +------------------+ + + +---------------------------------------+ | | CVE-2019-16943 | | | | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | com.p6spy.engine.spy.P6DataSource | | | | | | | -->avd.aquasec.com/nvd/cve-2019-16943 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-17267 | | | 2.9.10 | jackson-databind: Serialization | | | | | | | gadgets in classes of | | | | | | | the ehcache package | | | | | | | -->avd.aquasec.com/nvd/cve-2019-17267 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-17531 | | | 2.9.10.1 | jackson-databind: | | | | | | | Serialization gadgets in | | | | | | | org.apache.log4j.receivers.db.* | | | | | | | -->avd.aquasec.com/nvd/cve-2019-17531 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2019-20330 | | | 2.8.11.5, 2.9.10.2 | jackson-databind: lacks | | | | | | | certain net.sf.ehcache blocking | | | | | | | -->avd.aquasec.com/nvd/cve-2019-20330 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2020-8840 | | | 2.7.9.7, 2.8.11.5, 2.9.10.3 | jackson-databind: Lacks certain | | | | | | | xbean-reflect/JNDI blocking | | | | | | | -->avd.aquasec.com/nvd/cve-2020-8840 | + +------------------+ + +--------------------------------+---------------------------------------+ | | CVE-2020-9546 | | | 2.7.9.7, 2.8.11.6, 2.9.10.4 | jackson-databind: Serialization | | | | | | | gadgets in shaded-hikari-config | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9546 | + +------------------+ + + +---------------------------------------+ | | CVE-2020-9547 | | | | jackson-databind: Serialization | | | | | | | gadgets in ibatis-sqlmap | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9547 | + +------------------+ + + +---------------------------------------+ | | CVE-2020-9548 | | | | jackson-databind: Serialization | | | | | | | gadgets in anteros-core | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9548 | +---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+","title":"Remote scan of local filesystem"},{"location":"docs/references/modes/client-server/#remote-scan-of-root-filesystem","text":"Also, there is a way to scan root file system: $ trivy rootfs --server http://localhost:8080 --severity CRITICAL /tmp/rootfs Note : It's important to specify the protocol (http or https). Result /tmp/rootfs (alpine 3.10.2) Total: 1 (CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 apk-tools \u2502 CVE-2021-36159 \u2502 CRITICAL \u2502 2.10.4-r2 \u2502 2.10.7-r0 \u2502 libfetch before 2021-07-26, as used in apk-tools, xbps, and \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 other products, mishandles... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-36159 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Remote scan of root filesystem"},{"location":"docs/references/modes/client-server/#remote-scan-of-git-repository","text":"Also, there is a way to scan remote git repository: $ trivy repo https://github.com/knqyf263/trivy-ci-test --server http://localhost:8080 Note : It's important to specify the protocol (http or https). Result Cargo.lock (cargo) ================== Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 0) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 ammonia \u2502 CVE-2019-15542 \u2502 HIGH \u2502 1.9.0 \u2502 2.1.0 \u2502 Uncontrolled recursion in ammonia \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-15542 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-38193 \u2502 MEDIUM \u2502 \u2502 2.1.3, 3.1.0 \u2502 An issue was discovered in the ammonia crate before 3.1.0 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for Rust.... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-38193 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 smallvec \u2502 CVE-2019-15551 \u2502 \u2502 0.6.9 \u2502 0.6.10 \u2502 An issue was discovered in the smallvec crate before 0.6.10 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for Rust.... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-15551 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2018-25023 \u2502 HIGH \u2502 \u2502 0.6.13 \u2502 An issue was discovered in the smallvec crate before 0.6.13 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for Rust.... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2018-25023 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 GHSA-66p5-j55p-32r9 \u2502 MEDIUM \u2502 \u2502 \u2502 smallvec creates uninitialized value of any type \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://github.com/advisories/GHSA-66p5-j55p-32r9 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Pipfile.lock (pipenv) ===================== Total: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 celery \u2502 CVE-2021-23727 \u2502 HIGH \u2502 4.3.0 \u2502 5.2.2 \u2502 celery: stored command injection vulnerability may allow \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 privileges escalation \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-23727 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 django \u2502 CVE-2019-6975 \u2502 \u2502 2.0.9 \u2502 1.11.19, 2.0.12, 2.1.7 \u2502 python-django: memory exhaustion in \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 django.utils.numberformat.format() \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-6975 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2019-3498 \u2502 MEDIUM \u2502 \u2502 1.11.18, 2.0.10, 2.1.5 \u2502 python-django: Content spoofing via URL path in default 404 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 page \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-3498 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-33203 \u2502 \u2502 \u2502 2.2.24, 3.1.12, 3.2.4 \u2502 django: Potential directory traversal via ``admindocs`` \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-33203 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 urllib3 \u2502 CVE-2019-11324 \u2502 \u2502 1.24.1 \u2502 1.24.2 \u2502 python-urllib3: Certification mishandle when error should be \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 thrown \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-11324 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-33503 \u2502 \u2502 \u2502 1.26.5 \u2502 python-urllib3: ReDoS in the parsing of authority part of \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 URL \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-33503 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2019-11236 \u2502 MEDIUM \u2502 \u2502 1.24.3 \u2502 python-urllib3: CRLF injection due to not encoding the \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 '\\r\\n' sequence leading to... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-11236 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2020-26137 \u2502 \u2502 \u2502 1.25.9 \u2502 python-urllib3: CRLF injection via HTTP request method \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2020-26137 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Remote scan of git repository"},{"location":"docs/references/modes/client-server/#authentication","text":"$ trivy server --listen localhost:8080 --token dummy $ trivy image --server http://localhost:8080 --token dummy alpine:3.10","title":"Authentication"},{"location":"docs/references/modes/client-server/#architecture","text":"","title":"Architecture"},{"location":"docs/references/modes/standalone/","text":"Standalone trivy image , trivy filesystem , and trivy repo works as standalone mode. Image Filesystem Git Repository","title":"Standalone"},{"location":"docs/references/modes/standalone/#standalone","text":"trivy image , trivy filesystem , and trivy repo works as standalone mode.","title":"Standalone"},{"location":"docs/references/modes/standalone/#image","text":"","title":"Image"},{"location":"docs/references/modes/standalone/#filesystem","text":"","title":"Filesystem"},{"location":"docs/references/modes/standalone/#git-repository","text":"","title":"Git Repository"},{"location":"docs/scanner/license/","text":"License Scanning Trivy scans any container image for license files and offers an opinionated view on the risk associated with the license. License are classified using the Google License Classification - Forbidden Restricted Reciprocal Notice Permissive Unencumbered Unknown Tip Licenses that Trivy fails to recognize are classified as UNKNOWN. As those licenses may be in violation, it is recommended to check those unknown licenses as well. By default, Trivy scans licenses for packages installed by apk , apt-get , dnf , npm , pip , gem , etc. To enable extended license scanning, you can use --license-full . In addition to package licenses, Trivy scans source code files, Markdown documents, text files and LICENSE documents to identify license usage within the image or filesystem. By default, Trivy only classifies licenses that are matched with a confidence level of 0.9 or more by the classifer. To configure the confidence level, you can use --license-confidence-level . This enables us to classify licenses that might be matched with a lower confidence level by the classifer. Note The full license scanning is expensive. It takes a while. Currently, the standard license scanning doesn't support filesystem and repository scanning. License scanning Image Rootfs Filesystem Repository Standard \u2705 \u2705 - - Full (--license-full) \u2705 \u2705 \u2705 \u2705 License checking classifies the identified licenses and map the classification to severity. Classification Severity Forbidden CRITICAL Restricted HIGH Reciprocal MEDIUM Notice LOW Permissive LOW Unencumbered LOW Unknown UNKNOWN Quick start This section shows how to scan license in container image and filesystem. Standard scanning Specify an image name with --scanners license . $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15 2022 -07-13T17:28:39.526+0300 INFO License scanning is enabled OS Packages ( license ) ===================== Total: 6 ( UNKNOWN: 0 , HIGH: 6 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Package \u2502 License \u2502 Classification \u2502 Severity \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 apk-tools \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 busybox \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 scanelf \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 ssl_client \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Full scanning Specify --license-full $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana 2022 -07-13T17:48:40.905+0300 INFO Full license scanning is enabled OS Packages ( license ) ===================== Total: 20 ( UNKNOWN: 9 , HIGH: 11 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Package \u2502 License \u2502 Classification \u2502 Severity \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 apk-tools \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 bash \u2502 GPL-3.0 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 keyutils-libs \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 LGPL-2.0-or-later \u2502 Non Standard \u2502 UNKNOWN \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 libaio \u2502 LGPL-2.1-or-later \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 libcom_err \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 LGPL-2.0-or-later \u2502 Non Standard \u2502 UNKNOWN \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 tzdata \u2502 Public-Domain \u2502 Non Standard \u2502 UNKNOWN \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Loose File License ( s ) ( license ) =============================== Total: 6 ( UNKNOWN: 4 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Classification \u2502 Severity \u2502 License \u2502 File Location \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 Forbidden \u2502 CRITICAL \u2502 AGPL-3.0 \u2502 /usr/share/grafana/LICENSE \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 Non Standard \u2502 UNKNOWN \u2502 BSD-0-Clause \u2502 /usr/share/grafana/public/build/5069.d6aae9dd11d49c741a80.j- \u2502 \u2502 \u2502 \u2502 \u2502 s.LICENSE.txt \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 /usr/share/grafana/public/build/6444.d6aae9dd11d49c741a80.j- \u2502 \u2502 \u2502 \u2502 \u2502 s.LICENSE.txt \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 /usr/share/grafana/public/build/7889.d6aae9dd11d49c741a80.j- \u2502 \u2502 \u2502 \u2502 \u2502 s.LICENSE.txt \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 /usr/share/grafana/public/build/canvasPanel.d6aae9dd11d49c7- \u2502 \u2502 \u2502 \u2502 \u2502 41a80.js.LICENSE.txt \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Configuration Trivy has number of configuration flags for use with license scanning; Ignored Licenses Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the --ignored-licenses flag; $ trivy image --scanners license --ignored-licenses MPL-2.0,MIT --severity LOW grafana/grafana:latest 2022 -07-13T18:15:28.605Z INFO License scanning is enabled OS Packages ( license ) ===================== Total: 2 ( HIGH: 2 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Package \u2502 License \u2502 Classification \u2502 Severity \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 ssl_client \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Configuring Classifier Confidence Level You can use the --license-confidence-level flag to adjust the confidence level between 0.0 to 1.0 (default 0.9). For example, when you run the scanner with the default confidence level on SPDX license list data , it is able to detect only 258 licenses. $ trivy fs --scanners license --license-full 2023 -04-18T10:05:13.601-0700 INFO Full license scanning is enabled Loose File License ( s ) ( license ) =============================== Total: 258 ( UNKNOWN: 70 , LOW: 90 , MEDIUM: 18 , HIGH: 58 , CRITICAL: 22 ) However, by configuring the confidence level to 0.8, the scanner is now able to detect 282 licenses. $ trivy fs --scanners license --license-full --license-confidence-level 0 .8 2023 -04-18T10:21:39.637-0700 INFO Full license scanning is enabled Loose File License ( s ) ( license ) =============================== Total: 282 ( UNKNOWN: 81 , LOW: 97 , MEDIUM: 24 , HIGH: 58 , CRITICAL: 22 ) Custom Classification You can generate the default config by the --generate-default-config flag and customize the license classification. For example, if you want to forbid only AGPL-3.0, you can leave it under forbidden and move other licenses to another classification. $ trivy image --generate-default-config $ vim trivy.yaml license: forbidden: - AGPL-3.0 restricted: - AGPL-1.0 - CC-BY-NC-1.0 - CC-BY-NC-2.0 - CC-BY-NC-2.5 - CC-BY-NC-3.0 - CC-BY-NC-4.0 - CC-BY-NC-ND-1.0 - CC-BY-NC-ND-2.0 - CC-BY-NC-ND-2.5 - CC-BY-NC-ND-3.0 - CC-BY-NC-ND-4.0 - CC-BY-NC-SA-1.0 - CC-BY-NC-SA-2.0 - CC-BY-NC-SA-2.5 - CC-BY-NC-SA-3.0 - CC-BY-NC-SA-4.0 - Commons-Clause - Facebook-2-Clause - Facebook-3-Clause - Facebook-Examples - WTFPL - BCL - CC-BY-ND-1.0 - CC-BY-ND-2.0 - CC-BY-ND-2.5 - CC-BY-ND-3.0 - CC-BY-ND-4.0 - CC-BY-SA-1.0 - CC-BY-SA-2.0 - CC-BY-SA-2.5 - CC-BY-SA-3.0 - CC-BY-SA-4.0 - GPL-1.0 - GPL-2.0 - GPL-2.0-with-autoconf-exception - GPL-2.0-with-bison-exception - GPL-2.0-with-classpath-exception - GPL-2.0-with-font-exception - GPL-2.0-with-GCC-exception - GPL-3.0 - GPL-3.0-with-autoconf-exception - GPL-3.0-with-GCC-exception - LGPL-2.0 - LGPL-2.1 - LGPL-3.0 - NPL-1.0 - NPL-1.1 - OSL-1.0 - OSL-1.1 - OSL-2.0 - OSL-2.1 - OSL-3.0 - QPL-1.0 - Sleepycat reciprocal: - APSL-1.0 - APSL-1.1 - APSL-1.2 - APSL-2.0 - CDDL-1.0 - CDDL-1.1 - CPL-1.0 - EPL-1.0 - EPL-2.0 - FreeImage - IPL-1.0 - MPL-1.0 - MPL-1.1 - MPL-2.0 - Ruby notice: - AFL-1.1 - AFL-1.2 - AFL-2.0 - AFL-2.1 - AFL-3.0 - Apache-1.0 - Apache-1.1 - Apache-2.0 - Artistic-1.0-cl8 - Artistic-1.0-Perl - Artistic-1.0 - Artistic-2.0 - BSL-1.0 - BSD-2-Clause-FreeBSD - BSD-2-Clause-NetBSD - BSD-2-Clause - BSD-3-Clause-Attribution - BSD-3-Clause-Clear - BSD-3-Clause-LBNL - BSD-3-Clause - BSD-4-Clause - BSD-4-Clause-UC - BSD-Protection - CC-BY-1.0 - CC-BY-2.0 - CC-BY-2.5 - CC-BY-3.0 - CC-BY-4.0 - FTL - ISC - ImageMagick - Libpng - Lil-1.0 - Linux-OpenIB - LPL-1.02 - LPL-1.0 - MS-PL - MIT - NCSA - OpenSSL - PHP-3.01 - PHP-3.0 - PIL - Python-2.0 - Python-2.0-complete - PostgreSQL - SGI-B-1.0 - SGI-B-1.1 - SGI-B-2.0 - Unicode-DFS-2015 - Unicode-DFS-2016 - Unicode-TOU - UPL-1.0 - W3C-19980720 - W3C-20150513 - W3C - X11 - Xnet - Zend-2.0 - zlib-acknowledgement - Zlib - ZPL-1.1 - ZPL-2.0 - ZPL-2.1 unencumbered: - CC0-1.0 - Unlicense - 0BSD permissive: []","title":"License"},{"location":"docs/scanner/license/#license-scanning","text":"Trivy scans any container image for license files and offers an opinionated view on the risk associated with the license. License are classified using the Google License Classification - Forbidden Restricted Reciprocal Notice Permissive Unencumbered Unknown Tip Licenses that Trivy fails to recognize are classified as UNKNOWN. As those licenses may be in violation, it is recommended to check those unknown licenses as well. By default, Trivy scans licenses for packages installed by apk , apt-get , dnf , npm , pip , gem , etc. To enable extended license scanning, you can use --license-full . In addition to package licenses, Trivy scans source code files, Markdown documents, text files and LICENSE documents to identify license usage within the image or filesystem. By default, Trivy only classifies licenses that are matched with a confidence level of 0.9 or more by the classifer. To configure the confidence level, you can use --license-confidence-level . This enables us to classify licenses that might be matched with a lower confidence level by the classifer. Note The full license scanning is expensive. It takes a while. Currently, the standard license scanning doesn't support filesystem and repository scanning. License scanning Image Rootfs Filesystem Repository Standard \u2705 \u2705 - - Full (--license-full) \u2705 \u2705 \u2705 \u2705 License checking classifies the identified licenses and map the classification to severity. Classification Severity Forbidden CRITICAL Restricted HIGH Reciprocal MEDIUM Notice LOW Permissive LOW Unencumbered LOW Unknown UNKNOWN","title":"License Scanning"},{"location":"docs/scanner/license/#quick-start","text":"This section shows how to scan license in container image and filesystem.","title":"Quick start"},{"location":"docs/scanner/license/#standard-scanning","text":"Specify an image name with --scanners license . $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15 2022 -07-13T17:28:39.526+0300 INFO License scanning is enabled OS Packages ( license ) ===================== Total: 6 ( UNKNOWN: 0 , HIGH: 6 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Package \u2502 License \u2502 Classification \u2502 Severity \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 apk-tools \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 busybox \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 scanelf \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 ssl_client \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Standard scanning"},{"location":"docs/scanner/license/#full-scanning","text":"Specify --license-full $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana 2022 -07-13T17:48:40.905+0300 INFO Full license scanning is enabled OS Packages ( license ) ===================== Total: 20 ( UNKNOWN: 9 , HIGH: 11 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Package \u2502 License \u2502 Classification \u2502 Severity \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 apk-tools \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 bash \u2502 GPL-3.0 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 keyutils-libs \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 LGPL-2.0-or-later \u2502 Non Standard \u2502 UNKNOWN \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 libaio \u2502 LGPL-2.1-or-later \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 libcom_err \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 LGPL-2.0-or-later \u2502 Non Standard \u2502 UNKNOWN \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 tzdata \u2502 Public-Domain \u2502 Non Standard \u2502 UNKNOWN \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Loose File License ( s ) ( license ) =============================== Total: 6 ( UNKNOWN: 4 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Classification \u2502 Severity \u2502 License \u2502 File Location \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 Forbidden \u2502 CRITICAL \u2502 AGPL-3.0 \u2502 /usr/share/grafana/LICENSE \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 Non Standard \u2502 UNKNOWN \u2502 BSD-0-Clause \u2502 /usr/share/grafana/public/build/5069.d6aae9dd11d49c741a80.j- \u2502 \u2502 \u2502 \u2502 \u2502 s.LICENSE.txt \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 /usr/share/grafana/public/build/6444.d6aae9dd11d49c741a80.j- \u2502 \u2502 \u2502 \u2502 \u2502 s.LICENSE.txt \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 /usr/share/grafana/public/build/7889.d6aae9dd11d49c741a80.j- \u2502 \u2502 \u2502 \u2502 \u2502 s.LICENSE.txt \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 /usr/share/grafana/public/build/canvasPanel.d6aae9dd11d49c7- \u2502 \u2502 \u2502 \u2502 \u2502 41a80.js.LICENSE.txt \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Full scanning"},{"location":"docs/scanner/license/#configuration","text":"Trivy has number of configuration flags for use with license scanning;","title":"Configuration"},{"location":"docs/scanner/license/#ignored-licenses","text":"Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the --ignored-licenses flag; $ trivy image --scanners license --ignored-licenses MPL-2.0,MIT --severity LOW grafana/grafana:latest 2022 -07-13T18:15:28.605Z INFO License scanning is enabled OS Packages ( license ) ===================== Total: 2 ( HIGH: 2 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Package \u2502 License \u2502 Classification \u2502 Severity \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted \u2502 HIGH \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 ssl_client \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Ignored Licenses"},{"location":"docs/scanner/license/#configuring-classifier-confidence-level","text":"You can use the --license-confidence-level flag to adjust the confidence level between 0.0 to 1.0 (default 0.9). For example, when you run the scanner with the default confidence level on SPDX license list data , it is able to detect only 258 licenses. $ trivy fs --scanners license --license-full 2023 -04-18T10:05:13.601-0700 INFO Full license scanning is enabled Loose File License ( s ) ( license ) =============================== Total: 258 ( UNKNOWN: 70 , LOW: 90 , MEDIUM: 18 , HIGH: 58 , CRITICAL: 22 ) However, by configuring the confidence level to 0.8, the scanner is now able to detect 282 licenses. $ trivy fs --scanners license --license-full --license-confidence-level 0 .8 2023 -04-18T10:21:39.637-0700 INFO Full license scanning is enabled Loose File License ( s ) ( license ) =============================== Total: 282 ( UNKNOWN: 81 , LOW: 97 , MEDIUM: 24 , HIGH: 58 , CRITICAL: 22 )","title":"Configuring Classifier Confidence Level"},{"location":"docs/scanner/license/#custom-classification","text":"You can generate the default config by the --generate-default-config flag and customize the license classification. For example, if you want to forbid only AGPL-3.0, you can leave it under forbidden and move other licenses to another classification. $ trivy image --generate-default-config $ vim trivy.yaml license: forbidden: - AGPL-3.0 restricted: - AGPL-1.0 - CC-BY-NC-1.0 - CC-BY-NC-2.0 - CC-BY-NC-2.5 - CC-BY-NC-3.0 - CC-BY-NC-4.0 - CC-BY-NC-ND-1.0 - CC-BY-NC-ND-2.0 - CC-BY-NC-ND-2.5 - CC-BY-NC-ND-3.0 - CC-BY-NC-ND-4.0 - CC-BY-NC-SA-1.0 - CC-BY-NC-SA-2.0 - CC-BY-NC-SA-2.5 - CC-BY-NC-SA-3.0 - CC-BY-NC-SA-4.0 - Commons-Clause - Facebook-2-Clause - Facebook-3-Clause - Facebook-Examples - WTFPL - BCL - CC-BY-ND-1.0 - CC-BY-ND-2.0 - CC-BY-ND-2.5 - CC-BY-ND-3.0 - CC-BY-ND-4.0 - CC-BY-SA-1.0 - CC-BY-SA-2.0 - CC-BY-SA-2.5 - CC-BY-SA-3.0 - CC-BY-SA-4.0 - GPL-1.0 - GPL-2.0 - GPL-2.0-with-autoconf-exception - GPL-2.0-with-bison-exception - GPL-2.0-with-classpath-exception - GPL-2.0-with-font-exception - GPL-2.0-with-GCC-exception - GPL-3.0 - GPL-3.0-with-autoconf-exception - GPL-3.0-with-GCC-exception - LGPL-2.0 - LGPL-2.1 - LGPL-3.0 - NPL-1.0 - NPL-1.1 - OSL-1.0 - OSL-1.1 - OSL-2.0 - OSL-2.1 - OSL-3.0 - QPL-1.0 - Sleepycat reciprocal: - APSL-1.0 - APSL-1.1 - APSL-1.2 - APSL-2.0 - CDDL-1.0 - CDDL-1.1 - CPL-1.0 - EPL-1.0 - EPL-2.0 - FreeImage - IPL-1.0 - MPL-1.0 - MPL-1.1 - MPL-2.0 - Ruby notice: - AFL-1.1 - AFL-1.2 - AFL-2.0 - AFL-2.1 - AFL-3.0 - Apache-1.0 - Apache-1.1 - Apache-2.0 - Artistic-1.0-cl8 - Artistic-1.0-Perl - Artistic-1.0 - Artistic-2.0 - BSL-1.0 - BSD-2-Clause-FreeBSD - BSD-2-Clause-NetBSD - BSD-2-Clause - BSD-3-Clause-Attribution - BSD-3-Clause-Clear - BSD-3-Clause-LBNL - BSD-3-Clause - BSD-4-Clause - BSD-4-Clause-UC - BSD-Protection - CC-BY-1.0 - CC-BY-2.0 - CC-BY-2.5 - CC-BY-3.0 - CC-BY-4.0 - FTL - ISC - ImageMagick - Libpng - Lil-1.0 - Linux-OpenIB - LPL-1.02 - LPL-1.0 - MS-PL - MIT - NCSA - OpenSSL - PHP-3.01 - PHP-3.0 - PIL - Python-2.0 - Python-2.0-complete - PostgreSQL - SGI-B-1.0 - SGI-B-1.1 - SGI-B-2.0 - Unicode-DFS-2015 - Unicode-DFS-2016 - Unicode-TOU - UPL-1.0 - W3C-19980720 - W3C-20150513 - W3C - X11 - Xnet - Zend-2.0 - zlib-acknowledgement - Zlib - ZPL-1.1 - ZPL-2.0 - ZPL-2.1 unencumbered: - CC0-1.0 - Unlicense - 0BSD permissive: []","title":"Custom Classification"},{"location":"docs/scanner/secret/","text":"Secret Scanning Trivy scans any container image, filesystem and git repository to detect exposed secrets like passwords, api keys, and tokens. Secret scanning is enabled by default. Trivy will scan every plaintext file, according to builtin rules or configuration. There are plenty of builtin rules: AWS access key GCP service account GitHub personal access token GitLab personal access token Slack access token etc. You can see a full list of built-in rules and built-in allow rules . Tip If your secret is not detected properly, please make sure that your file including the secret is not in the allowed paths . You can disable allow rules via disable-allow-rules . Quick start This section shows how to scan secrets in container image and filesystem. Other subcommands should be the same. Container image Specify an image name. $ trivy image myimage:1.0.0 2022 -04-21T18:56:44.099+0300 INFO Detected OS: alpine 2022 -04-21T18:56:44.099+0300 INFO Detecting Alpine vulnerabilities... 2022 -04-21T18:56:44.101+0300 INFO Number of language-specific files: 0 myimage:1.0.0 ( alpine 3 .15.0 ) ============================= Total: 6 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | busybox | CVE-2022-28391 | CRITICAL | 1 .34.1-r3 | 1 .34.1-r5 | CVE-2022-28391 affecting | | | | | | | package busybox 1 .35.0 | | | | | | | -->avd.aquasec.com/nvd/cve-2022-28391 | +--------------+------------------ | | -------------------+---------------+---------------------------------------+ | ssl_client | CVE-2022-28391 | | 1 .34.1-r3 | 1 .34.1-r5 | CVE-2022-28391 affecting | | | | | | | package busybox 1 .35.0 | | | | | | | -->avd.aquasec.com/nvd/cve-2022-28391 | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ app/secret.sh ( secrets ) ======================= Total: 1 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 1 ) +----------+-------------------+----------+---------+--------------------------------+ | CATEGORY | DESCRIPTION | SEVERITY | LINE NO | MATCH | +----------+-------------------+----------+---------+--------------------------------+ | AWS | AWS Access Key ID | CRITICAL | 10 | export AWS_ACCESS_KEY_ID = ***** | +----------+-------------------+----------+---------+--------------------------------+ Tip Trivy tries to detect a base image and skip those layers for secret scanning. A base image usually contains a lot of files and makes secret scanning much slower. If a secret is not detected properly, you can see base layers with the --debug flag. Filesystem $ trivy fs /path/to/your_project ... ( snip ) ... certs/key.pem ( secrets ) ======================== Total: 1 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 1 , CRITICAL: 0 ) +----------------------+------------------------+----------+---------+---------------------------------+ | CATEGORY | DESCRIPTION | SEVERITY | LINE NO | MATCH | +----------------------+------------------------+----------+---------+---------------------------------+ | AsymmetricPrivateKey | Asymmetric Private Key | HIGH | 1 | -----BEGIN RSA PRIVATE KEY----- | +----------------------+------------------------+----------+---------+---------------------------------+ Tip Your project may have some secrets for testing. You can skip them with --skip-dirs or --skip-files . We would recommend specifying these options so that the secret scanning can be faster if those files don't need to be scanned. Also, you can specify paths to be allowed in a configuration file. See the detail here . Configuration This section describes secret-specific configuration. Other common options are documented here . Trivy has a set of builtin rules for secret scanning, which can be extended or modified by a configuration file. Trivy tries to load trivy-secret.yaml in the current directory by default. If the file doesn't exist, only built-in rules are used. You can customize the config file path via the --secret-config flag. Custom Rules Trivy allows defining custom rules. rules : - id : rule1 category : general title : Generic Rule severity : HIGH path : .*\\.sh keywords : - secret regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] secret-group-name : secret allow-rules : - id : skip-text description : skip text files path : .*\\.txt id (required) Unique identifier for this rule. category (required) String used for metadata and reporting purposes. title (required) Short human-readable title of the rule. severity (required) How critical this rule is. Allowed values: CRITICAL HIGH MEDIUM LOW regex (required) Golang regular expression used to detect secrets. path (optional) Golang regular expression used to match paths. keywords (optional, recommended) Keywords are used for pre-regex check filtering. Rules that contain keywords will perform a quick string compare check to make sure the keyword(s) are in the content being scanned. Ideally these values should either be part of the identifier or unique strings specific to the rule's regex. It is recommended to define for better performance. allow-rules (optional) Allow rules for a single rule to reduce false positives with known secrets. The details are below. Allow Rules If the detected secret is matched with the specified regex , then that secret will be skipped and not detected. The same logic applies for path . allow-rules can be defined globally and per each rule. The fields are the same. rules : - id : rule1 category : general title : Generic Rule severity : HIGH regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] allow-rules : - id : skip-text description : skip text files path : .*\\.txt allow-rules : - id : social-security-number description : skip social security number regex : 219-09-9999 id (required) Unique identifier for this allow rule. description (optional) Short human-readable description of this allow rule. regex (optional) Golang regular expression used to allow detected secrets. regex or path must be specified. path (optional) Golang regular expression used to allow matched paths. regex or path must be specified. Enable Rules Trivy provides plenty of out-of-box rules and allow rules, but you may not need all of them. In that case, enable-builtin-rules will be helpful. If you just need AWS secret detection, you can enable only relevant rules as shown below. It specifies AWS-related rule IDs in enable-builtin-rules . All other rules are disabled, so the scanning will be much faster. We would strongly recommend using this option if you don't need all rules. You can see a full list of built-in rule IDs and built-in allow rule IDs . enable-builtin-rules : - aws-access-key-id - aws-account-id - aws-secret-access-key Disable Rules Trivy offers built-in rules and allow rules, but you may want to disable some of them. For example, you don't use Slack, so Slack doesn't have to be scanned. You can specify the Slack rule IDs, slack-access-token and slack-web-hook in disable-rules so that those rules will be disabled for less false positives. You should specify either enable-builtin-rules or disable-rules . If they both are specified, disable-rules takes precedence. In case github-pat is specified in enable-builtin-rules and disable-rules , it will be disabled. In addition, there are some allow rules. Markdown files are ignored by default, but you may want to scan markdown files as well. You can disable the allow rule by adding markdown to disable-allow-rules . You can see a full list of built-in rule IDs and built-in allow rule IDs . disable-rules : - slack-access-token - slack-web-hook disable-allow-rules : - markdown Recommendation We would recommend specifying --skip-dirs for faster secret scanning. In container image scanning, Trivy walks the file tree rooted / and scans all the files other than built-in allowed paths . It will take a while if your image contains a lot of files even though Trivy tries to avoid scanning layers from a base image. If you want to make scanning faster, --skip-dirs and --skip-files helps so that Trivy will skip scanning those files and directories. You can see more options here . allow-rules is also helpful. See the allow-rules section. In addition, all the built-in rules are enabled by default, so it takes some time to scan all of them. If you don't need all those rules, you can use enable-builtin-rules or disable-rules in the configuration file. You should use enable-builtin-rules if you need only AWS secret detection, for example. All rules are disabled except for the ones you specify, so it runs very fast. On the other hand, you should use disable-rules if you just want to disable some built-in rules. See the enable-rules and disable-rules sections for the detail. If you don't need secret scanning, you can disable it via the --scanners flag. $ trivy image --scanners vuln alpine:3.15 Example trivy-secret.yaml in the working directory is loaded by default. $ cat trivy-secret.yaml rules : - id : rule1 category : general title : Generic Rule severity : HIGH regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] allow-rules : - id : social-security-number description : skip social security number regex : 219-09-9999 - id : log-dir description : skip log directory path : ^\\/var\\/log\\/ disable-rules : - slack-access-token - slack-web-hook disable-allow-rules : - markdown # The following command automatically loads the above configuration. $ trivy image YOUR_IMAGE Also, you can customize the config file path via --secret-config . $ cat ./secret-config/trivy.yaml rules : - id : rule1 category : general title : Generic Rule severity : HIGH regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] allow-rules : - id : skip-text description : skip text files path : .*\\.txt enable-builtin-rules : - aws-access-key-id - aws-account-id - aws-secret-access-key disable-allow-rules : - usr-dirs # Pass the above config with `--secret-config`. $ trivy fs --secret-config ./secret-config/trivy.yaml /path/to/your_project Credit This feature is inspired by gitleaks .","title":"Secret"},{"location":"docs/scanner/secret/#secret-scanning","text":"Trivy scans any container image, filesystem and git repository to detect exposed secrets like passwords, api keys, and tokens. Secret scanning is enabled by default. Trivy will scan every plaintext file, according to builtin rules or configuration. There are plenty of builtin rules: AWS access key GCP service account GitHub personal access token GitLab personal access token Slack access token etc. You can see a full list of built-in rules and built-in allow rules . Tip If your secret is not detected properly, please make sure that your file including the secret is not in the allowed paths . You can disable allow rules via disable-allow-rules .","title":"Secret Scanning"},{"location":"docs/scanner/secret/#quick-start","text":"This section shows how to scan secrets in container image and filesystem. Other subcommands should be the same.","title":"Quick start"},{"location":"docs/scanner/secret/#container-image","text":"Specify an image name. $ trivy image myimage:1.0.0 2022 -04-21T18:56:44.099+0300 INFO Detected OS: alpine 2022 -04-21T18:56:44.099+0300 INFO Detecting Alpine vulnerabilities... 2022 -04-21T18:56:44.101+0300 INFO Number of language-specific files: 0 myimage:1.0.0 ( alpine 3 .15.0 ) ============================= Total: 6 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ | busybox | CVE-2022-28391 | CRITICAL | 1 .34.1-r3 | 1 .34.1-r5 | CVE-2022-28391 affecting | | | | | | | package busybox 1 .35.0 | | | | | | | -->avd.aquasec.com/nvd/cve-2022-28391 | +--------------+------------------ | | -------------------+---------------+---------------------------------------+ | ssl_client | CVE-2022-28391 | | 1 .34.1-r3 | 1 .34.1-r5 | CVE-2022-28391 affecting | | | | | | | package busybox 1 .35.0 | | | | | | | -->avd.aquasec.com/nvd/cve-2022-28391 | +--------------+------------------+----------+-------------------+---------------+---------------------------------------+ app/secret.sh ( secrets ) ======================= Total: 1 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 1 ) +----------+-------------------+----------+---------+--------------------------------+ | CATEGORY | DESCRIPTION | SEVERITY | LINE NO | MATCH | +----------+-------------------+----------+---------+--------------------------------+ | AWS | AWS Access Key ID | CRITICAL | 10 | export AWS_ACCESS_KEY_ID = ***** | +----------+-------------------+----------+---------+--------------------------------+ Tip Trivy tries to detect a base image and skip those layers for secret scanning. A base image usually contains a lot of files and makes secret scanning much slower. If a secret is not detected properly, you can see base layers with the --debug flag.","title":"Container image"},{"location":"docs/scanner/secret/#filesystem","text":"$ trivy fs /path/to/your_project ... ( snip ) ... certs/key.pem ( secrets ) ======================== Total: 1 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 1 , CRITICAL: 0 ) +----------------------+------------------------+----------+---------+---------------------------------+ | CATEGORY | DESCRIPTION | SEVERITY | LINE NO | MATCH | +----------------------+------------------------+----------+---------+---------------------------------+ | AsymmetricPrivateKey | Asymmetric Private Key | HIGH | 1 | -----BEGIN RSA PRIVATE KEY----- | +----------------------+------------------------+----------+---------+---------------------------------+ Tip Your project may have some secrets for testing. You can skip them with --skip-dirs or --skip-files . We would recommend specifying these options so that the secret scanning can be faster if those files don't need to be scanned. Also, you can specify paths to be allowed in a configuration file. See the detail here .","title":"Filesystem"},{"location":"docs/scanner/secret/#configuration","text":"This section describes secret-specific configuration. Other common options are documented here . Trivy has a set of builtin rules for secret scanning, which can be extended or modified by a configuration file. Trivy tries to load trivy-secret.yaml in the current directory by default. If the file doesn't exist, only built-in rules are used. You can customize the config file path via the --secret-config flag.","title":"Configuration"},{"location":"docs/scanner/secret/#custom-rules","text":"Trivy allows defining custom rules. rules : - id : rule1 category : general title : Generic Rule severity : HIGH path : .*\\.sh keywords : - secret regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] secret-group-name : secret allow-rules : - id : skip-text description : skip text files path : .*\\.txt id (required) Unique identifier for this rule. category (required) String used for metadata and reporting purposes. title (required) Short human-readable title of the rule. severity (required) How critical this rule is. Allowed values: CRITICAL HIGH MEDIUM LOW regex (required) Golang regular expression used to detect secrets. path (optional) Golang regular expression used to match paths. keywords (optional, recommended) Keywords are used for pre-regex check filtering. Rules that contain keywords will perform a quick string compare check to make sure the keyword(s) are in the content being scanned. Ideally these values should either be part of the identifier or unique strings specific to the rule's regex. It is recommended to define for better performance. allow-rules (optional) Allow rules for a single rule to reduce false positives with known secrets. The details are below.","title":"Custom Rules"},{"location":"docs/scanner/secret/#allow-rules","text":"If the detected secret is matched with the specified regex , then that secret will be skipped and not detected. The same logic applies for path . allow-rules can be defined globally and per each rule. The fields are the same. rules : - id : rule1 category : general title : Generic Rule severity : HIGH regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] allow-rules : - id : skip-text description : skip text files path : .*\\.txt allow-rules : - id : social-security-number description : skip social security number regex : 219-09-9999 id (required) Unique identifier for this allow rule. description (optional) Short human-readable description of this allow rule. regex (optional) Golang regular expression used to allow detected secrets. regex or path must be specified. path (optional) Golang regular expression used to allow matched paths. regex or path must be specified.","title":"Allow Rules"},{"location":"docs/scanner/secret/#enable-rules","text":"Trivy provides plenty of out-of-box rules and allow rules, but you may not need all of them. In that case, enable-builtin-rules will be helpful. If you just need AWS secret detection, you can enable only relevant rules as shown below. It specifies AWS-related rule IDs in enable-builtin-rules . All other rules are disabled, so the scanning will be much faster. We would strongly recommend using this option if you don't need all rules. You can see a full list of built-in rule IDs and built-in allow rule IDs . enable-builtin-rules : - aws-access-key-id - aws-account-id - aws-secret-access-key","title":"Enable Rules"},{"location":"docs/scanner/secret/#disable-rules","text":"Trivy offers built-in rules and allow rules, but you may want to disable some of them. For example, you don't use Slack, so Slack doesn't have to be scanned. You can specify the Slack rule IDs, slack-access-token and slack-web-hook in disable-rules so that those rules will be disabled for less false positives. You should specify either enable-builtin-rules or disable-rules . If they both are specified, disable-rules takes precedence. In case github-pat is specified in enable-builtin-rules and disable-rules , it will be disabled. In addition, there are some allow rules. Markdown files are ignored by default, but you may want to scan markdown files as well. You can disable the allow rule by adding markdown to disable-allow-rules . You can see a full list of built-in rule IDs and built-in allow rule IDs . disable-rules : - slack-access-token - slack-web-hook disable-allow-rules : - markdown","title":"Disable Rules"},{"location":"docs/scanner/secret/#recommendation","text":"We would recommend specifying --skip-dirs for faster secret scanning. In container image scanning, Trivy walks the file tree rooted / and scans all the files other than built-in allowed paths . It will take a while if your image contains a lot of files even though Trivy tries to avoid scanning layers from a base image. If you want to make scanning faster, --skip-dirs and --skip-files helps so that Trivy will skip scanning those files and directories. You can see more options here . allow-rules is also helpful. See the allow-rules section. In addition, all the built-in rules are enabled by default, so it takes some time to scan all of them. If you don't need all those rules, you can use enable-builtin-rules or disable-rules in the configuration file. You should use enable-builtin-rules if you need only AWS secret detection, for example. All rules are disabled except for the ones you specify, so it runs very fast. On the other hand, you should use disable-rules if you just want to disable some built-in rules. See the enable-rules and disable-rules sections for the detail. If you don't need secret scanning, you can disable it via the --scanners flag. $ trivy image --scanners vuln alpine:3.15","title":"Recommendation"},{"location":"docs/scanner/secret/#example","text":"trivy-secret.yaml in the working directory is loaded by default. $ cat trivy-secret.yaml rules : - id : rule1 category : general title : Generic Rule severity : HIGH regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] allow-rules : - id : social-security-number description : skip social security number regex : 219-09-9999 - id : log-dir description : skip log directory path : ^\\/var\\/log\\/ disable-rules : - slack-access-token - slack-web-hook disable-allow-rules : - markdown # The following command automatically loads the above configuration. $ trivy image YOUR_IMAGE Also, you can customize the config file path via --secret-config . $ cat ./secret-config/trivy.yaml rules : - id : rule1 category : general title : Generic Rule severity : HIGH regex : (?i)(?P(secret))(=|:).{0,5}['\"](?P[0-9a-zA-Z\\-_=]{8,64})['\"] allow-rules : - id : skip-text description : skip text files path : .*\\.txt enable-builtin-rules : - aws-access-key-id - aws-account-id - aws-secret-access-key disable-allow-rules : - usr-dirs # Pass the above config with `--secret-config`. $ trivy fs --secret-config ./secret-config/trivy.yaml /path/to/your_project","title":"Example"},{"location":"docs/scanner/secret/#credit","text":"This feature is inspired by gitleaks .","title":"Credit"},{"location":"docs/scanner/misconfiguration/","text":"Misconfiguration Scanning Trivy provides built-in policies to detect configuration issues in popular Infrastructure as Code files, such as: Docker, Kubernetes, Terraform, CloudFormation, and more. In addition to built-in policies, you can write your own custom policies, as you can see here . Quick start Simply specify a directory containing IaC files such as Terraform, CloudFormation, Azure ARM templates, Helm Charts and Dockerfile. $ trivy config [ YOUR_IaC_DIRECTORY ] Example $ ls build/ Dockerfile $ trivy config ./build 2022-05-16T13:29:29.952+0100 INFO Detected config files: 1 Dockerfile (dockerfile) ======================= Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0) Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated. See https://avd.aquasec.com/misconfig/ds001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 [ FROM alpine:latest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 You can also enable misconfiguration detection in container image, filesystem and git repository scanning via --scanners config . $ trivy image --scanners config IMAGE_NAME $ trivy fs --scanners config /path/to/dir Note Misconfiguration detection is not enabled by default in image , fs and repo subcommands. Unlike the config subcommand, image , fs and repo subcommands can also scan for vulnerabilities and secrets at the same time. You can specify --scanners vuln,config,secret to enable vulnerability and secret detection as well as misconfiguration detection. Example $ ls myapp/ Dockerfile Pipfile.lock $ trivy fs --scanners vuln,config,secret --severity HIGH,CRITICAL myapp/ 2022 -05-16T13:42:21.440+0100 INFO Number of language-specific files: 1 2022 -05-16T13:42:21.440+0100 INFO Detecting pipenv vulnerabilities... 2022 -05-16T13:42:21.440+0100 INFO Detected config files: 1 Pipfile.lock ( pipenv ) ===================== Total: 1 ( HIGH: 1 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 httplib2 \u2502 CVE-2021-21240 \u2502 HIGH \u2502 0 .12.1 \u2502 0 .19.0 \u2502 python-httplib2: Regular expression denial of service via \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 malicious header \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-21240 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Dockerfile ( dockerfile ) ======================= Tests: 17 ( SUCCESSES: 16 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 1 , CRITICAL: 0 ) HIGH: Last USER command in Dockerfile should not be 'root' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3 [ USER root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 In the above example, Trivy detected vulnerabilities of Python dependencies and misconfigurations in Dockerfile. Type detection The specified directory can contain mixed types of IaC files. Trivy automatically detects config types and applies relevant policies. For example, the following example holds IaC files for Terraform, CloudFormation, Kubernetes, Helm Charts, and Dockerfile in the same directory. $ ls iac/ Dockerfile deployment.yaml main.tf mysql-8.8.26.tar $ trivy conf --severity HIGH,CRITICAL ./iac Result 2022-06-06T11:01:21.142+0100 INFO Detected config files: 8 Dockerfile (dockerfile) Tests: 21 (SUCCESSES: 20, FAILURES: 1, EXCEPTIONS: 0) Failures: 1 (MEDIUM: 0, HIGH: 1, CRITICAL: 0) HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml (kubernetes) Tests: 20 (SUCCESSES: 15, FAILURES: 5, EXCEPTIONS: 0) Failures: 5 (MEDIUM: 4, HIGH: 1, CRITICAL: 0) MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.allowPrivilegeEscalation' to false \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node. See https://avd.aquasec.com/misconfig/ksv001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:16-19 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 16 \u250c - name: hello-kubernetes 17 \u2502 image: hello-kubernetes:1.5 18 \u2502 ports: 19 \u2514 - containerPort: 8080 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 HIGH: Deployment 'hello-kubernetes' should not specify '/var/run/docker.socker' in 'spec.template.volumes.hostPath.path' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Mounting docker.sock from the host can give the container full root access to the host. See https://avd.aquasec.com/misconfig/ksv006 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:6-29 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 6 \u250c replicas: 3 7 \u2502 selector: 8 \u2502 matchLabels: 9 \u2502 app: hello-kubernetes 10 \u2502 template: 11 \u2502 metadata: 12 \u2502 labels: 13 \u2502 app: hello-kubernetes 14 \u2514 spec: .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.runAsNonRoot' to true \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges. See https://avd.aquasec.com/misconfig/ksv012 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:16-19 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 16 \u250c - name: hello-kubernetes 17 \u2502 image: hello-kubernetes:1.5 18 \u2502 ports: 19 \u2514 - containerPort: 8080 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Deployment 'hello-kubernetes' should not set 'spec.template.volumes.hostPath' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 HostPath volumes must be forbidden. See https://avd.aquasec.com/misconfig/ksv023 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:6-29 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 6 \u250c replicas: 3 7 \u2502 selector: 8 \u2502 matchLabels: 9 \u2502 app: hello-kubernetes 10 \u2502 template: 11 \u2502 metadata: 12 \u2502 labels: 13 \u2502 app: hello-kubernetes 14 \u2514 spec: .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Deployment 'hello-kubernetes' should set 'securityContext.sysctl' to the allowed values \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed 'safe' subset. A sysctl is considered safe if it is namespaced in the container or the Pod, and it is isolated from other Pods or processes on the same Node. See https://avd.aquasec.com/misconfig/ksv026 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:6-29 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 6 \u250c replicas: 3 7 \u2502 selector: 8 \u2502 matchLabels: 9 \u2502 app: hello-kubernetes 10 \u2502 template: 11 \u2502 metadata: 12 \u2502 labels: 13 \u2502 app: hello-kubernetes 14 \u2514 spec: .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mysql-8.8.26.tar:templates/primary/statefulset.yaml (helm) Tests: 20 (SUCCESSES: 18, FAILURES: 2, EXCEPTIONS: 0) Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0) MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.allowPrivilegeEscalation' to false \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node. See https://avd.aquasec.com/misconfig/ksv001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 56 \u250c - name: mysql 57 \u2502 image: docker.io/bitnami/mysql:8.0.28-debian-10-r23 58 \u2502 imagePullPolicy: \"IfNotPresent\" 59 \u2502 securityContext: 60 \u2502 runAsUser: 1001 61 \u2502 env: 62 \u2502 - name: BITNAMI_DEBUG 63 \u2502 value: \"false\" 64 \u2514 - name: MYSQL_ROOT_PASSWORD .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.runAsNonRoot' to true \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges. See https://avd.aquasec.com/misconfig/ksv012 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 56 \u250c - name: mysql 57 \u2502 image: docker.io/bitnami/mysql:8.0.28-debian-10-r23 58 \u2502 imagePullPolicy: \"IfNotPresent\" 59 \u2502 securityContext: 60 \u2502 runAsUser: 1001 61 \u2502 env: 62 \u2502 - name: BITNAMI_DEBUG 63 \u2502 value: \"false\" 64 \u2514 - name: MYSQL_ROOT_PASSWORD .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 You can see the config type next to each file name. Example Dockerfile ( dockerfile ) ======================= Tests: 23 ( SUCCESSES: 22 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 1 , CRITICAL: 0 ) ... deployment.yaml ( kubernetes ) ============================ Tests: 28 ( SUCCESSES: 15 , FAILURES: 13 , EXCEPTIONS: 0 ) Failures: 13 ( MEDIUM: 4 , HIGH: 1 , CRITICAL: 0 ) ... main.tf ( terraform ) =================== Tests: 23 ( SUCCESSES: 14 , FAILURES: 9 , EXCEPTIONS: 0 ) Failures: 9 ( HIGH: 6 , CRITICAL: 1 ) ... bucket.yaml ( cloudformation ) ============================ Tests: 9 ( SUCCESSES: 3 , FAILURES: 6 , EXCEPTIONS: 0 ) Failures: 6 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 2 , HIGH: 4 , CRITICAL: 0 ) ... mysql-8.8.26.tar:templates/primary/statefulset.yaml ( helm ) ========================================================== Tests: 20 ( SUCCESSES: 18 , FAILURES: 2 , EXCEPTIONS: 0 ) Failures: 2 ( MEDIUM: 2 , HIGH: 0 , CRITICAL: 0 ) Configuration This section describes misconfiguration-specific configuration. Other common options are documented here . Pass custom policies You can pass directories including your custom policies through --policy option. This can be repeated for specifying multiple directories. cd examplex/misconf/ trivy conf --policy custom-policy/policy --policy combine/policy --namespaces user misconf/mixed For more details, see Custom Policies . Tip You also need to specify --namespaces option. Pass custom data You can pass directories including your custom data through --data option. This can be repeated for specifying multiple directories. cd examples/misconf/custom-data trivy conf --policy ./policy --data ./data --namespaces user ./configs For more details, see Custom Data . Pass namespaces By default, Trivy evaluates policies defined in builtin.* . If you want to evaluate custom policies in other packages, you have to specify package prefixes through --namespaces option. This can be repeated for specifying multiple packages. trivy conf --policy ./policy --namespaces main --namespaces user ./configs Terraform value overrides You can pass tf-vars files to Trivy to override default values found in the Terraform HCL code. trivy conf --tf-vars dev.terraform.tfvars ./infrastructure/tf Helm value overrides There are a number of options for overriding values in Helm charts. When override values are passed to the Helm scanner, the values will be used during the Manifest rendering process and will become part of the scanned artifact. Setting inline value overrides Overrides can be set inline on the command line trivy conf --helm-set securityContext.runAsUser = 0 ./charts/mySql Setting value file overrides Overrides can be in a file that has the key=value set. # Example override file (overrides.yaml) securityContext : runAsUser : 0 trivy conf --helm-values overrides.yaml ./charts/mySql Setting value as explicit string the --helm-set-string is the same as --helm-set but explicitly retains the value as a string trivy config --helm-set-string name = false ./infrastructure/tf Setting specific values from files Specific override values can come from specific files trivy conf --helm-set-file environment = dev.values.yaml ./charts/mySql","title":"Overview"},{"location":"docs/scanner/misconfiguration/#misconfiguration-scanning","text":"Trivy provides built-in policies to detect configuration issues in popular Infrastructure as Code files, such as: Docker, Kubernetes, Terraform, CloudFormation, and more. In addition to built-in policies, you can write your own custom policies, as you can see here .","title":"Misconfiguration Scanning"},{"location":"docs/scanner/misconfiguration/#quick-start","text":"Simply specify a directory containing IaC files such as Terraform, CloudFormation, Azure ARM templates, Helm Charts and Dockerfile. $ trivy config [ YOUR_IaC_DIRECTORY ] Example $ ls build/ Dockerfile $ trivy config ./build 2022-05-16T13:29:29.952+0100 INFO Detected config files: 1 Dockerfile (dockerfile) ======================= Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0) Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated. See https://avd.aquasec.com/misconfig/ds001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 [ FROM alpine:latest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 You can also enable misconfiguration detection in container image, filesystem and git repository scanning via --scanners config . $ trivy image --scanners config IMAGE_NAME $ trivy fs --scanners config /path/to/dir Note Misconfiguration detection is not enabled by default in image , fs and repo subcommands. Unlike the config subcommand, image , fs and repo subcommands can also scan for vulnerabilities and secrets at the same time. You can specify --scanners vuln,config,secret to enable vulnerability and secret detection as well as misconfiguration detection. Example $ ls myapp/ Dockerfile Pipfile.lock $ trivy fs --scanners vuln,config,secret --severity HIGH,CRITICAL myapp/ 2022 -05-16T13:42:21.440+0100 INFO Number of language-specific files: 1 2022 -05-16T13:42:21.440+0100 INFO Detecting pipenv vulnerabilities... 2022 -05-16T13:42:21.440+0100 INFO Detected config files: 1 Pipfile.lock ( pipenv ) ===================== Total: 1 ( HIGH: 1 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 httplib2 \u2502 CVE-2021-21240 \u2502 HIGH \u2502 0 .12.1 \u2502 0 .19.0 \u2502 python-httplib2: Regular expression denial of service via \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 malicious header \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-21240 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Dockerfile ( dockerfile ) ======================= Tests: 17 ( SUCCESSES: 16 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 1 , CRITICAL: 0 ) HIGH: Last USER command in Dockerfile should not be 'root' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3 [ USER root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 In the above example, Trivy detected vulnerabilities of Python dependencies and misconfigurations in Dockerfile.","title":"Quick start"},{"location":"docs/scanner/misconfiguration/#type-detection","text":"The specified directory can contain mixed types of IaC files. Trivy automatically detects config types and applies relevant policies. For example, the following example holds IaC files for Terraform, CloudFormation, Kubernetes, Helm Charts, and Dockerfile in the same directory. $ ls iac/ Dockerfile deployment.yaml main.tf mysql-8.8.26.tar $ trivy conf --severity HIGH,CRITICAL ./iac Result 2022-06-06T11:01:21.142+0100 INFO Detected config files: 8 Dockerfile (dockerfile) Tests: 21 (SUCCESSES: 20, FAILURES: 1, EXCEPTIONS: 0) Failures: 1 (MEDIUM: 0, HIGH: 1, CRITICAL: 0) HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml (kubernetes) Tests: 20 (SUCCESSES: 15, FAILURES: 5, EXCEPTIONS: 0) Failures: 5 (MEDIUM: 4, HIGH: 1, CRITICAL: 0) MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.allowPrivilegeEscalation' to false \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node. See https://avd.aquasec.com/misconfig/ksv001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:16-19 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 16 \u250c - name: hello-kubernetes 17 \u2502 image: hello-kubernetes:1.5 18 \u2502 ports: 19 \u2514 - containerPort: 8080 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 HIGH: Deployment 'hello-kubernetes' should not specify '/var/run/docker.socker' in 'spec.template.volumes.hostPath.path' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Mounting docker.sock from the host can give the container full root access to the host. See https://avd.aquasec.com/misconfig/ksv006 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:6-29 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 6 \u250c replicas: 3 7 \u2502 selector: 8 \u2502 matchLabels: 9 \u2502 app: hello-kubernetes 10 \u2502 template: 11 \u2502 metadata: 12 \u2502 labels: 13 \u2502 app: hello-kubernetes 14 \u2514 spec: .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.runAsNonRoot' to true \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges. See https://avd.aquasec.com/misconfig/ksv012 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:16-19 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 16 \u250c - name: hello-kubernetes 17 \u2502 image: hello-kubernetes:1.5 18 \u2502 ports: 19 \u2514 - containerPort: 8080 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Deployment 'hello-kubernetes' should not set 'spec.template.volumes.hostPath' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 HostPath volumes must be forbidden. See https://avd.aquasec.com/misconfig/ksv023 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:6-29 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 6 \u250c replicas: 3 7 \u2502 selector: 8 \u2502 matchLabels: 9 \u2502 app: hello-kubernetes 10 \u2502 template: 11 \u2502 metadata: 12 \u2502 labels: 13 \u2502 app: hello-kubernetes 14 \u2514 spec: .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Deployment 'hello-kubernetes' should set 'securityContext.sysctl' to the allowed values \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed 'safe' subset. A sysctl is considered safe if it is namespaced in the container or the Pod, and it is isolated from other Pods or processes on the same Node. See https://avd.aquasec.com/misconfig/ksv026 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 deployment.yaml:6-29 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 6 \u250c replicas: 3 7 \u2502 selector: 8 \u2502 matchLabels: 9 \u2502 app: hello-kubernetes 10 \u2502 template: 11 \u2502 metadata: 12 \u2502 labels: 13 \u2502 app: hello-kubernetes 14 \u2514 spec: .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mysql-8.8.26.tar:templates/primary/statefulset.yaml (helm) Tests: 20 (SUCCESSES: 18, FAILURES: 2, EXCEPTIONS: 0) Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0) MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.allowPrivilegeEscalation' to false \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node. See https://avd.aquasec.com/misconfig/ksv001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 56 \u250c - name: mysql 57 \u2502 image: docker.io/bitnami/mysql:8.0.28-debian-10-r23 58 \u2502 imagePullPolicy: \"IfNotPresent\" 59 \u2502 securityContext: 60 \u2502 runAsUser: 1001 61 \u2502 env: 62 \u2502 - name: BITNAMI_DEBUG 63 \u2502 value: \"false\" 64 \u2514 - name: MYSQL_ROOT_PASSWORD .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.runAsNonRoot' to true \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges. See https://avd.aquasec.com/misconfig/ksv012 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 56 \u250c - name: mysql 57 \u2502 image: docker.io/bitnami/mysql:8.0.28-debian-10-r23 58 \u2502 imagePullPolicy: \"IfNotPresent\" 59 \u2502 securityContext: 60 \u2502 runAsUser: 1001 61 \u2502 env: 62 \u2502 - name: BITNAMI_DEBUG 63 \u2502 value: \"false\" 64 \u2514 - name: MYSQL_ROOT_PASSWORD .. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 You can see the config type next to each file name. Example Dockerfile ( dockerfile ) ======================= Tests: 23 ( SUCCESSES: 22 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( HIGH: 1 , CRITICAL: 0 ) ... deployment.yaml ( kubernetes ) ============================ Tests: 28 ( SUCCESSES: 15 , FAILURES: 13 , EXCEPTIONS: 0 ) Failures: 13 ( MEDIUM: 4 , HIGH: 1 , CRITICAL: 0 ) ... main.tf ( terraform ) =================== Tests: 23 ( SUCCESSES: 14 , FAILURES: 9 , EXCEPTIONS: 0 ) Failures: 9 ( HIGH: 6 , CRITICAL: 1 ) ... bucket.yaml ( cloudformation ) ============================ Tests: 9 ( SUCCESSES: 3 , FAILURES: 6 , EXCEPTIONS: 0 ) Failures: 6 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 2 , HIGH: 4 , CRITICAL: 0 ) ... mysql-8.8.26.tar:templates/primary/statefulset.yaml ( helm ) ========================================================== Tests: 20 ( SUCCESSES: 18 , FAILURES: 2 , EXCEPTIONS: 0 ) Failures: 2 ( MEDIUM: 2 , HIGH: 0 , CRITICAL: 0 )","title":"Type detection"},{"location":"docs/scanner/misconfiguration/#configuration","text":"This section describes misconfiguration-specific configuration. Other common options are documented here .","title":"Configuration"},{"location":"docs/scanner/misconfiguration/#pass-custom-policies","text":"You can pass directories including your custom policies through --policy option. This can be repeated for specifying multiple directories. cd examplex/misconf/ trivy conf --policy custom-policy/policy --policy combine/policy --namespaces user misconf/mixed For more details, see Custom Policies . Tip You also need to specify --namespaces option.","title":"Pass custom policies"},{"location":"docs/scanner/misconfiguration/#pass-custom-data","text":"You can pass directories including your custom data through --data option. This can be repeated for specifying multiple directories. cd examples/misconf/custom-data trivy conf --policy ./policy --data ./data --namespaces user ./configs For more details, see Custom Data .","title":"Pass custom data"},{"location":"docs/scanner/misconfiguration/#pass-namespaces","text":"By default, Trivy evaluates policies defined in builtin.* . If you want to evaluate custom policies in other packages, you have to specify package prefixes through --namespaces option. This can be repeated for specifying multiple packages. trivy conf --policy ./policy --namespaces main --namespaces user ./configs","title":"Pass namespaces"},{"location":"docs/scanner/misconfiguration/#terraform-value-overrides","text":"You can pass tf-vars files to Trivy to override default values found in the Terraform HCL code. trivy conf --tf-vars dev.terraform.tfvars ./infrastructure/tf","title":"Terraform value overrides"},{"location":"docs/scanner/misconfiguration/#helm-value-overrides","text":"There are a number of options for overriding values in Helm charts. When override values are passed to the Helm scanner, the values will be used during the Manifest rendering process and will become part of the scanned artifact.","title":"Helm value overrides"},{"location":"docs/scanner/misconfiguration/#setting-inline-value-overrides","text":"Overrides can be set inline on the command line trivy conf --helm-set securityContext.runAsUser = 0 ./charts/mySql","title":"Setting inline value overrides"},{"location":"docs/scanner/misconfiguration/#setting-value-file-overrides","text":"Overrides can be in a file that has the key=value set. # Example override file (overrides.yaml) securityContext : runAsUser : 0 trivy conf --helm-values overrides.yaml ./charts/mySql","title":"Setting value file overrides"},{"location":"docs/scanner/misconfiguration/#setting-value-as-explicit-string","text":"the --helm-set-string is the same as --helm-set but explicitly retains the value as a string trivy config --helm-set-string name = false ./infrastructure/tf","title":"Setting value as explicit string"},{"location":"docs/scanner/misconfiguration/#setting-specific-values-from-files","text":"Specific override values can come from specific files trivy conf --helm-set-file environment = dev.values.yaml ./charts/mySql","title":"Setting specific values from files"},{"location":"docs/scanner/misconfiguration/custom/","text":"Custom Policies Overview You can write custom policies in Rego . Once you finish writing custom policies, you can pass the directory where those policies are stored with --policy option. trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir As for --namespaces option, the detail is described as below. File formats If a file name matches the following file patterns, Trivy will parse the file and pass it as input to your Rego policy. File format File pattern JSON *.json YAML *.yaml and *.yml Dockerfile Dockerfile , Dockerfile.* , and *.Dockerfile Containerfile Containerfile , Containerfile.* , and *.Containerfile Terraform *.tf and *.tf.json Configuration languages In the above general file formats, Trivy automatically identifies the following types of configuration files: CloudFormation (JSON/YAML) Kubernetes (JSON/YAML) Helm (YAML) Terraform Plan (JSON) This is useful for filtering inputs, as described below. Rego format A single package must contain only one policy. Example # METADATA # title: Deployment not allowed # description: Deployments are not allowed because of some reasons. # schemas: # - input: schema[\"kubernetes\"] # custom: # id: ID001 # severity: LOW # input: # selector: # - type: kubernetes package user.kubernetes.ID001 deny[res] { input.kind == \"Deployment\" msg := sprintf(\"Found deployment '%s' but deployments are not allowed\", [input.metadata.name]) res := result.new(msg, input.kind) } In this example, ID001 \"Deployment not allowed\" is defined under user.kubernetes.ID001 . If you add a new custom policy, it must be defined under a new package like user.kubernetes.ID002 . Policy structure # METADATA (optional) SHOULD be defined for clarity since these values will be displayed in the scan results custom.input SHOULD be set to indicate the input type the policy should be applied to. See list of available types package (required) MUST follow the Rego's specification MUST be unique per policy SHOULD include policy id for uniqueness MAY include the group name such as kubernetes for clarity Group name has no effect on policy evaluation deny (required) SHOULD be deny or start with deny_ Although warn , warn_* , violation , violation_ also work for compatibility, deny is recommended as severity can be defined in __rego_metadata__ . SHOULD return ONE OF: The result of a call to result.new(msg, cause) . The msg is a string describing the issue occurrence, and the cause is the property/object where the issue occurred. Providing this allows Trivy to ascertain line numbers and highlight code in the output. A string denoting the detected issue Although object with msg field is accepted, other fields are dropped and string is recommended if result.new() is not utilised. e.g. {\"msg\": \"deny message\", \"details\": \"something\"} Package A package name must be unique per policy. Example package user.kubernetes.ID001 By default, only builtin.* packages will be evaluated. If you define custom packages, you have to specify the package prefix via --namespaces option. trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir In this case, user.* will be evaluated. Any package prefixes such as main and user are allowed. Metadata Metadata helps enrich Trivy's scan results with useful information. The annotation format is described in the OPA documentation . Trivy supports extra fields in the custom section as described below. Example # METADATA # title: Deployment not allowed # description: Deployments are not allowed because of some reasons. # custom: # id: ID001 # severity: LOW # input: # selector: # - type: kubernetes All fields are optional. The schemas field should be used to enable policy validation using a built-in schema. The schema that will be used is based on the input document type. It is recommended to use this to ensure your policies are correct and do not reference incorrect properties/values. Field name Allowed values Default value In table In JSON title Any characters N/A description Any characters schemas.input schema[\"kubernetes\"] , schema[\"dockerfile\"] , schema[\"cloud\"] (applied to all input types) custom.id Any characters N/A custom.severity LOW , MEDIUM , HIGH , CRITICAL UNKNOWN custom.recommended_actions Any characters custom.input.selector.type Any item(s) in this list url Any characters Some fields are displayed in scan results. k.yaml ( kubernetes ) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Tests: 32 ( SUCCESSES: 31 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( UNKNOWN: 0 , LOW: 1 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 0 ) LOW: Found deployment 'my-deployment' but deployments are not allowed \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Deployments are not allowed because of some reasons. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 k.yaml:1-2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 \u250c apiVersion: v1 2 \u2514 kind: Deployment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Input You can specify input format via the custom.input annotation. Example # METADATA # custom: # input: # combine: false # selector: # - type: kubernetes combine (boolean) The details are here . selector (array) This option filters the input by file format or configuration language. In the above example, Trivy passes only Kubernetes files to this policy. Even if a Dockerfile exists in the specified directory, it will not be passed to the policy as input. Possible values for input types are: - dockerfile (Dockerfile) - kubernetes (Kubernetes YAML/JSON) - rbac (Kubernetes RBAC YAML/JSON) - cloud (Cloud format, as defined by defsec - this is used for Terraform, CloudFormation, and Cloud/AWS scanning) - yaml (Generic YAML) - json (Generic JSON) - toml (Generic TOML) When configuration languages such as Kubernetes are not identified, file formats such as JSON will be used as type . When a configuration language is identified, it will overwrite type . Example pod.yaml including Kubernetes Pod will be handled as kubernetes , not yaml . type is overwritten by kubernetes from yaml . type accepts kubernetes , dockerfile , cloudformation , terraform , terraformplan , json , or yaml . Schemas See here for the detail.","title":"Overview"},{"location":"docs/scanner/misconfiguration/custom/#custom-policies","text":"","title":"Custom Policies"},{"location":"docs/scanner/misconfiguration/custom/#overview","text":"You can write custom policies in Rego . Once you finish writing custom policies, you can pass the directory where those policies are stored with --policy option. trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir As for --namespaces option, the detail is described as below.","title":"Overview"},{"location":"docs/scanner/misconfiguration/custom/#file-formats","text":"If a file name matches the following file patterns, Trivy will parse the file and pass it as input to your Rego policy. File format File pattern JSON *.json YAML *.yaml and *.yml Dockerfile Dockerfile , Dockerfile.* , and *.Dockerfile Containerfile Containerfile , Containerfile.* , and *.Containerfile Terraform *.tf and *.tf.json","title":"File formats"},{"location":"docs/scanner/misconfiguration/custom/#configuration-languages","text":"In the above general file formats, Trivy automatically identifies the following types of configuration files: CloudFormation (JSON/YAML) Kubernetes (JSON/YAML) Helm (YAML) Terraform Plan (JSON) This is useful for filtering inputs, as described below.","title":"Configuration languages"},{"location":"docs/scanner/misconfiguration/custom/#rego-format","text":"A single package must contain only one policy. Example # METADATA # title: Deployment not allowed # description: Deployments are not allowed because of some reasons. # schemas: # - input: schema[\"kubernetes\"] # custom: # id: ID001 # severity: LOW # input: # selector: # - type: kubernetes package user.kubernetes.ID001 deny[res] { input.kind == \"Deployment\" msg := sprintf(\"Found deployment '%s' but deployments are not allowed\", [input.metadata.name]) res := result.new(msg, input.kind) } In this example, ID001 \"Deployment not allowed\" is defined under user.kubernetes.ID001 . If you add a new custom policy, it must be defined under a new package like user.kubernetes.ID002 .","title":"Rego format"},{"location":"docs/scanner/misconfiguration/custom/#policy-structure","text":"# METADATA (optional) SHOULD be defined for clarity since these values will be displayed in the scan results custom.input SHOULD be set to indicate the input type the policy should be applied to. See list of available types package (required) MUST follow the Rego's specification MUST be unique per policy SHOULD include policy id for uniqueness MAY include the group name such as kubernetes for clarity Group name has no effect on policy evaluation deny (required) SHOULD be deny or start with deny_ Although warn , warn_* , violation , violation_ also work for compatibility, deny is recommended as severity can be defined in __rego_metadata__ . SHOULD return ONE OF: The result of a call to result.new(msg, cause) . The msg is a string describing the issue occurrence, and the cause is the property/object where the issue occurred. Providing this allows Trivy to ascertain line numbers and highlight code in the output. A string denoting the detected issue Although object with msg field is accepted, other fields are dropped and string is recommended if result.new() is not utilised. e.g. {\"msg\": \"deny message\", \"details\": \"something\"}","title":"Policy structure"},{"location":"docs/scanner/misconfiguration/custom/#package","text":"A package name must be unique per policy. Example package user.kubernetes.ID001 By default, only builtin.* packages will be evaluated. If you define custom packages, you have to specify the package prefix via --namespaces option. trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir In this case, user.* will be evaluated. Any package prefixes such as main and user are allowed.","title":"Package"},{"location":"docs/scanner/misconfiguration/custom/#metadata","text":"Metadata helps enrich Trivy's scan results with useful information. The annotation format is described in the OPA documentation . Trivy supports extra fields in the custom section as described below. Example # METADATA # title: Deployment not allowed # description: Deployments are not allowed because of some reasons. # custom: # id: ID001 # severity: LOW # input: # selector: # - type: kubernetes All fields are optional. The schemas field should be used to enable policy validation using a built-in schema. The schema that will be used is based on the input document type. It is recommended to use this to ensure your policies are correct and do not reference incorrect properties/values. Field name Allowed values Default value In table In JSON title Any characters N/A description Any characters schemas.input schema[\"kubernetes\"] , schema[\"dockerfile\"] , schema[\"cloud\"] (applied to all input types) custom.id Any characters N/A custom.severity LOW , MEDIUM , HIGH , CRITICAL UNKNOWN custom.recommended_actions Any characters custom.input.selector.type Any item(s) in this list url Any characters Some fields are displayed in scan results. k.yaml ( kubernetes ) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Tests: 32 ( SUCCESSES: 31 , FAILURES: 1 , EXCEPTIONS: 0 ) Failures: 1 ( UNKNOWN: 0 , LOW: 1 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 0 ) LOW: Found deployment 'my-deployment' but deployments are not allowed \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Deployments are not allowed because of some reasons. \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 k.yaml:1-2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 \u250c apiVersion: v1 2 \u2514 kind: Deployment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500","title":"Metadata"},{"location":"docs/scanner/misconfiguration/custom/#input","text":"You can specify input format via the custom.input annotation. Example # METADATA # custom: # input: # combine: false # selector: # - type: kubernetes combine (boolean) The details are here . selector (array) This option filters the input by file format or configuration language. In the above example, Trivy passes only Kubernetes files to this policy. Even if a Dockerfile exists in the specified directory, it will not be passed to the policy as input. Possible values for input types are: - dockerfile (Dockerfile) - kubernetes (Kubernetes YAML/JSON) - rbac (Kubernetes RBAC YAML/JSON) - cloud (Cloud format, as defined by defsec - this is used for Terraform, CloudFormation, and Cloud/AWS scanning) - yaml (Generic YAML) - json (Generic JSON) - toml (Generic TOML) When configuration languages such as Kubernetes are not identified, file formats such as JSON will be used as type . When a configuration language is identified, it will overwrite type . Example pod.yaml including Kubernetes Pod will be handled as kubernetes , not yaml . type is overwritten by kubernetes from yaml . type accepts kubernetes , dockerfile , cloudformation , terraform , terraformplan , json , or yaml .","title":"Input"},{"location":"docs/scanner/misconfiguration/custom/#schemas","text":"See here for the detail.","title":"Schemas"},{"location":"docs/scanner/misconfiguration/custom/combine/","text":"Combined input Overview Trivy usually scans each configuration file individually. Sometimes it might be useful to compare values from different configuration files simultaneously. When combine is set to true, all config files under the specified directory are combined into one input data structure. Example __rego_input__ := { \"combine\": false, } In \"combine\" mode, the input document becomes an array, where each element is an object with two fields: \"path\": \"path/to/file\" : the relative file path of the respective file \"contents\": ... : the parsed content of the respective file Now you can ensure that duplicate values match across the entirety of your configuration files. Return value In \"combine\" mode, the deny entrypoint must return an object with two keys filepath (required) the relative file path of the file being evaluated msg (required) the message describing an issue Example deny[res] { resource := input[i].contents ... some logic ... res := { \"filepath\": input[i].path, \"msg\": \"something bad\", } }","title":"Combine"},{"location":"docs/scanner/misconfiguration/custom/combine/#combined-input","text":"","title":"Combined input"},{"location":"docs/scanner/misconfiguration/custom/combine/#overview","text":"Trivy usually scans each configuration file individually. Sometimes it might be useful to compare values from different configuration files simultaneously. When combine is set to true, all config files under the specified directory are combined into one input data structure. Example __rego_input__ := { \"combine\": false, } In \"combine\" mode, the input document becomes an array, where each element is an object with two fields: \"path\": \"path/to/file\" : the relative file path of the respective file \"contents\": ... : the parsed content of the respective file Now you can ensure that duplicate values match across the entirety of your configuration files.","title":"Overview"},{"location":"docs/scanner/misconfiguration/custom/combine/#return-value","text":"In \"combine\" mode, the deny entrypoint must return an object with two keys filepath (required) the relative file path of the file being evaluated msg (required) the message describing an issue Example deny[res] { resource := input[i].contents ... some logic ... res := { \"filepath\": input[i].path, \"msg\": \"something bad\", } }","title":"Return value"},{"location":"docs/scanner/misconfiguration/custom/data/","text":"Custom Data Custom policies may require additional data in order to determine an answer. For example, an allowed list of resources that can be created. Instead of hardcoding this information inside of your policy, Trivy allows passing paths to data files with the --data flag. Given the following yaml file: $ cd examples/misconf/custom-data $ cat data/ports.yaml [ ~/src/github.com/aquasecurity/trivy/examples/misconf/custom-data ] services: ports: - \"20\" - \"20/tcp\" - \"20/udp\" - \"23\" - \"23/tcp\" This can be imported into your policy: import data.services ports := services.ports Then, you need to pass data paths through --data option. Trivy recursively searches the specified paths for JSON ( *.json ) and YAML ( *.yaml ) files. $ trivy conf --policy ./policy --data data --namespaces user ./configs","title":"Data"},{"location":"docs/scanner/misconfiguration/custom/data/#custom-data","text":"Custom policies may require additional data in order to determine an answer. For example, an allowed list of resources that can be created. Instead of hardcoding this information inside of your policy, Trivy allows passing paths to data files with the --data flag. Given the following yaml file: $ cd examples/misconf/custom-data $ cat data/ports.yaml [ ~/src/github.com/aquasecurity/trivy/examples/misconf/custom-data ] services: ports: - \"20\" - \"20/tcp\" - \"20/udp\" - \"23\" - \"23/tcp\" This can be imported into your policy: import data.services ports := services.ports Then, you need to pass data paths through --data option. Trivy recursively searches the specified paths for JSON ( *.json ) and YAML ( *.yaml ) files. $ trivy conf --policy ./policy --data data --namespaces user ./configs","title":"Custom Data"},{"location":"docs/scanner/misconfiguration/custom/debug/","text":"Debugging policies When working on more complex queries (or when learning Rego), it's useful to see exactly how the policy is applied. For this purpose you can use the --trace flag. This will output a large trace from Open Policy Agent like the following: Tip Only failed policies show traces. If you want to debug a passed policy, you need to make it fail on purpose. $ trivy conf --trace configs/ 2022 -05-16T13:47:58.853+0100 INFO Detected config files: 1 Dockerfile ( dockerfile ) ======================= Tests: 23 ( SUCCESSES: 21 , FAILURES: 2 , EXCEPTIONS: 0 ) Failures: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 1 , HIGH: 1 , CRITICAL: 0 ) MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated. See https://avd.aquasec.com/misconfig/ds001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 [ FROM alpine:latest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 HIGH: Last USER command in Dockerfile should not be 'root' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3 [ USER root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 ID: DS001 File: Dockerfile Namespace: builtin.dockerfile.DS001 Query: data.builtin.dockerfile.DS001.deny Message: Specify a tag in the 'FROM' statement for image 'alpine' TRACE Enter data.builtin.dockerfile.DS001.deny = _ TRACE | Eval data.builtin.dockerfile.DS001.deny = _ TRACE | Index data.builtin.dockerfile.DS001.deny ( matched 1 rule ) TRACE | Enter data.builtin.dockerfile.DS001.deny TRACE | | Eval output = data.builtin.dockerfile.DS001.fail_latest [ _ ] TRACE | | Index data.builtin.dockerfile.DS001.fail_latest ( matched 1 rule ) TRACE | | Enter data.builtin.dockerfile.DS001.fail_latest TRACE | | | Eval output = data.builtin.dockerfile.DS001.image_tags [ _ ] TRACE | | | Index data.builtin.dockerfile.DS001.image_tags ( matched 2 rules ) TRACE | | | Enter data.builtin.dockerfile.DS001.image_tags TRACE | | | | Eval from = data.lib.docker.from [ _ ] TRACE | | | | Index data.lib.docker.from ( matched 1 rule ) TRACE | | | | Enter data.lib.docker.from TRACE | | | | | Eval instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"from\" TRACE | | | | | Exit data.lib.docker.from TRACE | | | | Redo data.lib.docker.from TRACE | | | | | Redo instruction.Cmd = \"from\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"from\" TRACE | | | | | Fail instruction.Cmd = \"from\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"from\" TRACE | | | | | Fail instruction.Cmd = \"from\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | Eval name = from.Value [ 0 ] TRACE | | | | Eval not startswith ( name, \" $ \" ) TRACE | | | | Enter startswith ( name, \" $ \" ) TRACE | | | | | Eval startswith ( name, \" $ \" ) TRACE | | | | | Fail startswith ( name, \" $ \" ) TRACE | | | | Eval data.builtin.dockerfile.DS001.parse_tag ( name, __local505__ ) TRACE | | | | Index data.builtin.dockerfile.DS001.parse_tag ( matched 2 rules ) TRACE | | | | Enter data.builtin.dockerfile.DS001.parse_tag TRACE | | | | | Eval split ( name, \":\" , __local504__ ) TRACE | | | | | Eval [ img, tag ] = __local504__ TRACE | | | | | Exit data.builtin.dockerfile.DS001.parse_tag TRACE | | | | Eval [ img, tag ] = __local505__ TRACE | | | | Eval output = { \"cmd\" : from, \"img\" : img, \"tag\" : tag } TRACE | | | | Exit data.builtin.dockerfile.DS001.image_tags TRACE | | | Redo data.builtin.dockerfile.DS001.image_tags TRACE | | | | Redo output = { \"cmd\" : from, \"img\" : img, \"tag\" : tag } TRACE | | | | Redo [ img, tag ] = __local505__ TRACE | | | | Redo data.builtin.dockerfile.DS001.parse_tag ( name, __local505__ ) TRACE | | | | Redo data.builtin.dockerfile.DS001.parse_tag TRACE | | | | | Redo [ img, tag ] = __local504__ TRACE | | | | | Redo split ( name, \":\" , __local504__ ) TRACE | | | | Enter data.builtin.dockerfile.DS001.parse_tag TRACE | | | | | Eval tag = \"latest\" TRACE | | | | | Eval not contains ( img, \":\" ) TRACE | | | | | Enter contains ( img, \":\" ) TRACE | | | | | | Eval contains ( img, \":\" ) TRACE | | | | | | Exit contains ( img, \":\" ) TRACE | | | | | Redo contains ( img, \":\" ) TRACE | | | | | | Redo contains ( img, \":\" ) TRACE | | | | | Fail not contains ( img, \":\" ) TRACE | | | | | Redo tag = \"latest\" TRACE | | | | Redo name = from.Value [ 0 ] TRACE | | | | Redo from = data.lib.docker.from [ _ ] TRACE | | | Enter data.builtin.dockerfile.DS001.image_tags TRACE | | | | Eval from = data.lib.docker.from [ i ] TRACE | | | | Index data.lib.docker.from ( matched 1 rule ) TRACE | | | | Eval name = from.Value [ 0 ] TRACE | | | | Eval cmd_obj = input.stages [ j ][ k ] TRACE | | | | Eval possibilities = { \"arg\" , \"env\" } TRACE | | | | Eval cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Fail cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Redo possibilities = { \"arg\" , \"env\" } TRACE | | | | Redo cmd_obj = input.stages [ j ][ k ] TRACE | | | | Eval possibilities = { \"arg\" , \"env\" } TRACE | | | | Eval cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Fail cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Redo possibilities = { \"arg\" , \"env\" } TRACE | | | | Redo cmd_obj = input.stages [ j ][ k ] TRACE | | | | Eval possibilities = { \"arg\" , \"env\" } TRACE | | | | Eval cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Fail cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Redo possibilities = { \"arg\" , \"env\" } TRACE | | | | Redo cmd_obj = input.stages [ j ][ k ] TRACE | | | | Redo name = from.Value [ 0 ] TRACE | | | | Redo from = data.lib.docker.from [ i ] TRACE | | | Eval __local752__ = output.img TRACE | | | Eval neq ( __local752__, \"scratch\" ) TRACE | | | Eval __local753__ = output.img TRACE | | | Eval not data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | Enter data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | | Eval data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | | Index data.builtin.dockerfile.DS001.is_alias ( matched 1 rule, early exit ) TRACE | | | | Enter data.builtin.dockerfile.DS001.is_alias TRACE | | | | | Eval img = data.builtin.dockerfile.DS001.get_aliases [ _ ] TRACE | | | | | Index data.builtin.dockerfile.DS001.get_aliases ( matched 1 rule ) TRACE | | | | | Enter data.builtin.dockerfile.DS001.get_aliases TRACE | | | | | | Eval from_cmd = data.lib.docker.from [ _ ] TRACE | | | | | | Index data.lib.docker.from ( matched 1 rule ) TRACE | | | | | | Eval __local749__ = from_cmd.Value TRACE | | | | | | Eval data.builtin.dockerfile.DS001.get_alias ( __local749__, __local503__ ) TRACE | | | | | | Index data.builtin.dockerfile.DS001.get_alias ( matched 1 rule ) TRACE | | | | | | Enter data.builtin.dockerfile.DS001.get_alias TRACE | | | | | | | Eval __local748__ = values [ i ] TRACE | | | | | | | Eval lower ( __local748__, __local501__ ) TRACE | | | | | | | Eval \"as\" = __local501__ TRACE | | | | | | | Fail \"as\" = __local501__ TRACE | | | | | | | Redo lower ( __local748__, __local501__ ) TRACE | | | | | | | Redo __local748__ = values [ i ] TRACE | | | | | | Fail data.builtin.dockerfile.DS001.get_alias ( __local749__, __local503__ ) TRACE | | | | | | Redo __local749__ = from_cmd.Value TRACE | | | | | | Redo from_cmd = data.lib.docker.from [ _ ] TRACE | | | | | Fail img = data.builtin.dockerfile.DS001.get_aliases [ _ ] TRACE | | | | Fail data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | Eval output.tag = \"latest\" TRACE | | | Exit data.builtin.dockerfile.DS001.fail_latest TRACE | | Redo data.builtin.dockerfile.DS001.fail_latest TRACE | | | Redo output.tag = \"latest\" TRACE | | | Redo __local753__ = output.img TRACE | | | Redo neq ( __local752__, \"scratch\" ) TRACE | | | Redo __local752__ = output.img TRACE | | | Redo output = data.builtin.dockerfile.DS001.image_tags [ _ ] TRACE | | Eval __local754__ = output.img TRACE | | Eval sprintf ( \"Specify a tag in the 'FROM' statement for image '%s'\" , [ __local754__ ] , __local509__ ) TRACE | | Eval msg = __local509__ TRACE | | Eval __local755__ = output.cmd TRACE | | Eval data.lib.docker.result ( msg, __local755__, __local510__ ) TRACE | | Index data.lib.docker.result ( matched 1 rule ) TRACE | | Enter data.lib.docker.result TRACE | | | Eval object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | | Eval object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Eval object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Eval result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Exit data.lib.docker.result TRACE | | Eval res = __local510__ TRACE | | Exit data.builtin.dockerfile.DS001.deny TRACE | Redo data.builtin.dockerfile.DS001.deny TRACE | | Redo res = __local510__ TRACE | | Redo data.lib.docker.result ( msg, __local755__, __local510__ ) TRACE | | Redo data.lib.docker.result TRACE | | | Redo result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Redo object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Redo object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Redo object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | Redo __local755__ = output.cmd TRACE | | Redo msg = __local509__ TRACE | | Redo sprintf ( \"Specify a tag in the 'FROM' statement for image '%s'\" , [ __local754__ ] , __local509__ ) TRACE | | Redo __local754__ = output.img TRACE | | Redo output = data.builtin.dockerfile.DS001.fail_latest [ _ ] TRACE | Exit data.builtin.dockerfile.DS001.deny = _ TRACE Redo data.builtin.dockerfile.DS001.deny = _ TRACE | Redo data.builtin.dockerfile.DS001.deny = _ TRACE ID: DS002 File: Dockerfile Namespace: builtin.dockerfile.DS002 Query: data.builtin.dockerfile.DS002.deny Message: Last USER command in Dockerfile should not be 'root' TRACE Enter data.builtin.dockerfile.DS002.deny = _ TRACE | Eval data.builtin.dockerfile.DS002.deny = _ TRACE | Index data.builtin.dockerfile.DS002.deny ( matched 2 rules ) TRACE | Enter data.builtin.dockerfile.DS002.deny TRACE | | Eval data.builtin.dockerfile.DS002.fail_user_count TRACE | | Index data.builtin.dockerfile.DS002.fail_user_count ( matched 1 rule, early exit ) TRACE | | Enter data.builtin.dockerfile.DS002.fail_user_count TRACE | | | Eval __local771__ = data.builtin.dockerfile.DS002.get_user TRACE | | | Index data.builtin.dockerfile.DS002.get_user ( matched 1 rule ) TRACE | | | Enter data.builtin.dockerfile.DS002.get_user TRACE | | | | Eval user = data.lib.docker.user [ _ ] TRACE | | | | Index data.lib.docker.user ( matched 1 rule ) TRACE | | | | Enter data.lib.docker.user TRACE | | | | | Eval instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"user\" TRACE | | | | | Fail instruction.Cmd = \"user\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"user\" TRACE | | | | | Exit data.lib.docker.user TRACE | | | | Redo data.lib.docker.user TRACE | | | | | Redo instruction.Cmd = \"user\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"user\" TRACE | | | | | Fail instruction.Cmd = \"user\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | Eval username = user.Value [ _ ] TRACE | | | | Exit data.builtin.dockerfile.DS002.get_user TRACE | | | Redo data.builtin.dockerfile.DS002.get_user TRACE | | | | Redo username = user.Value [ _ ] TRACE | | | | Redo user = data.lib.docker.user [ _ ] TRACE | | | Eval count ( __local771__, __local536__ ) TRACE | | | Eval lt ( __local536__, 1 ) TRACE | | | Fail lt ( __local536__, 1 ) TRACE | | | Redo count ( __local771__, __local536__ ) TRACE | | | Redo __local771__ = data.builtin.dockerfile.DS002.get_user TRACE | | Fail data.builtin.dockerfile.DS002.fail_user_count TRACE | Enter data.builtin.dockerfile.DS002.deny TRACE | | Eval cmd = data.builtin.dockerfile.DS002.fail_last_user_root [ _ ] TRACE | | Index data.builtin.dockerfile.DS002.fail_last_user_root ( matched 1 rule ) TRACE | | Enter data.builtin.dockerfile.DS002.fail_last_user_root TRACE | | | Eval stage_users = data.lib.docker.stage_user [ _ ] TRACE | | | Index data.lib.docker.stage_user ( matched 1 rule ) TRACE | | | Enter data.lib.docker.stage_user TRACE | | | | Eval stage = input.stages [ stage_name ] TRACE | | | | Eval users = [ cmd | cmd = stage [ _ ] ; cmd.Cmd = \"user\" ] TRACE | | | | Enter cmd = stage [ _ ] ; cmd.Cmd = \"user\" TRACE | | | | | Eval cmd = stage [ _ ] TRACE | | | | | Eval cmd.Cmd = \"user\" TRACE | | | | | Fail cmd.Cmd = \"user\" TRACE | | | | | Redo cmd = stage [ _ ] TRACE | | | | | Eval cmd.Cmd = \"user\" TRACE | | | | | Exit cmd = stage [ _ ] ; cmd.Cmd = \"user\" TRACE | | | | Redo cmd = stage [ _ ] ; cmd.Cmd = \"user\" TRACE | | | | | Redo cmd.Cmd = \"user\" TRACE | | | | | Redo cmd = stage [ _ ] TRACE | | | | | Eval cmd.Cmd = \"user\" TRACE | | | | | Fail cmd.Cmd = \"user\" TRACE | | | | | Redo cmd = stage [ _ ] TRACE | | | | Exit data.lib.docker.stage_user TRACE | | | Redo data.lib.docker.stage_user TRACE | | | | Redo users = [ cmd | cmd = stage [ _ ] ; cmd.Cmd = \"user\" ] TRACE | | | | Redo stage = input.stages [ stage_name ] TRACE | | | Eval count ( stage_users, __local537__ ) TRACE | | | Eval len = __local537__ TRACE | | | Eval minus ( len, 1 , __local538__ ) TRACE | | | Eval last = stage_users [ __local538__ ] TRACE | | | Eval user = last.Value [ 0 ] TRACE | | | Eval user = \"root\" TRACE | | | Exit data.builtin.dockerfile.DS002.fail_last_user_root TRACE | | Redo data.builtin.dockerfile.DS002.fail_last_user_root TRACE | | | Redo user = \"root\" TRACE | | | Redo user = last.Value [ 0 ] TRACE | | | Redo last = stage_users [ __local538__ ] TRACE | | | Redo minus ( len, 1 , __local538__ ) TRACE | | | Redo len = __local537__ TRACE | | | Redo count ( stage_users, __local537__ ) TRACE | | | Redo stage_users = data.lib.docker.stage_user [ _ ] TRACE | | Eval msg = \"Last USER command in Dockerfile should not be 'root'\" TRACE | | Eval data.lib.docker.result ( msg, cmd, __local540__ ) TRACE | | Index data.lib.docker.result ( matched 1 rule ) TRACE | | Enter data.lib.docker.result TRACE | | | Eval object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | | Eval object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Eval object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Eval result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Exit data.lib.docker.result TRACE | | Eval res = __local540__ TRACE | | Exit data.builtin.dockerfile.DS002.deny TRACE | Redo data.builtin.dockerfile.DS002.deny TRACE | | Redo res = __local540__ TRACE | | Redo data.lib.docker.result ( msg, cmd, __local540__ ) TRACE | | Redo data.lib.docker.result TRACE | | | Redo result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Redo object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Redo object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Redo object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | Redo msg = \"Last USER command in Dockerfile should not be 'root'\" TRACE | | Redo cmd = data.builtin.dockerfile.DS002.fail_last_user_root [ _ ] TRACE | Exit data.builtin.dockerfile.DS002.deny = _ TRACE Redo data.builtin.dockerfile.DS002.deny = _ TRACE | Redo data.builtin.dockerfile.DS002.deny = _ TRACE","title":"Debugging Policies"},{"location":"docs/scanner/misconfiguration/custom/debug/#debugging-policies","text":"When working on more complex queries (or when learning Rego), it's useful to see exactly how the policy is applied. For this purpose you can use the --trace flag. This will output a large trace from Open Policy Agent like the following: Tip Only failed policies show traces. If you want to debug a passed policy, you need to make it fail on purpose. $ trivy conf --trace configs/ 2022 -05-16T13:47:58.853+0100 INFO Detected config files: 1 Dockerfile ( dockerfile ) ======================= Tests: 23 ( SUCCESSES: 21 , FAILURES: 2 , EXCEPTIONS: 0 ) Failures: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 1 , HIGH: 1 , CRITICAL: 0 ) MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated. See https://avd.aquasec.com/misconfig/ds001 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 [ FROM alpine:latest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 HIGH: Last USER command in Dockerfile should not be 'root' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Dockerfile:3 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 3 [ USER root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 ID: DS001 File: Dockerfile Namespace: builtin.dockerfile.DS001 Query: data.builtin.dockerfile.DS001.deny Message: Specify a tag in the 'FROM' statement for image 'alpine' TRACE Enter data.builtin.dockerfile.DS001.deny = _ TRACE | Eval data.builtin.dockerfile.DS001.deny = _ TRACE | Index data.builtin.dockerfile.DS001.deny ( matched 1 rule ) TRACE | Enter data.builtin.dockerfile.DS001.deny TRACE | | Eval output = data.builtin.dockerfile.DS001.fail_latest [ _ ] TRACE | | Index data.builtin.dockerfile.DS001.fail_latest ( matched 1 rule ) TRACE | | Enter data.builtin.dockerfile.DS001.fail_latest TRACE | | | Eval output = data.builtin.dockerfile.DS001.image_tags [ _ ] TRACE | | | Index data.builtin.dockerfile.DS001.image_tags ( matched 2 rules ) TRACE | | | Enter data.builtin.dockerfile.DS001.image_tags TRACE | | | | Eval from = data.lib.docker.from [ _ ] TRACE | | | | Index data.lib.docker.from ( matched 1 rule ) TRACE | | | | Enter data.lib.docker.from TRACE | | | | | Eval instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"from\" TRACE | | | | | Exit data.lib.docker.from TRACE | | | | Redo data.lib.docker.from TRACE | | | | | Redo instruction.Cmd = \"from\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"from\" TRACE | | | | | Fail instruction.Cmd = \"from\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"from\" TRACE | | | | | Fail instruction.Cmd = \"from\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | Eval name = from.Value [ 0 ] TRACE | | | | Eval not startswith ( name, \" $ \" ) TRACE | | | | Enter startswith ( name, \" $ \" ) TRACE | | | | | Eval startswith ( name, \" $ \" ) TRACE | | | | | Fail startswith ( name, \" $ \" ) TRACE | | | | Eval data.builtin.dockerfile.DS001.parse_tag ( name, __local505__ ) TRACE | | | | Index data.builtin.dockerfile.DS001.parse_tag ( matched 2 rules ) TRACE | | | | Enter data.builtin.dockerfile.DS001.parse_tag TRACE | | | | | Eval split ( name, \":\" , __local504__ ) TRACE | | | | | Eval [ img, tag ] = __local504__ TRACE | | | | | Exit data.builtin.dockerfile.DS001.parse_tag TRACE | | | | Eval [ img, tag ] = __local505__ TRACE | | | | Eval output = { \"cmd\" : from, \"img\" : img, \"tag\" : tag } TRACE | | | | Exit data.builtin.dockerfile.DS001.image_tags TRACE | | | Redo data.builtin.dockerfile.DS001.image_tags TRACE | | | | Redo output = { \"cmd\" : from, \"img\" : img, \"tag\" : tag } TRACE | | | | Redo [ img, tag ] = __local505__ TRACE | | | | Redo data.builtin.dockerfile.DS001.parse_tag ( name, __local505__ ) TRACE | | | | Redo data.builtin.dockerfile.DS001.parse_tag TRACE | | | | | Redo [ img, tag ] = __local504__ TRACE | | | | | Redo split ( name, \":\" , __local504__ ) TRACE | | | | Enter data.builtin.dockerfile.DS001.parse_tag TRACE | | | | | Eval tag = \"latest\" TRACE | | | | | Eval not contains ( img, \":\" ) TRACE | | | | | Enter contains ( img, \":\" ) TRACE | | | | | | Eval contains ( img, \":\" ) TRACE | | | | | | Exit contains ( img, \":\" ) TRACE | | | | | Redo contains ( img, \":\" ) TRACE | | | | | | Redo contains ( img, \":\" ) TRACE | | | | | Fail not contains ( img, \":\" ) TRACE | | | | | Redo tag = \"latest\" TRACE | | | | Redo name = from.Value [ 0 ] TRACE | | | | Redo from = data.lib.docker.from [ _ ] TRACE | | | Enter data.builtin.dockerfile.DS001.image_tags TRACE | | | | Eval from = data.lib.docker.from [ i ] TRACE | | | | Index data.lib.docker.from ( matched 1 rule ) TRACE | | | | Eval name = from.Value [ 0 ] TRACE | | | | Eval cmd_obj = input.stages [ j ][ k ] TRACE | | | | Eval possibilities = { \"arg\" , \"env\" } TRACE | | | | Eval cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Fail cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Redo possibilities = { \"arg\" , \"env\" } TRACE | | | | Redo cmd_obj = input.stages [ j ][ k ] TRACE | | | | Eval possibilities = { \"arg\" , \"env\" } TRACE | | | | Eval cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Fail cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Redo possibilities = { \"arg\" , \"env\" } TRACE | | | | Redo cmd_obj = input.stages [ j ][ k ] TRACE | | | | Eval possibilities = { \"arg\" , \"env\" } TRACE | | | | Eval cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Fail cmd_obj.Cmd = possibilities [ l ] TRACE | | | | Redo possibilities = { \"arg\" , \"env\" } TRACE | | | | Redo cmd_obj = input.stages [ j ][ k ] TRACE | | | | Redo name = from.Value [ 0 ] TRACE | | | | Redo from = data.lib.docker.from [ i ] TRACE | | | Eval __local752__ = output.img TRACE | | | Eval neq ( __local752__, \"scratch\" ) TRACE | | | Eval __local753__ = output.img TRACE | | | Eval not data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | Enter data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | | Eval data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | | Index data.builtin.dockerfile.DS001.is_alias ( matched 1 rule, early exit ) TRACE | | | | Enter data.builtin.dockerfile.DS001.is_alias TRACE | | | | | Eval img = data.builtin.dockerfile.DS001.get_aliases [ _ ] TRACE | | | | | Index data.builtin.dockerfile.DS001.get_aliases ( matched 1 rule ) TRACE | | | | | Enter data.builtin.dockerfile.DS001.get_aliases TRACE | | | | | | Eval from_cmd = data.lib.docker.from [ _ ] TRACE | | | | | | Index data.lib.docker.from ( matched 1 rule ) TRACE | | | | | | Eval __local749__ = from_cmd.Value TRACE | | | | | | Eval data.builtin.dockerfile.DS001.get_alias ( __local749__, __local503__ ) TRACE | | | | | | Index data.builtin.dockerfile.DS001.get_alias ( matched 1 rule ) TRACE | | | | | | Enter data.builtin.dockerfile.DS001.get_alias TRACE | | | | | | | Eval __local748__ = values [ i ] TRACE | | | | | | | Eval lower ( __local748__, __local501__ ) TRACE | | | | | | | Eval \"as\" = __local501__ TRACE | | | | | | | Fail \"as\" = __local501__ TRACE | | | | | | | Redo lower ( __local748__, __local501__ ) TRACE | | | | | | | Redo __local748__ = values [ i ] TRACE | | | | | | Fail data.builtin.dockerfile.DS001.get_alias ( __local749__, __local503__ ) TRACE | | | | | | Redo __local749__ = from_cmd.Value TRACE | | | | | | Redo from_cmd = data.lib.docker.from [ _ ] TRACE | | | | | Fail img = data.builtin.dockerfile.DS001.get_aliases [ _ ] TRACE | | | | Fail data.builtin.dockerfile.DS001.is_alias ( __local753__ ) TRACE | | | Eval output.tag = \"latest\" TRACE | | | Exit data.builtin.dockerfile.DS001.fail_latest TRACE | | Redo data.builtin.dockerfile.DS001.fail_latest TRACE | | | Redo output.tag = \"latest\" TRACE | | | Redo __local753__ = output.img TRACE | | | Redo neq ( __local752__, \"scratch\" ) TRACE | | | Redo __local752__ = output.img TRACE | | | Redo output = data.builtin.dockerfile.DS001.image_tags [ _ ] TRACE | | Eval __local754__ = output.img TRACE | | Eval sprintf ( \"Specify a tag in the 'FROM' statement for image '%s'\" , [ __local754__ ] , __local509__ ) TRACE | | Eval msg = __local509__ TRACE | | Eval __local755__ = output.cmd TRACE | | Eval data.lib.docker.result ( msg, __local755__, __local510__ ) TRACE | | Index data.lib.docker.result ( matched 1 rule ) TRACE | | Enter data.lib.docker.result TRACE | | | Eval object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | | Eval object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Eval object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Eval result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Exit data.lib.docker.result TRACE | | Eval res = __local510__ TRACE | | Exit data.builtin.dockerfile.DS001.deny TRACE | Redo data.builtin.dockerfile.DS001.deny TRACE | | Redo res = __local510__ TRACE | | Redo data.lib.docker.result ( msg, __local755__, __local510__ ) TRACE | | Redo data.lib.docker.result TRACE | | | Redo result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Redo object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Redo object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Redo object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | Redo __local755__ = output.cmd TRACE | | Redo msg = __local509__ TRACE | | Redo sprintf ( \"Specify a tag in the 'FROM' statement for image '%s'\" , [ __local754__ ] , __local509__ ) TRACE | | Redo __local754__ = output.img TRACE | | Redo output = data.builtin.dockerfile.DS001.fail_latest [ _ ] TRACE | Exit data.builtin.dockerfile.DS001.deny = _ TRACE Redo data.builtin.dockerfile.DS001.deny = _ TRACE | Redo data.builtin.dockerfile.DS001.deny = _ TRACE ID: DS002 File: Dockerfile Namespace: builtin.dockerfile.DS002 Query: data.builtin.dockerfile.DS002.deny Message: Last USER command in Dockerfile should not be 'root' TRACE Enter data.builtin.dockerfile.DS002.deny = _ TRACE | Eval data.builtin.dockerfile.DS002.deny = _ TRACE | Index data.builtin.dockerfile.DS002.deny ( matched 2 rules ) TRACE | Enter data.builtin.dockerfile.DS002.deny TRACE | | Eval data.builtin.dockerfile.DS002.fail_user_count TRACE | | Index data.builtin.dockerfile.DS002.fail_user_count ( matched 1 rule, early exit ) TRACE | | Enter data.builtin.dockerfile.DS002.fail_user_count TRACE | | | Eval __local771__ = data.builtin.dockerfile.DS002.get_user TRACE | | | Index data.builtin.dockerfile.DS002.get_user ( matched 1 rule ) TRACE | | | Enter data.builtin.dockerfile.DS002.get_user TRACE | | | | Eval user = data.lib.docker.user [ _ ] TRACE | | | | Index data.lib.docker.user ( matched 1 rule ) TRACE | | | | Enter data.lib.docker.user TRACE | | | | | Eval instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"user\" TRACE | | | | | Fail instruction.Cmd = \"user\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"user\" TRACE | | | | | Exit data.lib.docker.user TRACE | | | | Redo data.lib.docker.user TRACE | | | | | Redo instruction.Cmd = \"user\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | | Eval instruction.Cmd = \"user\" TRACE | | | | | Fail instruction.Cmd = \"user\" TRACE | | | | | Redo instruction = input.stages [ _ ][ _ ] TRACE | | | | Eval username = user.Value [ _ ] TRACE | | | | Exit data.builtin.dockerfile.DS002.get_user TRACE | | | Redo data.builtin.dockerfile.DS002.get_user TRACE | | | | Redo username = user.Value [ _ ] TRACE | | | | Redo user = data.lib.docker.user [ _ ] TRACE | | | Eval count ( __local771__, __local536__ ) TRACE | | | Eval lt ( __local536__, 1 ) TRACE | | | Fail lt ( __local536__, 1 ) TRACE | | | Redo count ( __local771__, __local536__ ) TRACE | | | Redo __local771__ = data.builtin.dockerfile.DS002.get_user TRACE | | Fail data.builtin.dockerfile.DS002.fail_user_count TRACE | Enter data.builtin.dockerfile.DS002.deny TRACE | | Eval cmd = data.builtin.dockerfile.DS002.fail_last_user_root [ _ ] TRACE | | Index data.builtin.dockerfile.DS002.fail_last_user_root ( matched 1 rule ) TRACE | | Enter data.builtin.dockerfile.DS002.fail_last_user_root TRACE | | | Eval stage_users = data.lib.docker.stage_user [ _ ] TRACE | | | Index data.lib.docker.stage_user ( matched 1 rule ) TRACE | | | Enter data.lib.docker.stage_user TRACE | | | | Eval stage = input.stages [ stage_name ] TRACE | | | | Eval users = [ cmd | cmd = stage [ _ ] ; cmd.Cmd = \"user\" ] TRACE | | | | Enter cmd = stage [ _ ] ; cmd.Cmd = \"user\" TRACE | | | | | Eval cmd = stage [ _ ] TRACE | | | | | Eval cmd.Cmd = \"user\" TRACE | | | | | Fail cmd.Cmd = \"user\" TRACE | | | | | Redo cmd = stage [ _ ] TRACE | | | | | Eval cmd.Cmd = \"user\" TRACE | | | | | Exit cmd = stage [ _ ] ; cmd.Cmd = \"user\" TRACE | | | | Redo cmd = stage [ _ ] ; cmd.Cmd = \"user\" TRACE | | | | | Redo cmd.Cmd = \"user\" TRACE | | | | | Redo cmd = stage [ _ ] TRACE | | | | | Eval cmd.Cmd = \"user\" TRACE | | | | | Fail cmd.Cmd = \"user\" TRACE | | | | | Redo cmd = stage [ _ ] TRACE | | | | Exit data.lib.docker.stage_user TRACE | | | Redo data.lib.docker.stage_user TRACE | | | | Redo users = [ cmd | cmd = stage [ _ ] ; cmd.Cmd = \"user\" ] TRACE | | | | Redo stage = input.stages [ stage_name ] TRACE | | | Eval count ( stage_users, __local537__ ) TRACE | | | Eval len = __local537__ TRACE | | | Eval minus ( len, 1 , __local538__ ) TRACE | | | Eval last = stage_users [ __local538__ ] TRACE | | | Eval user = last.Value [ 0 ] TRACE | | | Eval user = \"root\" TRACE | | | Exit data.builtin.dockerfile.DS002.fail_last_user_root TRACE | | Redo data.builtin.dockerfile.DS002.fail_last_user_root TRACE | | | Redo user = \"root\" TRACE | | | Redo user = last.Value [ 0 ] TRACE | | | Redo last = stage_users [ __local538__ ] TRACE | | | Redo minus ( len, 1 , __local538__ ) TRACE | | | Redo len = __local537__ TRACE | | | Redo count ( stage_users, __local537__ ) TRACE | | | Redo stage_users = data.lib.docker.stage_user [ _ ] TRACE | | Eval msg = \"Last USER command in Dockerfile should not be 'root'\" TRACE | | Eval data.lib.docker.result ( msg, cmd, __local540__ ) TRACE | | Index data.lib.docker.result ( matched 1 rule ) TRACE | | Enter data.lib.docker.result TRACE | | | Eval object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | | Eval object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Eval object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Eval result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Exit data.lib.docker.result TRACE | | Eval res = __local540__ TRACE | | Exit data.builtin.dockerfile.DS002.deny TRACE | Redo data.builtin.dockerfile.DS002.deny TRACE | | Redo res = __local540__ TRACE | | Redo data.lib.docker.result ( msg, cmd, __local540__ ) TRACE | | Redo data.lib.docker.result TRACE | | | Redo result = { \"endline\" : __local470__, \"filepath\" : __local471__, \"msg\" : msg, \"startline\" : __local472__ } TRACE | | | Redo object.get ( cmd, \"StartLine\" , 0 , __local472__ ) TRACE | | | Redo object.get ( cmd, \"Path\" , \"\" , __local471__ ) TRACE | | | Redo object.get ( cmd, \"EndLine\" , 0 , __local470__ ) TRACE | | Redo msg = \"Last USER command in Dockerfile should not be 'root'\" TRACE | | Redo cmd = data.builtin.dockerfile.DS002.fail_last_user_root [ _ ] TRACE | Exit data.builtin.dockerfile.DS002.deny = _ TRACE Redo data.builtin.dockerfile.DS002.deny = _ TRACE | Redo data.builtin.dockerfile.DS002.deny = _ TRACE","title":"Debugging policies"},{"location":"docs/scanner/misconfiguration/custom/schema/","text":"Input Schema Overview Policies can be defined with custom schemas that allow inputs to be verified against them. Adding a policy schema enables Trivy to show more detailed error messages when an invalid input is encountered. In Trivy we have been able to define a schema for a Dockerfile . Without input schemas, a policy would be as follows: Example # METADATA package mypackage deny { input.evil == \"foo bar\" } If this policy is run against offending Dockerfile(s), there will not be any issues as the policy will fail to evaluate. Although the policy's failure to evaluate is legitimate, this should not result in a positive result for the scan. For instance if we have a policy that checks for misconfigurations in a Dockerfile , we could define the schema as such Example # METADATA # schemas: # - input: schema[\"dockerfile\"] package mypackage deny { input.evil == \"foo bar\" } Here input: schema[\"dockerfile\"] points to a schema that expects a valid Dockerfile as input. An example of this can be found here Now if this policy is evaluated against, a more descriptive error will be available to help fix the problem. 1 error occurred: testpolicy.rego:8: rego_type_error: undefined ref: input.evil input.evil ^ have: \"evil\" want ( one of ) : [ \"Stages\" ] Currently, out of the box the following schemas are supported natively: Docker Kubernetes Cloud Custom Policies with Custom Schemas You can also bring a custom policy that defines one or more custom schema. Example # METADATA # schemas: # - input: schema[\"fooschema\"] # - input: schema[\"barschema\"] package mypackage deny { input.evil == \"foo bar\" } The policies can be placed in a structure as follows Example /Users/user/my-custom-policies \u251c\u2500\u2500 my_policy.rego \u2514\u2500\u2500 schemas \u2514\u2500\u2500 fooschema.json \u2514\u2500\u2500 barschema.json To use such a policy with Trivy, use the --config-policy flag that points to the directory where the schemas and policies are contained. $ trivy --config-policy = /Users/user/my-custom-policies For more details on how to define schemas within Rego policies, please see the OPA guide that describes it in more detail.","title":"Schemas"},{"location":"docs/scanner/misconfiguration/custom/schema/#input-schema","text":"","title":"Input Schema"},{"location":"docs/scanner/misconfiguration/custom/schema/#overview","text":"Policies can be defined with custom schemas that allow inputs to be verified against them. Adding a policy schema enables Trivy to show more detailed error messages when an invalid input is encountered. In Trivy we have been able to define a schema for a Dockerfile . Without input schemas, a policy would be as follows: Example # METADATA package mypackage deny { input.evil == \"foo bar\" } If this policy is run against offending Dockerfile(s), there will not be any issues as the policy will fail to evaluate. Although the policy's failure to evaluate is legitimate, this should not result in a positive result for the scan. For instance if we have a policy that checks for misconfigurations in a Dockerfile , we could define the schema as such Example # METADATA # schemas: # - input: schema[\"dockerfile\"] package mypackage deny { input.evil == \"foo bar\" } Here input: schema[\"dockerfile\"] points to a schema that expects a valid Dockerfile as input. An example of this can be found here Now if this policy is evaluated against, a more descriptive error will be available to help fix the problem. 1 error occurred: testpolicy.rego:8: rego_type_error: undefined ref: input.evil input.evil ^ have: \"evil\" want ( one of ) : [ \"Stages\" ] Currently, out of the box the following schemas are supported natively: Docker Kubernetes Cloud","title":"Overview"},{"location":"docs/scanner/misconfiguration/custom/schema/#custom-policies-with-custom-schemas","text":"You can also bring a custom policy that defines one or more custom schema. Example # METADATA # schemas: # - input: schema[\"fooschema\"] # - input: schema[\"barschema\"] package mypackage deny { input.evil == \"foo bar\" } The policies can be placed in a structure as follows Example /Users/user/my-custom-policies \u251c\u2500\u2500 my_policy.rego \u2514\u2500\u2500 schemas \u2514\u2500\u2500 fooschema.json \u2514\u2500\u2500 barschema.json To use such a policy with Trivy, use the --config-policy flag that points to the directory where the schemas and policies are contained. $ trivy --config-policy = /Users/user/my-custom-policies For more details on how to define schemas within Rego policies, please see the OPA guide that describes it in more detail.","title":"Custom Policies with Custom Schemas"},{"location":"docs/scanner/misconfiguration/custom/selectors/","text":"Input Selectors Overview Sometimes you might want to limit a certain policy to only be run on certain resources. This can be achieved with input selectors. Use case For instance, if you have a custom policy that you only want to be evaluated if a certain resource type is being scanned. In such a case you could utilize input selectors to limit its evaluation on only those resources. Example # METADATA # title: \"RDS Publicly Accessible\" # description: \"Ensures RDS instances are not launched into the public cloud.\" # custom: # input: # selector: # - type: cloud # subtypes: # - provider: aws # service: rds package builtin.aws.rds.aws0999 deny[res] { instance := input.aws.rds.instances[_] instance.publicaccess.value res := result.new(\"Instance has Public Access enabled\", instance.publicaccess) Observe the following subtypes defined: # subtypes: # - provider: aws # service: rds They will ensure that the policy is only run when the input to such a policy contains an RDS instance. Enabling selectors and subtypes Currently, the following are supported: Selector Subtype fields required Example Cloud (AWS, Azure, etc.) provider , service provider: aws , service: rds Kubernetes type: kubernetes Dockerfile type: dockerfile Default behaviour If no subtypes or selectors are specified, the policy will be evaluated regardless of input.","title":"Selectors"},{"location":"docs/scanner/misconfiguration/custom/selectors/#input-selectors","text":"","title":"Input Selectors"},{"location":"docs/scanner/misconfiguration/custom/selectors/#overview","text":"Sometimes you might want to limit a certain policy to only be run on certain resources. This can be achieved with input selectors.","title":"Overview"},{"location":"docs/scanner/misconfiguration/custom/selectors/#use-case","text":"For instance, if you have a custom policy that you only want to be evaluated if a certain resource type is being scanned. In such a case you could utilize input selectors to limit its evaluation on only those resources. Example # METADATA # title: \"RDS Publicly Accessible\" # description: \"Ensures RDS instances are not launched into the public cloud.\" # custom: # input: # selector: # - type: cloud # subtypes: # - provider: aws # service: rds package builtin.aws.rds.aws0999 deny[res] { instance := input.aws.rds.instances[_] instance.publicaccess.value res := result.new(\"Instance has Public Access enabled\", instance.publicaccess) Observe the following subtypes defined: # subtypes: # - provider: aws # service: rds They will ensure that the policy is only run when the input to such a policy contains an RDS instance.","title":"Use case"},{"location":"docs/scanner/misconfiguration/custom/selectors/#enabling-selectors-and-subtypes","text":"Currently, the following are supported: Selector Subtype fields required Example Cloud (AWS, Azure, etc.) provider , service provider: aws , service: rds Kubernetes type: kubernetes Dockerfile type: dockerfile","title":"Enabling selectors and subtypes"},{"location":"docs/scanner/misconfiguration/custom/selectors/#default-behaviour","text":"If no subtypes or selectors are specified, the policy will be evaluated regardless of input.","title":"Default behaviour"},{"location":"docs/scanner/misconfiguration/custom/testing/","text":"Testing It is highly recommended to write tests for your custom policies. Rego testing To help you verify the correctness of your custom policies, OPA gives you a framework that you can use to write tests for your policies. By writing tests for your custom policies you can speed up the development process of new rules and reduce the amount of time it takes to modify rules as requirements evolve. For more details, see Policy Testing . Example package user.dockerfile.ID002 test_add_denied { r := deny with input as {\"stages\": {\"alpine:3.13\": [ {\"Cmd\": \"add\", \"Value\": [\"/target/resources.tar.gz\", \"resources.jar\"]}, {\"Cmd\": \"add\", \"Value\": [\"/target/app.jar\", \"app.jar\"]}, ]}} count(r) == 1 r[_] == \"Consider using 'COPY /target/app.jar app.jar' command instead of 'ADD /target/app.jar app.jar'\" } To write tests for custom policies, you can refer to existing tests under defsec . Go testing Fanal which is a core library of Trivy can be imported as a Go library. You can scan config files in Go and test your custom policies using Go's testing methods, such as table-driven tests . This allows you to use the actual configuration file as input, making it easy to prepare test data and ensure that your custom policies work in practice. In particular, Dockerfile and HCL need to be converted to structural data as input, which may be different from the expected input format. Tip We recommend writing OPA and Go tests both since they have different roles, like unit tests and integration tests. The following example stores allowed and denied configuration files in a directory. Successes contains the result of successes, and Failures contains the result of failures. { name : \"disallowed ports\" , input : \"configs/\" , fields : fields { policyPaths : [] string { \"policy\" }, dataPaths : [] string { \"data\" }, namespaces : [] string { \"user\" }, }, want : [] types . Misconfiguration { { FileType : types . Dockerfile , FilePath : \"Dockerfile.allowed\" , Successes : types . MisconfResults { { Namespace : \"user.dockerfile.ID002\" , PolicyMetadata : types . PolicyMetadata { ID : \"ID002\" , Type : \"Docker Custom Check\" , Title : \"Disallowed ports exposed\" , Severity : \"HIGH\" , }, }, }, }, { FileType : types . Dockerfile , FilePath : \"Dockerfile.denied\" , Failures : types . MisconfResults { { Namespace : \"user.dockerfile.ID002\" , Message : \"Port 23 should not be exposed\" , PolicyMetadata : types . PolicyMetadata { ID : \"ID002\" , Type : \"Docker Custom Check\" , Title : \"Disallowed ports exposed\" , Severity : \"HIGH\" , }, }, }, }, }, }, Dockerfile.allowed has one successful result in Successes , while Dockerfile.denied has one failure result in Failures .","title":"Testing"},{"location":"docs/scanner/misconfiguration/custom/testing/#testing","text":"It is highly recommended to write tests for your custom policies.","title":"Testing"},{"location":"docs/scanner/misconfiguration/custom/testing/#rego-testing","text":"To help you verify the correctness of your custom policies, OPA gives you a framework that you can use to write tests for your policies. By writing tests for your custom policies you can speed up the development process of new rules and reduce the amount of time it takes to modify rules as requirements evolve. For more details, see Policy Testing . Example package user.dockerfile.ID002 test_add_denied { r := deny with input as {\"stages\": {\"alpine:3.13\": [ {\"Cmd\": \"add\", \"Value\": [\"/target/resources.tar.gz\", \"resources.jar\"]}, {\"Cmd\": \"add\", \"Value\": [\"/target/app.jar\", \"app.jar\"]}, ]}} count(r) == 1 r[_] == \"Consider using 'COPY /target/app.jar app.jar' command instead of 'ADD /target/app.jar app.jar'\" } To write tests for custom policies, you can refer to existing tests under defsec .","title":"Rego testing"},{"location":"docs/scanner/misconfiguration/custom/testing/#go-testing","text":"Fanal which is a core library of Trivy can be imported as a Go library. You can scan config files in Go and test your custom policies using Go's testing methods, such as table-driven tests . This allows you to use the actual configuration file as input, making it easy to prepare test data and ensure that your custom policies work in practice. In particular, Dockerfile and HCL need to be converted to structural data as input, which may be different from the expected input format. Tip We recommend writing OPA and Go tests both since they have different roles, like unit tests and integration tests. The following example stores allowed and denied configuration files in a directory. Successes contains the result of successes, and Failures contains the result of failures. { name : \"disallowed ports\" , input : \"configs/\" , fields : fields { policyPaths : [] string { \"policy\" }, dataPaths : [] string { \"data\" }, namespaces : [] string { \"user\" }, }, want : [] types . Misconfiguration { { FileType : types . Dockerfile , FilePath : \"Dockerfile.allowed\" , Successes : types . MisconfResults { { Namespace : \"user.dockerfile.ID002\" , PolicyMetadata : types . PolicyMetadata { ID : \"ID002\" , Type : \"Docker Custom Check\" , Title : \"Disallowed ports exposed\" , Severity : \"HIGH\" , }, }, }, }, { FileType : types . Dockerfile , FilePath : \"Dockerfile.denied\" , Failures : types . MisconfResults { { Namespace : \"user.dockerfile.ID002\" , Message : \"Port 23 should not be exposed\" , PolicyMetadata : types . PolicyMetadata { ID : \"ID002\" , Type : \"Docker Custom Check\" , Title : \"Disallowed ports exposed\" , Severity : \"HIGH\" , }, }, }, }, }, }, Dockerfile.allowed has one successful result in Successes , while Dockerfile.denied has one failure result in Failures .","title":"Go testing"},{"location":"docs/scanner/misconfiguration/policy/builtin/","text":"Built-in Policies Policy Sources Built-in policies are mainly written in Rego and Go. Those policies are managed under defsec repository . Config type Source Kubernetes defsec Dockerfile, Containerfile defsec Terraform defsec CloudFormation defsec Azure ARM Template defsec Helm Chart defsec For suggestions or issues regarding policy content, please open an issue under the defsec repository. Helm Chart scanning will resolve the chart to Kubernetes manifests then run the kubernetes checks. Policy Distribution defsec policies are distributed as an OPA bundle on GitHub Container Registry (GHCR). When misconfiguration detection is enabled, Trivy pulls the OPA bundle from GHCR as an OCI artifact and stores it in the cache. Those policies are then loaded into Trivy OPA engine and used for detecting misconfigurations. If Trivy is unable to pull down newer policies, it will use the embedded set of policies as a fallback. This is also the case in air-gap environments where --skip-policy-update might be passed. Update Interval Trivy checks for updates to OPA bundle on GHCR every 24 hours and pulls it if there are any updates.","title":"Built-in Policies"},{"location":"docs/scanner/misconfiguration/policy/builtin/#built-in-policies","text":"","title":"Built-in Policies"},{"location":"docs/scanner/misconfiguration/policy/builtin/#policy-sources","text":"Built-in policies are mainly written in Rego and Go. Those policies are managed under defsec repository . Config type Source Kubernetes defsec Dockerfile, Containerfile defsec Terraform defsec CloudFormation defsec Azure ARM Template defsec Helm Chart defsec For suggestions or issues regarding policy content, please open an issue under the defsec repository. Helm Chart scanning will resolve the chart to Kubernetes manifests then run the kubernetes checks.","title":"Policy Sources"},{"location":"docs/scanner/misconfiguration/policy/builtin/#policy-distribution","text":"defsec policies are distributed as an OPA bundle on GitHub Container Registry (GHCR). When misconfiguration detection is enabled, Trivy pulls the OPA bundle from GHCR as an OCI artifact and stores it in the cache. Those policies are then loaded into Trivy OPA engine and used for detecting misconfigurations. If Trivy is unable to pull down newer policies, it will use the embedded set of policies as a fallback. This is also the case in air-gap environments where --skip-policy-update might be passed.","title":"Policy Distribution"},{"location":"docs/scanner/misconfiguration/policy/builtin/#update-interval","text":"Trivy checks for updates to OPA bundle on GHCR every 24 hours and pulls it if there are any updates.","title":"Update Interval"},{"location":"docs/scanner/misconfiguration/policy/exceptions/","text":"Exceptions Exceptions let you specify cases where you allow policy violations. Trivy supports two types of exceptions. Info Exceptions can be applied to built-in policies as well as custom policies. Namespace-based exceptions There are some cases where you need to disable built-in policies partially or fully. Namespace-based exceptions lets you rough choose which individual packages to exempt. To use namespace-based exceptions, create a Rego rule with the name exception that returns the package names to exempt. The exception rule must be defined under namespace.exceptions . data.namespaces includes all package names. Example package namespace.exceptions import data.namespaces exception[ns] { ns := data.namespaces[_] startswith(ns, \"builtin.kubernetes\") } This example exempts all built-in policies for Kubernetes. For more details, see an example . Rule-based exceptions There are some cases where you need more flexibility and granularity in defining which cases to exempt. Rule-based exceptions lets you granularly choose which individual rules to exempt, while also declaring under which conditions to exempt them. To use rule-based exceptions, create a Rego rule with the name exception that returns the rule name suffixes to exempt, prefixed by deny_ (for example, returning foo will exempt deny_foo ). The rule can make any other assertion, for example, on the input or data documents. This is useful to specify the exemption for a specific case. Note that if you specify the empty string, the exception will match all rules named deny . exception[rules] { # Logic rules = [\"foo\",\"bar\"] } The above would provide an exception from deny_foo and deny_bar . Example package user.kubernetes.ID100 __rego_metadata := { \"id\": \"ID100\", \"title\": \"Deployment not allowed\", \"severity\": \"HIGH\", \"type\": \"Kubernetes Custom Check\", } deny_deployment[msg] { input.kind == \"Deployment\" msg = sprintf(\"Found deployment '%s' but deployments are not allowed\", [name]) } exception[rules] { input.kind == \"Deployment\" input.metadata.name == \"allow-deployment\" rules := [\"deployment\"] } If you want to apply rule-based exceptions to built-in policies, you have to define the exception under the same package. Example package builtin.kubernetes.KSV012 exception[rules] { input.metadata.name == \"can-run-as-root\" rules := [\"\"] } This exception is applied to KSV012 in defsec. You can get the package names in the defsec repository or the JSON output from Trivy. For more details, see an example .","title":"Exceptions"},{"location":"docs/scanner/misconfiguration/policy/exceptions/#exceptions","text":"Exceptions let you specify cases where you allow policy violations. Trivy supports two types of exceptions. Info Exceptions can be applied to built-in policies as well as custom policies.","title":"Exceptions"},{"location":"docs/scanner/misconfiguration/policy/exceptions/#namespace-based-exceptions","text":"There are some cases where you need to disable built-in policies partially or fully. Namespace-based exceptions lets you rough choose which individual packages to exempt. To use namespace-based exceptions, create a Rego rule with the name exception that returns the package names to exempt. The exception rule must be defined under namespace.exceptions . data.namespaces includes all package names. Example package namespace.exceptions import data.namespaces exception[ns] { ns := data.namespaces[_] startswith(ns, \"builtin.kubernetes\") } This example exempts all built-in policies for Kubernetes. For more details, see an example .","title":"Namespace-based exceptions"},{"location":"docs/scanner/misconfiguration/policy/exceptions/#rule-based-exceptions","text":"There are some cases where you need more flexibility and granularity in defining which cases to exempt. Rule-based exceptions lets you granularly choose which individual rules to exempt, while also declaring under which conditions to exempt them. To use rule-based exceptions, create a Rego rule with the name exception that returns the rule name suffixes to exempt, prefixed by deny_ (for example, returning foo will exempt deny_foo ). The rule can make any other assertion, for example, on the input or data documents. This is useful to specify the exemption for a specific case. Note that if you specify the empty string, the exception will match all rules named deny . exception[rules] { # Logic rules = [\"foo\",\"bar\"] } The above would provide an exception from deny_foo and deny_bar . Example package user.kubernetes.ID100 __rego_metadata := { \"id\": \"ID100\", \"title\": \"Deployment not allowed\", \"severity\": \"HIGH\", \"type\": \"Kubernetes Custom Check\", } deny_deployment[msg] { input.kind == \"Deployment\" msg = sprintf(\"Found deployment '%s' but deployments are not allowed\", [name]) } exception[rules] { input.kind == \"Deployment\" input.metadata.name == \"allow-deployment\" rules := [\"deployment\"] } If you want to apply rule-based exceptions to built-in policies, you have to define the exception under the same package. Example package builtin.kubernetes.KSV012 exception[rules] { input.metadata.name == \"can-run-as-root\" rules := [\"\"] } This exception is applied to KSV012 in defsec. You can get the package names in the defsec repository or the JSON output from Trivy. For more details, see an example .","title":"Rule-based exceptions"},{"location":"docs/scanner/vulnerability/","text":"Vulnerability Scanning Overview This section describes the overview of vulnerability scanning. Trivy detects known vulnerabilities according to the versions of installed packages. The following packages are supported. OS packages Language-specific packages Trivy downloads the vulnerabillity database every 6 hours. Database Trivy uses two types of databases for vulnerability detection: Vulnerability Database Java Index Database This page provides detailed information about these databases. Vulnerability Database Trivy utilizes a database containing vulnerability information. This database is built every six hours on GitHub and is distributed via GitHub Container registry (GHCR) . The database is cached and updated as needed. As Trivy updates the database automatically during execution, users don't need to be concerned about it. For CLI flags related to the database, please refer to this page . Private Hosting If you host the database on your own OCI registry, you can specify a different repository with the --db-repository flag. The default is ghcr.io/aquasecurity/trivy-db . $ trivy image --db-repository YOUR_REPO YOUR_IMAGE If authentication is required, it can be configured in the same way as for private images. Please refer to the documentation for more details. Java Index Database This database is only downloaded when scanning JAR files so that Trivy can identify the groupId, artifactId, and version of JAR files. It is built once a day on GitHub and distributed via GitHub Container registry (GHCR) . Like the vulnerability database, it is automatically downloaded and updated when needed, so users don't need to worry about it. Private Hosting If you host the database on your own OCI registry, you can specify a different repository with the --java-db-repository flag. The default is ghcr.io/aquasecurity/trivy-java-db . If authentication is required, you need to run docker login YOUR_REGISTRY . Currently, specifying a username and password is not supported.","title":"Overview"},{"location":"docs/scanner/vulnerability/#vulnerability-scanning","text":"","title":"Vulnerability Scanning"},{"location":"docs/scanner/vulnerability/#overview","text":"This section describes the overview of vulnerability scanning. Trivy detects known vulnerabilities according to the versions of installed packages. The following packages are supported. OS packages Language-specific packages Trivy downloads the vulnerabillity database every 6 hours.","title":"Overview"},{"location":"docs/scanner/vulnerability/#database","text":"Trivy uses two types of databases for vulnerability detection: Vulnerability Database Java Index Database This page provides detailed information about these databases.","title":"Database"},{"location":"docs/scanner/vulnerability/#vulnerability-database","text":"Trivy utilizes a database containing vulnerability information. This database is built every six hours on GitHub and is distributed via GitHub Container registry (GHCR) . The database is cached and updated as needed. As Trivy updates the database automatically during execution, users don't need to be concerned about it. For CLI flags related to the database, please refer to this page .","title":"Vulnerability Database"},{"location":"docs/scanner/vulnerability/#private-hosting","text":"If you host the database on your own OCI registry, you can specify a different repository with the --db-repository flag. The default is ghcr.io/aquasecurity/trivy-db . $ trivy image --db-repository YOUR_REPO YOUR_IMAGE If authentication is required, it can be configured in the same way as for private images. Please refer to the documentation for more details.","title":"Private Hosting"},{"location":"docs/scanner/vulnerability/#java-index-database","text":"This database is only downloaded when scanning JAR files so that Trivy can identify the groupId, artifactId, and version of JAR files. It is built once a day on GitHub and distributed via GitHub Container registry (GHCR) . Like the vulnerability database, it is automatically downloaded and updated when needed, so users don't need to worry about it.","title":"Java Index Database"},{"location":"docs/scanner/vulnerability/#private-hosting_1","text":"If you host the database on your own OCI registry, you can specify a different repository with the --java-db-repository flag. The default is ghcr.io/aquasecurity/trivy-java-db . If authentication is required, you need to run docker login YOUR_REGISTRY . Currently, specifying a username and password is not supported.","title":"Private Hosting"},{"location":"docs/scanner/vulnerability/os/","text":"OS Packages Trivy is capable of automatically detecting installed OS packages when scanning container images, VM images and running hosts. This page provides an overview of OS packages in the context of Trivy scans. Supported OS The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution. To hide unfixed/unfixable vulnerabilities, you can use the --ignore-unfixed flag. Trivy doesn't support self-compiled packages/binaries, but official packages provided by vendors such as Red Hat and Debian. OS Supported Versions Target Packages Detection of unfixed vulnerabilities Alpine Linux 2.2 - 2.7, 3.0 - 3.18, edge Installed by apk NO Wolfi Linux (n/a) Installed by apk NO Chainguard (n/a) Installed by apk NO Red Hat Universal Base Image 1 7, 8, 9 Installed by yum/rpm YES Red Hat Enterprise Linux 6, 7, 8 Installed by yum/rpm YES CentOS 6, 7, 8 Installed by yum/rpm YES AlmaLinux 8, 9 Installed by yum/rpm NO Rocky Linux 8, 9 Installed by yum/rpm NO Oracle Linux 5, 6, 7, 8 Installed by yum/rpm NO CBL-Mariner 1.0, 2.0 Installed by yum/rpm YES Amazon Linux 1, 2, 2023 Installed by yum/rpm NO openSUSE Leap 42, 15 Installed by zypper/rpm NO SUSE Enterprise Linux 11, 12, 15 Installed by zypper/rpm NO Photon OS 1.0, 2.0, 3.0, 4.0 Installed by tdnf/yum/rpm NO Debian GNU/Linux wheezy, jessie, stretch, buster, bullseye Installed by apt/apt-get/dpkg YES Ubuntu All versions supported by Canonical Installed by apt/apt-get/dpkg YES Distroless 2 Any Installed by apt/apt-get/dpkg YES Data Sources OS Source Arch Linux Vulnerable Issues Alpine Linux secdb Wolfi Linux secdb Chainguard secdb Amazon Linux Amazon Linux Security Center Debian Security Bug Tracker OVAL Ubuntu Ubuntu CVE Tracker RHEL/CentOS OVAL Security Data AlmaLinux AlmaLinux Product Errata Rocky Linux Rocky Linux UpdateInfo Oracle Linux OVAL CBL-Mariner OVAL OpenSUSE/SLES CVRF Photon OS Photon Security Advisory Data source selection Trivy only consumes security advisories from the sources listed in the above table. As for packages installed from OS package managers ( dpkg , yum , apk , etc.), Trivy uses the advisory database from the appropriate OS vendor . For example: for a python package installed from yum (Amazon linux), Trivy will only get advisories from ALAS . But for a python package installed from another source (e.g. pip ), Trivy will get advisories from the GitLab and GitHub databases. This advisory selection is essential to avoid getting false positives because OS vendors usually backport upstream fixes, and the fixed version can be different from the upstream fixed version. The severity is from the selected data source. If the data source does not provide severity, it falls back to NVD , and if NVD does not have severity, it will be UNKNOWN. Distributions CBL-Mariner Trivy scans CBL-Mariner . Support The following table provides an outline of the features Trivy offers. Version Container image Virtual machine Distroless Multi-arch Unfixed support 1.0 \u2714 \u2714 \u2714 amd64, arm64 \u2714 2.0 \u2714 \u2714 \u2714 amd64, arm64 \u2714 Examples image rootfs \u279c trivy image mcr.microsoft.com/cbl-mariner/base/core:2.0 2022-07-27T14:48:20.355+0600 INFO Detected OS: cbl-mariner 2022-07-27T14:48:20.355+0600 INFO Detecting CBL-Mariner vulnerabilities... 2022-07-27T14:48:20.356+0600 INFO Number of language-specific files: 0 mcr.microsoft.com/cbl-mariner/base/core:2.0 (cbl-mariner 2.0.20220527) Total: 33 (UNKNOWN: 0, LOW: 0, MEDIUM: 15, HIGH: 13, CRITICAL: 5) \u279c docker run -it --rm --entrypoint bin/bash mcr.microsoft.com/cbl-mariner/base/core:2.0 root [ / ]# tdnf -y install ca-certificates root [ / ]# # Install the latest Trivy root [ / ]# trivy rootfs / 2022-07-27T09:30:06.815Z INFO Need to update DB 2022-07-27T09:30:06.815Z INFO DB Repository: ghcr.io/aquasecurity/trivy-db 2022-07-27T09:30:06.815Z INFO Downloading DB... 33.25 MiB / 33.25 MiB [------------------------------] 100.00% 4.20 MiB p/s 8.1s 2022-07-27T09:30:21.756Z INFO Vulnerability scanning is enabled 2022-07-27T09:30:21.756Z INFO Secret scanning is enabled 2022-07-27T09:30:21.756Z INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning 2022-07-27T09:30:21.756Z INFO Please see also https://aquasecurity.github.io/trivy/v0.30.4/docs/secret/scanning/#recommendation for faster secret detection 2022-07-27T09:30:22.205Z INFO Detected OS: cbl-mariner 2022-07-27T09:30:22.205Z INFO Detecting CBL-Mariner vulnerabilities... 2022-07-27T09:30:22.205Z INFO Number of language-specific files: 0 40ba9a55397c (cbl-mariner 2.0.20220527) ======================================= Total: 33 (UNKNOWN: 0, LOW: 0, MEDIUM: 15, HIGH: 13, CRITICAL: 5) https://developers.redhat.com/products/rhel/ubi \u21a9 https://github.com/GoogleContainerTools/distroless \u21a9","title":"OS Packages"},{"location":"docs/scanner/vulnerability/os/#os-packages","text":"Trivy is capable of automatically detecting installed OS packages when scanning container images, VM images and running hosts. This page provides an overview of OS packages in the context of Trivy scans.","title":"OS Packages"},{"location":"docs/scanner/vulnerability/os/#supported-os","text":"The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution. To hide unfixed/unfixable vulnerabilities, you can use the --ignore-unfixed flag. Trivy doesn't support self-compiled packages/binaries, but official packages provided by vendors such as Red Hat and Debian. OS Supported Versions Target Packages Detection of unfixed vulnerabilities Alpine Linux 2.2 - 2.7, 3.0 - 3.18, edge Installed by apk NO Wolfi Linux (n/a) Installed by apk NO Chainguard (n/a) Installed by apk NO Red Hat Universal Base Image 1 7, 8, 9 Installed by yum/rpm YES Red Hat Enterprise Linux 6, 7, 8 Installed by yum/rpm YES CentOS 6, 7, 8 Installed by yum/rpm YES AlmaLinux 8, 9 Installed by yum/rpm NO Rocky Linux 8, 9 Installed by yum/rpm NO Oracle Linux 5, 6, 7, 8 Installed by yum/rpm NO CBL-Mariner 1.0, 2.0 Installed by yum/rpm YES Amazon Linux 1, 2, 2023 Installed by yum/rpm NO openSUSE Leap 42, 15 Installed by zypper/rpm NO SUSE Enterprise Linux 11, 12, 15 Installed by zypper/rpm NO Photon OS 1.0, 2.0, 3.0, 4.0 Installed by tdnf/yum/rpm NO Debian GNU/Linux wheezy, jessie, stretch, buster, bullseye Installed by apt/apt-get/dpkg YES Ubuntu All versions supported by Canonical Installed by apt/apt-get/dpkg YES Distroless 2 Any Installed by apt/apt-get/dpkg YES","title":"Supported OS"},{"location":"docs/scanner/vulnerability/os/#data-sources","text":"OS Source Arch Linux Vulnerable Issues Alpine Linux secdb Wolfi Linux secdb Chainguard secdb Amazon Linux Amazon Linux Security Center Debian Security Bug Tracker OVAL Ubuntu Ubuntu CVE Tracker RHEL/CentOS OVAL Security Data AlmaLinux AlmaLinux Product Errata Rocky Linux Rocky Linux UpdateInfo Oracle Linux OVAL CBL-Mariner OVAL OpenSUSE/SLES CVRF Photon OS Photon Security Advisory","title":"Data Sources"},{"location":"docs/scanner/vulnerability/os/#data-source-selection","text":"Trivy only consumes security advisories from the sources listed in the above table. As for packages installed from OS package managers ( dpkg , yum , apk , etc.), Trivy uses the advisory database from the appropriate OS vendor . For example: for a python package installed from yum (Amazon linux), Trivy will only get advisories from ALAS . But for a python package installed from another source (e.g. pip ), Trivy will get advisories from the GitLab and GitHub databases. This advisory selection is essential to avoid getting false positives because OS vendors usually backport upstream fixes, and the fixed version can be different from the upstream fixed version. The severity is from the selected data source. If the data source does not provide severity, it falls back to NVD , and if NVD does not have severity, it will be UNKNOWN.","title":"Data source selection"},{"location":"docs/scanner/vulnerability/os/#distributions","text":"","title":"Distributions"},{"location":"docs/scanner/vulnerability/os/#cbl-mariner","text":"Trivy scans CBL-Mariner .","title":"CBL-Mariner"},{"location":"docs/scanner/vulnerability/os/#support","text":"The following table provides an outline of the features Trivy offers. Version Container image Virtual machine Distroless Multi-arch Unfixed support 1.0 \u2714 \u2714 \u2714 amd64, arm64 \u2714 2.0 \u2714 \u2714 \u2714 amd64, arm64 \u2714","title":"Support"},{"location":"docs/scanner/vulnerability/os/#examples","text":"image rootfs \u279c trivy image mcr.microsoft.com/cbl-mariner/base/core:2.0 2022-07-27T14:48:20.355+0600 INFO Detected OS: cbl-mariner 2022-07-27T14:48:20.355+0600 INFO Detecting CBL-Mariner vulnerabilities... 2022-07-27T14:48:20.356+0600 INFO Number of language-specific files: 0 mcr.microsoft.com/cbl-mariner/base/core:2.0 (cbl-mariner 2.0.20220527) Total: 33 (UNKNOWN: 0, LOW: 0, MEDIUM: 15, HIGH: 13, CRITICAL: 5) \u279c docker run -it --rm --entrypoint bin/bash mcr.microsoft.com/cbl-mariner/base/core:2.0 root [ / ]# tdnf -y install ca-certificates root [ / ]# # Install the latest Trivy root [ / ]# trivy rootfs / 2022-07-27T09:30:06.815Z INFO Need to update DB 2022-07-27T09:30:06.815Z INFO DB Repository: ghcr.io/aquasecurity/trivy-db 2022-07-27T09:30:06.815Z INFO Downloading DB... 33.25 MiB / 33.25 MiB [------------------------------] 100.00% 4.20 MiB p/s 8.1s 2022-07-27T09:30:21.756Z INFO Vulnerability scanning is enabled 2022-07-27T09:30:21.756Z INFO Secret scanning is enabled 2022-07-27T09:30:21.756Z INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning 2022-07-27T09:30:21.756Z INFO Please see also https://aquasecurity.github.io/trivy/v0.30.4/docs/secret/scanning/#recommendation for faster secret detection 2022-07-27T09:30:22.205Z INFO Detected OS: cbl-mariner 2022-07-27T09:30:22.205Z INFO Detecting CBL-Mariner vulnerabilities... 2022-07-27T09:30:22.205Z INFO Number of language-specific files: 0 40ba9a55397c (cbl-mariner 2.0.20220527) ======================================= Total: 33 (UNKNOWN: 0, LOW: 0, MEDIUM: 15, HIGH: 13, CRITICAL: 5) https://developers.redhat.com/products/rhel/ubi \u21a9 https://github.com/GoogleContainerTools/distroless \u21a9","title":"Examples"},{"location":"docs/scanner/vulnerability/language/","text":"Language-specific Packages Trivy automatically detects the following files and scans vulnerabilities in the application dependencies. Supported languages Language File Image 7 Rootfs 8 Filesystem 9 Repository 10 Dev dependencies Dependency location 11 Ruby Gemfile.lock - - \u2705 \u2705 included - gemspec \u2705 \u2705 - - included - Python Pipfile.lock - - \u2705 \u2705 excluded \u2705 poetry.lock - - \u2705 \u2705 excluded - requirements.txt - - \u2705 \u2705 included - egg package 1 \u2705 \u2705 - - excluded - wheel package 2 \u2705 \u2705 - - excluded - PHP composer.lock \u2705 \u2705 \u2705 \u2705 excluded \u2705 Node.js package-lock.json - - \u2705 \u2705 excluded \u2705 yarn.lock - - \u2705 \u2705 included \u2705 pnpm-lock.yaml - - \u2705 \u2705 excluded - package.json \u2705 \u2705 - - excluded - .NET packages.lock.json \u2705 \u2705 \u2705 \u2705 included \u2705 packages.config \u2705 \u2705 \u2705 \u2705 excluded - .deps.json \u2705 \u2705 \u2705 \u2705 excluded \u2705 Java JAR/WAR/PAR/EAR 3 \u2705 \u2705 - - included - pom.xml 4 - - \u2705 \u2705 excluded - *gradle.lockfile - - \u2705 \u2705 excluded - Go Binaries built by Go 5 \u2705 \u2705 - - excluded - go.mod 6 - - \u2705 \u2705 included - Rust Cargo.lock \u2705 \u2705 \u2705 \u2705 excluded \u2705 Binaries built with cargo-auditable \u2705 \u2705 - - excluded - C/C++ conan.lock 12 - - \u2705 \u2705 excluded - Elixir mix.lock 12 - - \u2705 \u2705 excluded \u2705 Dart pubspec.lock \u2705 \u2705 - - included - The path of these files does not matter. Example: Dockerfile Data Sources Language Source Commercial Use Delay 1 PHP PHP Security Advisories Database \u2705 - GitHub Advisory Database (Composer) \u2705 - Python GitHub Advisory Database (pip) \u2705 - Open Source Vulnerabilities (PyPI) \u2705 - Ruby Ruby Advisory Database \u2705 - GitHub Advisory Database (RubyGems) \u2705 - Node.js Ecosystem Security Working Group \u2705 - GitHub Advisory Database (npm) \u2705 - Java GitLab Advisories Community \u2705 1 month GitHub Advisory Database (Maven) \u2705 - Go GitLab Advisories Community \u2705 1 month The Go Vulnerability Database \u2705 - Rust Open Source Vulnerabilities (crates.io) \u2705 - .NET GitHub Advisory Database (NuGet) \u2705 - C/C++ GitLab Advisories Community \u2705 1 month Dart GitHub Advisory Database (Pub) \u2705 - Elixir GitHub Advisory Database (Erlang) \u2705 Intentional delay between vulnerability disclosure and registration in the DB \u21a9 \u21a9 .dist-info/META-DATA \u21a9 *.jar , *.war , *.par and *.ear \u21a9 It requires Internet access when the POM doesn't exist in your local repository \u21a9 UPX-compressed binaries don't work \u21a9 If smaller than go 1.17, go.sum is also required \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the image scanning \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the rootfs scanning \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the filesystem scanning \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the git repository scanning \u21a9 \u2705 means that Trivy detects line numbers where each dependency is declared in the scanned file. Only supported in json and sarif formats. SARIF uses startline == 1 and endline == 1 for unsupported file types \u21a9 To scan a filename other than the default filename use file-patterns \u21a9 \u21a9 When you scan Cargo.lock and Cargo.toml together. See about it here . \u21a9","title":"Overview"},{"location":"docs/scanner/vulnerability/language/#language-specific-packages","text":"Trivy automatically detects the following files and scans vulnerabilities in the application dependencies.","title":"Language-specific Packages"},{"location":"docs/scanner/vulnerability/language/#supported-languages","text":"Language File Image 7 Rootfs 8 Filesystem 9 Repository 10 Dev dependencies Dependency location 11 Ruby Gemfile.lock - - \u2705 \u2705 included - gemspec \u2705 \u2705 - - included - Python Pipfile.lock - - \u2705 \u2705 excluded \u2705 poetry.lock - - \u2705 \u2705 excluded - requirements.txt - - \u2705 \u2705 included - egg package 1 \u2705 \u2705 - - excluded - wheel package 2 \u2705 \u2705 - - excluded - PHP composer.lock \u2705 \u2705 \u2705 \u2705 excluded \u2705 Node.js package-lock.json - - \u2705 \u2705 excluded \u2705 yarn.lock - - \u2705 \u2705 included \u2705 pnpm-lock.yaml - - \u2705 \u2705 excluded - package.json \u2705 \u2705 - - excluded - .NET packages.lock.json \u2705 \u2705 \u2705 \u2705 included \u2705 packages.config \u2705 \u2705 \u2705 \u2705 excluded - .deps.json \u2705 \u2705 \u2705 \u2705 excluded \u2705 Java JAR/WAR/PAR/EAR 3 \u2705 \u2705 - - included - pom.xml 4 - - \u2705 \u2705 excluded - *gradle.lockfile - - \u2705 \u2705 excluded - Go Binaries built by Go 5 \u2705 \u2705 - - excluded - go.mod 6 - - \u2705 \u2705 included - Rust Cargo.lock \u2705 \u2705 \u2705 \u2705 excluded \u2705 Binaries built with cargo-auditable \u2705 \u2705 - - excluded - C/C++ conan.lock 12 - - \u2705 \u2705 excluded - Elixir mix.lock 12 - - \u2705 \u2705 excluded \u2705 Dart pubspec.lock \u2705 \u2705 - - included - The path of these files does not matter. Example: Dockerfile","title":"Supported languages"},{"location":"docs/scanner/vulnerability/language/#data-sources","text":"Language Source Commercial Use Delay 1 PHP PHP Security Advisories Database \u2705 - GitHub Advisory Database (Composer) \u2705 - Python GitHub Advisory Database (pip) \u2705 - Open Source Vulnerabilities (PyPI) \u2705 - Ruby Ruby Advisory Database \u2705 - GitHub Advisory Database (RubyGems) \u2705 - Node.js Ecosystem Security Working Group \u2705 - GitHub Advisory Database (npm) \u2705 - Java GitLab Advisories Community \u2705 1 month GitHub Advisory Database (Maven) \u2705 - Go GitLab Advisories Community \u2705 1 month The Go Vulnerability Database \u2705 - Rust Open Source Vulnerabilities (crates.io) \u2705 - .NET GitHub Advisory Database (NuGet) \u2705 - C/C++ GitLab Advisories Community \u2705 1 month Dart GitHub Advisory Database (Pub) \u2705 - Elixir GitHub Advisory Database (Erlang) \u2705 Intentional delay between vulnerability disclosure and registration in the DB \u21a9 \u21a9 .dist-info/META-DATA \u21a9 *.jar , *.war , *.par and *.ear \u21a9 It requires Internet access when the POM doesn't exist in your local repository \u21a9 UPX-compressed binaries don't work \u21a9 If smaller than go 1.17, go.sum is also required \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the image scanning \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the rootfs scanning \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the filesystem scanning \u21a9 \u2705 means \"enabled\" and - means \"disabled\" in the git repository scanning \u21a9 \u2705 means that Trivy detects line numbers where each dependency is declared in the scanned file. Only supported in json and sarif formats. SARIF uses startline == 1 and endline == 1 for unsupported file types \u21a9 To scan a filename other than the default filename use file-patterns \u21a9 \u21a9 When you scan Cargo.lock and Cargo.toml together. See about it here . \u21a9","title":"Data Sources"},{"location":"docs/scanner/vulnerability/language/golang/","text":"Go Features Trivy supports two types of Go scanning, Go Modules and binaries built by Go. The following table provides an outline of the features Trivy offers. Artifact Offline 1 Dev dependencies License Dependency graph Modules \u2705 Include \u2705 2 \u2705 2 Binaries \u2705 Exclude - - Note Trivy scans only dependencies of the Go project. Let's say you scan the Docker binary, Trivy doesn't detect vulnerabilities of Docker itself. Also, when you scan go.mod in Kubernetes, the Kubernetes vulnerabilities will not be found. Go Modules Depending on Go versions, the required files are different. Version Required files Offline >=1.17 go.mod \u2705 <1.17 go.mod, go.sum \u2705 In Go 1.17+ projects, Trivy uses go.mod for direct/indirect dependencies. On the other hand, it uses go.mod for direct dependencies and go.sum for indirect dependencies in Go 1.16 or less. Go 1.17+ holds actually needed indirect dependencies in go.mod , and it reduces false detection. go.sum in Go 1.16 or less contains all indirect dependencies that are even not needed for compiling. If you want to have better detection, please consider updating the Go version in your project. Note The Go version doesn't mean your CLI version, but the Go version in your go.mod. module github.com/aquasecurity/trivy go 1.18 require ( github.com/CycloneDX/cyclonedx-go v0.5.0 ... ) To update the Go version in your project, you need to run the following command. $ go mod tidy -go=1.18 To identify licenses and dependency relationships, you need to download modules to local cache beforehand, such as go mod download , go mod tidy , etc. Trivy traverses $GOPATH/pkg/mod and collects those extra information. Go binaries Trivy scans binaries built by Go. If there is a Go binary in your container image, Trivy automatically finds and scans it. Also, you can scan your local binaries. $ trivy fs ./your_binary It doesn't require the Internet access. \u21a9 Need to download modules to local cache beforehand \u21a9 \u21a9","title":"Go"},{"location":"docs/scanner/vulnerability/language/golang/#go","text":"","title":"Go"},{"location":"docs/scanner/vulnerability/language/golang/#features","text":"Trivy supports two types of Go scanning, Go Modules and binaries built by Go. The following table provides an outline of the features Trivy offers. Artifact Offline 1 Dev dependencies License Dependency graph Modules \u2705 Include \u2705 2 \u2705 2 Binaries \u2705 Exclude - - Note Trivy scans only dependencies of the Go project. Let's say you scan the Docker binary, Trivy doesn't detect vulnerabilities of Docker itself. Also, when you scan go.mod in Kubernetes, the Kubernetes vulnerabilities will not be found.","title":"Features"},{"location":"docs/scanner/vulnerability/language/golang/#go-modules","text":"Depending on Go versions, the required files are different. Version Required files Offline >=1.17 go.mod \u2705 <1.17 go.mod, go.sum \u2705 In Go 1.17+ projects, Trivy uses go.mod for direct/indirect dependencies. On the other hand, it uses go.mod for direct dependencies and go.sum for indirect dependencies in Go 1.16 or less. Go 1.17+ holds actually needed indirect dependencies in go.mod , and it reduces false detection. go.sum in Go 1.16 or less contains all indirect dependencies that are even not needed for compiling. If you want to have better detection, please consider updating the Go version in your project. Note The Go version doesn't mean your CLI version, but the Go version in your go.mod. module github.com/aquasecurity/trivy go 1.18 require ( github.com/CycloneDX/cyclonedx-go v0.5.0 ... ) To update the Go version in your project, you need to run the following command. $ go mod tidy -go=1.18 To identify licenses and dependency relationships, you need to download modules to local cache beforehand, such as go mod download , go mod tidy , etc. Trivy traverses $GOPATH/pkg/mod and collects those extra information.","title":"Go Modules"},{"location":"docs/scanner/vulnerability/language/golang/#go-binaries","text":"Trivy scans binaries built by Go. If there is a Go binary in your container image, Trivy automatically finds and scans it. Also, you can scan your local binaries. $ trivy fs ./your_binary It doesn't require the Internet access. \u21a9 Need to download modules to local cache beforehand \u21a9 \u21a9","title":"Go binaries"},{"location":"docs/scanner/vulnerability/language/java/","text":"Java Trivy supports three types of Java scanning: JAR/WAR/PAR/EAR , pom.xml and *gradle.lockfile files. The following table provides an outline of the features Trivy offers. Artifact Internet access Dev dependencies JAR/WAR/PAR/EAR Trivy Java DB Include pom.xml Maven repository 1 Exclude *gradle.lockfile - Exclude These may be enabled or disabled depending on the target. See here for the detail. JAR/WAR/PAR/EAR To find information about your JAR 2 file, Trivy parses pom.properties and MANIFEST.MF files in your JAR 2 file and takes required properties 3 . If those files don't exist or don't contain enough information - Trivy will try to find this JAR 2 file in trivy-java-db . The Java DB will be automatically downloaded/updated when any JAR 2 file is found. It is stored in the cache directory . EXPERIMENTAL Finding JARs in trivy-java-db is an experimental function. Base JAR 2 may contain inner JARs 2 within itself. To find information about these JARs 2 , the same logic is used as for the base JAR 2 . table format only contains the name of root JAR 2 . To get the full path to inner JARs 2 use the json format. pom.xml Trivy parses your pom.xml file and tries to find files with dependencies from these local locations. project directory 4 relativePath field 5 local repository directory 6 . If your machine doesn't have the necessary files - Trivy tries to find the information about these dependencies in the maven repository . Note Trivy only takes information about packages. We don't take a list of vulnerabilities for packages from the maven repository . Information about data sources for Java you can see here . You can disable connecting to the maven repository with the --offline-scan flag. The --offline-scan flag does not affect the Trivy database. The vulnerability database will be downloaded anyway. Warning Trivy may skip some dependencies (that were not found on your local machine) when the --offline-scan flag is passed. Gradle.lock gradle.lock files contain all necessary information about used dependencies. Trivy simply parses the file, extract dependencies, and finds vulnerabilities for them. It doesn't require the internet access. Uses maven repository to get information about dependencies. Internet access required. \u21a9 It means *.jar , *.war , *.par and *.ear file \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 ArtifactID , GroupID and Version \u21a9 e.g. when parent pom.xml file has ../pom.xml path \u21a9 When you use dependency path in relativePath field in pom.xml file \u21a9 /Users//.m2/repository (for Linux and Mac) and C:/Users//.m2/repository (for Windows) by default \u21a9","title":"Java"},{"location":"docs/scanner/vulnerability/language/java/#java","text":"Trivy supports three types of Java scanning: JAR/WAR/PAR/EAR , pom.xml and *gradle.lockfile files. The following table provides an outline of the features Trivy offers. Artifact Internet access Dev dependencies JAR/WAR/PAR/EAR Trivy Java DB Include pom.xml Maven repository 1 Exclude *gradle.lockfile - Exclude These may be enabled or disabled depending on the target. See here for the detail.","title":"Java"},{"location":"docs/scanner/vulnerability/language/java/#jarwarparear","text":"To find information about your JAR 2 file, Trivy parses pom.properties and MANIFEST.MF files in your JAR 2 file and takes required properties 3 . If those files don't exist or don't contain enough information - Trivy will try to find this JAR 2 file in trivy-java-db . The Java DB will be automatically downloaded/updated when any JAR 2 file is found. It is stored in the cache directory . EXPERIMENTAL Finding JARs in trivy-java-db is an experimental function. Base JAR 2 may contain inner JARs 2 within itself. To find information about these JARs 2 , the same logic is used as for the base JAR 2 . table format only contains the name of root JAR 2 . To get the full path to inner JARs 2 use the json format.","title":"JAR/WAR/PAR/EAR"},{"location":"docs/scanner/vulnerability/language/java/#pomxml","text":"Trivy parses your pom.xml file and tries to find files with dependencies from these local locations. project directory 4 relativePath field 5 local repository directory 6 . If your machine doesn't have the necessary files - Trivy tries to find the information about these dependencies in the maven repository . Note Trivy only takes information about packages. We don't take a list of vulnerabilities for packages from the maven repository . Information about data sources for Java you can see here . You can disable connecting to the maven repository with the --offline-scan flag. The --offline-scan flag does not affect the Trivy database. The vulnerability database will be downloaded anyway. Warning Trivy may skip some dependencies (that were not found on your local machine) when the --offline-scan flag is passed.","title":"pom.xml"},{"location":"docs/scanner/vulnerability/language/java/#gradlelock","text":"gradle.lock files contain all necessary information about used dependencies. Trivy simply parses the file, extract dependencies, and finds vulnerabilities for them. It doesn't require the internet access. Uses maven repository to get information about dependencies. Internet access required. \u21a9 It means *.jar , *.war , *.par and *.ear file \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 ArtifactID , GroupID and Version \u21a9 e.g. when parent pom.xml file has ../pom.xml path \u21a9 When you use dependency path in relativePath field in pom.xml file \u21a9 /Users//.m2/repository (for Linux and Mac) and C:/Users//.m2/repository (for Windows) by default \u21a9","title":"Gradle.lock"},{"location":"docs/scanner/vulnerability/language/nodejs/","text":"Node.js Trivy supports three types of Node.js package managers: npm , Yarn and pnpm . The following table provides an outline of the features Trivy offers. Package manager File Transitive dependencies Dev dependencies Dependency graph Position License npm package-lock.json \u2705 Excluded \u2705 \u2705 \u2705 Yarn yarn.lock \u2705 Excluded \u2705 \u2705 - pnpm pnpm-lock.yaml \u2705 Excluded \u2705 - - In addition, Trivy scans installed packages with package.json . File Dependency graph Position License package.json - - \u2705 These may be enabled or disabled depending on the target. See here for the detail. Package managers Trivy parses your files generated by package managers in filesystem/repository scanning. Tip Please make sure your lock file is up-to-date after modifying package.json . npm Trivy parses package-lock.json . To identify licenses, you need to download dependencies to node_modules beforehand. Trivy analyzes node_modules for licenses. Yarn Trivy parses yarn.lock , which doesn't contain information about development dependencies. To exclude devDependencies, package.json also needs to be present next to yarn.lock . pnpm Trivy parses pnpm-lock.yaml , then finds production dependencies and builds a tree of dependencies with vulnerabilities. Packages Trivy parses the manifest files of installed packages in container image scanning and so on. package.json Trivy searches for package.json files under node_modules and identifies installed packages. It only extracts package names, versions and licenses for those packages.","title":"Node.js"},{"location":"docs/scanner/vulnerability/language/nodejs/#nodejs","text":"Trivy supports three types of Node.js package managers: npm , Yarn and pnpm . The following table provides an outline of the features Trivy offers. Package manager File Transitive dependencies Dev dependencies Dependency graph Position License npm package-lock.json \u2705 Excluded \u2705 \u2705 \u2705 Yarn yarn.lock \u2705 Excluded \u2705 \u2705 - pnpm pnpm-lock.yaml \u2705 Excluded \u2705 - - In addition, Trivy scans installed packages with package.json . File Dependency graph Position License package.json - - \u2705 These may be enabled or disabled depending on the target. See here for the detail.","title":"Node.js"},{"location":"docs/scanner/vulnerability/language/nodejs/#package-managers","text":"Trivy parses your files generated by package managers in filesystem/repository scanning. Tip Please make sure your lock file is up-to-date after modifying package.json .","title":"Package managers"},{"location":"docs/scanner/vulnerability/language/nodejs/#npm","text":"Trivy parses package-lock.json . To identify licenses, you need to download dependencies to node_modules beforehand. Trivy analyzes node_modules for licenses.","title":"npm"},{"location":"docs/scanner/vulnerability/language/nodejs/#yarn","text":"Trivy parses yarn.lock , which doesn't contain information about development dependencies. To exclude devDependencies, package.json also needs to be present next to yarn.lock .","title":"Yarn"},{"location":"docs/scanner/vulnerability/language/nodejs/#pnpm","text":"Trivy parses pnpm-lock.yaml , then finds production dependencies and builds a tree of dependencies with vulnerabilities.","title":"pnpm"},{"location":"docs/scanner/vulnerability/language/nodejs/#packages","text":"Trivy parses the manifest files of installed packages in container image scanning and so on.","title":"Packages"},{"location":"docs/scanner/vulnerability/language/nodejs/#packagejson","text":"Trivy searches for package.json files under node_modules and identifies installed packages. It only extracts package names, versions and licenses for those packages.","title":"package.json"},{"location":"docs/scanner/vulnerability/language/php/","text":"PHP Trivy supports Composer , which is a tool for dependency management in PHP. The following table provides an outline of the features Trivy offers. Package Manager File Transitive dependencies Dev dependencies Dependency graph Position License Composer composer.lock \u2705 Excluded \u2705 \u2705 \u2705 Composer In order to detect dependencies, Trivy searches for composer.lock . Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in composer.lock , Trivy parses composer.json , which should be located next to composer.lock . If you want to see the dependency tree, please ensure that composer.json is present.","title":"PHP"},{"location":"docs/scanner/vulnerability/language/php/#php","text":"Trivy supports Composer , which is a tool for dependency management in PHP. The following table provides an outline of the features Trivy offers. Package Manager File Transitive dependencies Dev dependencies Dependency graph Position License Composer composer.lock \u2705 Excluded \u2705 \u2705 \u2705","title":"PHP"},{"location":"docs/scanner/vulnerability/language/php/#composer","text":"In order to detect dependencies, Trivy searches for composer.lock . Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in composer.lock , Trivy parses composer.json , which should be located next to composer.lock . If you want to see the dependency tree, please ensure that composer.json is present.","title":"Composer"},{"location":"docs/scanner/vulnerability/language/python/","text":"Python Trivy supports three types of Python package managers: pip , Pipenv and Poetry . The following table provides an outline of the features Trivy offers. Package manager File Transitive dependencies Dev dependencies Dependency graph Position License pip requirements.txt - Include - - - Pipenv Pipfile.lock \u2705 Include - \u2705 - Poetry poetry.lock \u2705 Exclude \u2705 - In addition, Trivy supports two formats of Python packages: egg and wheel . Packaging License Egg \u2705 Wheel \u2705 These may be enabled or disabled depending on the target. See here for the detail. Package managers Trivy parses your files generated by package managers in filesystem/repository scanning. pip requirements.txt files usually contain only the direct dependencies and not contain the transitive dependencies. Therefore, Trivy scans only for the direct dependencies with requirements.txt . To detect transitive dependencies as well, you need to generate requirements.txt with pip freeze . $ cat requirements.txt # it will only find `requests@2.28.2`. requests == 2 .28.2 $ pip install -r requirements.txt ... $ pip freeze > requirements.txt $ cat requirements.txt # it will also find the transitive dependencies of `requests@2.28.2`. certifi == 2022 .12.7 charset-normalizer == 3 .1.0 idna == 3 .4 PyJWT == 2 .1.0 requests == 2 .28.2 urllib3 == 1 .26.15 pip freeze also helps to resolve extras (optional) dependencies (like package[extras]=0.0.0 ). requirements.txt files don't contain information about dependencies used for development. Trivy could detect vulnerabilities on the development packages, which not affect your production environment. License detection is not supported for pip . Pipenv Trivy parses Pipfile.lock . Pipfile.lock files don't contain information about dependencies used for development. Trivy could detect vulnerabilities on the development packages, which not affect your production environment. License detection is not supported for Pipenv . Poetry Trivy uses poetry.lock to identify dependencies and find vulnerabilities. To build the correct dependency graph, pyproject.toml also needs to be present next to poetry.lock . License detection is not supported for Poetry . Packaging Trivy parses the manifest files of installed packages in container image scanning and so on. See here for the detail. Egg Trivy looks for *.egg-info , *.egg-info/PKG-INFO , *.egg and EGG-INFO/PKG-INFO to identify Python packages. Wheel Trivy looks for .dist-info/META-DATA to identify Python packages.","title":"Python"},{"location":"docs/scanner/vulnerability/language/python/#python","text":"Trivy supports three types of Python package managers: pip , Pipenv and Poetry . The following table provides an outline of the features Trivy offers. Package manager File Transitive dependencies Dev dependencies Dependency graph Position License pip requirements.txt - Include - - - Pipenv Pipfile.lock \u2705 Include - \u2705 - Poetry poetry.lock \u2705 Exclude \u2705 - In addition, Trivy supports two formats of Python packages: egg and wheel . Packaging License Egg \u2705 Wheel \u2705 These may be enabled or disabled depending on the target. See here for the detail.","title":"Python"},{"location":"docs/scanner/vulnerability/language/python/#package-managers","text":"Trivy parses your files generated by package managers in filesystem/repository scanning.","title":"Package managers"},{"location":"docs/scanner/vulnerability/language/python/#pip","text":"requirements.txt files usually contain only the direct dependencies and not contain the transitive dependencies. Therefore, Trivy scans only for the direct dependencies with requirements.txt . To detect transitive dependencies as well, you need to generate requirements.txt with pip freeze . $ cat requirements.txt # it will only find `requests@2.28.2`. requests == 2 .28.2 $ pip install -r requirements.txt ... $ pip freeze > requirements.txt $ cat requirements.txt # it will also find the transitive dependencies of `requests@2.28.2`. certifi == 2022 .12.7 charset-normalizer == 3 .1.0 idna == 3 .4 PyJWT == 2 .1.0 requests == 2 .28.2 urllib3 == 1 .26.15 pip freeze also helps to resolve extras (optional) dependencies (like package[extras]=0.0.0 ). requirements.txt files don't contain information about dependencies used for development. Trivy could detect vulnerabilities on the development packages, which not affect your production environment. License detection is not supported for pip .","title":"pip"},{"location":"docs/scanner/vulnerability/language/python/#pipenv","text":"Trivy parses Pipfile.lock . Pipfile.lock files don't contain information about dependencies used for development. Trivy could detect vulnerabilities on the development packages, which not affect your production environment. License detection is not supported for Pipenv .","title":"Pipenv"},{"location":"docs/scanner/vulnerability/language/python/#poetry","text":"Trivy uses poetry.lock to identify dependencies and find vulnerabilities. To build the correct dependency graph, pyproject.toml also needs to be present next to poetry.lock . License detection is not supported for Poetry .","title":"Poetry"},{"location":"docs/scanner/vulnerability/language/python/#packaging","text":"Trivy parses the manifest files of installed packages in container image scanning and so on. See here for the detail.","title":"Packaging"},{"location":"docs/scanner/vulnerability/language/python/#egg","text":"Trivy looks for *.egg-info , *.egg-info/PKG-INFO , *.egg and EGG-INFO/PKG-INFO to identify Python packages.","title":"Egg"},{"location":"docs/scanner/vulnerability/language/python/#wheel","text":"Trivy looks for .dist-info/META-DATA to identify Python packages.","title":"Wheel"},{"location":"docs/scanner/vulnerability/language/rust/","text":"Rust Features Trivy supports Cargo , which is the Rust package manager. The following table provides an outline of the features Trivy offers. Package manager File Transitive dependencies Dev dependencies License Dependency graph Position Cargo Cargo.lock \u2705 Excluded 1 - \u2705 \u2705 In addition, it supports binaries built with cargo-auditable . Artifact Transitive dependencies Dev dependencies License Dependency graph Position Binaries \u2705 Excluded - - - Cargo Trivy searches for Cargo.lock to detect dependencies. Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in Cargo.lock , Trivy parses Cargo.toml , which should be located next to Cargo.lock . If you want to see the dependency tree, please ensure that Cargo.toml is present. Scan Cargo.lock and Cargo.toml together also removes developer dependencies. Binaries Trivy scans binaries built with cargo-auditable . If such a binary exists, Trivy will identify it as being built with cargo-audit and scan it. When you scan Cargo.lock and Cargo.toml together. \u21a9","title":"Rust"},{"location":"docs/scanner/vulnerability/language/rust/#rust","text":"","title":"Rust"},{"location":"docs/scanner/vulnerability/language/rust/#features","text":"Trivy supports Cargo , which is the Rust package manager. The following table provides an outline of the features Trivy offers. Package manager File Transitive dependencies Dev dependencies License Dependency graph Position Cargo Cargo.lock \u2705 Excluded 1 - \u2705 \u2705 In addition, it supports binaries built with cargo-auditable . Artifact Transitive dependencies Dev dependencies License Dependency graph Position Binaries \u2705 Excluded - - -","title":"Features"},{"location":"docs/scanner/vulnerability/language/rust/#cargo","text":"Trivy searches for Cargo.lock to detect dependencies. Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in Cargo.lock , Trivy parses Cargo.toml , which should be located next to Cargo.lock . If you want to see the dependency tree, please ensure that Cargo.toml is present. Scan Cargo.lock and Cargo.toml together also removes developer dependencies.","title":"Cargo"},{"location":"docs/scanner/vulnerability/language/rust/#binaries","text":"Trivy scans binaries built with cargo-auditable . If such a binary exists, Trivy will identify it as being built with cargo-audit and scan it. When you scan Cargo.lock and Cargo.toml together. \u21a9","title":"Binaries"},{"location":"docs/supply-chain/sbom/","text":"SBOM generation Trivy can generate the following SBOM formats. CycloneDX SPDX CLI commands To generate SBOM, you can use the --format option for each subcommand such as image , fs and vm . $ trivy image --format spdx-json --output result.json alpine:3.15 $ trivy fs --format cyclonedx --output result.json /app/myproject Result { \"bomFormat\": \"CycloneDX\", \"specVersion\": \"1.3\", \"serialNumber\": \"urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace\", \"version\": 1, \"metadata\": { \"timestamp\": \"2022-02-22T15:11:40.270597Z\", \"tools\": [ { \"vendor\": \"aquasecurity\", \"name\": \"trivy\", \"version\": \"dev\" } ], \"component\": { \"bom-ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"type\": \"container\", \"name\": \"alpine:3.15\", \"version\": \"\", \"purl\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SchemaVersion\", \"value\": \"2\" }, { \"name\": \"aquasecurity:trivy:ImageID\", \"value\": \"sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18\" }, { \"name\": \"aquasecurity:trivy:RepoDigest\", \"value\": \"alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300\" }, { \"name\": \"aquasecurity:trivy:DiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" }, { \"name\": \"aquasecurity:trivy:RepoTag\", \"value\": \"alpine:3.15\" } ] } }, \"components\": [ { \"bom-ref\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"type\": \"library\", \"name\": \"alpine-baselayout\", \"version\": \"3.2.0-r18\", \"licenses\": [ { \"expression\": \"GPL-2.0-only\" } ], \"purl\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"alpine-baselayout\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"3.2.0-r18\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, ...(snip)... { \"bom-ref\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"type\": \"library\", \"name\": \"zlib\", \"version\": \"1.2.11-r3\", \"licenses\": [ { \"expression\": \"Zlib\" } ], \"purl\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"zlib\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"1.2.11-r3\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, { \"bom-ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"type\": \"operating-system\", \"name\": \"alpine\", \"version\": \"3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:Type\", \"value\": \"alpine\" }, { \"name\": \"aquasecurity:trivy:Class\", \"value\": \"os-pkgs\" } ] } ], \"dependencies\": [ { \"ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"dependsOn\": [ \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0\", \"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0\", \"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0\", \"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0\", \"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0\", \"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0\", \"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\" ] }, { \"ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"dependsOn\": [ \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\" ] } ] } Supported packages Trivy supports the following packages. OS packages Language-specific packages In addition to the above packages, Trivy also supports the following packages for generating SBOM. Note These packages are not supported for vulnerability scanning. Language File Dependency location 1 Python conda package 2 - Swift Podfile.lock - Formats CycloneDX Trivy can generate SBOM in the CycloneDX format. Note that XML format is not supported at the moment. You can use the regular subcommands (like image , fs and rootfs ) and specify cyclonedx with the --format option. CycloneDX can represent either or both SBOM or BOV. Software Bill of Materials (SBOM) Bill of Vulnerabilities (BOV) By default, --format cyclonedx represents SBOM and doesn't include vulnerabilities in the CycloneDX output. $ trivy image --format cyclonedx --output result.json alpine:3.15 2022-07-19T07:47:27.624Z INFO \"--format cyclonedx\" disables security scanning. Specify \"--scanners vuln\" explicitly if you want to include vulnerabilities in the CycloneDX report. Result $ cat result.json | jq . { \"bomFormat\": \"CycloneDX\", \"specVersion\": \"1.4\", \"serialNumber\": \"urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace\", \"version\": 1, \"metadata\": { \"timestamp\": \"2022-02-22T15:11:40.270597Z\", \"tools\": [ { \"vendor\": \"aquasecurity\", \"name\": \"trivy\", \"version\": \"dev\" } ], \"component\": { \"bom-ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"type\": \"container\", \"name\": \"alpine:3.15\", \"version\": \"\", \"purl\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SchemaVersion\", \"value\": \"2\" }, { \"name\": \"aquasecurity:trivy:ImageID\", \"value\": \"sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18\" }, { \"name\": \"aquasecurity:trivy:RepoDigest\", \"value\": \"alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300\" }, { \"name\": \"aquasecurity:trivy:DiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" }, { \"name\": \"aquasecurity:trivy:RepoTag\", \"value\": \"alpine:3.15\" } ] } }, \"components\": [ { \"bom-ref\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"type\": \"library\", \"name\": \"alpine-baselayout\", \"version\": \"3.2.0-r18\", \"licenses\": [ { \"expression\": \"GPL-2.0-only\" } ], \"purl\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"alpine-baselayout\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"3.2.0-r18\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, ...(snip)... { \"bom-ref\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"type\": \"library\", \"name\": \"zlib\", \"version\": \"1.2.11-r3\", \"licenses\": [ { \"expression\": \"Zlib\" } ], \"purl\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"zlib\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"1.2.11-r3\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, { \"bom-ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"type\": \"operating-system\", \"name\": \"alpine\", \"version\": \"3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:Type\", \"value\": \"alpine\" }, { \"name\": \"aquasecurity:trivy:Class\", \"value\": \"os-pkgs\" } ] } ], \"dependencies\": [ { \"ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"dependsOn\": [ \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0\", \"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0\", \"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0\", \"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0\", \"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0\", \"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0\", \"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\" ] }, { \"ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"dependsOn\": [ \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\" ] } ], \"vulnerabilities\": [ { \"id\": \"CVE-2021-42386\", \"source\": { \"name\": \"alpine\", \"url\": \"https://secdb.alpinelinux.org/\" }, \"ratings\": [ { \"source\": { \"name\": \"nvd\" }, \"score\": 7.2, \"severity\": \"high\", \"method\": \"CVSSv31\", \"vector\": \"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H\" }, { \"source\": { \"name\": \"nvd\" }, \"score\": 6.5, \"severity\": \"medium\", \"method\": \"CVSSv2\", \"vector\": \"AV:N/AC:L/Au:S/C:P/I:P/A:P\" }, { \"source\": { \"name\": \"redhat\" }, \"score\": 6.6, \"severity\": \"medium\", \"method\": \"CVSSv31\", \"vector\": \"CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H\" } ], \"cwes\": [ 416 ], \"description\": \"A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the nvalloc function\", \"advisories\": [ { \"url\": \"https://access.redhat.com/security/cve/CVE-2021-42386\" }, { \"url\": \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42386\" } ], \"published\": \"2021-11-15 21:15:00 +0000 UTC\", \"updated\": \"2022-01-04 17:14:00 +0000 UTC\", \"affects\": [ { \"ref\": \"pkg:apk/alpine/busybox@1.33.1-r3?distro=3.14.2\" }, { \"ref\": \"pkg:apk/alpine/ssl_client@1.33.1-r3?distro=3.14.2\" } ] } ] } If you want to include vulnerabilities, you can enable vulnerability scanning via --scanners vuln . $ trivy image --scanners vuln --format cyclonedx --output result.json alpine:3.15 SPDX Trivy can generate SBOM in the SPDX format. You can use the regular subcommands (like image , fs and rootfs ) and specify spdx with the --format option. $ trivy image --format spdx --output result.spdx alpine:3.15 Result $ cat result.spdx SPDXVersion: SPDX-2.2 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: alpine:3.15 DocumentNamespace: https://aquasecurity.github.io/trivy/container_image/alpine:3.15-bebf6b19-a94c-4e2c-af44-065f63923f48 Creator: Organization: aquasecurity Creator: Tool: trivy-0.38.1 Created: 2022-04-28T07:32:57.142806Z ##### Package: zlib PackageName: zlib SPDXID: SPDXRef-12bc938ac028a5e1 PackageVersion: 1.2.12-r0 FilesAnalyzed: false PackageLicenseConcluded: Zlib PackageLicenseDeclared: Zlib ##### Package: apk-tools PackageName: apk-tools SPDXID: SPDXRef-26c274652190d87f PackageVersion: 2.12.7-r3 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: libretls PackageName: libretls SPDXID: SPDXRef-2b021966d19a8211 PackageVersion: 3.3.4-r3 FilesAnalyzed: false PackageLicenseConcluded: ISC AND (BSD-3-Clause OR MIT) PackageLicenseDeclared: ISC AND (BSD-3-Clause OR MIT) ##### Package: busybox PackageName: busybox SPDXID: SPDXRef-317ce3476703f20d PackageVersion: 1.34.1-r5 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: libcrypto1.1 PackageName: libcrypto1.1 SPDXID: SPDXRef-34f407fb4dbd67f4 PackageVersion: 1.1.1n-r0 FilesAnalyzed: false PackageLicenseConcluded: OpenSSL PackageLicenseDeclared: OpenSSL ##### Package: libc-utils PackageName: libc-utils SPDXID: SPDXRef-4bbc1cb449d54083 PackageVersion: 0.7.2-r3 FilesAnalyzed: false PackageLicenseConcluded: BSD-2-Clause AND BSD-3-Clause PackageLicenseDeclared: BSD-2-Clause AND BSD-3-Clause ##### Package: alpine-keys PackageName: alpine-keys SPDXID: SPDXRef-a3bdd174be1456b6 PackageVersion: 2.4-r1 FilesAnalyzed: false PackageLicenseConcluded: MIT PackageLicenseDeclared: MIT ##### Package: ca-certificates-bundle PackageName: ca-certificates-bundle SPDXID: SPDXRef-ac6472ba26fb991c PackageVersion: 20211220-r0 FilesAnalyzed: false PackageLicenseConcluded: MPL-2.0 AND MIT PackageLicenseDeclared: MPL-2.0 AND MIT ##### Package: libssl1.1 PackageName: libssl1.1 SPDXID: SPDXRef-b2d1b1d70fe90f7d PackageVersion: 1.1.1n-r0 FilesAnalyzed: false PackageLicenseConcluded: OpenSSL PackageLicenseDeclared: OpenSSL ##### Package: scanelf PackageName: scanelf SPDXID: SPDXRef-c617077ba6649520 PackageVersion: 1.3.3-r0 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: musl PackageName: musl SPDXID: SPDXRef-ca80b810029cde0e PackageVersion: 1.2.2-r7 FilesAnalyzed: false PackageLicenseConcluded: MIT PackageLicenseDeclared: MIT ##### Package: alpine-baselayout PackageName: alpine-baselayout SPDXID: SPDXRef-d782e64751ba9faa PackageVersion: 3.2.0-r18 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: musl-utils PackageName: musl-utils SPDXID: SPDXRef-e5e8a237f6162e22 PackageVersion: 1.2.2-r7 FilesAnalyzed: false PackageLicenseConcluded: MIT BSD GPL2+ PackageLicenseDeclared: MIT BSD GPL2+ ##### Package: ssl_client PackageName: ssl_client SPDXID: SPDXRef-fdf0ce84f6337be4 PackageVersion: 1.34.1-r5 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only SPDX-JSON format is also supported by using spdx-json with the --format option. $ trivy image --format spdx-json --output result.spdx.json alpine:3.15 Result $ cat result.spdx.json | jq . { \"SPDXID\": \"SPDXRef-DOCUMENT\", \"creationInfo\": { \"created\": \"2022-04-28T08:16:55.328255Z\", \"creators\": [ \"Tool: trivy-0.38.1\", \"Organization: aquasecurity\" ] }, \"dataLicense\": \"CC0-1.0\", \"documentNamespace\": \"http://aquasecurity.github.io/trivy/container_image/alpine:3.15-d9549e3a-a4c5-4ee3-8bde-8c78d451fbe7\", \"name\": \"alpine:3.15\", \"packages\": [ { \"SPDXID\": \"SPDXRef-12bc938ac028a5e1\", \"filesAnalyzed\": false, \"licenseConcluded\": \"Zlib\", \"licenseDeclared\": \"Zlib\", \"name\": \"zlib\", \"versionInfo\": \"1.2.12-r0\" }, { \"SPDXID\": \"SPDXRef-26c274652190d87f\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"apk-tools\", \"versionInfo\": \"2.12.7-r3\" }, { \"SPDXID\": \"SPDXRef-2b021966d19a8211\", \"filesAnalyzed\": false, \"licenseConcluded\": \"ISC AND (BSD-3-Clause OR MIT)\", \"licenseDeclared\": \"ISC AND (BSD-3-Clause OR MIT)\", \"name\": \"libretls\", \"versionInfo\": \"3.3.4-r3\" }, { \"SPDXID\": \"SPDXRef-317ce3476703f20d\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"busybox\", \"versionInfo\": \"1.34.1-r5\" }, { \"SPDXID\": \"SPDXRef-34f407fb4dbd67f4\", \"filesAnalyzed\": false, \"licenseConcluded\": \"OpenSSL\", \"licenseDeclared\": \"OpenSSL\", \"name\": \"libcrypto1.1\", \"versionInfo\": \"1.1.1n-r0\" }, { \"SPDXID\": \"SPDXRef-4bbc1cb449d54083\", \"filesAnalyzed\": false, \"licenseConcluded\": \"BSD-2-Clause AND BSD-3-Clause\", \"licenseDeclared\": \"BSD-2-Clause AND BSD-3-Clause\", \"name\": \"libc-utils\", \"versionInfo\": \"0.7.2-r3\" }, { \"SPDXID\": \"SPDXRef-a3bdd174be1456b6\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MIT\", \"licenseDeclared\": \"MIT\", \"name\": \"alpine-keys\", \"versionInfo\": \"2.4-r1\" }, { \"SPDXID\": \"SPDXRef-ac6472ba26fb991c\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MPL-2.0 AND MIT\", \"licenseDeclared\": \"MPL-2.0 AND MIT\", \"name\": \"ca-certificates-bundle\", \"versionInfo\": \"20211220-r0\" }, { \"SPDXID\": \"SPDXRef-b2d1b1d70fe90f7d\", \"filesAnalyzed\": false, \"licenseConcluded\": \"OpenSSL\", \"licenseDeclared\": \"OpenSSL\", \"name\": \"libssl1.1\", \"versionInfo\": \"1.1.1n-r0\" }, { \"SPDXID\": \"SPDXRef-c617077ba6649520\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"scanelf\", \"versionInfo\": \"1.3.3-r0\" }, { \"SPDXID\": \"SPDXRef-ca80b810029cde0e\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MIT\", \"licenseDeclared\": \"MIT\", \"name\": \"musl\", \"versionInfo\": \"1.2.2-r7\" }, { \"SPDXID\": \"SPDXRef-d782e64751ba9faa\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"alpine-baselayout\", \"versionInfo\": \"3.2.0-r18\" }, { \"SPDXID\": \"SPDXRef-e5e8a237f6162e22\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MIT BSD GPL2+\", \"licenseDeclared\": \"MIT BSD GPL2+\", \"name\": \"musl-utils\", \"versionInfo\": \"1.2.2-r7\" }, { \"SPDXID\": \"SPDXRef-fdf0ce84f6337be4\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"ssl_client\", \"versionInfo\": \"1.34.1-r5\" } ], \"spdxVersion\": \"SPDX-2.2\" } Use startline == 1 and endline == 1 for unsupported file types \u21a9 envs/*/conda-meta/*.json \u21a9","title":"SBOM"},{"location":"docs/supply-chain/sbom/#sbom-generation","text":"Trivy can generate the following SBOM formats. CycloneDX SPDX","title":"SBOM generation"},{"location":"docs/supply-chain/sbom/#cli-commands","text":"To generate SBOM, you can use the --format option for each subcommand such as image , fs and vm . $ trivy image --format spdx-json --output result.json alpine:3.15 $ trivy fs --format cyclonedx --output result.json /app/myproject Result { \"bomFormat\": \"CycloneDX\", \"specVersion\": \"1.3\", \"serialNumber\": \"urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace\", \"version\": 1, \"metadata\": { \"timestamp\": \"2022-02-22T15:11:40.270597Z\", \"tools\": [ { \"vendor\": \"aquasecurity\", \"name\": \"trivy\", \"version\": \"dev\" } ], \"component\": { \"bom-ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"type\": \"container\", \"name\": \"alpine:3.15\", \"version\": \"\", \"purl\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SchemaVersion\", \"value\": \"2\" }, { \"name\": \"aquasecurity:trivy:ImageID\", \"value\": \"sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18\" }, { \"name\": \"aquasecurity:trivy:RepoDigest\", \"value\": \"alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300\" }, { \"name\": \"aquasecurity:trivy:DiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" }, { \"name\": \"aquasecurity:trivy:RepoTag\", \"value\": \"alpine:3.15\" } ] } }, \"components\": [ { \"bom-ref\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"type\": \"library\", \"name\": \"alpine-baselayout\", \"version\": \"3.2.0-r18\", \"licenses\": [ { \"expression\": \"GPL-2.0-only\" } ], \"purl\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"alpine-baselayout\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"3.2.0-r18\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, ...(snip)... { \"bom-ref\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"type\": \"library\", \"name\": \"zlib\", \"version\": \"1.2.11-r3\", \"licenses\": [ { \"expression\": \"Zlib\" } ], \"purl\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"zlib\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"1.2.11-r3\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, { \"bom-ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"type\": \"operating-system\", \"name\": \"alpine\", \"version\": \"3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:Type\", \"value\": \"alpine\" }, { \"name\": \"aquasecurity:trivy:Class\", \"value\": \"os-pkgs\" } ] } ], \"dependencies\": [ { \"ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"dependsOn\": [ \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0\", \"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0\", \"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0\", \"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0\", \"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0\", \"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0\", \"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\" ] }, { \"ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"dependsOn\": [ \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\" ] } ] }","title":"CLI commands"},{"location":"docs/supply-chain/sbom/#supported-packages","text":"Trivy supports the following packages. OS packages Language-specific packages In addition to the above packages, Trivy also supports the following packages for generating SBOM. Note These packages are not supported for vulnerability scanning. Language File Dependency location 1 Python conda package 2 - Swift Podfile.lock -","title":"Supported packages"},{"location":"docs/supply-chain/sbom/#formats","text":"","title":"Formats"},{"location":"docs/supply-chain/sbom/#cyclonedx","text":"Trivy can generate SBOM in the CycloneDX format. Note that XML format is not supported at the moment. You can use the regular subcommands (like image , fs and rootfs ) and specify cyclonedx with the --format option. CycloneDX can represent either or both SBOM or BOV. Software Bill of Materials (SBOM) Bill of Vulnerabilities (BOV) By default, --format cyclonedx represents SBOM and doesn't include vulnerabilities in the CycloneDX output. $ trivy image --format cyclonedx --output result.json alpine:3.15 2022-07-19T07:47:27.624Z INFO \"--format cyclonedx\" disables security scanning. Specify \"--scanners vuln\" explicitly if you want to include vulnerabilities in the CycloneDX report. Result $ cat result.json | jq . { \"bomFormat\": \"CycloneDX\", \"specVersion\": \"1.4\", \"serialNumber\": \"urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace\", \"version\": 1, \"metadata\": { \"timestamp\": \"2022-02-22T15:11:40.270597Z\", \"tools\": [ { \"vendor\": \"aquasecurity\", \"name\": \"trivy\", \"version\": \"dev\" } ], \"component\": { \"bom-ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"type\": \"container\", \"name\": \"alpine:3.15\", \"version\": \"\", \"purl\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SchemaVersion\", \"value\": \"2\" }, { \"name\": \"aquasecurity:trivy:ImageID\", \"value\": \"sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18\" }, { \"name\": \"aquasecurity:trivy:RepoDigest\", \"value\": \"alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300\" }, { \"name\": \"aquasecurity:trivy:DiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" }, { \"name\": \"aquasecurity:trivy:RepoTag\", \"value\": \"alpine:3.15\" } ] } }, \"components\": [ { \"bom-ref\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"type\": \"library\", \"name\": \"alpine-baselayout\", \"version\": \"3.2.0-r18\", \"licenses\": [ { \"expression\": \"GPL-2.0-only\" } ], \"purl\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"alpine-baselayout\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"3.2.0-r18\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, ...(snip)... { \"bom-ref\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"type\": \"library\", \"name\": \"zlib\", \"version\": \"1.2.11-r3\", \"licenses\": [ { \"expression\": \"Zlib\" } ], \"purl\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:SrcName\", \"value\": \"zlib\" }, { \"name\": \"aquasecurity:trivy:SrcVersion\", \"value\": \"1.2.11-r3\" }, { \"name\": \"aquasecurity:trivy:LayerDigest\", \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\" }, { \"name\": \"aquasecurity:trivy:LayerDiffID\", \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\" } ] }, { \"bom-ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"type\": \"operating-system\", \"name\": \"alpine\", \"version\": \"3.15.0\", \"properties\": [ { \"name\": \"aquasecurity:trivy:Type\", \"value\": \"alpine\" }, { \"name\": \"aquasecurity:trivy:Class\", \"value\": \"os-pkgs\" } ] } ], \"dependencies\": [ { \"ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\", \"dependsOn\": [ \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\", \"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0\", \"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0\", \"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0\", \"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0\", \"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0\", \"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0\", \"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0\", \"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0\", \"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0\", \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\" ] }, { \"ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\", \"dependsOn\": [ \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\" ] } ], \"vulnerabilities\": [ { \"id\": \"CVE-2021-42386\", \"source\": { \"name\": \"alpine\", \"url\": \"https://secdb.alpinelinux.org/\" }, \"ratings\": [ { \"source\": { \"name\": \"nvd\" }, \"score\": 7.2, \"severity\": \"high\", \"method\": \"CVSSv31\", \"vector\": \"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H\" }, { \"source\": { \"name\": \"nvd\" }, \"score\": 6.5, \"severity\": \"medium\", \"method\": \"CVSSv2\", \"vector\": \"AV:N/AC:L/Au:S/C:P/I:P/A:P\" }, { \"source\": { \"name\": \"redhat\" }, \"score\": 6.6, \"severity\": \"medium\", \"method\": \"CVSSv31\", \"vector\": \"CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H\" } ], \"cwes\": [ 416 ], \"description\": \"A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the nvalloc function\", \"advisories\": [ { \"url\": \"https://access.redhat.com/security/cve/CVE-2021-42386\" }, { \"url\": \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42386\" } ], \"published\": \"2021-11-15 21:15:00 +0000 UTC\", \"updated\": \"2022-01-04 17:14:00 +0000 UTC\", \"affects\": [ { \"ref\": \"pkg:apk/alpine/busybox@1.33.1-r3?distro=3.14.2\" }, { \"ref\": \"pkg:apk/alpine/ssl_client@1.33.1-r3?distro=3.14.2\" } ] } ] } If you want to include vulnerabilities, you can enable vulnerability scanning via --scanners vuln . $ trivy image --scanners vuln --format cyclonedx --output result.json alpine:3.15","title":"CycloneDX"},{"location":"docs/supply-chain/sbom/#spdx","text":"Trivy can generate SBOM in the SPDX format. You can use the regular subcommands (like image , fs and rootfs ) and specify spdx with the --format option. $ trivy image --format spdx --output result.spdx alpine:3.15 Result $ cat result.spdx SPDXVersion: SPDX-2.2 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: alpine:3.15 DocumentNamespace: https://aquasecurity.github.io/trivy/container_image/alpine:3.15-bebf6b19-a94c-4e2c-af44-065f63923f48 Creator: Organization: aquasecurity Creator: Tool: trivy-0.38.1 Created: 2022-04-28T07:32:57.142806Z ##### Package: zlib PackageName: zlib SPDXID: SPDXRef-12bc938ac028a5e1 PackageVersion: 1.2.12-r0 FilesAnalyzed: false PackageLicenseConcluded: Zlib PackageLicenseDeclared: Zlib ##### Package: apk-tools PackageName: apk-tools SPDXID: SPDXRef-26c274652190d87f PackageVersion: 2.12.7-r3 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: libretls PackageName: libretls SPDXID: SPDXRef-2b021966d19a8211 PackageVersion: 3.3.4-r3 FilesAnalyzed: false PackageLicenseConcluded: ISC AND (BSD-3-Clause OR MIT) PackageLicenseDeclared: ISC AND (BSD-3-Clause OR MIT) ##### Package: busybox PackageName: busybox SPDXID: SPDXRef-317ce3476703f20d PackageVersion: 1.34.1-r5 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: libcrypto1.1 PackageName: libcrypto1.1 SPDXID: SPDXRef-34f407fb4dbd67f4 PackageVersion: 1.1.1n-r0 FilesAnalyzed: false PackageLicenseConcluded: OpenSSL PackageLicenseDeclared: OpenSSL ##### Package: libc-utils PackageName: libc-utils SPDXID: SPDXRef-4bbc1cb449d54083 PackageVersion: 0.7.2-r3 FilesAnalyzed: false PackageLicenseConcluded: BSD-2-Clause AND BSD-3-Clause PackageLicenseDeclared: BSD-2-Clause AND BSD-3-Clause ##### Package: alpine-keys PackageName: alpine-keys SPDXID: SPDXRef-a3bdd174be1456b6 PackageVersion: 2.4-r1 FilesAnalyzed: false PackageLicenseConcluded: MIT PackageLicenseDeclared: MIT ##### Package: ca-certificates-bundle PackageName: ca-certificates-bundle SPDXID: SPDXRef-ac6472ba26fb991c PackageVersion: 20211220-r0 FilesAnalyzed: false PackageLicenseConcluded: MPL-2.0 AND MIT PackageLicenseDeclared: MPL-2.0 AND MIT ##### Package: libssl1.1 PackageName: libssl1.1 SPDXID: SPDXRef-b2d1b1d70fe90f7d PackageVersion: 1.1.1n-r0 FilesAnalyzed: false PackageLicenseConcluded: OpenSSL PackageLicenseDeclared: OpenSSL ##### Package: scanelf PackageName: scanelf SPDXID: SPDXRef-c617077ba6649520 PackageVersion: 1.3.3-r0 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: musl PackageName: musl SPDXID: SPDXRef-ca80b810029cde0e PackageVersion: 1.2.2-r7 FilesAnalyzed: false PackageLicenseConcluded: MIT PackageLicenseDeclared: MIT ##### Package: alpine-baselayout PackageName: alpine-baselayout SPDXID: SPDXRef-d782e64751ba9faa PackageVersion: 3.2.0-r18 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only ##### Package: musl-utils PackageName: musl-utils SPDXID: SPDXRef-e5e8a237f6162e22 PackageVersion: 1.2.2-r7 FilesAnalyzed: false PackageLicenseConcluded: MIT BSD GPL2+ PackageLicenseDeclared: MIT BSD GPL2+ ##### Package: ssl_client PackageName: ssl_client SPDXID: SPDXRef-fdf0ce84f6337be4 PackageVersion: 1.34.1-r5 FilesAnalyzed: false PackageLicenseConcluded: GPL-2.0-only PackageLicenseDeclared: GPL-2.0-only SPDX-JSON format is also supported by using spdx-json with the --format option. $ trivy image --format spdx-json --output result.spdx.json alpine:3.15 Result $ cat result.spdx.json | jq . { \"SPDXID\": \"SPDXRef-DOCUMENT\", \"creationInfo\": { \"created\": \"2022-04-28T08:16:55.328255Z\", \"creators\": [ \"Tool: trivy-0.38.1\", \"Organization: aquasecurity\" ] }, \"dataLicense\": \"CC0-1.0\", \"documentNamespace\": \"http://aquasecurity.github.io/trivy/container_image/alpine:3.15-d9549e3a-a4c5-4ee3-8bde-8c78d451fbe7\", \"name\": \"alpine:3.15\", \"packages\": [ { \"SPDXID\": \"SPDXRef-12bc938ac028a5e1\", \"filesAnalyzed\": false, \"licenseConcluded\": \"Zlib\", \"licenseDeclared\": \"Zlib\", \"name\": \"zlib\", \"versionInfo\": \"1.2.12-r0\" }, { \"SPDXID\": \"SPDXRef-26c274652190d87f\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"apk-tools\", \"versionInfo\": \"2.12.7-r3\" }, { \"SPDXID\": \"SPDXRef-2b021966d19a8211\", \"filesAnalyzed\": false, \"licenseConcluded\": \"ISC AND (BSD-3-Clause OR MIT)\", \"licenseDeclared\": \"ISC AND (BSD-3-Clause OR MIT)\", \"name\": \"libretls\", \"versionInfo\": \"3.3.4-r3\" }, { \"SPDXID\": \"SPDXRef-317ce3476703f20d\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"busybox\", \"versionInfo\": \"1.34.1-r5\" }, { \"SPDXID\": \"SPDXRef-34f407fb4dbd67f4\", \"filesAnalyzed\": false, \"licenseConcluded\": \"OpenSSL\", \"licenseDeclared\": \"OpenSSL\", \"name\": \"libcrypto1.1\", \"versionInfo\": \"1.1.1n-r0\" }, { \"SPDXID\": \"SPDXRef-4bbc1cb449d54083\", \"filesAnalyzed\": false, \"licenseConcluded\": \"BSD-2-Clause AND BSD-3-Clause\", \"licenseDeclared\": \"BSD-2-Clause AND BSD-3-Clause\", \"name\": \"libc-utils\", \"versionInfo\": \"0.7.2-r3\" }, { \"SPDXID\": \"SPDXRef-a3bdd174be1456b6\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MIT\", \"licenseDeclared\": \"MIT\", \"name\": \"alpine-keys\", \"versionInfo\": \"2.4-r1\" }, { \"SPDXID\": \"SPDXRef-ac6472ba26fb991c\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MPL-2.0 AND MIT\", \"licenseDeclared\": \"MPL-2.0 AND MIT\", \"name\": \"ca-certificates-bundle\", \"versionInfo\": \"20211220-r0\" }, { \"SPDXID\": \"SPDXRef-b2d1b1d70fe90f7d\", \"filesAnalyzed\": false, \"licenseConcluded\": \"OpenSSL\", \"licenseDeclared\": \"OpenSSL\", \"name\": \"libssl1.1\", \"versionInfo\": \"1.1.1n-r0\" }, { \"SPDXID\": \"SPDXRef-c617077ba6649520\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"scanelf\", \"versionInfo\": \"1.3.3-r0\" }, { \"SPDXID\": \"SPDXRef-ca80b810029cde0e\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MIT\", \"licenseDeclared\": \"MIT\", \"name\": \"musl\", \"versionInfo\": \"1.2.2-r7\" }, { \"SPDXID\": \"SPDXRef-d782e64751ba9faa\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"alpine-baselayout\", \"versionInfo\": \"3.2.0-r18\" }, { \"SPDXID\": \"SPDXRef-e5e8a237f6162e22\", \"filesAnalyzed\": false, \"licenseConcluded\": \"MIT BSD GPL2+\", \"licenseDeclared\": \"MIT BSD GPL2+\", \"name\": \"musl-utils\", \"versionInfo\": \"1.2.2-r7\" }, { \"SPDXID\": \"SPDXRef-fdf0ce84f6337be4\", \"filesAnalyzed\": false, \"licenseConcluded\": \"GPL-2.0-only\", \"licenseDeclared\": \"GPL-2.0-only\", \"name\": \"ssl_client\", \"versionInfo\": \"1.34.1-r5\" } ], \"spdxVersion\": \"SPDX-2.2\" } Use startline == 1 and endline == 1 for unsupported file types \u21a9 envs/*/conda-meta/*.json \u21a9","title":"SPDX"},{"location":"docs/supply-chain/vex/","text":"Vulnerability Exploitability Exchange (VEX) EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy supports filtering detected vulnerabilities using the Vulnerability Exploitability Exchange (VEX) , a standardized format for sharing and exchanging information about vulnerabilities. By providing VEX alongside the Software Bill of Materials (SBOM) during scanning, it is possible to filter vulnerabilities based on their status. Currently, Trivy supports the following two formats: CycloneDX OpenVEX This is still an experimental implementation, with only minimal functionality added. CycloneDX There are two VEX formats for CycloneDX: Independent BOM and VEX BOM BOM With Embedded VEX Trivy only supports the Independent BOM and VEX BOM format, so you need to provide a separate VEX file alongside the SBOM. The input SBOM format must be in CycloneDX format. The following steps are required: Generate a CycloneDX SBOM Create a VEX based on the SBOM generated in step 1 Provide the VEX when scanning the CycloneDX SBOM Generating the SBOM You can generate a CycloneDX SBOM with Trivy as follows: $ trivy image --format cyclonedx --output debian11.sbom.cdx debian:11 Create the VEX Next, create a VEX based on the generated SBOM. Multiple vulnerability statuses can be defined under vulnerabilities . Take a look at the example below. $ cat < trivy.vex.cdx { \"bomFormat\": \"CycloneDX\", \"specVersion\": \"1.4\", \"version\": 1, \"vulnerabilities\": [ { \"id\": \"CVE-2020-8911\", \"analysis\": { \"state\": \"not_affected\", \"justification\": \"code_not_reachable\", \"response\": [\"will_not_fix\", \"update\"], \"detail\": \"The vulnerable function is not called\" }, \"affects\": [ { \"ref\": \"urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#pkg:golang/github.com/aws/aws-sdk-go@1.44.234\" } ] } ] } EOF This is a VEX document in the CycloneDX format. The vulnerability ID, such as a CVE-ID or GHSA-ID, should be placed in vulnerabilities.id . When the analysis.state is set to not_affected , Trivy will not detect the vulnerability. BOM-Links must be placed in affects.ref . The BOM-Link has the following syntax and consists of three elements: urn:cdx:serialNumber/version#bom-ref serialNumber version bom-ref These values must be obtained from the CycloneDX SBOM. Please note that while the serialNumber starts with urn:uuid: , the BOM-Link starts with urn:cdx: . The bom-ref must contain the BOM-Ref of the package affected by the vulnerability. In the example above, since the Go package github.com/aws/aws-sdk-go is affected by CVE-2020-8911, it was necessary to specify the SBOM's BOM-Ref, pkg:golang/github.com/aws/aws-sdk-go@1.44.234 . For more details on CycloneDX VEX and BOM-Link, please refer to the following links: CycloneDX VEX BOM-Link Examples Scan SBOM with VEX Provide the VEX when scanning the CycloneDX SBOM. $ trivy sbom trivy.sbom.cdx --vex trivy.vex.cdx ... 2023-04-13T12:55:44.838+0300 INFO Filtered out the detected vulnerability {\"VEX format\": \"CycloneDX\", \"vulnerability-id\": \"CVE-2020-8911\", \"status\": \"not_affected\", \"justification\": \"code_not_reachable\"} go.mod (gomod) ============== Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 github.com/aws/aws-sdk-go \u2502 CVE-2020-8912 \u2502 LOW \u2502 1.44.234 \u2502 \u2502 aws-sdk-go: In-band key negotiation issue in AWS S3 Crypto \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 SDK for golang... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2020-8912 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document. OpenVEX Trivy also supports OpenVEX that is designed to be minimal, compliant, interoperable, and embeddable. Since OpenVEX aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy. The following steps are required: Generate a SBOM (CycloneDX or SPDX) Create a VEX based on the SBOM generated in step 1 Provide the VEX when scanning the SBOM Generating the SBOM You can generate a CycloneDX or SPDX SBOM with Trivy as follows: $ trivy image --format spdx-json --output debian11.spdx.json debian:11 Create the VEX Please see also the example . The product identifiers differ depending on the SBOM format the VEX references. SPDX: Package URL (PURL) CycloneDX: BOM-Link $ cat < trivy.openvex { \"@context\": \"https://openvex.dev/ns\", \"@id\": \"https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f\", \"author\": \"Aqua Security\", \"timestamp\": \"2023-01-16T19:07:16.853479631-06:00\", \"version\": \"1\", \"statements\": [ { \"vulnerability\": \"CVE-2019-8457\", \"products\": [ \"pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8?arch=arm64\\u0026distro=debian-11.6\" ], \"status\": \"not_affected\", \"justification\": \"vulnerable_code_not_in_execute_path\" } ] } EOF In the above example, PURLs, located in packages.externalRefs.referenceLocator are used since the input SBOM format is SPDX. As for CycloneDX BOM-Link, please reference the CycloneDX section . Scan SBOM with VEX Provide the VEX when scanning the SBOM. $ trivy sbom debian11.spdx.json --vex trivy.openvex ... 2023-04-26T17:56:05.358+0300 INFO Filtered out the detected vulnerability {\"VEX format\": \"OpenVEX\", \"vulnerability-id\": \"CVE-2019-8457\", \"status\": \"not_affected\", \"justification\": \"vulnerable_code_not_in_execute_path\"} debian11.spdx.json (debian 11.6) ================================ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0) CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document.","title":"VEX"},{"location":"docs/supply-chain/vex/#vulnerability-exploitability-exchange-vex","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy supports filtering detected vulnerabilities using the Vulnerability Exploitability Exchange (VEX) , a standardized format for sharing and exchanging information about vulnerabilities. By providing VEX alongside the Software Bill of Materials (SBOM) during scanning, it is possible to filter vulnerabilities based on their status. Currently, Trivy supports the following two formats: CycloneDX OpenVEX This is still an experimental implementation, with only minimal functionality added.","title":"Vulnerability Exploitability Exchange (VEX)"},{"location":"docs/supply-chain/vex/#cyclonedx","text":"There are two VEX formats for CycloneDX: Independent BOM and VEX BOM BOM With Embedded VEX Trivy only supports the Independent BOM and VEX BOM format, so you need to provide a separate VEX file alongside the SBOM. The input SBOM format must be in CycloneDX format. The following steps are required: Generate a CycloneDX SBOM Create a VEX based on the SBOM generated in step 1 Provide the VEX when scanning the CycloneDX SBOM","title":"CycloneDX"},{"location":"docs/supply-chain/vex/#generating-the-sbom","text":"You can generate a CycloneDX SBOM with Trivy as follows: $ trivy image --format cyclonedx --output debian11.sbom.cdx debian:11","title":"Generating the SBOM"},{"location":"docs/supply-chain/vex/#create-the-vex","text":"Next, create a VEX based on the generated SBOM. Multiple vulnerability statuses can be defined under vulnerabilities . Take a look at the example below. $ cat < trivy.vex.cdx { \"bomFormat\": \"CycloneDX\", \"specVersion\": \"1.4\", \"version\": 1, \"vulnerabilities\": [ { \"id\": \"CVE-2020-8911\", \"analysis\": { \"state\": \"not_affected\", \"justification\": \"code_not_reachable\", \"response\": [\"will_not_fix\", \"update\"], \"detail\": \"The vulnerable function is not called\" }, \"affects\": [ { \"ref\": \"urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#pkg:golang/github.com/aws/aws-sdk-go@1.44.234\" } ] } ] } EOF This is a VEX document in the CycloneDX format. The vulnerability ID, such as a CVE-ID or GHSA-ID, should be placed in vulnerabilities.id . When the analysis.state is set to not_affected , Trivy will not detect the vulnerability. BOM-Links must be placed in affects.ref . The BOM-Link has the following syntax and consists of three elements: urn:cdx:serialNumber/version#bom-ref serialNumber version bom-ref These values must be obtained from the CycloneDX SBOM. Please note that while the serialNumber starts with urn:uuid: , the BOM-Link starts with urn:cdx: . The bom-ref must contain the BOM-Ref of the package affected by the vulnerability. In the example above, since the Go package github.com/aws/aws-sdk-go is affected by CVE-2020-8911, it was necessary to specify the SBOM's BOM-Ref, pkg:golang/github.com/aws/aws-sdk-go@1.44.234 . For more details on CycloneDX VEX and BOM-Link, please refer to the following links: CycloneDX VEX BOM-Link Examples","title":"Create the VEX"},{"location":"docs/supply-chain/vex/#scan-sbom-with-vex","text":"Provide the VEX when scanning the CycloneDX SBOM. $ trivy sbom trivy.sbom.cdx --vex trivy.vex.cdx ... 2023-04-13T12:55:44.838+0300 INFO Filtered out the detected vulnerability {\"VEX format\": \"CycloneDX\", \"vulnerability-id\": \"CVE-2020-8911\", \"status\": \"not_affected\", \"justification\": \"code_not_reachable\"} go.mod (gomod) ============== Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 github.com/aws/aws-sdk-go \u2502 CVE-2020-8912 \u2502 LOW \u2502 1.44.234 \u2502 \u2502 aws-sdk-go: In-band key negotiation issue in AWS S3 Crypto \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 SDK for golang... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2020-8912 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document.","title":"Scan SBOM with VEX"},{"location":"docs/supply-chain/vex/#openvex","text":"Trivy also supports OpenVEX that is designed to be minimal, compliant, interoperable, and embeddable. Since OpenVEX aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy. The following steps are required: Generate a SBOM (CycloneDX or SPDX) Create a VEX based on the SBOM generated in step 1 Provide the VEX when scanning the SBOM","title":"OpenVEX"},{"location":"docs/supply-chain/vex/#generating-the-sbom_1","text":"You can generate a CycloneDX or SPDX SBOM with Trivy as follows: $ trivy image --format spdx-json --output debian11.spdx.json debian:11","title":"Generating the SBOM"},{"location":"docs/supply-chain/vex/#create-the-vex_1","text":"Please see also the example . The product identifiers differ depending on the SBOM format the VEX references. SPDX: Package URL (PURL) CycloneDX: BOM-Link $ cat < trivy.openvex { \"@context\": \"https://openvex.dev/ns\", \"@id\": \"https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f\", \"author\": \"Aqua Security\", \"timestamp\": \"2023-01-16T19:07:16.853479631-06:00\", \"version\": \"1\", \"statements\": [ { \"vulnerability\": \"CVE-2019-8457\", \"products\": [ \"pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8?arch=arm64\\u0026distro=debian-11.6\" ], \"status\": \"not_affected\", \"justification\": \"vulnerable_code_not_in_execute_path\" } ] } EOF In the above example, PURLs, located in packages.externalRefs.referenceLocator are used since the input SBOM format is SPDX. As for CycloneDX BOM-Link, please reference the CycloneDX section .","title":"Create the VEX"},{"location":"docs/supply-chain/vex/#scan-sbom-with-vex_1","text":"Provide the VEX when scanning the SBOM. $ trivy sbom debian11.spdx.json --vex trivy.openvex ... 2023-04-26T17:56:05.358+0300 INFO Filtered out the detected vulnerability {\"VEX format\": \"OpenVEX\", \"vulnerability-id\": \"CVE-2019-8457\", \"status\": \"not_affected\", \"justification\": \"vulnerable_code_not_in_execute_path\"} debian11.spdx.json (debian 11.6) ================================ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0) CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document.","title":"Scan SBOM with VEX"},{"location":"docs/supply-chain/attestation/rekor/","text":"Scan SBOM attestation in Rekor EXPERIMENTAL This feature might change without preserving backwards compatibility. Container images Trivy can retrieve SBOM attestation of the specified container image in the Rekor instance and scan it for vulnerabilities. Prerequisites SBOM attestation stored in Rekor See the \"Keyless signing\" section if you want to upload your SBOM attestation to Rekor. Scanning You need to pass --sbom-sources rekor so that Trivy will look for SBOM attestation in Rekor. Note --sbom-sources can be used only with trivy image at the moment. $ trivy image --sbom-sources rekor otms61/alpine:3.7.3 [ ~/src/github.com/aquasecurity/trivy ] 2022 -09-16T17:37:13.258+0900 INFO Vulnerability scanning is enabled 2022 -09-16T17:37:13.258+0900 INFO Secret scanning is enabled 2022 -09-16T17:37:13.258+0900 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning 2022 -09-16T17:37:13.258+0900 INFO Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection 2022 -09-16T17:37:14.827+0900 INFO Detected SBOM format: cyclonedx-json 2022 -09-16T17:37:14.901+0900 INFO Found SBOM ( cyclonedx ) attestation in Rekor 2022 -09-16T17:37:14.903+0900 INFO Detected OS: alpine 2022 -09-16T17:37:14.903+0900 INFO Detecting Alpine vulnerabilities... 2022 -09-16T17:37:14.907+0900 INFO Number of language-specific files: 0 2022 -09-16T17:37:14.908+0900 WARN This OS version is no longer supported by the distribution: alpine 3 .7.3 2022 -09-16T17:37:14.908+0900 WARN The vulnerability detection may be insufficient because security updates are not provided otms61/alpine:3.7.3 ( alpine 3 .7.3 ) ================================== Total: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 musl \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1 .1.18-r3 \u2502 1 .1.18-r4 \u2502 musl libc through 1 .1.23 has an x87 floating-point stack \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 adjustment im ...... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-14697 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 If you have your own Rekor instance, you can specify the URL via --rekor-url . $ trivy image --sbom-sources rekor --rekor-url https://my-rekor.dev otms61/alpine:3.7.3 Non-packaged binaries Trivy can retrieve SBOM attestation of non-packaged binaries in the Rekor instance and scan it for vulnerabilities. Prerequisites SBOM attestation stored in Rekor See the \"Keyless signing\" section if you want to upload your SBOM attestation to Rekor. Cosign currently does not support keyless signing for blob attestation, so use our plugin at the moment. This example uses a cat clone bat written in Rust. You need to generate SBOM from lock files like Cargo.lock at first. $ git clone -b v0.20.0 https://github.com/sharkdp/bat $ trivy fs --format cyclonedx --output bat.cdx ./bat/Cargo.lock Then our attestation plugin allows you to store the SBOM attestation linking to a bat binary in the Rekor instance. $ wget https://github.com/sharkdp/bat/releases/download/v0.20.0/bat-v0.20.0-x86_64-apple-darwin.tar.gz $ tar xvf bat-v0.20.0-x86_64-apple-darwin.tar.gz $ trivy plugin install github.com/aquasecurity/trivy-plugin-attest $ trivy attest --predicate ./bat.cdx --type cyclonedx ./bat-v0.20.0-x86_64-apple-darwin/bat Note The public instance of the Rekor maintained by the Sigstore team limits the attestation size. If you are using the public instance, please make sure that your SBOM is small enough. To get more detail, please refer to the Rekor project's documentation . Scan a non-packaged binary Trivy calculates the digest of the bat binary and searches for the SBOM attestation by the digest in Rekor. If it is found, Trivy uses that for vulnerability scanning. $ trivy fs --sbom-sources rekor ./bat-v0.20.0-x86_64-apple-darwin/bat 2022 -10-25T13:27:25.950+0300 INFO Found SBOM attestation in Rekor: bat 2022 -10-25T13:27:25.993+0300 INFO Number of language-specific files: 1 2022 -10-25T13:27:25.993+0300 INFO Detecting cargo vulnerabilities... bat ( cargo ) =========== Total: 1 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 1 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 regex \u2502 CVE-2022-24713 \u2502 HIGH \u2502 1 .5.4 \u2502 1 .5.5 \u2502 Mozilla: Denial of Service via complex regular expressions \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-24713 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Also, it is applied to non-packaged binaries even in container images. $ trivy image --sbom-sources rekor --scanners vuln alpine-with-bat 2022 -10-25T13:40:14.920+0300 INFO Vulnerability scanning is enabled 2022 -10-25T13:40:18.047+0300 INFO Found SBOM attestation in Rekor: bat 2022 -10-25T13:40:18.186+0300 INFO Detected OS: alpine 2022 -10-25T13:40:18.186+0300 INFO Detecting Alpine vulnerabilities... 2022 -10-25T13:40:18.199+0300 INFO Number of language-specific files: 1 2022 -10-25T13:40:18.199+0300 INFO Detecting cargo vulnerabilities... alpine-with-bat ( alpine 3 .15.6 ) =============================== Total: 0 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 0 ) bat ( cargo ) =========== Total: 4 ( UNKNOWN: 3 , LOW: 0 , MEDIUM: 0 , HIGH: 1 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 regex \u2502 CVE-2022-24713 \u2502 HIGH \u2502 1 .5.4 \u2502 1 .5.5 \u2502 Mozilla: Denial of Service via complex regular expressions \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-24713 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Note The --sbom-sources rekor flag slows down the scanning as it queries Rekor on the Internet for all non-packaged binaries.","title":"SBOM Attestation in Rekor"},{"location":"docs/supply-chain/attestation/rekor/#scan-sbom-attestation-in-rekor","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility.","title":"Scan SBOM attestation in Rekor"},{"location":"docs/supply-chain/attestation/rekor/#container-images","text":"Trivy can retrieve SBOM attestation of the specified container image in the Rekor instance and scan it for vulnerabilities.","title":"Container images"},{"location":"docs/supply-chain/attestation/rekor/#prerequisites","text":"SBOM attestation stored in Rekor See the \"Keyless signing\" section if you want to upload your SBOM attestation to Rekor.","title":"Prerequisites"},{"location":"docs/supply-chain/attestation/rekor/#scanning","text":"You need to pass --sbom-sources rekor so that Trivy will look for SBOM attestation in Rekor. Note --sbom-sources can be used only with trivy image at the moment. $ trivy image --sbom-sources rekor otms61/alpine:3.7.3 [ ~/src/github.com/aquasecurity/trivy ] 2022 -09-16T17:37:13.258+0900 INFO Vulnerability scanning is enabled 2022 -09-16T17:37:13.258+0900 INFO Secret scanning is enabled 2022 -09-16T17:37:13.258+0900 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning 2022 -09-16T17:37:13.258+0900 INFO Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection 2022 -09-16T17:37:14.827+0900 INFO Detected SBOM format: cyclonedx-json 2022 -09-16T17:37:14.901+0900 INFO Found SBOM ( cyclonedx ) attestation in Rekor 2022 -09-16T17:37:14.903+0900 INFO Detected OS: alpine 2022 -09-16T17:37:14.903+0900 INFO Detecting Alpine vulnerabilities... 2022 -09-16T17:37:14.907+0900 INFO Number of language-specific files: 0 2022 -09-16T17:37:14.908+0900 WARN This OS version is no longer supported by the distribution: alpine 3 .7.3 2022 -09-16T17:37:14.908+0900 WARN The vulnerability detection may be insufficient because security updates are not provided otms61/alpine:3.7.3 ( alpine 3 .7.3 ) ================================== Total: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 musl \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1 .1.18-r3 \u2502 1 .1.18-r4 \u2502 musl libc through 1 .1.23 has an x87 floating-point stack \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 adjustment im ...... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-14697 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 If you have your own Rekor instance, you can specify the URL via --rekor-url . $ trivy image --sbom-sources rekor --rekor-url https://my-rekor.dev otms61/alpine:3.7.3","title":"Scanning"},{"location":"docs/supply-chain/attestation/rekor/#non-packaged-binaries","text":"Trivy can retrieve SBOM attestation of non-packaged binaries in the Rekor instance and scan it for vulnerabilities.","title":"Non-packaged binaries"},{"location":"docs/supply-chain/attestation/rekor/#prerequisites_1","text":"SBOM attestation stored in Rekor See the \"Keyless signing\" section if you want to upload your SBOM attestation to Rekor. Cosign currently does not support keyless signing for blob attestation, so use our plugin at the moment. This example uses a cat clone bat written in Rust. You need to generate SBOM from lock files like Cargo.lock at first. $ git clone -b v0.20.0 https://github.com/sharkdp/bat $ trivy fs --format cyclonedx --output bat.cdx ./bat/Cargo.lock Then our attestation plugin allows you to store the SBOM attestation linking to a bat binary in the Rekor instance. $ wget https://github.com/sharkdp/bat/releases/download/v0.20.0/bat-v0.20.0-x86_64-apple-darwin.tar.gz $ tar xvf bat-v0.20.0-x86_64-apple-darwin.tar.gz $ trivy plugin install github.com/aquasecurity/trivy-plugin-attest $ trivy attest --predicate ./bat.cdx --type cyclonedx ./bat-v0.20.0-x86_64-apple-darwin/bat Note The public instance of the Rekor maintained by the Sigstore team limits the attestation size. If you are using the public instance, please make sure that your SBOM is small enough. To get more detail, please refer to the Rekor project's documentation .","title":"Prerequisites"},{"location":"docs/supply-chain/attestation/rekor/#scan-a-non-packaged-binary","text":"Trivy calculates the digest of the bat binary and searches for the SBOM attestation by the digest in Rekor. If it is found, Trivy uses that for vulnerability scanning. $ trivy fs --sbom-sources rekor ./bat-v0.20.0-x86_64-apple-darwin/bat 2022 -10-25T13:27:25.950+0300 INFO Found SBOM attestation in Rekor: bat 2022 -10-25T13:27:25.993+0300 INFO Number of language-specific files: 1 2022 -10-25T13:27:25.993+0300 INFO Detecting cargo vulnerabilities... bat ( cargo ) =========== Total: 1 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 1 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 regex \u2502 CVE-2022-24713 \u2502 HIGH \u2502 1 .5.4 \u2502 1 .5.5 \u2502 Mozilla: Denial of Service via complex regular expressions \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-24713 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Also, it is applied to non-packaged binaries even in container images. $ trivy image --sbom-sources rekor --scanners vuln alpine-with-bat 2022 -10-25T13:40:14.920+0300 INFO Vulnerability scanning is enabled 2022 -10-25T13:40:18.047+0300 INFO Found SBOM attestation in Rekor: bat 2022 -10-25T13:40:18.186+0300 INFO Detected OS: alpine 2022 -10-25T13:40:18.186+0300 INFO Detecting Alpine vulnerabilities... 2022 -10-25T13:40:18.199+0300 INFO Number of language-specific files: 1 2022 -10-25T13:40:18.199+0300 INFO Detecting cargo vulnerabilities... alpine-with-bat ( alpine 3 .15.6 ) =============================== Total: 0 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 0 ) bat ( cargo ) =========== Total: 4 ( UNKNOWN: 3 , LOW: 0 , MEDIUM: 0 , HIGH: 1 , CRITICAL: 0 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 regex \u2502 CVE-2022-24713 \u2502 HIGH \u2502 1 .5.4 \u2502 1 .5.5 \u2502 Mozilla: Denial of Service via complex regular expressions \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-24713 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Note The --sbom-sources rekor flag slows down the scanning as it queries Rekor on the Internet for all non-packaged binaries.","title":"Scan a non-packaged binary"},{"location":"docs/supply-chain/attestation/sbom/","text":"SBOM attestation Cosign supports generating and verifying in-toto attestations . This tool enables you to sign and verify SBOM attestation. And, Trivy can take an SBOM attestation as input and scan for vulnerabilities Note In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command. Sign with a local key pair Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs . $ cosign generate-key-pair In the following example, Trivy generates an SBOM in the CycloneDX format, and then Cosign attaches an attestation of the SBOM to a container image with a local key pair. # The cyclonedx type is supported in Cosign v1.10.0 or later. $ trivy image --format cyclonedx -o sbom.cdx.json $ cosign attest --key /path/to/cosign.key --type cyclonedx --predicate sbom.cdx.json Then, you can verify attestations on the image. $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx You can also create attestations of other formatted SBOM. # spdx $ trivy image --format spdx -o sbom.spdx $ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx # spdx-json $ trivy image --format spdx-json -o sbom.spdx.json $ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx.json Keyless signing You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft). # The cyclonedx type is supported in Cosign v1.10.0 or later. $ trivy image --format cyclonedx -o sbom.cdx.json # The following command uploads SBOM attestation to the public Rekor instance. $ COSIGN_EXPERIMENTAL = 1 cosign attest --type cyclonedx --predicate sbom.cdx.json You can verify attestations. $ COSIGN_EXPERIMENTAL = 1 cosign verify-attestation --type cyclonedx Scanning Trivy can take an SBOM attestation as input and scan for vulnerabilities. Currently, Trivy supports CycloneDX-type attestation. In the following example, Cosign can get an CycloneDX-type attestation and trivy scan it. You must create CycloneDX-type attestation before trying the example. To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the Sign with a local key pair section. $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx > sbom.cdx.intoto.jsonl $ trivy sbom ./sbom.cdx.intoto.jsonl sbom.cdx.intoto.jsonl ( alpine 3 .7.3 ) ========================= Total: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 musl \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1 .1.18-r3 \u2502 1 .1.18-r4 \u2502 musl libc through 1 .1.23 has an x87 floating-point stack \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 adjustment im ...... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-14697 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"SBOM"},{"location":"docs/supply-chain/attestation/sbom/#sbom-attestation","text":"Cosign supports generating and verifying in-toto attestations . This tool enables you to sign and verify SBOM attestation. And, Trivy can take an SBOM attestation as input and scan for vulnerabilities Note In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.","title":"SBOM attestation"},{"location":"docs/supply-chain/attestation/sbom/#sign-with-a-local-key-pair","text":"Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs . $ cosign generate-key-pair In the following example, Trivy generates an SBOM in the CycloneDX format, and then Cosign attaches an attestation of the SBOM to a container image with a local key pair. # The cyclonedx type is supported in Cosign v1.10.0 or later. $ trivy image --format cyclonedx -o sbom.cdx.json $ cosign attest --key /path/to/cosign.key --type cyclonedx --predicate sbom.cdx.json Then, you can verify attestations on the image. $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx You can also create attestations of other formatted SBOM. # spdx $ trivy image --format spdx -o sbom.spdx $ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx # spdx-json $ trivy image --format spdx-json -o sbom.spdx.json $ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx.json ","title":"Sign with a local key pair"},{"location":"docs/supply-chain/attestation/sbom/#keyless-signing","text":"You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft). # The cyclonedx type is supported in Cosign v1.10.0 or later. $ trivy image --format cyclonedx -o sbom.cdx.json # The following command uploads SBOM attestation to the public Rekor instance. $ COSIGN_EXPERIMENTAL = 1 cosign attest --type cyclonedx --predicate sbom.cdx.json You can verify attestations. $ COSIGN_EXPERIMENTAL = 1 cosign verify-attestation --type cyclonedx ","title":"Keyless signing"},{"location":"docs/supply-chain/attestation/sbom/#scanning","text":"Trivy can take an SBOM attestation as input and scan for vulnerabilities. Currently, Trivy supports CycloneDX-type attestation. In the following example, Cosign can get an CycloneDX-type attestation and trivy scan it. You must create CycloneDX-type attestation before trying the example. To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the Sign with a local key pair section. $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx > sbom.cdx.intoto.jsonl $ trivy sbom ./sbom.cdx.intoto.jsonl sbom.cdx.intoto.jsonl ( alpine 3 .7.3 ) ========================= Total: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 musl \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1 .1.18-r3 \u2502 1 .1.18-r4 \u2502 musl libc through 1 .1.23 has an x87 floating-point stack \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 adjustment im ...... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-14697 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Scanning"},{"location":"docs/supply-chain/attestation/vuln/","text":"Cosign Vulnerability Attestation Generate Cosign Vulnerability Scan Record Trivy generates reports in the Cosign vulnerability scan record format . You can use the regular subcommands (like image, fs and rootfs) and specify cosign-vuln with the --format option. $ trivy image --format cosign-vuln --output vuln.json alpine:3.10 Result { \"invocation\" : { \"parameters\" : null , \"uri\" : \"\" , \"event_id\" : \"\" , \"builder.id\" : \"\" }, \"scanner\" : { \"uri\" : \"pkg:github/aquasecurity/trivy@v0.30.1-8-gf9cb8a28\" , \"version\" : \"v0.30.1-8-gf9cb8a28\" , \"db\" : { \"uri\" : \"\" , \"version\" : \"\" }, \"result\" : { \"SchemaVersion\" : 2 , \"ArtifactName\" : \"alpine:3.10\" , \"ArtifactType\" : \"container_image\" , \"Metadata\" : { \"OS\" : { \"Family\" : \"alpine\" , \"Name\" : \"3.10.9\" , \"EOSL\" : true }, \"ImageID\" : \"sha256:e7b300aee9f9bf3433d32bc9305bfdd22183beb59d933b48d77ab56ba53a197a\" , \"DiffIDs\" : [ \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\" ], \"RepoTags\" : [ \"alpine:3.10\" ], \"RepoDigests\" : [ \"alpine@sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98\" ], \"ImageConfig\" : { \"architecture\" : \"amd64\" , \"container\" : \"fdb7e80e3339e8d0599282e606c907aa5881ee4c668a68136119e6dfac6ce3a4\" , \"created\" : \"2021-04-14T19:20:05.338397761Z\" , \"docker_version\" : \"19.03.12\" , \"history\" : [ { \"created\" : \"2021-04-14T19:20:04.987219124Z\" , \"created_by\" : \"/bin/sh -c #(nop) ADD file:c5377eaa926bf412dd8d4a08b0a1f2399cfd708743533b0aa03b53d14cb4bb4e in / \" }, { \"created\" : \"2021-04-14T19:20:05.338397761Z\" , \"created_by\" : \"/bin/sh -c #(nop) CMD [\\\"/bin/sh\\\"]\" , \"empty_layer\" : true } ], \"os\" : \"linux\" , \"rootfs\" : { \"type\" : \"layers\" , \"diff_ids\" : [ \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\" ] }, \"config\" : { \"Cmd\" : [ \"/bin/sh\" ], \"Env\" : [ \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\" ], \"Image\" : \"sha256:eb2080c455e94c22ae35b3aef9e078c492a00795412e026e4d6b41ef64bc7dd8\" } } }, \"Results\" : [ { \"Target\" : \"alpine:3.10 (alpine 3.10.9)\" , \"Class\" : \"os-pkgs\" , \"Type\" : \"alpine\" , \"Vulnerabilities\" : [ { \"VulnerabilityID\" : \"CVE-2021-36159\" , \"PkgName\" : \"apk-tools\" , \"InstalledVersion\" : \"2.10.6-r0\" , \"FixedVersion\" : \"2.10.7-r0\" , \"Layer\" : { \"Digest\" : \"sha256:396c31837116ac290458afcb928f68b6cc1c7bdd6963fc72f52f365a2a89c1b5\" , \"DiffID\" : \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\" }, \"SeveritySource\" : \"nvd\" , \"PrimaryURL\" : \"https://avd.aquasec.com/nvd/cve-2021-36159\" , \"DataSource\" : { \"ID\" : \"alpine\" , \"Name\" : \"Alpine Secdb\" , \"URL\" : \"https://secdb.alpinelinux.org/\" }, \"Description\" : \"libfetch before 2021-07-26, as used in apk-tools, xbps, and other products, mishandles numeric strings for the FTP and HTTP protocols. The FTP passive mode implementation allows an out-of-bounds read because strtol is used to parse the relevant numbers into address bytes. It does not check if the line ends prematurely. If it does, the for-loop condition checks for the '\\\\0' terminator one byte too late.\" , \"Severity\" : \"CRITICAL\" , \"CweIDs\" : [ \"CWE-125\" ], \"CVSS\" : { \"nvd\" : { \"V2Vector\" : \"AV:N/AC:L/Au:N/C:P/I:N/A:P\" , \"V3Vector\" : \"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H\" , \"V2Score\" : 6.4 , \"V3Score\" : 9.1 } }, \"References\" : [ \"https://github.com/freebsd/freebsd-src/commits/main/lib/libfetch\" , \"https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10749\" , \"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cdev.kafka.apache.org%3E\" , \"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cusers.kafka.apache.org%3E\" , \"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cdev.kafka.apache.org%3E\" , \"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cusers.kafka.apache.org%3E\" ], \"PublishedDate\" : \"2021-08-03T14:15:00Z\" , \"LastModifiedDate\" : \"2021-10-18T12:19:00Z\" } ] } ] } }, \"metadata\" : { \"scanStartedOn\" : \"2022-07-24T17:14:04.864682+09:00\" , \"scanFinishedOn\" : \"2022-07-24T17:14:04.864682+09:00\" } } Create Cosign Vulnerability Attestation Cosign supports generating and verifying in-toto attestations . This tool enables you to sign and verify Cosign vulnerability attestation. Note In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command. Sign with a local key pair Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs . $ cosign generate-key-pair In the following example, Trivy generates a cosign vulnerability scan record, and then Cosign attaches an attestation of it to a container image with a local key pair. $ trivy image --format cosign-vuln --output vuln.json $ cosign attest --key /path/to/cosign.key --type vuln --predicate vuln.json Then, you can verify attestations on the image. $ cosign verify-attestation --key /path/to/cosign.pub --type vuln Keyless signing You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft). $ trivy image --format cosign-vuln -o vuln.json $ COSIGN_EXPERIMENTAL=1 cosign attest --type vuln --predicate vuln.json You can verify attestations. $ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type vuln ","title":"Cosign Vulnerability Scan Record"},{"location":"docs/supply-chain/attestation/vuln/#cosign-vulnerability-attestation","text":"","title":"Cosign Vulnerability Attestation"},{"location":"docs/supply-chain/attestation/vuln/#generate-cosign-vulnerability-scan-record","text":"Trivy generates reports in the Cosign vulnerability scan record format . You can use the regular subcommands (like image, fs and rootfs) and specify cosign-vuln with the --format option. $ trivy image --format cosign-vuln --output vuln.json alpine:3.10 Result { \"invocation\" : { \"parameters\" : null , \"uri\" : \"\" , \"event_id\" : \"\" , \"builder.id\" : \"\" }, \"scanner\" : { \"uri\" : \"pkg:github/aquasecurity/trivy@v0.30.1-8-gf9cb8a28\" , \"version\" : \"v0.30.1-8-gf9cb8a28\" , \"db\" : { \"uri\" : \"\" , \"version\" : \"\" }, \"result\" : { \"SchemaVersion\" : 2 , \"ArtifactName\" : \"alpine:3.10\" , \"ArtifactType\" : \"container_image\" , \"Metadata\" : { \"OS\" : { \"Family\" : \"alpine\" , \"Name\" : \"3.10.9\" , \"EOSL\" : true }, \"ImageID\" : \"sha256:e7b300aee9f9bf3433d32bc9305bfdd22183beb59d933b48d77ab56ba53a197a\" , \"DiffIDs\" : [ \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\" ], \"RepoTags\" : [ \"alpine:3.10\" ], \"RepoDigests\" : [ \"alpine@sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98\" ], \"ImageConfig\" : { \"architecture\" : \"amd64\" , \"container\" : \"fdb7e80e3339e8d0599282e606c907aa5881ee4c668a68136119e6dfac6ce3a4\" , \"created\" : \"2021-04-14T19:20:05.338397761Z\" , \"docker_version\" : \"19.03.12\" , \"history\" : [ { \"created\" : \"2021-04-14T19:20:04.987219124Z\" , \"created_by\" : \"/bin/sh -c #(nop) ADD file:c5377eaa926bf412dd8d4a08b0a1f2399cfd708743533b0aa03b53d14cb4bb4e in / \" }, { \"created\" : \"2021-04-14T19:20:05.338397761Z\" , \"created_by\" : \"/bin/sh -c #(nop) CMD [\\\"/bin/sh\\\"]\" , \"empty_layer\" : true } ], \"os\" : \"linux\" , \"rootfs\" : { \"type\" : \"layers\" , \"diff_ids\" : [ \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\" ] }, \"config\" : { \"Cmd\" : [ \"/bin/sh\" ], \"Env\" : [ \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\" ], \"Image\" : \"sha256:eb2080c455e94c22ae35b3aef9e078c492a00795412e026e4d6b41ef64bc7dd8\" } } }, \"Results\" : [ { \"Target\" : \"alpine:3.10 (alpine 3.10.9)\" , \"Class\" : \"os-pkgs\" , \"Type\" : \"alpine\" , \"Vulnerabilities\" : [ { \"VulnerabilityID\" : \"CVE-2021-36159\" , \"PkgName\" : \"apk-tools\" , \"InstalledVersion\" : \"2.10.6-r0\" , \"FixedVersion\" : \"2.10.7-r0\" , \"Layer\" : { \"Digest\" : \"sha256:396c31837116ac290458afcb928f68b6cc1c7bdd6963fc72f52f365a2a89c1b5\" , \"DiffID\" : \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\" }, \"SeveritySource\" : \"nvd\" , \"PrimaryURL\" : \"https://avd.aquasec.com/nvd/cve-2021-36159\" , \"DataSource\" : { \"ID\" : \"alpine\" , \"Name\" : \"Alpine Secdb\" , \"URL\" : \"https://secdb.alpinelinux.org/\" }, \"Description\" : \"libfetch before 2021-07-26, as used in apk-tools, xbps, and other products, mishandles numeric strings for the FTP and HTTP protocols. The FTP passive mode implementation allows an out-of-bounds read because strtol is used to parse the relevant numbers into address bytes. It does not check if the line ends prematurely. If it does, the for-loop condition checks for the '\\\\0' terminator one byte too late.\" , \"Severity\" : \"CRITICAL\" , \"CweIDs\" : [ \"CWE-125\" ], \"CVSS\" : { \"nvd\" : { \"V2Vector\" : \"AV:N/AC:L/Au:N/C:P/I:N/A:P\" , \"V3Vector\" : \"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H\" , \"V2Score\" : 6.4 , \"V3Score\" : 9.1 } }, \"References\" : [ \"https://github.com/freebsd/freebsd-src/commits/main/lib/libfetch\" , \"https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10749\" , \"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cdev.kafka.apache.org%3E\" , \"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cusers.kafka.apache.org%3E\" , \"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cdev.kafka.apache.org%3E\" , \"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cusers.kafka.apache.org%3E\" ], \"PublishedDate\" : \"2021-08-03T14:15:00Z\" , \"LastModifiedDate\" : \"2021-10-18T12:19:00Z\" } ] } ] } }, \"metadata\" : { \"scanStartedOn\" : \"2022-07-24T17:14:04.864682+09:00\" , \"scanFinishedOn\" : \"2022-07-24T17:14:04.864682+09:00\" } }","title":"Generate Cosign Vulnerability Scan Record"},{"location":"docs/supply-chain/attestation/vuln/#create-cosign-vulnerability-attestation","text":"Cosign supports generating and verifying in-toto attestations . This tool enables you to sign and verify Cosign vulnerability attestation. Note In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.","title":"Create Cosign Vulnerability Attestation"},{"location":"docs/supply-chain/attestation/vuln/#sign-with-a-local-key-pair","text":"Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs . $ cosign generate-key-pair In the following example, Trivy generates a cosign vulnerability scan record, and then Cosign attaches an attestation of it to a container image with a local key pair. $ trivy image --format cosign-vuln --output vuln.json $ cosign attest --key /path/to/cosign.key --type vuln --predicate vuln.json Then, you can verify attestations on the image. $ cosign verify-attestation --key /path/to/cosign.pub --type vuln ","title":"Sign with a local key pair"},{"location":"docs/supply-chain/attestation/vuln/#keyless-signing","text":"You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft). $ trivy image --format cosign-vuln -o vuln.json $ COSIGN_EXPERIMENTAL=1 cosign attest --type vuln --predicate vuln.json You can verify attestations. $ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type vuln ","title":"Keyless signing"},{"location":"docs/target/aws/","text":"Amazon Web Services EXPERIMENTAL This feature might change without preserving backwards compatibility. The Trivy AWS CLI allows you to scan your AWS account for misconfigurations. You can either run the CLI locally or integrate it into your CI/CD pipeline. Whilst you can already scan the infrastructure-as-code that defines your AWS resources with trivy config , you can now scan your live AWS account(s) directly too. The included checks cover all of the aspects of the AWS CIS 1.2 automated benchmarks. Trivy uses the same authentication methods as the AWS CLI to configure and authenticate your access to the AWS platform. You will need permissions configured to read all AWS resources - we recommend using a group/role with the ReadOnlyAccess policy attached. Once you've scanned your account, you can run additional commands to filter the results without having to run the entire scan again - infrastructure information is cached locally per AWS account/region. Trivy currently supports the following scanning for AWS accounts. Misconfigurations CLI Commands Scan a full AWS account (all supported services): trivy aws --region us-east-1 You can allow Trivy to determine the AWS region etc. by using the standard AWS configuration files and environment variables. The --region flag overrides these. The summary view is the default when scanning multiple services. Scan a specific service: trivy aws --service s3 Scan multiple services: # --service s3,ec2 works too trivy aws --service s3 --service ec2 Show results for a specific AWS resource: trivy aws --service s3 --arn arn:aws:s3:::example-bucket All ARNs with detected issues will be displayed when showing results for their associated service. Compliance This section describes AWS specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation . Built in reports the following reports are available out of the box: Compliance Name for command More info AWS CIS Foundations Benchmark v1.2 aws-cis-1.2 link AWS CIS Foundations Benchmark v1.4 aws-cis-1.4 link Examples Scan a cloud account and generate a compliance summary report: $ trivy aws --compliance= --report=summary Note : The Issues column represent the total number of failed checks for this control. Get all of the detailed output for checks: $ trivy aws --compliance= --report all Report result in JSON format: $ trivy aws --compliance= --report all --format json Cached Results By default, Trivy will cache a representation of each AWS service for 24 hours. This means you can filter and view results for a service without having to wait for the entire scan to run again. If you want to force the cache to be refreshed with the latest data, you can use --update-cache . Or if you'd like to use cached data for a different timeframe, you can specify --max-cache-age (e.g. --max-cache-age 2h .). Regardless of whether the cache is used or not, rules will be evaluated again with each run of trivy aws . Custom Policies You can write custom policies for Trivy to evaluate against your AWS account. These policies are written in Rego , the same language used by Open Policy Agent . See the Custom Policies page for more information.","title":"AWS"},{"location":"docs/target/aws/#amazon-web-services","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. The Trivy AWS CLI allows you to scan your AWS account for misconfigurations. You can either run the CLI locally or integrate it into your CI/CD pipeline. Whilst you can already scan the infrastructure-as-code that defines your AWS resources with trivy config , you can now scan your live AWS account(s) directly too. The included checks cover all of the aspects of the AWS CIS 1.2 automated benchmarks. Trivy uses the same authentication methods as the AWS CLI to configure and authenticate your access to the AWS platform. You will need permissions configured to read all AWS resources - we recommend using a group/role with the ReadOnlyAccess policy attached. Once you've scanned your account, you can run additional commands to filter the results without having to run the entire scan again - infrastructure information is cached locally per AWS account/region. Trivy currently supports the following scanning for AWS accounts. Misconfigurations","title":"Amazon Web Services"},{"location":"docs/target/aws/#cli-commands","text":"Scan a full AWS account (all supported services): trivy aws --region us-east-1 You can allow Trivy to determine the AWS region etc. by using the standard AWS configuration files and environment variables. The --region flag overrides these. The summary view is the default when scanning multiple services. Scan a specific service: trivy aws --service s3 Scan multiple services: # --service s3,ec2 works too trivy aws --service s3 --service ec2 Show results for a specific AWS resource: trivy aws --service s3 --arn arn:aws:s3:::example-bucket All ARNs with detected issues will be displayed when showing results for their associated service.","title":"CLI Commands"},{"location":"docs/target/aws/#compliance","text":"This section describes AWS specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation .","title":"Compliance"},{"location":"docs/target/aws/#built-in-reports","text":"the following reports are available out of the box: Compliance Name for command More info AWS CIS Foundations Benchmark v1.2 aws-cis-1.2 link AWS CIS Foundations Benchmark v1.4 aws-cis-1.4 link","title":"Built in reports"},{"location":"docs/target/aws/#examples","text":"Scan a cloud account and generate a compliance summary report: $ trivy aws --compliance= --report=summary Note : The Issues column represent the total number of failed checks for this control. Get all of the detailed output for checks: $ trivy aws --compliance= --report all Report result in JSON format: $ trivy aws --compliance= --report all --format json","title":"Examples"},{"location":"docs/target/aws/#cached-results","text":"By default, Trivy will cache a representation of each AWS service for 24 hours. This means you can filter and view results for a service without having to wait for the entire scan to run again. If you want to force the cache to be refreshed with the latest data, you can use --update-cache . Or if you'd like to use cached data for a different timeframe, you can specify --max-cache-age (e.g. --max-cache-age 2h .). Regardless of whether the cache is used or not, rules will be evaluated again with each run of trivy aws .","title":"Cached Results"},{"location":"docs/target/aws/#custom-policies","text":"You can write custom policies for Trivy to evaluate against your AWS account. These policies are written in Rego , the same language used by Open Policy Agent . See the Custom Policies page for more information.","title":"Custom Policies"},{"location":"docs/target/container_image/","text":"Container Image Trivy supports two targets for container images. Files inside container images Container image metadata Files inside container images Container images consist of files. For instance, new files will be installed if you install a package. Trivy scans the files inside container images for Vulnerabilities Misconfigurations Secrets Licenses By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners . Vulnerabilities It is enabled by default. You can simply specify your image name (and a tag). It detects known vulnerabilities in your container image. See here for the detail. $ trivy image [YOUR_IMAGE_NAME] For example: $ trivy image python:3.4-alpine Result 2019-05-16T01:20:43.180+0900 INFO Updating vulnerability database... 2019-05-16T01:20:53.029+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 (alpine 3.9.2) =================================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+--------------------------------+ | openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 | | | | | | | with long nonces | +---------+------------------+----------+-------------------+---------------+--------------------------------+ To enable only vulnerability scanning, you can specify --scanners vuln . $ trivy image --scanners vuln [ YOUR_IMAGE_NAME ] Misconfigurations It is supported, but it is not useful in most cases. As mentioned here , Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. If your container image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners config . $ trivy image --scanners config [YOUR_IMAGE_NAME] Secrets It is enabled by default. See here for the detail. $ trivy image [ YOUR_IMAGE_NAME ] Licenses It is disabled by default. See here for the detail. $ trivy image --scanners license [ YOUR_IMAGE_NAME ] Container image metadata Container images have configuration . docker inspect and docker history show the information according to the configuration. Trivy scans the configuration of container images for Misconfigurations Secrets They are disabled by default. You can enable them with --image-config-scanners . Tips The configuration can be exported as the JSON file by docker save . Misconfigurations Trivy detects misconfigurations on the configuration of container images. The image config is converted into Dockerfile and Trivy handles it as Dockerfile. See here for the detail of Dockerfile scanning. It is disabled by default. You can enable it with --image-config-scanners config . $ trivy image --image-config-scanners config [YOUR_IMAGE_NAME] If you just want to scan the image config, you can disable scanners with --scanners none . For example: $ trivy image --scanners none --image-config-scanners config alpine:3.17.0 Result alpine:3.17 (dockerfile) ======================== Tests: 24 (SUCCESSES: 21, FAILURES: 3, EXCEPTIONS: 0) Failures: 3 (UNKNOWN: 0, LOW: 2, MEDIUM: 0, HIGH: 1, CRITICAL: 0) HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 LOW: Consider using 'COPY file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' command instead of 'ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files. See https://avd.aquasec.com/misconfig/ds005 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 alpine:3.17:1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 [ ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in / \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 LOW: Add HEALTHCHECK instruction in your Dockerfile \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers. See https://avd.aquasec.com/misconfig/ds026 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Tip You can see how each layer is created with docker history . Secrets Trivy detects secrets on the configuration of container images. The image config is converted into JSON and Trivy scans the file for secrets. It is especially useful for environment variables that are likely to have credentials by accident. See here for the detail. $ trivy image --image-config-scanners secret [ YOUR_IMAGE_NAME ] If you just want to scan the image config, you can disable scanners with --scanners none . For example: $ trivy image --scanners none --image-config-scanners secret vuln-image Result vuln-image (alpine 3.17.1) ========================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) vuln-image (secrets) ==================== Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2) CRITICAL: GitHub (github-pat) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 GitHub Personal Access Token \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 test:16 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 14 { 15 \"created\": \"2023-01-09T17:05:20Z\", 16 [ \"created_by\": \"ENV secret=****************************************\", 17 \"comment\": \"buildkit.dockerfile.v0\", \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 CRITICAL: GitHub (github-pat) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 GitHub Personal Access Token \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 test:34 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 32 \"Env\": [ 33 \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\", 34 [ \"secret=****************************************\" 35 ] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Tip You can see environment variables with docker inspect . Supported Trivy will look for the specified image in a series of locations. By default, it will first look in the local Docker Engine, then Containerd, Podman, and finally container registry. This behavior can be modified with the --image-src flag. For example, the command trivy image --image-src podman,containerd alpine:3.7.3 Will first search in Podman. If the image is found there, it will be scanned and the results returned. If the image is not found in Podman, then Trivy will search in Containerd. If the image is not found there either, the scan will fail and no more image sources will be searched. Docker Engine Trivy tries to looks for the specified image in your local Docker Engine. It will be skipped if Docker Engine is not running locally. If your docker socket is not the default path, you can override it via DOCKER_HOST . containerd EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy tries to looks for the specified image in your local containerd . It will be skipped if containerd is not running locally. Specify your image name in containerd running locally. $ nerdctl images REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE aquasec/nginx latest 2bcabc23b454 3 hours ago linux/amd64 149 .1 MiB 54 .1 MiB $ trivy image aquasec/nginx If your containerd socket is not the default path ( //run/containerd/containerd.sock ), you can override it via CONTAINERD_ADDRESS . $ export CONTAINERD_ADDRESS = /run/k3s/containerd/containerd.sock $ trivy image aquasec/nginx If your scan targets are images in a namespace other than containerd's default namespace ( default ), you can override it via CONTAINERD_NAMESPACE . $ export CONTAINERD_NAMESPACE = k8s.io $ trivy image aquasec/nginx Podman EXPERIMENTAL This feature might change without preserving backwards compatibility. Scan your image in Podman (>=2.0) running locally. The remote Podman is not supported. Before performing Trivy commands, you must enable the podman.sock systemd service on your machine. For more details, see here . $ systemctl --user enable --now podman.socket Then, you can scan your image in Podman. $ cat Dockerfile FROM alpine:3.12 RUN apk add --no-cache bash $ podman build -t test . $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/test latest efc372d4e0de About a minute ago 7 .94 MB $ trivy image test Container Registry Trivy supports registries that comply with the following specifications. Docker Registry HTTP API V2 OCI Distribution Specification You can configure credentials with docker login . See here for the detail. Tar Files Trivy supports image tar files generated by the following tools. Docker Image Specification Moby Project Buildah Podman img Kaniko $ docker pull ruby:3.1-alpine3.15 $ docker save ruby:3.1-alpine3.15 -o ruby-3.1.tar $ trivy image --input ruby-3.1.tar Result 2022-02-03T10:08:19.127Z INFO Detected OS: alpine 2022-02-03T10:08:19.127Z WARN This OS version is not on the EOL list: alpine 3.15 2022-02-03T10:08:19.127Z INFO Detecting Alpine vulnerabilities... 2022-02-03T10:08:19.127Z INFO Number of language-specific files: 2 2022-02-03T10:08:19.127Z INFO Detecting gemspec vulnerabilities... 2022-02-03T10:08:19.128Z INFO Detecting node-pkg vulnerabilities... 2022-02-03T10:08:19.128Z WARN This OS version is no longer supported by the distribution: alpine 3.15.0 2022-02-03T10:08:19.128Z WARN The vulnerability detection may be insufficient because security updates are not provided ruby-3.1.tar (alpine 3.15.0) ============================ Total: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0) +----------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +----------+------------------+----------+-------------------+---------------+---------------------------------------+ | gmp | CVE-2021-43618 | HIGH | 6.2.1-r0 | 6.2.1-r1 | gmp: Integer overflow and resultant | | | | | | | buffer overflow via crafted input | | | | | | | -->avd.aquasec.com/nvd/cve-2021-43618 | +----------+ + + + + + | gmp-dev | | | | | | | | | | | | | | | | | | | | +----------+ + + + + + | libgmpxx | | | | | | | | | | | | | | | | | | | | +----------+------------------+----------+-------------------+---------------+---------------------------------------+ Node.js (node-pkg) ================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) Ruby (gemspec) ============== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) OCI Layout Trivy supports image directories compliant with Open Container Image Layout Specification . Buildah: $ buildah push docker.io/library/alpine:3.11 oci:/path/to/alpine $ trivy image --input /path/to/alpine Skopeo: $ skopeo copy docker-daemon:alpine:3.11 oci:/path/to/alpine $ trivy image --input /path/to/alpine SBOM Trivy supports the generation of Software Bill of Materials (SBOM) for container images and the search for SBOMs during vulnerability scanning. Generation Trivy can generate SBOM for container images. See here for the detail. Discovery Trivy can search for Software Bill of Materials (SBOMs) that reference container images. If an SBOM is found, the vulnerability scan is performed using the SBOM instead of the container image. By using the SBOM, you can perform a vulnerability scan more quickly, as it allows you to skip pulling the container image and analyzing its layers. To enable this functionality, you need to specify the --sbom-sources flag. The following two sources are supported: OCI Registry ( oci ) Rekor ( rekor ) Example: $ trivy image --sbom-sources oci ghcr.io/knqyf263/oci-referrers 2023 -03-05T17:36:55.278+0200 INFO Vulnerability scanning is enabled 2023 -03-05T17:36:58.103+0200 INFO Detected SBOM format: cyclonedx-json 2023 -03-05T17:36:58.129+0200 INFO Found SBOM ( cyclonedx ) in the OCI referrers ... ghcr.io/knqyf263/oci-referrers ( alpine 3 .16.2 ) ============================================== Total: 17 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 5 , HIGH: 9 , CRITICAL: 3 ) The OCI Registry utilizes the Referrers API . For more information about Rekor, please refer to its documentation . Compliance EXPERIMENTAL This feature might change without preserving backwards compatibility. This section describes container image specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation . Built in reports The following reports are available out of the box: Compliance Version Name for command More info CIS Docker Community Edition Benchmark 1.1.0 docker-cis Link Examples Scan a container image configuration and generate a compliance summary report: $ trivy image --compliance docker-cis [YOUR_IMAGE_NAME] Note The Issues column represent the total number of failed checks for this control. Authentication Please reference this page . Options Scan Image on a specific Architecture and OS By default, Trivy loads an image on a \"linux/amd64\" machine. To customise this, pass a --platform argument in the format OS/Architecture for the image: $ trivy image --platform=os/architecture [YOUR_IMAGE_NAME] For example: $ trivy image --platform=linux/arm alpine:3.16.1 Result 2022-10-25T21:00:50.972+0300 INFO Vulnerability scanning is enabled 2022-10-25T21:00:50.972+0300 INFO Secret scanning is enabled 2022-10-25T21:00:50.972+0300 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning 2022-10-25T21:00:50.972+0300 INFO Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection 2022-10-25T21:00:56.190+0300 INFO Detected OS: alpine 2022-10-25T21:00:56.190+0300 INFO Detecting Alpine vulnerabilities... 2022-10-25T21:00:56.191+0300 INFO Number of language-specific files: 0 alpine:3.16.1 (alpine 3.16.1) ============================= Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 zlib \u2502 CVE-2022-37434 \u2502 CRITICAL \u2502 1.2.12-r1 \u2502 1.2.12-r2 \u2502 zlib: heap-based buffer over-read and overflow in inflate() \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 in inflate.c via a... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-37434 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Configure Docker daemon socket to connect to. You can configure Docker daemon socket with DOCKER_HOST or --docker-host . $ trivy image --docker-host tcp://127.0.0.1:2375 YOUR_IMAGE","title":"Container Image"},{"location":"docs/target/container_image/#container-image","text":"Trivy supports two targets for container images. Files inside container images Container image metadata","title":"Container Image"},{"location":"docs/target/container_image/#files-inside-container-images","text":"Container images consist of files. For instance, new files will be installed if you install a package. Trivy scans the files inside container images for Vulnerabilities Misconfigurations Secrets Licenses By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners .","title":"Files inside container images"},{"location":"docs/target/container_image/#vulnerabilities","text":"It is enabled by default. You can simply specify your image name (and a tag). It detects known vulnerabilities in your container image. See here for the detail. $ trivy image [YOUR_IMAGE_NAME] For example: $ trivy image python:3.4-alpine Result 2019-05-16T01:20:43.180+0900 INFO Updating vulnerability database... 2019-05-16T01:20:53.029+0900 INFO Detecting Alpine vulnerabilities... python:3.4-alpine3.9 (alpine 3.9.2) =================================== Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) +---------+------------------+----------+-------------------+---------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------+------------------+----------+-------------------+---------------+--------------------------------+ | openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 | | | | | | | with long nonces | +---------+------------------+----------+-------------------+---------------+--------------------------------+ To enable only vulnerability scanning, you can specify --scanners vuln . $ trivy image --scanners vuln [ YOUR_IMAGE_NAME ]","title":"Vulnerabilities"},{"location":"docs/target/container_image/#misconfigurations","text":"It is supported, but it is not useful in most cases. As mentioned here , Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. If your container image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners config . $ trivy image --scanners config [YOUR_IMAGE_NAME]","title":"Misconfigurations"},{"location":"docs/target/container_image/#secrets","text":"It is enabled by default. See here for the detail. $ trivy image [ YOUR_IMAGE_NAME ]","title":"Secrets"},{"location":"docs/target/container_image/#licenses","text":"It is disabled by default. See here for the detail. $ trivy image --scanners license [ YOUR_IMAGE_NAME ]","title":"Licenses"},{"location":"docs/target/container_image/#container-image-metadata","text":"Container images have configuration . docker inspect and docker history show the information according to the configuration. Trivy scans the configuration of container images for Misconfigurations Secrets They are disabled by default. You can enable them with --image-config-scanners . Tips The configuration can be exported as the JSON file by docker save .","title":"Container image metadata"},{"location":"docs/target/container_image/#misconfigurations_1","text":"Trivy detects misconfigurations on the configuration of container images. The image config is converted into Dockerfile and Trivy handles it as Dockerfile. See here for the detail of Dockerfile scanning. It is disabled by default. You can enable it with --image-config-scanners config . $ trivy image --image-config-scanners config [YOUR_IMAGE_NAME] If you just want to scan the image config, you can disable scanners with --scanners none . For example: $ trivy image --scanners none --image-config-scanners config alpine:3.17.0 Result alpine:3.17 (dockerfile) ======================== Tests: 24 (SUCCESSES: 21, FAILURES: 3, EXCEPTIONS: 0) Failures: 3 (UNKNOWN: 0, LOW: 2, MEDIUM: 0, HIGH: 1, CRITICAL: 0) HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile. See https://avd.aquasec.com/misconfig/ds002 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 LOW: Consider using 'COPY file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' command instead of 'ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files. See https://avd.aquasec.com/misconfig/ds005 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 alpine:3.17:1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 1 [ ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in / \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 LOW: Add HEALTHCHECK instruction in your Dockerfile \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers. See https://avd.aquasec.com/misconfig/ds026 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Tip You can see how each layer is created with docker history .","title":"Misconfigurations"},{"location":"docs/target/container_image/#secrets_1","text":"Trivy detects secrets on the configuration of container images. The image config is converted into JSON and Trivy scans the file for secrets. It is especially useful for environment variables that are likely to have credentials by accident. See here for the detail. $ trivy image --image-config-scanners secret [ YOUR_IMAGE_NAME ] If you just want to scan the image config, you can disable scanners with --scanners none . For example: $ trivy image --scanners none --image-config-scanners secret vuln-image Result vuln-image (alpine 3.17.1) ========================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) vuln-image (secrets) ==================== Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2) CRITICAL: GitHub (github-pat) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 GitHub Personal Access Token \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 test:16 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 14 { 15 \"created\": \"2023-01-09T17:05:20Z\", 16 [ \"created_by\": \"ENV secret=****************************************\", 17 \"comment\": \"buildkit.dockerfile.v0\", \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 CRITICAL: GitHub (github-pat) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 GitHub Personal Access Token \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 test:34 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 32 \"Env\": [ 33 \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\", 34 [ \"secret=****************************************\" 35 ] \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Tip You can see environment variables with docker inspect .","title":"Secrets"},{"location":"docs/target/container_image/#supported","text":"Trivy will look for the specified image in a series of locations. By default, it will first look in the local Docker Engine, then Containerd, Podman, and finally container registry. This behavior can be modified with the --image-src flag. For example, the command trivy image --image-src podman,containerd alpine:3.7.3 Will first search in Podman. If the image is found there, it will be scanned and the results returned. If the image is not found in Podman, then Trivy will search in Containerd. If the image is not found there either, the scan will fail and no more image sources will be searched.","title":"Supported"},{"location":"docs/target/container_image/#docker-engine","text":"Trivy tries to looks for the specified image in your local Docker Engine. It will be skipped if Docker Engine is not running locally. If your docker socket is not the default path, you can override it via DOCKER_HOST .","title":"Docker Engine"},{"location":"docs/target/container_image/#containerd","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. Trivy tries to looks for the specified image in your local containerd . It will be skipped if containerd is not running locally. Specify your image name in containerd running locally. $ nerdctl images REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE aquasec/nginx latest 2bcabc23b454 3 hours ago linux/amd64 149 .1 MiB 54 .1 MiB $ trivy image aquasec/nginx If your containerd socket is not the default path ( //run/containerd/containerd.sock ), you can override it via CONTAINERD_ADDRESS . $ export CONTAINERD_ADDRESS = /run/k3s/containerd/containerd.sock $ trivy image aquasec/nginx If your scan targets are images in a namespace other than containerd's default namespace ( default ), you can override it via CONTAINERD_NAMESPACE . $ export CONTAINERD_NAMESPACE = k8s.io $ trivy image aquasec/nginx","title":"containerd"},{"location":"docs/target/container_image/#podman","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. Scan your image in Podman (>=2.0) running locally. The remote Podman is not supported. Before performing Trivy commands, you must enable the podman.sock systemd service on your machine. For more details, see here . $ systemctl --user enable --now podman.socket Then, you can scan your image in Podman. $ cat Dockerfile FROM alpine:3.12 RUN apk add --no-cache bash $ podman build -t test . $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/test latest efc372d4e0de About a minute ago 7 .94 MB $ trivy image test","title":"Podman"},{"location":"docs/target/container_image/#container-registry","text":"Trivy supports registries that comply with the following specifications. Docker Registry HTTP API V2 OCI Distribution Specification You can configure credentials with docker login . See here for the detail.","title":"Container Registry"},{"location":"docs/target/container_image/#tar-files","text":"Trivy supports image tar files generated by the following tools. Docker Image Specification Moby Project Buildah Podman img Kaniko $ docker pull ruby:3.1-alpine3.15 $ docker save ruby:3.1-alpine3.15 -o ruby-3.1.tar $ trivy image --input ruby-3.1.tar Result 2022-02-03T10:08:19.127Z INFO Detected OS: alpine 2022-02-03T10:08:19.127Z WARN This OS version is not on the EOL list: alpine 3.15 2022-02-03T10:08:19.127Z INFO Detecting Alpine vulnerabilities... 2022-02-03T10:08:19.127Z INFO Number of language-specific files: 2 2022-02-03T10:08:19.127Z INFO Detecting gemspec vulnerabilities... 2022-02-03T10:08:19.128Z INFO Detecting node-pkg vulnerabilities... 2022-02-03T10:08:19.128Z WARN This OS version is no longer supported by the distribution: alpine 3.15.0 2022-02-03T10:08:19.128Z WARN The vulnerability detection may be insufficient because security updates are not provided ruby-3.1.tar (alpine 3.15.0) ============================ Total: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0) +----------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +----------+------------------+----------+-------------------+---------------+---------------------------------------+ | gmp | CVE-2021-43618 | HIGH | 6.2.1-r0 | 6.2.1-r1 | gmp: Integer overflow and resultant | | | | | | | buffer overflow via crafted input | | | | | | | -->avd.aquasec.com/nvd/cve-2021-43618 | +----------+ + + + + + | gmp-dev | | | | | | | | | | | | | | | | | | | | +----------+ + + + + + | libgmpxx | | | | | | | | | | | | | | | | | | | | +----------+------------------+----------+-------------------+---------------+---------------------------------------+ Node.js (node-pkg) ================== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) Ruby (gemspec) ============== Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)","title":"Tar Files"},{"location":"docs/target/container_image/#oci-layout","text":"Trivy supports image directories compliant with Open Container Image Layout Specification . Buildah: $ buildah push docker.io/library/alpine:3.11 oci:/path/to/alpine $ trivy image --input /path/to/alpine Skopeo: $ skopeo copy docker-daemon:alpine:3.11 oci:/path/to/alpine $ trivy image --input /path/to/alpine","title":"OCI Layout"},{"location":"docs/target/container_image/#sbom","text":"Trivy supports the generation of Software Bill of Materials (SBOM) for container images and the search for SBOMs during vulnerability scanning.","title":"SBOM"},{"location":"docs/target/container_image/#generation","text":"Trivy can generate SBOM for container images. See here for the detail.","title":"Generation"},{"location":"docs/target/container_image/#discovery","text":"Trivy can search for Software Bill of Materials (SBOMs) that reference container images. If an SBOM is found, the vulnerability scan is performed using the SBOM instead of the container image. By using the SBOM, you can perform a vulnerability scan more quickly, as it allows you to skip pulling the container image and analyzing its layers. To enable this functionality, you need to specify the --sbom-sources flag. The following two sources are supported: OCI Registry ( oci ) Rekor ( rekor ) Example: $ trivy image --sbom-sources oci ghcr.io/knqyf263/oci-referrers 2023 -03-05T17:36:55.278+0200 INFO Vulnerability scanning is enabled 2023 -03-05T17:36:58.103+0200 INFO Detected SBOM format: cyclonedx-json 2023 -03-05T17:36:58.129+0200 INFO Found SBOM ( cyclonedx ) in the OCI referrers ... ghcr.io/knqyf263/oci-referrers ( alpine 3 .16.2 ) ============================================== Total: 17 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 5 , HIGH: 9 , CRITICAL: 3 ) The OCI Registry utilizes the Referrers API . For more information about Rekor, please refer to its documentation .","title":"Discovery"},{"location":"docs/target/container_image/#compliance","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. This section describes container image specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation .","title":"Compliance"},{"location":"docs/target/container_image/#built-in-reports","text":"The following reports are available out of the box: Compliance Version Name for command More info CIS Docker Community Edition Benchmark 1.1.0 docker-cis Link","title":"Built in reports"},{"location":"docs/target/container_image/#examples","text":"Scan a container image configuration and generate a compliance summary report: $ trivy image --compliance docker-cis [YOUR_IMAGE_NAME] Note The Issues column represent the total number of failed checks for this control.","title":"Examples"},{"location":"docs/target/container_image/#authentication","text":"Please reference this page .","title":"Authentication"},{"location":"docs/target/container_image/#options","text":"","title":"Options"},{"location":"docs/target/container_image/#scan-image-on-a-specific-architecture-and-os","text":"By default, Trivy loads an image on a \"linux/amd64\" machine. To customise this, pass a --platform argument in the format OS/Architecture for the image: $ trivy image --platform=os/architecture [YOUR_IMAGE_NAME] For example: $ trivy image --platform=linux/arm alpine:3.16.1 Result 2022-10-25T21:00:50.972+0300 INFO Vulnerability scanning is enabled 2022-10-25T21:00:50.972+0300 INFO Secret scanning is enabled 2022-10-25T21:00:50.972+0300 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning 2022-10-25T21:00:50.972+0300 INFO Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection 2022-10-25T21:00:56.190+0300 INFO Detected OS: alpine 2022-10-25T21:00:56.190+0300 INFO Detecting Alpine vulnerabilities... 2022-10-25T21:00:56.191+0300 INFO Number of language-specific files: 0 alpine:3.16.1 (alpine 3.16.1) ============================= Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 zlib \u2502 CVE-2022-37434 \u2502 CRITICAL \u2502 1.2.12-r1 \u2502 1.2.12-r2 \u2502 zlib: heap-based buffer over-read and overflow in inflate() \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 in inflate.c via a... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-37434 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"Scan Image on a specific Architecture and OS"},{"location":"docs/target/container_image/#configure-docker-daemon-socket-to-connect-to","text":"You can configure Docker daemon socket with DOCKER_HOST or --docker-host . $ trivy image --docker-host tcp://127.0.0.1:2375 YOUR_IMAGE","title":"Configure Docker daemon socket to connect to."},{"location":"docs/target/filesystem/","text":"Filesystem Scan your local projects for Vulnerabilities Misconfigurations Secrets Licenses By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners . $ trivy fs /path/to/project It's also possible to scan a single file. $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test/Pipfile.lock Scanners Vulnerabilities It is enabled by default. Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. See here for the detail. $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test Result 2020-06-01T17:06:58.652+0300 WARN OS is not detected and vulnerabilities in OS packages are not detected. 2020-06-01T17:06:58.652+0300 INFO Detecting pipenv vulnerabilities... 2020-06-01T17:06:58.691+0300 INFO Detecting cargo vulnerabilities... Pipfile.lock ============ Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0) +---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ | django | CVE-2020-7471 | HIGH | 2.0.9 | 3.0.3, 2.2.10, 1.11.28 | django: potential | | | | | | | SQL injection via | | | | | | | StringAgg(delimiter) | + +------------------+----------+ +------------------------+------------------------------------+ | | CVE-2019-19844 | MEDIUM | | 3.0.1, 2.2.9, 1.11.27 | Django: crafted email address | | | | | | | allows account takeover | + +------------------+ + +------------------------+------------------------------------+ | | CVE-2019-3498 | | | 2.1.5, 2.0.10, 1.11.18 | python-django: Content | | | | | | | spoofing via URL path in | | | | | | | default 404 page | + +------------------+ + +------------------------+------------------------------------+ | | CVE-2019-6975 | | | 2.1.6, 2.0.11, 1.11.19 | python-django: | | | | | | | memory exhaustion in | | | | | | | django.utils.numberformat.format() | +---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ ... Misconfigurations It is disabled by default and can be enabled with --scanners config . See here for the detail. $ trivy fs --scanners config /path/to/project Secrets It is enabled by default. See here for the detail. $ trivy fs /path/to/project Licenses It is disabled by default. See here for the detail. $ trivy fs --scanners license /path/to/project SBOM generation Trivy can generate SBOM for local projects. See here for the detail.","title":"Filesystem"},{"location":"docs/target/filesystem/#filesystem","text":"Scan your local projects for Vulnerabilities Misconfigurations Secrets Licenses By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners . $ trivy fs /path/to/project It's also possible to scan a single file. $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test/Pipfile.lock","title":"Filesystem"},{"location":"docs/target/filesystem/#scanners","text":"","title":"Scanners"},{"location":"docs/target/filesystem/#vulnerabilities","text":"It is enabled by default. Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. See here for the detail. $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test Result 2020-06-01T17:06:58.652+0300 WARN OS is not detected and vulnerabilities in OS packages are not detected. 2020-06-01T17:06:58.652+0300 INFO Detecting pipenv vulnerabilities... 2020-06-01T17:06:58.691+0300 INFO Detecting cargo vulnerabilities... Pipfile.lock ============ Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0) +---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ | django | CVE-2020-7471 | HIGH | 2.0.9 | 3.0.3, 2.2.10, 1.11.28 | django: potential | | | | | | | SQL injection via | | | | | | | StringAgg(delimiter) | + +------------------+----------+ +------------------------+------------------------------------+ | | CVE-2019-19844 | MEDIUM | | 3.0.1, 2.2.9, 1.11.27 | Django: crafted email address | | | | | | | allows account takeover | + +------------------+ + +------------------------+------------------------------------+ | | CVE-2019-3498 | | | 2.1.5, 2.0.10, 1.11.18 | python-django: Content | | | | | | | spoofing via URL path in | | | | | | | default 404 page | + +------------------+ + +------------------------+------------------------------------+ | | CVE-2019-6975 | | | 2.1.6, 2.0.11, 1.11.19 | python-django: | | | | | | | memory exhaustion in | | | | | | | django.utils.numberformat.format() | +---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ ...","title":"Vulnerabilities"},{"location":"docs/target/filesystem/#misconfigurations","text":"It is disabled by default and can be enabled with --scanners config . See here for the detail. $ trivy fs --scanners config /path/to/project","title":"Misconfigurations"},{"location":"docs/target/filesystem/#secrets","text":"It is enabled by default. See here for the detail. $ trivy fs /path/to/project","title":"Secrets"},{"location":"docs/target/filesystem/#licenses","text":"It is disabled by default. See here for the detail. $ trivy fs --scanners license /path/to/project","title":"Licenses"},{"location":"docs/target/filesystem/#sbom-generation","text":"Trivy can generate SBOM for local projects. See here for the detail.","title":"SBOM generation"},{"location":"docs/target/git-repository/","text":"Git Repository Scan your remote git repositories for Vulnerabilities Misconfigurations Secrets Licenses By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners . $ trivy repo [ YOUR_REPO_URL ] Scanners Vulnerabilities It is enabled by default. Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. See here for the detail. $ trivy repo https://github.com/knqyf263/trivy-ci-test Result 2021-03-09T15:04:19.003+0200 INFO Detecting cargo vulnerabilities... 2021-03-09T15:04:19.005+0200 INFO Detecting pipenv vulnerabilities... Cargo.lock ========== Total: 7 (UNKNOWN: 7, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) +----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ | ammonia | RUSTSEC-2019-0001 | UNKNOWN | 1.9.0 | >= 2.1.0 | Uncontrolled recursion leads | | | | | | | to abort in HTML serialization | | | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0001 | +----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ | openssl | RUSTSEC-2016-0001 | | 0.8.3 | >= 0.9.0 | SSL/TLS MitM vulnerability | | | | | | | due to insecure defaults | | | | | | | -->rustsec.org/advisories/RUSTSEC-2016-0001 | +----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ | smallvec | RUSTSEC-2018-0018 | | 0.6.9 | >= 0.6.13 | smallvec creates uninitialized | | | | | | | value of any type | | | | | | | -->rustsec.org/advisories/RUSTSEC-2018-0018 | + +-------------------+ + +------------------------------+---------------------------------------------+ | | RUSTSEC-2019-0009 | | | >= 0.6.10 | Double-free and use-after-free | | | | | | | in SmallVec::grow() | | | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0009 | + +-------------------+ + + +---------------------------------------------+ | | RUSTSEC-2019-0012 | | | | Memory corruption in SmallVec::grow() | | | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0012 | + +-------------------+ + +------------------------------+---------------------------------------------+ | | RUSTSEC-2021-0003 | | | >= 0.6.14, < 1.0.0, >= 1.6.1 | Buffer overflow in SmallVec::insert_many | | | | | | | -->rustsec.org/advisories/RUSTSEC-2021-0003 | +----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ | tempdir | RUSTSEC-2018-0017 | | 0.3.7 | | `tempdir` crate has been | | | | | | | deprecated; use `tempfile` instead | | | | | | | -->rustsec.org/advisories/RUSTSEC-2018-0017 | +----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ Pipfile.lock ============ Total: 20 (UNKNOWN: 3, LOW: 0, MEDIUM: 7, HIGH: 5, CRITICAL: 5) +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | django | CVE-2019-19844 | CRITICAL | 2.0.9 | 3.0.1, 2.2.9, 1.11.27 | Django: crafted email address | | | | | | | allows account takeover | | | | | | | -->avd.aquasec.com/nvd/cve-2019-19844 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-7471 | | | 3.0.3, 2.2.10, 1.11.28 | django: potential SQL injection | | | | | | | via StringAgg(delimiter) | | | | | | | -->avd.aquasec.com/nvd/cve-2020-7471 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2019-6975 | HIGH | | 2.1.6, 2.0.11, 1.11.19 | python-django: memory exhaustion in | | | | | | | django.utils.numberformat.format() | | | | | | | -->avd.aquasec.com/nvd/cve-2019-6975 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-9402 | | | 3.0.4, 2.2.11, 1.11.29 | django: potential SQL injection | | | | | | | via \"tolerance\" parameter in | | | | | | | GIS functions and aggregates... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9402 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2019-3498 | MEDIUM | | 2.1.5, 2.0.10, 1.11.18 | python-django: Content spoofing | | | | | | | via URL path in default 404 page | | | | | | | -->avd.aquasec.com/nvd/cve-2019-3498 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-13254 | | | 3.0.7, 2.2.13 | django: potential data leakage | | | | | | | via malformed memcached keys | | | | | | | -->avd.aquasec.com/nvd/cve-2020-13254 | + +------------------+ + + +---------------------------------------+ | | CVE-2020-13596 | | | | django: possible XSS via | | | | | | | admin ForeignKeyRawIdWidget | | | | | | | -->avd.aquasec.com/nvd/cve-2020-13596 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | django-cors-headers | pyup.io-37132 | UNKNOWN | 2.5.2 | 3.0.0 | In django-cors-headers | | | | | | | version 3.0.0, | | | | | | | ``CORS_ORIGIN_WHITELIST`` | | | | | | | requires URI schemes, and | | | | | | | optionally ports. This... | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | djangorestframework | CVE-2020-25626 | MEDIUM | 3.9.2 | 3.11.2 | django-rest-framework: XSS | | | | | | | Vulnerability in API viewer | | | | | | | -->avd.aquasec.com/nvd/cve-2020-25626 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | httplib2 | CVE-2021-21240 | HIGH | 0.12.1 | 0.19.0 | python-httplib2: Regular | | | | | | | expression denial of | | | | | | | service via malicious header | | | | | | | -->avd.aquasec.com/nvd/cve-2021-21240 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2020-11078 | MEDIUM | | 0.18.0 | python-httplib2: CRLF injection | | | | | | | via an attacker controlled | | | | | | | unescaped part of uri for... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-11078 | + +------------------+----------+ + +---------------------------------------+ | | pyup.io-38303 | UNKNOWN | | | Httplib2 0.18.0 is an | | | | | | | important security update to | | | | | | | patch a CWE-93 CRLF... | +---------------------+------------------+ +-------------------+------------------------+---------------------------------------+ | jinja2 | pyup.io-39525 | | 2.10.1 | 2.11.3 | This affects the package | | | | | | | jinja2 from 0.0.0 and before | | | | | | | 2.11.3. The ReDOS... | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | py | CVE-2020-29651 | HIGH | 1.8.0 | | python-py: ReDoS in the py.path.svnwc | | | | | | | component via malicious input | | | | | | | to blame functionality... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-29651 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | pyyaml | CVE-2019-20477 | CRITICAL | 5.1 | | PyYAML: command execution | | | | | | | through python/object/apply | | | | | | | constructor in FullLoader | | | | | | | -->avd.aquasec.com/nvd/cve-2019-20477 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-14343 | | | 5.4 | PyYAML: incomplete | | | | | | | fix for CVE-2020-1747 | | | | | | | -->avd.aquasec.com/nvd/cve-2020-14343 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-1747 | | | 5.3.1 | PyYAML: arbitrary command | | | | | | | execution through python/object/new | | | | | | | when FullLoader is used | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1747 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | urllib3 | CVE-2019-11324 | HIGH | 1.24.1 | 1.24.2 | python-urllib3: Certification | | | | | | | mishandle when error should be thrown | | | | | | | -->avd.aquasec.com/nvd/cve-2019-11324 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2019-11236 | MEDIUM | | | python-urllib3: CRLF injection | | | | | | | due to not encoding the | | | | | | | '\\r\\n' sequence leading to... | | | | | | | -->avd.aquasec.com/nvd/cve-2019-11236 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-26137 | | | 1.25.9 | python-urllib3: CRLF injection | | | | | | | via HTTP request method | | | | | | | -->avd.aquasec.com/nvd/cve-2020-26137 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ Misconfigurations It is disabled by default and can be enabled with --scanners config . See here for the detail. $ trivy repo --scanners config [ YOUR_REPO_URL ] Secrets It is enabled by default. See here for the detail. $ trivy repo [ YOUR_REPO_URL ] Licenses It is disabled by default. See here for the detail. $ trivy repo --scanners license [ YOUR_REPO_URL ] SBOM generation Trivy can generate SBOM for git repositories. See here for the detail. References Scanning a Branch Pass a --branch argument with a valid branch name on the remote repository provided: $ trivy repo --branch Scanning upto a Commit Pass a --commit argument with a valid commit hash on the remote repository provided: $ trivy repo --commit Scanning a Tag Pass a --tag argument with a valid tag on the remote repository provided: $ trivy repo --tag Scanning Private Repositories In order to scan private GitHub or GitLab repositories, the environment variable GITHUB_TOKEN or GITLAB_TOKEN must be set, respectively, with a valid token that has access to the private repository being scanned. The GITHUB_TOKEN environment variable will take precedence over GITLAB_TOKEN , so if a private GitLab repository will be scanned, then GITHUB_TOKEN must be unset. You can find how to generate your GitHub Token in the following GitHub documentation. For example: $ export GITHUB_TOKEN=\"your_private_github_token\" $ trivy repo $ $ # or $ export GITLAB_TOKEN=\"your_private_gitlab_token\" $ trivy repo ","title":"Git Repository"},{"location":"docs/target/git-repository/#git-repository","text":"Scan your remote git repositories for Vulnerabilities Misconfigurations Secrets Licenses By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners . $ trivy repo [ YOUR_REPO_URL ]","title":"Git Repository"},{"location":"docs/target/git-repository/#scanners","text":"","title":"Scanners"},{"location":"docs/target/git-repository/#vulnerabilities","text":"It is enabled by default. Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. See here for the detail. $ trivy repo https://github.com/knqyf263/trivy-ci-test Result 2021-03-09T15:04:19.003+0200 INFO Detecting cargo vulnerabilities... 2021-03-09T15:04:19.005+0200 INFO Detecting pipenv vulnerabilities... Cargo.lock ========== Total: 7 (UNKNOWN: 7, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) +----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ | ammonia | RUSTSEC-2019-0001 | UNKNOWN | 1.9.0 | >= 2.1.0 | Uncontrolled recursion leads | | | | | | | to abort in HTML serialization | | | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0001 | +----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ | openssl | RUSTSEC-2016-0001 | | 0.8.3 | >= 0.9.0 | SSL/TLS MitM vulnerability | | | | | | | due to insecure defaults | | | | | | | -->rustsec.org/advisories/RUSTSEC-2016-0001 | +----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ | smallvec | RUSTSEC-2018-0018 | | 0.6.9 | >= 0.6.13 | smallvec creates uninitialized | | | | | | | value of any type | | | | | | | -->rustsec.org/advisories/RUSTSEC-2018-0018 | + +-------------------+ + +------------------------------+---------------------------------------------+ | | RUSTSEC-2019-0009 | | | >= 0.6.10 | Double-free and use-after-free | | | | | | | in SmallVec::grow() | | | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0009 | + +-------------------+ + + +---------------------------------------------+ | | RUSTSEC-2019-0012 | | | | Memory corruption in SmallVec::grow() | | | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0012 | + +-------------------+ + +------------------------------+---------------------------------------------+ | | RUSTSEC-2021-0003 | | | >= 0.6.14, < 1.0.0, >= 1.6.1 | Buffer overflow in SmallVec::insert_many | | | | | | | -->rustsec.org/advisories/RUSTSEC-2021-0003 | +----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ | tempdir | RUSTSEC-2018-0017 | | 0.3.7 | | `tempdir` crate has been | | | | | | | deprecated; use `tempfile` instead | | | | | | | -->rustsec.org/advisories/RUSTSEC-2018-0017 | +----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ Pipfile.lock ============ Total: 20 (UNKNOWN: 3, LOW: 0, MEDIUM: 7, HIGH: 5, CRITICAL: 5) +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | django | CVE-2019-19844 | CRITICAL | 2.0.9 | 3.0.1, 2.2.9, 1.11.27 | Django: crafted email address | | | | | | | allows account takeover | | | | | | | -->avd.aquasec.com/nvd/cve-2019-19844 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-7471 | | | 3.0.3, 2.2.10, 1.11.28 | django: potential SQL injection | | | | | | | via StringAgg(delimiter) | | | | | | | -->avd.aquasec.com/nvd/cve-2020-7471 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2019-6975 | HIGH | | 2.1.6, 2.0.11, 1.11.19 | python-django: memory exhaustion in | | | | | | | django.utils.numberformat.format() | | | | | | | -->avd.aquasec.com/nvd/cve-2019-6975 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-9402 | | | 3.0.4, 2.2.11, 1.11.29 | django: potential SQL injection | | | | | | | via \"tolerance\" parameter in | | | | | | | GIS functions and aggregates... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-9402 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2019-3498 | MEDIUM | | 2.1.5, 2.0.10, 1.11.18 | python-django: Content spoofing | | | | | | | via URL path in default 404 page | | | | | | | -->avd.aquasec.com/nvd/cve-2019-3498 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-13254 | | | 3.0.7, 2.2.13 | django: potential data leakage | | | | | | | via malformed memcached keys | | | | | | | -->avd.aquasec.com/nvd/cve-2020-13254 | + +------------------+ + + +---------------------------------------+ | | CVE-2020-13596 | | | | django: possible XSS via | | | | | | | admin ForeignKeyRawIdWidget | | | | | | | -->avd.aquasec.com/nvd/cve-2020-13596 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | django-cors-headers | pyup.io-37132 | UNKNOWN | 2.5.2 | 3.0.0 | In django-cors-headers | | | | | | | version 3.0.0, | | | | | | | ``CORS_ORIGIN_WHITELIST`` | | | | | | | requires URI schemes, and | | | | | | | optionally ports. This... | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | djangorestframework | CVE-2020-25626 | MEDIUM | 3.9.2 | 3.11.2 | django-rest-framework: XSS | | | | | | | Vulnerability in API viewer | | | | | | | -->avd.aquasec.com/nvd/cve-2020-25626 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | httplib2 | CVE-2021-21240 | HIGH | 0.12.1 | 0.19.0 | python-httplib2: Regular | | | | | | | expression denial of | | | | | | | service via malicious header | | | | | | | -->avd.aquasec.com/nvd/cve-2021-21240 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2020-11078 | MEDIUM | | 0.18.0 | python-httplib2: CRLF injection | | | | | | | via an attacker controlled | | | | | | | unescaped part of uri for... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-11078 | + +------------------+----------+ + +---------------------------------------+ | | pyup.io-38303 | UNKNOWN | | | Httplib2 0.18.0 is an | | | | | | | important security update to | | | | | | | patch a CWE-93 CRLF... | +---------------------+------------------+ +-------------------+------------------------+---------------------------------------+ | jinja2 | pyup.io-39525 | | 2.10.1 | 2.11.3 | This affects the package | | | | | | | jinja2 from 0.0.0 and before | | | | | | | 2.11.3. The ReDOS... | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | py | CVE-2020-29651 | HIGH | 1.8.0 | | python-py: ReDoS in the py.path.svnwc | | | | | | | component via malicious input | | | | | | | to blame functionality... | | | | | | | -->avd.aquasec.com/nvd/cve-2020-29651 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | pyyaml | CVE-2019-20477 | CRITICAL | 5.1 | | PyYAML: command execution | | | | | | | through python/object/apply | | | | | | | constructor in FullLoader | | | | | | | -->avd.aquasec.com/nvd/cve-2019-20477 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-14343 | | | 5.4 | PyYAML: incomplete | | | | | | | fix for CVE-2020-1747 | | | | | | | -->avd.aquasec.com/nvd/cve-2020-14343 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-1747 | | | 5.3.1 | PyYAML: arbitrary command | | | | | | | execution through python/object/new | | | | | | | when FullLoader is used | | | | | | | -->avd.aquasec.com/nvd/cve-2020-1747 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ | urllib3 | CVE-2019-11324 | HIGH | 1.24.1 | 1.24.2 | python-urllib3: Certification | | | | | | | mishandle when error should be thrown | | | | | | | -->avd.aquasec.com/nvd/cve-2019-11324 | + +------------------+----------+ +------------------------+---------------------------------------+ | | CVE-2019-11236 | MEDIUM | | | python-urllib3: CRLF injection | | | | | | | due to not encoding the | | | | | | | '\\r\\n' sequence leading to... | | | | | | | -->avd.aquasec.com/nvd/cve-2019-11236 | + +------------------+ + +------------------------+---------------------------------------+ | | CVE-2020-26137 | | | 1.25.9 | python-urllib3: CRLF injection | | | | | | | via HTTP request method | | | | | | | -->avd.aquasec.com/nvd/cve-2020-26137 | +---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+","title":"Vulnerabilities"},{"location":"docs/target/git-repository/#misconfigurations","text":"It is disabled by default and can be enabled with --scanners config . See here for the detail. $ trivy repo --scanners config [ YOUR_REPO_URL ]","title":"Misconfigurations"},{"location":"docs/target/git-repository/#secrets","text":"It is enabled by default. See here for the detail. $ trivy repo [ YOUR_REPO_URL ]","title":"Secrets"},{"location":"docs/target/git-repository/#licenses","text":"It is disabled by default. See here for the detail. $ trivy repo --scanners license [ YOUR_REPO_URL ]","title":"Licenses"},{"location":"docs/target/git-repository/#sbom-generation","text":"Trivy can generate SBOM for git repositories. See here for the detail.","title":"SBOM generation"},{"location":"docs/target/git-repository/#references","text":"","title":"References"},{"location":"docs/target/git-repository/#scanning-a-branch","text":"Pass a --branch argument with a valid branch name on the remote repository provided: $ trivy repo --branch ","title":"Scanning a Branch"},{"location":"docs/target/git-repository/#scanning-upto-a-commit","text":"Pass a --commit argument with a valid commit hash on the remote repository provided: $ trivy repo --commit ","title":"Scanning upto a Commit"},{"location":"docs/target/git-repository/#scanning-a-tag","text":"Pass a --tag argument with a valid tag on the remote repository provided: $ trivy repo --tag ","title":"Scanning a Tag"},{"location":"docs/target/git-repository/#scanning-private-repositories","text":"In order to scan private GitHub or GitLab repositories, the environment variable GITHUB_TOKEN or GITLAB_TOKEN must be set, respectively, with a valid token that has access to the private repository being scanned. The GITHUB_TOKEN environment variable will take precedence over GITLAB_TOKEN , so if a private GitLab repository will be scanned, then GITHUB_TOKEN must be unset. You can find how to generate your GitHub Token in the following GitHub documentation. For example: $ export GITHUB_TOKEN=\"your_private_github_token\" $ trivy repo $ $ # or $ export GITLAB_TOKEN=\"your_private_gitlab_token\" $ trivy repo ","title":"Scanning Private Repositories"},{"location":"docs/target/kubernetes/","text":"Kubernetes EXPERIMENTAL This feature might change without preserving backwards compatibility. CLI The Trivy K8s CLI allows you to scan your Kubernetes cluster for Vulnerabilities Misconfigurations Secrets You can either run the CLI locally or integrate it into your CI/CD pipeline. The difference to the Trivy CLI is that the Trivy K8s CLI allows you to scan running workloads directly within your cluster. If you are looking for continuous cluster audit scanning, have a look at the Trivy K8s operator below. Trivy uses your local kubectl configuration to access the API server to list artifacts. Commands Scan a full cluster and generate a simple summary report: $ trivy k8s --report=summary cluster The summary report is the default. To get all of the detail the output contains, use --report all . Filter by severity: $ trivy k8s --severity=CRITICAL --report=all cluster Filter by scanners (Vulnerabilities, Secrets or Misconfigurations): $ trivy k8s --scanners=secret --report=summary cluster # or $ trivy k8s --scanners=config --report=summary cluster Scan a specific namespace: $ trivy k8s -n kube-system --report=summary all Use a specific kubeconfig file: $ trivy k8s --kubeconfig ~/.kube/config2 -n kube-system --report=summary all Scan a specific resource and get all the output: $ trivy k8s deployment appname Scan all deploys, or deploys and configmaps: $ trivy k8s --report=summary deployment $ trivy k8s --report=summary deployment,configmaps If you want to pass in flags before scanning specific workloads, you will have to do it before the resource name. For example, scanning a deployment in the app namespace of your Kubernetes cluster for critical vulnerabilities would be done through the following command: $ trivy k8s -n app --severity=CRITICAL deployment/appname This is specific to all Trivy CLI commands. The supported formats are table , which is the default, and json . To get a JSON output on a full cluster scan: $ trivy k8s --format json -o results.json cluster Result { \"ClusterName\" : \"minikube\" , \"Vulnerabilities\" : [ { \"Namespace\" : \"default\" , \"Kind\" : \"Deployment\" , \"Name\" : \"app\" , \"Results\" : [ { \"Target\" : \"ubuntu:latest (ubuntu 22.04)\" , \"Class\" : \"os-pkgs\" , \"Type\" : \"ubuntu\" , \"Vulnerabilities\" : [ { \"VulnerabilityID\" : \"CVE-2016-2781\" , \"PkgName\" : \"coreutils\" , \"InstalledVersion\" : \"8.32-4.1ubuntu1\" , \"Layer\" : { \"Digest\" : \"sha256:125a6e411906fe6b0aaa50fc9d600bf6ff9bb11a8651727ce1ed482dc271c24c\" , \"DiffID\" : \"sha256:e59fc94956120a6c7629f085027578e6357b48061d45714107e79f04a81a6f0c\" }, \"SeveritySource\" : \"ubuntu\" , \"PrimaryURL\" : \"https://avd.aquasec.com/nvd/cve-2016-2781\" , \"DataSource\" : { \"ID\" : \"ubuntu\" , \"Name\" : \"Ubuntu CVE Tracker\" , \"URL\" : \"https://git.launchpad.net/ubuntu-cve-tracker\" }, \"Title\" : \"coreutils: Non-privileged session can escape to the parent session in chroot\" , \"Description\" : \"chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.\" , \"Severity\" : \"LOW\" , \"CweIDs\" : [ \"CWE-20\" ], \"VendorSeverity\" : { \"cbl-mariner\" : 2 , \"nvd\" : 2 , \"redhat\" : 2 , \"ubuntu\" : 1 }, \"CVSS\" : { \"nvd\" : { \"V2Vector\" : \"AV:L/AC:L/Au:N/C:N/I:P/A:N\" , \"V3Vector\" : \"CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N\" , \"V2Score\" : 2.1 , \"V3Score\" : 6.5 }, \"redhat\" : { \"V2Vector\" : \"AV:L/AC:H/Au:N/C:C/I:C/A:C\" , \"V3Vector\" : \"CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H\" , \"V2Score\" : 6.2 , \"V3Score\" : 8.6 } }, \"References\" : [ \"http://seclists.org/oss-sec/2016/q1/452\" , \"http://www.openwall.com/lists/oss-security/2016/02/28/2\" , \"http://www.openwall.com/lists/oss-security/2016/02/28/3\" , \"https://access.redhat.com/security/cve/CVE-2016-2781\" , \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2781\" , \"https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E\" , \"https://lore.kernel.org/patchwork/patch/793178/\" , \"https://nvd.nist.gov/vuln/detail/CVE-2016-2781\" ], \"PublishedDate\" : \"2017-02-07T15:59:00Z\" , \"LastModifiedDate\" : \"2021-02-25T17:15:00Z\" } ] } ] } ], \"Misconfigurations\" : [ { \"Namespace\" : \"default\" , \"Kind\" : \"Deployment\" , \"Name\" : \"app\" , \"Results\" : [ { \"Target\" : \"Deployment/app\" , \"Class\" : \"config\" , \"Type\" : \"kubernetes\" , \"MisconfSummary\" : { \"Successes\" : 20 , \"Failures\" : 19 , \"Exceptions\" : 0 }, \"Misconfigurations\" : [ { \"Type\" : \"Kubernetes Security Check\" , \"ID\" : \"KSV001\" , \"Title\" : \"Process can elevate its own privileges\" , \"Description\" : \"A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.\" , \"Message\" : \"Container 'app' of Deployment 'app' should set 'securityContext.allowPrivilegeEscalation' to false\" , \"Namespace\" : \"builtin.kubernetes.KSV001\" , \"Query\" : \"data.builtin.kubernetes.KSV001.deny\" , \"Resolution\" : \"Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.\" , \"Severity\" : \"MEDIUM\" , \"PrimaryURL\" : \"https://avd.aquasec.com/misconfig/ksv001\" , \"References\" : [ \"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted\" , \"https://avd.aquasec.com/misconfig/ksv001\" ], \"Status\" : \"FAIL\" , \"Layer\" : {}, \"IacMetadata\" : { \"Provider\" : \"Kubernetes\" , \"Service\" : \"general\" , \"StartLine\" : 121 , \"EndLine\" : 133 } }, { \"Type\" : \"Kubernetes Security Check\" , \"ID\" : \"KSV003\" , \"Title\" : \"Default capabilities not dropped\" , \"Description\" : \"The container should drop all default capabilities and add only those that are needed for its execution.\" , \"Message\" : \"Container 'app' of Deployment 'app' should add 'ALL' to 'securityContext.capabilities.drop'\" , \"Namespace\" : \"builtin.kubernetes.KSV003\" , \"Query\" : \"data.builtin.kubernetes.KSV003.deny\" , \"Resolution\" : \"Add 'ALL' to containers[].securityContext.capabilities.drop.\" , \"Severity\" : \"LOW\" , \"PrimaryURL\" : \"https://avd.aquasec.com/misconfig/ksv003\" , \"References\" : [ \"https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/\" , \"https://avd.aquasec.com/misconfig/ksv003\" ], \"Status\" : \"FAIL\" , \"Layer\" : {}, \"IacMetadata\" : { \"Provider\" : \"Kubernetes\" , \"Service\" : \"general\" , \"StartLine\" : 121 , \"EndLine\" : 133 } } ] } ] }, { \"Namespace\" : \"default\" , \"Kind\" : \"ConfigMap\" , \"Name\" : \"kube-root-ca.crt\" } ] } Infra checks Trivy by default scans kubernetes infra components (apiserver, controller-manager, scheduler and etcd) if they exist under the kube-system namespace. For example, if you run a full cluster scan, or scan all components under kube-system with commands: $ trivy k8s cluster --report summary # full cluster scan $ trivy k8s all -n kube-system --report summary # scan all components under kube-system A table will be printed about misconfigurations found on kubernetes core components: Summary Report for minikube \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Namespace \u2502 Resource \u2502 Kubernetes Infra Assessment \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 C \u2502 H \u2502 M \u2502 L \u2502 U \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 kube-system \u2502 Pod/kube-apiserver-minikube \u2502 \u2502 \u2502 1 \u2502 10 \u2502 \u2502 \u2502 kube-system \u2502 Pod/kube-controller-manager-minikube \u2502 \u2502 \u2502 \u2502 3 \u2502 \u2502 \u2502 kube-system \u2502 Pod/kube-scheduler-minikube \u2502 \u2502 \u2502 \u2502 1 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN The infra checks are based on CIS Benchmarks recommendations for kubernetes. If you want filter only for the infra checks, you can use the flag --components along with the --scanners=config $ trivy k8s cluster --report summary --components=infra --scanners=config # scan only infra Or, to filter for all other checks besides the infra checks, you can: $ trivy k8s cluster --report summary --components=workload --scanners=config # scan all components besides infra Compliance This section describes Kubernetes specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation . Built in reports The following reports are available out of the box: Compliance Name for command More info NSA, CISA Kubernetes Hardening Guidance v1.2 k8s-nsa Link CIS Benchmark for Kubernetes v1.23 k8s-cis Link Pod Security Standards, Baseline k8s-pss-baseline Link Pod Security Standards, Restricted k8s-pss-restricted Link Examples Scan a full cluster and generate a compliance summary report: $ trivy k8s cluster --compliance= --report summary Note : The Issues column represent the total number of failed checks for this control. Get all of the detailed output for checks: trivy k8s cluster --compliance= --report all Report result in JSON format: trivy k8s cluster --compliance= --report summary --format json trivy k8s cluster --compliance= --report all --format json Operator Trivy has a native Kubernetes Operator which continuously scans your Kubernetes cluster for security issues, and generates security reports as Kubernetes Custom Resources . It does it by watching Kubernetes for state changes and automatically triggering scans in response to changes, for example initiating a vulnerability scan when a new Pod is created. Kubernetes-native security toolkit. ( Documentation ). Workload reconcilers discover K8s controllers, manage scan jobs, and create VulnerabilityReport and ConfigAuditReport objects.","title":"Kubernetes"},{"location":"docs/target/kubernetes/#kubernetes","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility.","title":"Kubernetes"},{"location":"docs/target/kubernetes/#cli","text":"The Trivy K8s CLI allows you to scan your Kubernetes cluster for Vulnerabilities Misconfigurations Secrets You can either run the CLI locally or integrate it into your CI/CD pipeline. The difference to the Trivy CLI is that the Trivy K8s CLI allows you to scan running workloads directly within your cluster. If you are looking for continuous cluster audit scanning, have a look at the Trivy K8s operator below. Trivy uses your local kubectl configuration to access the API server to list artifacts.","title":"CLI"},{"location":"docs/target/kubernetes/#commands","text":"Scan a full cluster and generate a simple summary report: $ trivy k8s --report=summary cluster The summary report is the default. To get all of the detail the output contains, use --report all . Filter by severity: $ trivy k8s --severity=CRITICAL --report=all cluster Filter by scanners (Vulnerabilities, Secrets or Misconfigurations): $ trivy k8s --scanners=secret --report=summary cluster # or $ trivy k8s --scanners=config --report=summary cluster Scan a specific namespace: $ trivy k8s -n kube-system --report=summary all Use a specific kubeconfig file: $ trivy k8s --kubeconfig ~/.kube/config2 -n kube-system --report=summary all Scan a specific resource and get all the output: $ trivy k8s deployment appname Scan all deploys, or deploys and configmaps: $ trivy k8s --report=summary deployment $ trivy k8s --report=summary deployment,configmaps If you want to pass in flags before scanning specific workloads, you will have to do it before the resource name. For example, scanning a deployment in the app namespace of your Kubernetes cluster for critical vulnerabilities would be done through the following command: $ trivy k8s -n app --severity=CRITICAL deployment/appname This is specific to all Trivy CLI commands. The supported formats are table , which is the default, and json . To get a JSON output on a full cluster scan: $ trivy k8s --format json -o results.json cluster Result { \"ClusterName\" : \"minikube\" , \"Vulnerabilities\" : [ { \"Namespace\" : \"default\" , \"Kind\" : \"Deployment\" , \"Name\" : \"app\" , \"Results\" : [ { \"Target\" : \"ubuntu:latest (ubuntu 22.04)\" , \"Class\" : \"os-pkgs\" , \"Type\" : \"ubuntu\" , \"Vulnerabilities\" : [ { \"VulnerabilityID\" : \"CVE-2016-2781\" , \"PkgName\" : \"coreutils\" , \"InstalledVersion\" : \"8.32-4.1ubuntu1\" , \"Layer\" : { \"Digest\" : \"sha256:125a6e411906fe6b0aaa50fc9d600bf6ff9bb11a8651727ce1ed482dc271c24c\" , \"DiffID\" : \"sha256:e59fc94956120a6c7629f085027578e6357b48061d45714107e79f04a81a6f0c\" }, \"SeveritySource\" : \"ubuntu\" , \"PrimaryURL\" : \"https://avd.aquasec.com/nvd/cve-2016-2781\" , \"DataSource\" : { \"ID\" : \"ubuntu\" , \"Name\" : \"Ubuntu CVE Tracker\" , \"URL\" : \"https://git.launchpad.net/ubuntu-cve-tracker\" }, \"Title\" : \"coreutils: Non-privileged session can escape to the parent session in chroot\" , \"Description\" : \"chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.\" , \"Severity\" : \"LOW\" , \"CweIDs\" : [ \"CWE-20\" ], \"VendorSeverity\" : { \"cbl-mariner\" : 2 , \"nvd\" : 2 , \"redhat\" : 2 , \"ubuntu\" : 1 }, \"CVSS\" : { \"nvd\" : { \"V2Vector\" : \"AV:L/AC:L/Au:N/C:N/I:P/A:N\" , \"V3Vector\" : \"CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N\" , \"V2Score\" : 2.1 , \"V3Score\" : 6.5 }, \"redhat\" : { \"V2Vector\" : \"AV:L/AC:H/Au:N/C:C/I:C/A:C\" , \"V3Vector\" : \"CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H\" , \"V2Score\" : 6.2 , \"V3Score\" : 8.6 } }, \"References\" : [ \"http://seclists.org/oss-sec/2016/q1/452\" , \"http://www.openwall.com/lists/oss-security/2016/02/28/2\" , \"http://www.openwall.com/lists/oss-security/2016/02/28/3\" , \"https://access.redhat.com/security/cve/CVE-2016-2781\" , \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2781\" , \"https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E\" , \"https://lore.kernel.org/patchwork/patch/793178/\" , \"https://nvd.nist.gov/vuln/detail/CVE-2016-2781\" ], \"PublishedDate\" : \"2017-02-07T15:59:00Z\" , \"LastModifiedDate\" : \"2021-02-25T17:15:00Z\" } ] } ] } ], \"Misconfigurations\" : [ { \"Namespace\" : \"default\" , \"Kind\" : \"Deployment\" , \"Name\" : \"app\" , \"Results\" : [ { \"Target\" : \"Deployment/app\" , \"Class\" : \"config\" , \"Type\" : \"kubernetes\" , \"MisconfSummary\" : { \"Successes\" : 20 , \"Failures\" : 19 , \"Exceptions\" : 0 }, \"Misconfigurations\" : [ { \"Type\" : \"Kubernetes Security Check\" , \"ID\" : \"KSV001\" , \"Title\" : \"Process can elevate its own privileges\" , \"Description\" : \"A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.\" , \"Message\" : \"Container 'app' of Deployment 'app' should set 'securityContext.allowPrivilegeEscalation' to false\" , \"Namespace\" : \"builtin.kubernetes.KSV001\" , \"Query\" : \"data.builtin.kubernetes.KSV001.deny\" , \"Resolution\" : \"Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.\" , \"Severity\" : \"MEDIUM\" , \"PrimaryURL\" : \"https://avd.aquasec.com/misconfig/ksv001\" , \"References\" : [ \"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted\" , \"https://avd.aquasec.com/misconfig/ksv001\" ], \"Status\" : \"FAIL\" , \"Layer\" : {}, \"IacMetadata\" : { \"Provider\" : \"Kubernetes\" , \"Service\" : \"general\" , \"StartLine\" : 121 , \"EndLine\" : 133 } }, { \"Type\" : \"Kubernetes Security Check\" , \"ID\" : \"KSV003\" , \"Title\" : \"Default capabilities not dropped\" , \"Description\" : \"The container should drop all default capabilities and add only those that are needed for its execution.\" , \"Message\" : \"Container 'app' of Deployment 'app' should add 'ALL' to 'securityContext.capabilities.drop'\" , \"Namespace\" : \"builtin.kubernetes.KSV003\" , \"Query\" : \"data.builtin.kubernetes.KSV003.deny\" , \"Resolution\" : \"Add 'ALL' to containers[].securityContext.capabilities.drop.\" , \"Severity\" : \"LOW\" , \"PrimaryURL\" : \"https://avd.aquasec.com/misconfig/ksv003\" , \"References\" : [ \"https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/\" , \"https://avd.aquasec.com/misconfig/ksv003\" ], \"Status\" : \"FAIL\" , \"Layer\" : {}, \"IacMetadata\" : { \"Provider\" : \"Kubernetes\" , \"Service\" : \"general\" , \"StartLine\" : 121 , \"EndLine\" : 133 } } ] } ] }, { \"Namespace\" : \"default\" , \"Kind\" : \"ConfigMap\" , \"Name\" : \"kube-root-ca.crt\" } ] }","title":"Commands"},{"location":"docs/target/kubernetes/#infra-checks","text":"Trivy by default scans kubernetes infra components (apiserver, controller-manager, scheduler and etcd) if they exist under the kube-system namespace. For example, if you run a full cluster scan, or scan all components under kube-system with commands: $ trivy k8s cluster --report summary # full cluster scan $ trivy k8s all -n kube-system --report summary # scan all components under kube-system A table will be printed about misconfigurations found on kubernetes core components: Summary Report for minikube \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Namespace \u2502 Resource \u2502 Kubernetes Infra Assessment \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 C \u2502 H \u2502 M \u2502 L \u2502 U \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 kube-system \u2502 Pod/kube-apiserver-minikube \u2502 \u2502 \u2502 1 \u2502 10 \u2502 \u2502 \u2502 kube-system \u2502 Pod/kube-controller-manager-minikube \u2502 \u2502 \u2502 \u2502 3 \u2502 \u2502 \u2502 kube-system \u2502 Pod/kube-scheduler-minikube \u2502 \u2502 \u2502 \u2502 1 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN The infra checks are based on CIS Benchmarks recommendations for kubernetes. If you want filter only for the infra checks, you can use the flag --components along with the --scanners=config $ trivy k8s cluster --report summary --components=infra --scanners=config # scan only infra Or, to filter for all other checks besides the infra checks, you can: $ trivy k8s cluster --report summary --components=workload --scanners=config # scan all components besides infra","title":"Infra checks"},{"location":"docs/target/kubernetes/#compliance","text":"This section describes Kubernetes specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation .","title":"Compliance"},{"location":"docs/target/kubernetes/#built-in-reports","text":"The following reports are available out of the box: Compliance Name for command More info NSA, CISA Kubernetes Hardening Guidance v1.2 k8s-nsa Link CIS Benchmark for Kubernetes v1.23 k8s-cis Link Pod Security Standards, Baseline k8s-pss-baseline Link Pod Security Standards, Restricted k8s-pss-restricted Link","title":"Built in reports"},{"location":"docs/target/kubernetes/#examples","text":"Scan a full cluster and generate a compliance summary report: $ trivy k8s cluster --compliance= --report summary Note : The Issues column represent the total number of failed checks for this control. Get all of the detailed output for checks: trivy k8s cluster --compliance= --report all Report result in JSON format: trivy k8s cluster --compliance= --report summary --format json trivy k8s cluster --compliance= --report all --format json","title":"Examples"},{"location":"docs/target/kubernetes/#operator","text":"Trivy has a native Kubernetes Operator which continuously scans your Kubernetes cluster for security issues, and generates security reports as Kubernetes Custom Resources . It does it by watching Kubernetes for state changes and automatically triggering scans in response to changes, for example initiating a vulnerability scan when a new Pod is created. Kubernetes-native security toolkit. ( Documentation ). Workload reconcilers discover K8s controllers, manage scan jobs, and create VulnerabilityReport and ConfigAuditReport objects.","title":"Operator"},{"location":"docs/target/rootfs/","text":"Rootfs Rootfs scanning is for special use cases such as Host machine Root filesystem Unpacked filesystem $ trivy rootfs /path/to/rootfs Note Rootfs scanning works differently from the Filesystem scanning. You should use trivy fs to scan your local projects in CI/CD. See here for the differences.","title":"Rootfs"},{"location":"docs/target/rootfs/#rootfs","text":"Rootfs scanning is for special use cases such as Host machine Root filesystem Unpacked filesystem $ trivy rootfs /path/to/rootfs Note Rootfs scanning works differently from the Filesystem scanning. You should use trivy fs to scan your local projects in CI/CD. See here for the differences.","title":"Rootfs"},{"location":"docs/target/sbom/","text":"SBOM scanning Trivy can take the following SBOM formats as an input and scan for vulnerabilities. CycloneDX SPDX SPDX JSON CycloneDX-type attestation To scan SBOM, you can use the sbom subcommand and pass the path to the SBOM. The input format is automatically detected. $ trivy sbom /path/to/sbom_file Note Passing SBOMs generated by tool other than Trivy may result in inaccurate detection because Trivy relies on custom properties in SBOM for accurate scanning. CycloneDX Trivy supports CycloneDX as an input. Note CycloneDX XML is not supported at the moment. $ trivy sbom /path/to/cyclonedx.json Note If you want to generate a CycloneDX report from a CycloneDX input, please be aware that the output stores references to your original CycloneDX report and contains only detected vulnerabilities, not components. The report is called BOV . SPDX Trivy supports the SPDX SBOM as an input. The following SPDX formats are supported: Tag-value ( --format spdx ) JSON ( --format spdx-json ) $ trivy image --format spdx-json --output spdx.json alpine:3.16.0 $ trivy sbom spdx.json Result 2022-09-15T21:32:27.168+0300 INFO Vulnerability scanning is enabled 2022-09-15T21:32:27.169+0300 INFO Detected SBOM format: spdx-json 2022-09-15T21:32:27.210+0300 INFO Detected OS: alpine 2022-09-15T21:32:27.210+0300 INFO Detecting Alpine vulnerabilities... 2022-09-15T21:32:27.211+0300 INFO Number of language-specific files: 0 spdx.json (alpine 3.16.0) ========================= Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 busybox \u2502 CVE-2022-30065 \u2502 HIGH \u2502 1.35.0-r13 \u2502 1.35.0-r15 \u2502 busybox: A use-after-free in Busybox's awk applet leads to \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 denial of service... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-30065 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 libcrypto1.1 \u2502 CVE-2022-2097 \u2502 MEDIUM \u2502 1.1.1o-r0 \u2502 1.1.1q-r0 \u2502 openssl: AES OCB fails to encrypt some bytes \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-2097 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 libssl1.1 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 ssl_client \u2502 CVE-2022-30065 \u2502 HIGH \u2502 1.35.0-r13 \u2502 1.35.0-r15 \u2502 busybox: A use-after-free in Busybox's awk applet leads to \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 denial of service... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-30065 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 zlib \u2502 CVE-2022-37434 \u2502 CRITICAL \u2502 1.2.12-r1 \u2502 1.2.12-r2 \u2502 zlib: a heap-based buffer over-read or buffer overflow in \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 inflate in inflate.c... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-37434 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 SBOM attestation You can also scan an SBOM attestation. In the following example, Cosign gets an attestation and Trivy scans it. You must create CycloneDX-type attestation before trying the example. To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the SBOM attestation page . $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx > sbom.cdx.intoto.jsonl $ trivy sbom ./sbom.cdx.intoto.jsonl sbom.cdx.intoto.jsonl ( alpine 3 .7.3 ) ========================= Total: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 musl \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1 .1.18-r3 \u2502 1 .1.18-r4 \u2502 musl libc through 1 .1.23 has an x87 floating-point stack \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 adjustment im ...... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-14697 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"SBOM"},{"location":"docs/target/sbom/#sbom-scanning","text":"Trivy can take the following SBOM formats as an input and scan for vulnerabilities. CycloneDX SPDX SPDX JSON CycloneDX-type attestation To scan SBOM, you can use the sbom subcommand and pass the path to the SBOM. The input format is automatically detected. $ trivy sbom /path/to/sbom_file Note Passing SBOMs generated by tool other than Trivy may result in inaccurate detection because Trivy relies on custom properties in SBOM for accurate scanning.","title":"SBOM scanning"},{"location":"docs/target/sbom/#cyclonedx","text":"Trivy supports CycloneDX as an input. Note CycloneDX XML is not supported at the moment. $ trivy sbom /path/to/cyclonedx.json Note If you want to generate a CycloneDX report from a CycloneDX input, please be aware that the output stores references to your original CycloneDX report and contains only detected vulnerabilities, not components. The report is called BOV .","title":"CycloneDX"},{"location":"docs/target/sbom/#spdx","text":"Trivy supports the SPDX SBOM as an input. The following SPDX formats are supported: Tag-value ( --format spdx ) JSON ( --format spdx-json ) $ trivy image --format spdx-json --output spdx.json alpine:3.16.0 $ trivy sbom spdx.json Result 2022-09-15T21:32:27.168+0300 INFO Vulnerability scanning is enabled 2022-09-15T21:32:27.169+0300 INFO Detected SBOM format: spdx-json 2022-09-15T21:32:27.210+0300 INFO Detected OS: alpine 2022-09-15T21:32:27.210+0300 INFO Detecting Alpine vulnerabilities... 2022-09-15T21:32:27.211+0300 INFO Number of language-specific files: 0 spdx.json (alpine 3.16.0) ========================= Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 1) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 busybox \u2502 CVE-2022-30065 \u2502 HIGH \u2502 1.35.0-r13 \u2502 1.35.0-r15 \u2502 busybox: A use-after-free in Busybox's awk applet leads to \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 denial of service... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-30065 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 libcrypto1.1 \u2502 CVE-2022-2097 \u2502 MEDIUM \u2502 1.1.1o-r0 \u2502 1.1.1q-r0 \u2502 openssl: AES OCB fails to encrypt some bytes \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-2097 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 libssl1.1 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 ssl_client \u2502 CVE-2022-30065 \u2502 HIGH \u2502 1.35.0-r13 \u2502 1.35.0-r15 \u2502 busybox: A use-after-free in Busybox's awk applet leads to \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 denial of service... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-30065 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 zlib \u2502 CVE-2022-37434 \u2502 CRITICAL \u2502 1.2.12-r1 \u2502 1.2.12-r2 \u2502 zlib: a heap-based buffer over-read or buffer overflow in \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 inflate in inflate.c... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-37434 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"SPDX"},{"location":"docs/target/sbom/#sbom-attestation","text":"You can also scan an SBOM attestation. In the following example, Cosign gets an attestation and Trivy scans it. You must create CycloneDX-type attestation before trying the example. To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the SBOM attestation page . $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx > sbom.cdx.intoto.jsonl $ trivy sbom ./sbom.cdx.intoto.jsonl sbom.cdx.intoto.jsonl ( alpine 3 .7.3 ) ========================= Total: 2 ( UNKNOWN: 0 , LOW: 0 , MEDIUM: 0 , HIGH: 0 , CRITICAL: 2 ) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 musl \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1 .1.18-r3 \u2502 1 .1.18-r4 \u2502 musl libc through 1 .1.23 has an x87 floating-point stack \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 adjustment im ...... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2019-14697 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 musl-utils \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518","title":"SBOM attestation"},{"location":"docs/target/vm/","text":"Virtual Machine Image EXPERIMENTAL This feature might change without preserving backwards compatibility. To scan virtual machine (VM) images, you can use the vm subcommand. Targets The following targets are currently supported: Local file AWS EC2 Amazon Machine Image (AMI) Amazon Elastic Block Store (EBS) Snapshot Local file Pass the path to your local VM image file. $ trivy vm --scanners vuln disk.vmdk Result disk.vmdk (amazon 2 (Karoo)) =========================================================================================== Total: 802 (UNKNOWN: 0, LOW: 17, MEDIUM: 554, HIGH: 221, CRITICAL: 10) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 amazon-ssm-agent \u2502 CVE-2022-24675 \u2502 HIGH \u2502 3.0.529.0-1.amzn2 \u2502 3.1.1575.0-1.amzn2 \u2502 golang: encoding/pem: fix stack overflow in Decode \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-24675 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 bind-export-libs \u2502 CVE-2021-25215 \u2502 \u2502 32:9.11.4-26.P2.amzn2.4 \u2502 32:9.11.4-26.P2.amzn2.5 \u2502 bind: An assertion check can fail while answering queries \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for DNAME records... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25215 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-25214 \u2502 MEDIUM \u2502 \u2502 32:9.11.4-26.P2.amzn2.5.2 \u2502 bind: Broken inbound incremental zone update (IXFR) can \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 cause named to terminate... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25214 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 bind-libs \u2502 CVE-2021-25215 \u2502 HIGH \u2502 \u2502 32:9.11.4-26.P2.amzn2.5 \u2502 bind: An assertion check can fail while answering queries \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for DNAME records... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25215 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-25214 \u2502 MEDIUM \u2502 \u2502 32:9.11.4-26.P2.amzn2.5.2 \u2502 bind: Broken inbound incremental zone update (IXFR) can \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 cause named to terminate... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25214 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 bind-libs-lite \u2502 CVE-2021-25215 \u2502 HIGH \u2502 \u2502 32:9.11.4-26.P2.amzn2.5 \u2502 bind: An assertion check can fail while answering queries \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for DNAME records... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25215 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-25214 \u2502 MEDIUM \u2502 \u2502 32:9.11.4-26.P2.amzn2.5.2 \u2502 bind: Broken inbound incremental zone update (IXFR) can \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 cause named to terminate... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25214 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 ... Amazon Machine Image (AMI) You can specify your AMI ID with the ami: prefix. $ trivy vm ami: ${ your_ami_id } Note AMIs in the marketplace are not supported because the EBS direct APIs don't support that. See the AWS documentation for the detail. Example $ trivy vm --scanners vuln ami:ami-0123456789abcdefg If you want to scan a AMI of non-default setting region, you can set any region via --aws-region option. $ trivy vm --aws-region ap-northeast-1 ami:ami-0123456789abcdefg Required Actions Some actions on EBS are also necessary since Trivy scans an EBS snapshot tied to the specified AMI under the hood. ec2:DescribeImages ebs:ListSnapshotBlocks ebs:GetSnapshotBlock Amazon Elastic Block Store (EBS) Snapshot You can specify your EBS snapshot ID with the ebs: prefix. $ trivy vm ebs: ${ your_ebs_snapshot_id } Note Public snapshots are not supported because the EBS direct APIs don't support that. See the AWS documentation for the detail. Example $ trivy vm --scanners vuln ebs:snap-0123456789abcdefg If you want to scan an EBS Snapshot of non-default setting region, you can set any region via --aws-region option. $ trivy vm --aws-region ap-northeast-1 ebs:ebs-0123456789abcdefg The above command takes a while as it calls EBS API and fetches the EBS blocks. If you want to scan the same snapshot several times, you can download the snapshot locally by using coldsnap maintained by AWS. Then, Trivy can scan the local VM image file. $ coldsnap download snap-0123456789abcdefg disk.img $ trivy vm ./disk.img Required Actions ebs:ListSnapshotBlocks ebs:GetSnapshotBlock Scanners Trivy supports VM image scanning for Vulnerabilities Misconfigurations Secrets Licenses Vulnerabilities It is enabled by default. You can simply specify your VM image location. It detects known vulnerabilities in your VM image. See here for the detail. $ trivy vm [YOUR_VM_IMAGE] Misconfigurations It is supported, but it is not useful in most cases. As mentioned here , Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. If your VM image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners config . $ trivy vm --scanners config [YOUR_VM_IMAGE] Secrets It is enabled by default. See here for the detail. $ trivy vm [ YOUR_VM_IMAGE ] Tip The scanning could be faster if you enable only vulnerability scanning ( --scanners vuln ) because Trivy tries to download only necessary blocks for vulnerability detection. Licenses It is disabled by default. See here for the detail. $ trivy vm --scanners license [ YOUR_VM_IMAGE ] SBOM generation Trivy can generate SBOM for VM images. See here for the detail. Supported Architectures Virtual machine images Image format Support VMDK \u2714 OVA VHD VHDX QCOW2 VMDK disk types VMDK disk type Support streamOptimized \u2714 monolithicSparse vmfs vmfsSparse twoGbMaxExtentSparse monolithicFlat twoGbMaxExtentFlat vmfsRaw fullDevice partitionedDevice vmfsRawDeviceMap vmfsPassthroughRawDeviceMap Reference: VMware Virtual Disk Format 1.1.pdf Disk partitions Disk format Support Master boot record (MBR) \u2714 Extended master boot record GUID partition table (GPT) \u2714 Logical volume manager (LVM) Filesystems Filesystem format Support XFS \u2714 EXT4 \u2714 EXT2/3 ZFS","title":"Virtual Machine Image"},{"location":"docs/target/vm/#virtual-machine-image","text":"EXPERIMENTAL This feature might change without preserving backwards compatibility. To scan virtual machine (VM) images, you can use the vm subcommand.","title":"Virtual Machine Image"},{"location":"docs/target/vm/#targets","text":"The following targets are currently supported: Local file AWS EC2 Amazon Machine Image (AMI) Amazon Elastic Block Store (EBS) Snapshot","title":"Targets"},{"location":"docs/target/vm/#local-file","text":"Pass the path to your local VM image file. $ trivy vm --scanners vuln disk.vmdk Result disk.vmdk (amazon 2 (Karoo)) =========================================================================================== Total: 802 (UNKNOWN: 0, LOW: 17, MEDIUM: 554, HIGH: 221, CRITICAL: 10) \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 Library \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502 Title \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 amazon-ssm-agent \u2502 CVE-2022-24675 \u2502 HIGH \u2502 3.0.529.0-1.amzn2 \u2502 3.1.1575.0-1.amzn2 \u2502 golang: encoding/pem: fix stack overflow in Decode \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2022-24675 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 bind-export-libs \u2502 CVE-2021-25215 \u2502 \u2502 32:9.11.4-26.P2.amzn2.4 \u2502 32:9.11.4-26.P2.amzn2.5 \u2502 bind: An assertion check can fail while answering queries \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for DNAME records... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25215 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-25214 \u2502 MEDIUM \u2502 \u2502 32:9.11.4-26.P2.amzn2.5.2 \u2502 bind: Broken inbound incremental zone update (IXFR) can \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 cause named to terminate... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25214 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 bind-libs \u2502 CVE-2021-25215 \u2502 HIGH \u2502 \u2502 32:9.11.4-26.P2.amzn2.5 \u2502 bind: An assertion check can fail while answering queries \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for DNAME records... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25215 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-25214 \u2502 MEDIUM \u2502 \u2502 32:9.11.4-26.P2.amzn2.5.2 \u2502 bind: Broken inbound incremental zone update (IXFR) can \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 cause named to terminate... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25214 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 bind-libs-lite \u2502 CVE-2021-25215 \u2502 HIGH \u2502 \u2502 32:9.11.4-26.P2.amzn2.5 \u2502 bind: An assertion check can fail while answering queries \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 for DNAME records... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25215 \u2502 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u2502 \u2502 CVE-2021-25214 \u2502 MEDIUM \u2502 \u2502 32:9.11.4-26.P2.amzn2.5.2 \u2502 bind: Broken inbound incremental zone update (IXFR) can \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 cause named to terminate... \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 https://avd.aquasec.com/nvd/cve-2021-25214 \u2502 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 ...","title":"Local file"},{"location":"docs/target/vm/#amazon-machine-image-ami","text":"You can specify your AMI ID with the ami: prefix. $ trivy vm ami: ${ your_ami_id } Note AMIs in the marketplace are not supported because the EBS direct APIs don't support that. See the AWS documentation for the detail.","title":"Amazon Machine Image (AMI)"},{"location":"docs/target/vm/#example","text":"$ trivy vm --scanners vuln ami:ami-0123456789abcdefg If you want to scan a AMI of non-default setting region, you can set any region via --aws-region option. $ trivy vm --aws-region ap-northeast-1 ami:ami-0123456789abcdefg","title":"Example"},{"location":"docs/target/vm/#required-actions","text":"Some actions on EBS are also necessary since Trivy scans an EBS snapshot tied to the specified AMI under the hood. ec2:DescribeImages ebs:ListSnapshotBlocks ebs:GetSnapshotBlock","title":"Required Actions"},{"location":"docs/target/vm/#amazon-elastic-block-store-ebs-snapshot","text":"You can specify your EBS snapshot ID with the ebs: prefix. $ trivy vm ebs: ${ your_ebs_snapshot_id } Note Public snapshots are not supported because the EBS direct APIs don't support that. See the AWS documentation for the detail.","title":"Amazon Elastic Block Store (EBS) Snapshot"},{"location":"docs/target/vm/#example_1","text":"$ trivy vm --scanners vuln ebs:snap-0123456789abcdefg If you want to scan an EBS Snapshot of non-default setting region, you can set any region via --aws-region option. $ trivy vm --aws-region ap-northeast-1 ebs:ebs-0123456789abcdefg The above command takes a while as it calls EBS API and fetches the EBS blocks. If you want to scan the same snapshot several times, you can download the snapshot locally by using coldsnap maintained by AWS. Then, Trivy can scan the local VM image file. $ coldsnap download snap-0123456789abcdefg disk.img $ trivy vm ./disk.img","title":"Example"},{"location":"docs/target/vm/#required-actions_1","text":"ebs:ListSnapshotBlocks ebs:GetSnapshotBlock","title":"Required Actions"},{"location":"docs/target/vm/#scanners","text":"Trivy supports VM image scanning for Vulnerabilities Misconfigurations Secrets Licenses","title":"Scanners"},{"location":"docs/target/vm/#vulnerabilities","text":"It is enabled by default. You can simply specify your VM image location. It detects known vulnerabilities in your VM image. See here for the detail. $ trivy vm [YOUR_VM_IMAGE]","title":"Vulnerabilities"},{"location":"docs/target/vm/#misconfigurations","text":"It is supported, but it is not useful in most cases. As mentioned here , Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. If your VM image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners config . $ trivy vm --scanners config [YOUR_VM_IMAGE]","title":"Misconfigurations"},{"location":"docs/target/vm/#secrets","text":"It is enabled by default. See here for the detail. $ trivy vm [ YOUR_VM_IMAGE ] Tip The scanning could be faster if you enable only vulnerability scanning ( --scanners vuln ) because Trivy tries to download only necessary blocks for vulnerability detection.","title":"Secrets"},{"location":"docs/target/vm/#licenses","text":"It is disabled by default. See here for the detail. $ trivy vm --scanners license [ YOUR_VM_IMAGE ]","title":"Licenses"},{"location":"docs/target/vm/#sbom-generation","text":"Trivy can generate SBOM for VM images. See here for the detail.","title":"SBOM generation"},{"location":"docs/target/vm/#supported-architectures","text":"","title":"Supported Architectures"},{"location":"docs/target/vm/#virtual-machine-images","text":"Image format Support VMDK \u2714 OVA VHD VHDX QCOW2","title":"Virtual machine images"},{"location":"docs/target/vm/#vmdk-disk-types","text":"VMDK disk type Support streamOptimized \u2714 monolithicSparse vmfs vmfsSparse twoGbMaxExtentSparse monolithicFlat twoGbMaxExtentFlat vmfsRaw fullDevice partitionedDevice vmfsRawDeviceMap vmfsPassthroughRawDeviceMap Reference: VMware Virtual Disk Format 1.1.pdf","title":"VMDK disk types"},{"location":"docs/target/vm/#disk-partitions","text":"Disk format Support Master boot record (MBR) \u2714 Extended master boot record GUID partition table (GPT) \u2714 Logical volume manager (LVM)","title":"Disk partitions"},{"location":"docs/target/vm/#filesystems","text":"Filesystem format Support XFS \u2714 EXT4 \u2714 EXT2/3 ZFS","title":"Filesystems"},{"location":"ecosystem/","text":"Ecosystem Trivy is integrated into many popular tools and applications, so that you can easily add security to your workflow. In this section you will find an aggregation of the different integrations. Integrations are listed as either \"official\" or \"community\". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers. \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics. Add missing integration We are happy to showcase community integrations in this section. To suggest an addition simply make a Pull Request to add the missing integration.","title":"Overview"},{"location":"ecosystem/#ecosystem","text":"Trivy is integrated into many popular tools and applications, so that you can easily add security to your workflow. In this section you will find an aggregation of the different integrations. Integrations are listed as either \"official\" or \"community\". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers. \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics.","title":"Ecosystem"},{"location":"ecosystem/#add-missing-integration","text":"We are happy to showcase community integrations in this section. To suggest an addition simply make a Pull Request to add the missing integration.","title":"Add missing integration"},{"location":"ecosystem/cicd/","text":"CI/CD Integrations GitHub Actions GitHub Actions is GitHub's native CI/CD and job orchestration service. trivy-action (Official) GitHub Action for integrating Trivy into your GitHub pipeline \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-action trivy-action (Community) GitHub Action to scan vulnerability using Trivy. If vulnerabilities are found by Trivy, it creates a GitHub Issue. \ud83d\udc49 Get it at: https://github.com/marketplace/actions/trivy-action trivy-github-issues (Community) In this action, Trivy scans the dependency files such as package-lock.json and go.sum in your repository, then create GitHub issues according to the result. \ud83d\udc49 Get it at: https://github.com/marketplace/actions/trivy-github-issues Azure DevOps (Official) Azure Devops is Microsoft Azure cloud native CI/CD service. Trivy has a \"Azure Devops Pipelines Task\" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-azure-pipelines-task Semaphore (Community) Semaphore is a CI/CD service. You can use Trivy in Semaphore for scanning code, containers, infrastructure, and Kubernetes in Semaphore workflow. \ud83d\udc49 Get it at: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy CircleCI (Community) CircleCI is a CI/CD service. You can use the Trivy Orb for Circle CI to introduce security scanning into your workflow. \ud83d\udc49 Get it at: https://circleci.com/developer/orbs/orb/fifteen5/trivy-orb Source: https://github.com/15five/trivy-orb Woodpecker CI (Community) Example Trivy step in pipeline pipeline: securitycheck: image: aquasec/trivy:latest commands: # use any trivy command, if exit code is 0 woodpecker marks it as passed, else it assumes it failed - trivy fs --exit-code 1 --skip-dirs web/ --skip-dirs docs/ --severity MEDIUM,HIGH,CRITICAL . Woodpecker does use Trivy itself so you can see it in use there . Concourse CI (Community) Concourse CI is a CI/CD service. You can use Trivy Resource in Concourse for scanning containers and introducing security scanning into your workflow. It has capabilities to fail the pipeline, create issues, alert communication channels (using respective resources) based on Trivy scan output. \ud83d\udc49 Get it at: https://github.com/Comcast/trivy-resource/","title":"CI/CD"},{"location":"ecosystem/cicd/#cicd-integrations","text":"","title":"CI/CD Integrations"},{"location":"ecosystem/cicd/#github-actions","text":"GitHub Actions is GitHub's native CI/CD and job orchestration service.","title":"GitHub Actions"},{"location":"ecosystem/cicd/#trivy-action-official","text":"GitHub Action for integrating Trivy into your GitHub pipeline \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-action","title":"trivy-action (Official)"},{"location":"ecosystem/cicd/#trivy-action-community","text":"GitHub Action to scan vulnerability using Trivy. If vulnerabilities are found by Trivy, it creates a GitHub Issue. \ud83d\udc49 Get it at: https://github.com/marketplace/actions/trivy-action","title":"trivy-action (Community)"},{"location":"ecosystem/cicd/#trivy-github-issues-community","text":"In this action, Trivy scans the dependency files such as package-lock.json and go.sum in your repository, then create GitHub issues according to the result. \ud83d\udc49 Get it at: https://github.com/marketplace/actions/trivy-github-issues","title":"trivy-github-issues (Community)"},{"location":"ecosystem/cicd/#azure-devops-official","text":"Azure Devops is Microsoft Azure cloud native CI/CD service. Trivy has a \"Azure Devops Pipelines Task\" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-azure-pipelines-task","title":"Azure DevOps (Official)"},{"location":"ecosystem/cicd/#semaphore-community","text":"Semaphore is a CI/CD service. You can use Trivy in Semaphore for scanning code, containers, infrastructure, and Kubernetes in Semaphore workflow. \ud83d\udc49 Get it at: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy","title":"Semaphore (Community)"},{"location":"ecosystem/cicd/#circleci-community","text":"CircleCI is a CI/CD service. You can use the Trivy Orb for Circle CI to introduce security scanning into your workflow. \ud83d\udc49 Get it at: https://circleci.com/developer/orbs/orb/fifteen5/trivy-orb Source: https://github.com/15five/trivy-orb","title":"CircleCI (Community)"},{"location":"ecosystem/cicd/#woodpecker-ci-community","text":"Example Trivy step in pipeline pipeline: securitycheck: image: aquasec/trivy:latest commands: # use any trivy command, if exit code is 0 woodpecker marks it as passed, else it assumes it failed - trivy fs --exit-code 1 --skip-dirs web/ --skip-dirs docs/ --severity MEDIUM,HIGH,CRITICAL . Woodpecker does use Trivy itself so you can see it in use there .","title":"Woodpecker CI (Community)"},{"location":"ecosystem/cicd/#concourse-ci-community","text":"Concourse CI is a CI/CD service. You can use Trivy Resource in Concourse for scanning containers and introducing security scanning into your workflow. It has capabilities to fail the pipeline, create issues, alert communication channels (using respective resources) based on Trivy scan output. \ud83d\udc49 Get it at: https://github.com/Comcast/trivy-resource/","title":"Concourse CI (Community)"},{"location":"ecosystem/ide/","text":"IDE and developer tools Integrations VSCode (Official) Visual Studio Code is an open source versatile code editor and development environment. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-vscode-extension JetBrains (Official) JetBrains makes IDEs such as Goland, Pycharm, IntelliJ, Webstorm, and more. The Trivy plugin for JetBrains IDEs lets you use Trivy right from your development environment. \ud83d\udc49 Get it at: https://plugins.jetbrains.com/plugin/18690-trivy-findings-explorer Kubernetes Lens (Official) Kubernetes Lens is a management application for Kubernetes clusters. Trivy has an extension for Kubernetes Lens that lets you scan Kubernetes workloads and view the results in the Lens UI. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-operator-lens-extension Vim (Community) Vim is a terminal based text editor. Vim plugin for Trivy to install and run Trivy. \ud83d\udc49 Get it at: https://github.com/aquasecurity/vim-trivy Docker Desktop (Community) Docker Desktop is an easy way to install Docker container engine on your development machine, and manage it in a GUI . Trivy Docker Desktop extension for scanning container images for vulnerabilities and generating SBOMs \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-docker-extension Rancher Desktop (Community) Rancher Desktop is an easy way to use containers and Kubernetes on your development machine, and mange it in a GUI. Trivy is natively integrated with Rancher, no installation is needed. More info in Rancher documentation: https://docs.rancherdesktop.io/getting-started/features#scanning-images LazyTrivy (Community) A terminal native UI for Trivy \ud83d\udc49 Get it at: https://github.com/owenrumney/lazytrivy Trivy Vulnerability explorer (Community) Web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table \ud83d\udc49 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer Trivy pre-commit (Community) A trivy pre-commit hook that runs a trivy fs in your git repo before commiting, preventing you from commiting secrets in the first place. \ud83d\udc49 Get it at: https://github.com/mxab/pre-commit-trivy","title":"IDE and Dev tools"},{"location":"ecosystem/ide/#ide-and-developer-tools-integrations","text":"","title":"IDE and developer tools Integrations"},{"location":"ecosystem/ide/#vscode-official","text":"Visual Studio Code is an open source versatile code editor and development environment. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-vscode-extension","title":"VSCode (Official)"},{"location":"ecosystem/ide/#jetbrains-official","text":"JetBrains makes IDEs such as Goland, Pycharm, IntelliJ, Webstorm, and more. The Trivy plugin for JetBrains IDEs lets you use Trivy right from your development environment. \ud83d\udc49 Get it at: https://plugins.jetbrains.com/plugin/18690-trivy-findings-explorer","title":"JetBrains (Official)"},{"location":"ecosystem/ide/#kubernetes-lens-official","text":"Kubernetes Lens is a management application for Kubernetes clusters. Trivy has an extension for Kubernetes Lens that lets you scan Kubernetes workloads and view the results in the Lens UI. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-operator-lens-extension","title":"Kubernetes Lens (Official)"},{"location":"ecosystem/ide/#vim-community","text":"Vim is a terminal based text editor. Vim plugin for Trivy to install and run Trivy. \ud83d\udc49 Get it at: https://github.com/aquasecurity/vim-trivy","title":"Vim (Community)"},{"location":"ecosystem/ide/#docker-desktop-community","text":"Docker Desktop is an easy way to install Docker container engine on your development machine, and manage it in a GUI . Trivy Docker Desktop extension for scanning container images for vulnerabilities and generating SBOMs \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-docker-extension","title":"Docker Desktop (Community)"},{"location":"ecosystem/ide/#rancher-desktop-community","text":"Rancher Desktop is an easy way to use containers and Kubernetes on your development machine, and mange it in a GUI. Trivy is natively integrated with Rancher, no installation is needed. More info in Rancher documentation: https://docs.rancherdesktop.io/getting-started/features#scanning-images","title":"Rancher Desktop (Community)"},{"location":"ecosystem/ide/#lazytrivy-community","text":"A terminal native UI for Trivy \ud83d\udc49 Get it at: https://github.com/owenrumney/lazytrivy","title":"LazyTrivy (Community)"},{"location":"ecosystem/ide/#trivy-vulnerability-explorer-community","text":"Web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table \ud83d\udc49 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer","title":"Trivy Vulnerability explorer (Community)"},{"location":"ecosystem/ide/#trivy-pre-commit-community","text":"A trivy pre-commit hook that runs a trivy fs in your git repo before commiting, preventing you from commiting secrets in the first place. \ud83d\udc49 Get it at: https://github.com/mxab/pre-commit-trivy","title":"Trivy pre-commit (Community)"},{"location":"ecosystem/prod/","text":"Production and cloud Integrations Kubernetes Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. Trivy Operator (Official) Using the Trivy Operator you can install Trivy into a Kubernetes cluster so that it automatically and continuously scan your workloads and cluster for security issues. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-operator Harbor (Official) Harbor is an open source cloud native container and artifact registry. Trivy is natively integrated into Harbor, no installation is needed. More info in Harbor documentation: https://goharbor.io/docs/2.6.0/administration/vulnerability-scanning Kyverno (Community) Kyverno is a policy management tool for Kubernetes. You can use Kyverno to ensure and enforce that deployed workloads' images are scanned for vulnerabilities. \ud83d\udc49 Get it at: https://neonmirrors.net/post/2022-07/attesting-image-scans-kyverno","title":"Production and Clouds"},{"location":"ecosystem/prod/#production-and-cloud-integrations","text":"","title":"Production and cloud Integrations"},{"location":"ecosystem/prod/#kubernetes","text":"Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.","title":"Kubernetes"},{"location":"ecosystem/prod/#trivy-operator-official","text":"Using the Trivy Operator you can install Trivy into a Kubernetes cluster so that it automatically and continuously scan your workloads and cluster for security issues. \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-operator","title":"Trivy Operator (Official)"},{"location":"ecosystem/prod/#harbor-official","text":"Harbor is an open source cloud native container and artifact registry. Trivy is natively integrated into Harbor, no installation is needed. More info in Harbor documentation: https://goharbor.io/docs/2.6.0/administration/vulnerability-scanning","title":"Harbor (Official)"},{"location":"ecosystem/prod/#kyverno-community","text":"Kyverno is a policy management tool for Kubernetes. You can use Kyverno to ensure and enforce that deployed workloads' images are scanned for vulnerabilities. \ud83d\udc49 Get it at: https://neonmirrors.net/post/2022-07/attesting-image-scans-kyverno","title":"Kyverno (Community)"},{"location":"ecosystem/security/","text":"Security Management SonarQube (Community) A Trivy plugin that converts JSON report to SonarQube generic issues format . \ud83d\udc49 Get it at: https://github.com/umax/trivy-plugin-sonarqube DefectDojo (Community) DefectDojo can parse Trivy JSON reports. The parser supports deduplication and auto-close features. \ud83d\udc49 Get it at: https://github.com/DefectDojo/django-DefectDojo","title":"Security Management"},{"location":"ecosystem/security/#security-management","text":"","title":"Security Management"},{"location":"ecosystem/security/#sonarqube-community","text":"A Trivy plugin that converts JSON report to SonarQube generic issues format . \ud83d\udc49 Get it at: https://github.com/umax/trivy-plugin-sonarqube","title":"SonarQube (Community)"},{"location":"ecosystem/security/#defectdojo-community","text":"DefectDojo can parse Trivy JSON reports. The parser supports deduplication and auto-close features. \ud83d\udc49 Get it at: https://github.com/DefectDojo/django-DefectDojo","title":"DefectDojo (Community)"},{"location":"getting-started/faq/","text":"FAQ How to pronounce the name \"Trivy\"? tri is pronounced like tri gger, vy is pronounced like en vy .","title":"FAQ"},{"location":"getting-started/faq/#faq","text":"","title":"FAQ"},{"location":"getting-started/faq/#how-to-pronounce-the-name-trivy","text":"tri is pronounced like tri gger, vy is pronounced like en vy .","title":"How to pronounce the name \"Trivy\"?"},{"location":"getting-started/installation/","text":"Installing Trivy In this section you will find an aggregation of the different ways to install Trivy. installations are listed as either \"official\" or \"community\". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers. Install using Package Manager RHEL/CentOS (Official) Repository RPM Add repository setting to /etc/yum.repos.d . RELEASE_VERSION = $( grep -Po '(?<=VERSION_ID=\")[0-9]' /etc/os-release ) cat << EOF | sudo tee -a /etc/yum.repos.d/trivy.repo [trivy] name=Trivy repository baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$RELEASE_VERSION/\\$basearch/ gpgcheck=1 enabled=1 gpgkey=https://aquasecurity.github.io/trivy-repo/rpm/public.key EOF sudo yum -y update sudo yum -y install trivy rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.41.0/trivy_0.41.0_Linux-64bit.rpm Debian/Ubuntu (Official) Repository DEB Add repository setting to /etc/apt/sources.list.d . sudo apt-get install wget apt-transport-https gnupg lsb-release wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null echo \"deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $( lsb_release -sc ) main\" | sudo tee -a /etc/apt/sources.list.d/trivy.list sudo apt-get update sudo apt-get install trivy wget https://github.com/aquasecurity/trivy/releases/download/v0.41.0/trivy_0.41.0_Linux-64bit.deb sudo dpkg -i trivy_0.41.0_Linux-64bit.deb Homebrew (Official) Homebrew for MacOS and Linux. brew install trivy Arch Linux (Community) Arch Community Package Manager. pacman -S trivy References: - https://archlinux.org/packages/community/x86_64/trivy/ - https://github.com/archlinux/svntogit-community/blob/packages/trivy/trunk/PKGBUILD MacPorts (Community) MacPorts for MacOS. sudo port install trivy References: - https://ports.macports.org/port/trivy/details/ Nix/NixOS (Community) Nix package manager for Linux and MacOS. Command line nix-env --install -A nixpkgs.trivy Configuration # your other config ... environment . systemPackages = with pkgs ; [ # your other packages ... trivy ]; Home Manager # your other config ... home . packages = with pkgs ; [ # your other packages ... trivy ]; References: - https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/admin/trivy/default.nix Install from GitHub Release (Official) Download Binary Download the file for your operating system/architecture from GitHub Release assets ( curl -LO https://url.to/trivy.tar.gz ). Unpack the downloaded archive ( tar -xzf ./trivy.tar.gz ). Put the binary somewhere in your $PATH (e.g mv ./trivy /usr/local/bin/ ). Make sure the binary has execution bit turned on ( chmod +x ./trivy ). Install Script The process above can be automated by the following script: curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.41.0 Install from source git clone --depth 1 --branch v0.41.0 https://github.com/aquasecurity/trivy cd trivy go install Use container image Pull Trivy image ( docker pull aquasec/trivy:0.41.0 ) It is advisable to mount a consistent cache dir on the host into the Trivy container. For scanning container images with Trivy, mount docker.sock from the host into the Trivy container. Example: docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME /Library/Caches:/root/.cache/ aquasec/trivy:0.41.0 image python:3.4-alpine Registry | Repository | Link | Supportability Docker Hub | docker.io/aquasec/trivy | https://hub.docker.com/r/aquasec/trivy | Official GitHub Container Registry (GHCR) | ghcr.io/aquasecurity/trivy | https://github.com/orgs/aquasecurity/packages/container/package/trivy | Official AWS Elastic Container Registry (ECR) | public.ecr.aws/aquasecurity/trivy | https://gallery.ecr.aws/aquasecurity/trivy | Official Other Tools to use and deploy Trivy For additional tools and ways to install and use Trivy in different environments such as in IDE, Kubernetes or CI/CD, see Ecosystem section .","title":"Installation"},{"location":"getting-started/installation/#installing-trivy","text":"In this section you will find an aggregation of the different ways to install Trivy. installations are listed as either \"official\" or \"community\". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers.","title":"Installing Trivy"},{"location":"getting-started/installation/#install-using-package-manager","text":"","title":"Install using Package Manager"},{"location":"getting-started/installation/#rhelcentos-official","text":"Repository RPM Add repository setting to /etc/yum.repos.d . RELEASE_VERSION = $( grep -Po '(?<=VERSION_ID=\")[0-9]' /etc/os-release ) cat << EOF | sudo tee -a /etc/yum.repos.d/trivy.repo [trivy] name=Trivy repository baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$RELEASE_VERSION/\\$basearch/ gpgcheck=1 enabled=1 gpgkey=https://aquasecurity.github.io/trivy-repo/rpm/public.key EOF sudo yum -y update sudo yum -y install trivy rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.41.0/trivy_0.41.0_Linux-64bit.rpm","title":"RHEL/CentOS (Official)"},{"location":"getting-started/installation/#debianubuntu-official","text":"Repository DEB Add repository setting to /etc/apt/sources.list.d . sudo apt-get install wget apt-transport-https gnupg lsb-release wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null echo \"deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $( lsb_release -sc ) main\" | sudo tee -a /etc/apt/sources.list.d/trivy.list sudo apt-get update sudo apt-get install trivy wget https://github.com/aquasecurity/trivy/releases/download/v0.41.0/trivy_0.41.0_Linux-64bit.deb sudo dpkg -i trivy_0.41.0_Linux-64bit.deb","title":"Debian/Ubuntu (Official)"},{"location":"getting-started/installation/#homebrew-official","text":"Homebrew for MacOS and Linux. brew install trivy","title":"Homebrew (Official)"},{"location":"getting-started/installation/#arch-linux-community","text":"Arch Community Package Manager. pacman -S trivy References: - https://archlinux.org/packages/community/x86_64/trivy/ - https://github.com/archlinux/svntogit-community/blob/packages/trivy/trunk/PKGBUILD","title":"Arch Linux (Community)"},{"location":"getting-started/installation/#macports-community","text":"MacPorts for MacOS. sudo port install trivy References: - https://ports.macports.org/port/trivy/details/","title":"MacPorts (Community)"},{"location":"getting-started/installation/#nixnixos-community","text":"Nix package manager for Linux and MacOS. Command line nix-env --install -A nixpkgs.trivy Configuration # your other config ... environment . systemPackages = with pkgs ; [ # your other packages ... trivy ]; Home Manager # your other config ... home . packages = with pkgs ; [ # your other packages ... trivy ]; References: - https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/admin/trivy/default.nix","title":"Nix/NixOS (Community)"},{"location":"getting-started/installation/#install-from-github-release-official","text":"","title":"Install from GitHub Release (Official)"},{"location":"getting-started/installation/#download-binary","text":"Download the file for your operating system/architecture from GitHub Release assets ( curl -LO https://url.to/trivy.tar.gz ). Unpack the downloaded archive ( tar -xzf ./trivy.tar.gz ). Put the binary somewhere in your $PATH (e.g mv ./trivy /usr/local/bin/ ). Make sure the binary has execution bit turned on ( chmod +x ./trivy ).","title":"Download Binary"},{"location":"getting-started/installation/#install-script","text":"The process above can be automated by the following script: curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.41.0","title":"Install Script"},{"location":"getting-started/installation/#install-from-source","text":"git clone --depth 1 --branch v0.41.0 https://github.com/aquasecurity/trivy cd trivy go install","title":"Install from source"},{"location":"getting-started/installation/#use-container-image","text":"Pull Trivy image ( docker pull aquasec/trivy:0.41.0 ) It is advisable to mount a consistent cache dir on the host into the Trivy container. For scanning container images with Trivy, mount docker.sock from the host into the Trivy container. Example: docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME /Library/Caches:/root/.cache/ aquasec/trivy:0.41.0 image python:3.4-alpine Registry | Repository | Link | Supportability Docker Hub | docker.io/aquasec/trivy | https://hub.docker.com/r/aquasec/trivy | Official GitHub Container Registry (GHCR) | ghcr.io/aquasecurity/trivy | https://github.com/orgs/aquasecurity/packages/container/package/trivy | Official AWS Elastic Container Registry (ECR) | public.ecr.aws/aquasecurity/trivy | https://gallery.ecr.aws/aquasecurity/trivy | Official","title":"Use container image"},{"location":"getting-started/installation/#other-tools-to-use-and-deploy-trivy","text":"For additional tools and ways to install and use Trivy in different environments such as in IDE, Kubernetes or CI/CD, see Ecosystem section .","title":"Other Tools to use and deploy Trivy"},{"location":"tutorials/overview/","text":"Tutorials In this section you can find step-by-step guides that help you accomplish specific tasks. \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics. Adding tutorials You are welcome to create tutorials and showcase them here. Tutorials can be either included in here as full articles, or included as external links under external community resources . Before sending PR, please first create an issue (of kind \"Documentation\") and describe the suggestion, if it's external link or article, and what category it's under. Guidelines: Focus on a specific use case. Start by clearly describing the use case and when/who it is relevant for. Provide an end-to-end set of instructions. Make sure anyone can easily follow. Describe the expected outcome after each step. Include examples as much as possible.","title":"Overview"},{"location":"tutorials/overview/#tutorials","text":"In this section you can find step-by-step guides that help you accomplish specific tasks. \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics.","title":"Tutorials"},{"location":"tutorials/overview/#adding-tutorials","text":"You are welcome to create tutorials and showcase them here. Tutorials can be either included in here as full articles, or included as external links under external community resources . Before sending PR, please first create an issue (of kind \"Documentation\") and describe the suggestion, if it's external link or article, and what category it's under. Guidelines: Focus on a specific use case. Start by clearly describing the use case and when/who it is relevant for. Provide an end-to-end set of instructions. Make sure anyone can easily follow. Describe the expected outcome after each step. Include examples as much as possible.","title":"Adding tutorials"},{"location":"tutorials/additional-resources/cks/","text":"CKS preparation resources The Certified Kubernetes Security Specialist (CKS) Exam is offered by The Linux Foundation. It provides assurance that a CKS has the skills, knowledge, and competence on a broad range of best practices for securing container-based applications and Kubernetes platforms during build, deployment and runtime. CKA certification is required to sit for this exam. Community Resources Trivy Video overview (short) Example questions from the exam More example questions CKS exam study guide Docker Image Vulnerabilities & Trivy Image Scanning Demo | K21Academy Aqua Security Blog posts to learn more Supply chain security best practices Supply chain attacks If you know of interesting resources, please start a PR to add those to the list.","title":"CKS Reference"},{"location":"tutorials/additional-resources/cks/#cks-preparation-resources","text":"The Certified Kubernetes Security Specialist (CKS) Exam is offered by The Linux Foundation. It provides assurance that a CKS has the skills, knowledge, and competence on a broad range of best practices for securing container-based applications and Kubernetes platforms during build, deployment and runtime. CKA certification is required to sit for this exam.","title":"CKS preparation resources"},{"location":"tutorials/additional-resources/cks/#community-resources","text":"Trivy Video overview (short) Example questions from the exam More example questions CKS exam study guide Docker Image Vulnerabilities & Trivy Image Scanning Demo | K21Academy","title":"Community Resources"},{"location":"tutorials/additional-resources/cks/#aqua-security-blog-posts-to-learn-more","text":"Supply chain security best practices Supply chain attacks If you know of interesting resources, please start a PR to add those to the list.","title":"Aqua Security Blog posts to learn more"},{"location":"tutorials/additional-resources/community/","text":"Community References Below is a list of additional resources from the community. Vulnderability Scanning Detecting Spring4Shell with Trivy and Grype CI/CD Pipelines How to use Tekton to set up a CI pipeline with OpenShift Pipelines Continuous Container Vulnerability Testing with Trivy Getting Started With Trivy and Jenkins How to use Tekton to set up a CI pipeline with OpenShift Pipelines Misconfiguration Scanning Identifying Misconfigurations in your Terraform How to write custom policies for Trivy SBOM, Attestation & related Attesting Image Scans With Kyverno Trivy Kubernetes Using Trivy Kubernetes in OVHCloud documentation. Comparisons the vulnerability remediation lifecycle of Alpine containers Open Source CVE Scanner Round-Up: Clair vs Anchore vs Trivy Docker Image Security: Static Analysis Tool Comparison \u2013 Anchore Engine vs Clair vs Trivy Evaluations Istio evaluating to use Trivy Research Spike: evaluate Trivy for scanning running containers","title":"Community References"},{"location":"tutorials/additional-resources/community/#community-references","text":"Below is a list of additional resources from the community.","title":"Community References"},{"location":"tutorials/additional-resources/community/#vulnderability-scanning","text":"Detecting Spring4Shell with Trivy and Grype","title":"Vulnderability Scanning"},{"location":"tutorials/additional-resources/community/#cicd-pipelines","text":"How to use Tekton to set up a CI pipeline with OpenShift Pipelines Continuous Container Vulnerability Testing with Trivy Getting Started With Trivy and Jenkins How to use Tekton to set up a CI pipeline with OpenShift Pipelines","title":"CI/CD Pipelines"},{"location":"tutorials/additional-resources/community/#misconfiguration-scanning","text":"Identifying Misconfigurations in your Terraform How to write custom policies for Trivy","title":"Misconfiguration Scanning"},{"location":"tutorials/additional-resources/community/#sbom-attestation-related","text":"Attesting Image Scans With Kyverno","title":"SBOM, Attestation & related"},{"location":"tutorials/additional-resources/community/#trivy-kubernetes","text":"Using Trivy Kubernetes in OVHCloud documentation.","title":"Trivy Kubernetes"},{"location":"tutorials/additional-resources/community/#comparisons","text":"the vulnerability remediation lifecycle of Alpine containers Open Source CVE Scanner Round-Up: Clair vs Anchore vs Trivy Docker Image Security: Static Analysis Tool Comparison \u2013 Anchore Engine vs Clair vs Trivy","title":"Comparisons"},{"location":"tutorials/additional-resources/community/#evaluations","text":"Istio evaluating to use Trivy Research Spike: evaluate Trivy for scanning running containers","title":"Evaluations"},{"location":"tutorials/additional-resources/references/","text":"Additional Resources and Tutorials Below is a list of additional resources from Aqua Security. Announcements Trivy Vulnerability Scanner Joins the Aqua Open-source Family Trivy Image Vulnerability Scanner Now Under Apache 2.0 License Vulnerability Scanning Using Trivy to Discover Vulnerabilities in VS Code Projects How does a vulnerability scanner identify packages? Handling Container Vulnerabilities with Open Policy Agent - Teppei Fukuda, Aqua Security CI/CD Pipelines DevSecOps with Trivy and GitHub Actions Find Image Vulnerabilities Using GitHub and Aqua Security Trivy Action Misconfiguration Scanning Identifying Misconfigurations in your Terraform Client/Server Using Trivy in client server mode Workshops Trivy Live Demo & Q&A First Steps to Full Lifecycle Security with Open Source Tools - Rory McCune & Anais Urlichs Older Resources Webinar: Trivy Open Source Scanner for Container Images \u2013 Just Download and Run! Kubernetes Security through GitOps Best Practices: ArgoCD and Starboard Get started with Kubernetes Security and Starboard","title":"Additional Resources"},{"location":"tutorials/additional-resources/references/#additional-resources-and-tutorials","text":"Below is a list of additional resources from Aqua Security.","title":"Additional Resources and Tutorials"},{"location":"tutorials/additional-resources/references/#announcements","text":"Trivy Vulnerability Scanner Joins the Aqua Open-source Family Trivy Image Vulnerability Scanner Now Under Apache 2.0 License","title":"Announcements"},{"location":"tutorials/additional-resources/references/#vulnerability-scanning","text":"Using Trivy to Discover Vulnerabilities in VS Code Projects How does a vulnerability scanner identify packages? Handling Container Vulnerabilities with Open Policy Agent - Teppei Fukuda, Aqua Security","title":"Vulnerability Scanning"},{"location":"tutorials/additional-resources/references/#cicd-pipelines","text":"DevSecOps with Trivy and GitHub Actions Find Image Vulnerabilities Using GitHub and Aqua Security Trivy Action","title":"CI/CD Pipelines"},{"location":"tutorials/additional-resources/references/#misconfiguration-scanning","text":"Identifying Misconfigurations in your Terraform","title":"Misconfiguration Scanning"},{"location":"tutorials/additional-resources/references/#clientserver","text":"Using Trivy in client server mode","title":"Client/Server"},{"location":"tutorials/additional-resources/references/#workshops","text":"Trivy Live Demo & Q&A First Steps to Full Lifecycle Security with Open Source Tools - Rory McCune & Anais Urlichs","title":"Workshops"},{"location":"tutorials/additional-resources/references/#older-resources","text":"Webinar: Trivy Open Source Scanner for Container Images \u2013 Just Download and Run! Kubernetes Security through GitOps Best Practices: ArgoCD and Starboard Get started with Kubernetes Security and Starboard","title":"Older Resources"},{"location":"tutorials/integrations/","text":"Integrations Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify --exit-code 0 .","title":"Overview"},{"location":"tutorials/integrations/#integrations","text":"Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify --exit-code 0 .","title":"Integrations"},{"location":"tutorials/integrations/aws-codepipeline/","text":"AWS CodePipeline See this blog post for an example of using Trivy within AWS CodePipeline.","title":"AWS CodePipeline"},{"location":"tutorials/integrations/aws-codepipeline/#aws-codepipeline","text":"See this blog post for an example of using Trivy within AWS CodePipeline.","title":"AWS CodePipeline"},{"location":"tutorials/integrations/aws-security-hub/","text":"AWS Security Hub Upload findings to Security Hub In the following example using the template asff.tpl , ASFF file can be generated. $ AWS_REGION=us-west-1 AWS_ACCOUNT_ID=123456789012 trivy image --format template --template \"@contrib/asff.tpl\" -o report.asff golang:1.12-alpine ASFF template needs AWS_REGION and AWS_ACCOUNT_ID from environment variables. The Product ARN field follows the pattern below to match what AWS requires for the product resource type . \"ProductArn\": \"arn:aws:securityhub:{{ env \"AWS_REGION\" }}::product/aquasecurity/aquasecurity\", In order to upload results you must first run enable-import-findings-for-product like: aws securityhub enable-import-findings-for-product --product-arn arn:aws:securityhub:::product/aquasecurity/aquasecurity The findings are formatted for the API with a key of Findings and a value of the array of findings. In order to upload via the CLI the outer wrapping must be removed being left with only the array of findings. The easiest way of doing this is with the jq library using the command cat report.asff | jq '.Findings' Then, you can upload it with AWS CLI. $ aws securityhub batch-import-findings --findings file://report.asff Note The batch-import-findings command limits the number of findings uploaded to 100 per request. The best known workaround to this problem is using jq to run the following command jq '.[:100]' report.asff 1> short_report.asff Customize You can customize asff.tpl $ export AWS_REGION=us-west-1 $ export AWS_ACCOUNT_ID=123456789012 $ trivy image --format template --template \"@your-asff.tpl\" -o report.asff golang:1.12-alpine Reference aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/","title":"AWS Security Hub"},{"location":"tutorials/integrations/aws-security-hub/#aws-security-hub","text":"","title":"AWS Security Hub"},{"location":"tutorials/integrations/aws-security-hub/#upload-findings-to-security-hub","text":"In the following example using the template asff.tpl , ASFF file can be generated. $ AWS_REGION=us-west-1 AWS_ACCOUNT_ID=123456789012 trivy image --format template --template \"@contrib/asff.tpl\" -o report.asff golang:1.12-alpine ASFF template needs AWS_REGION and AWS_ACCOUNT_ID from environment variables. The Product ARN field follows the pattern below to match what AWS requires for the product resource type . \"ProductArn\": \"arn:aws:securityhub:{{ env \"AWS_REGION\" }}::product/aquasecurity/aquasecurity\", In order to upload results you must first run enable-import-findings-for-product like: aws securityhub enable-import-findings-for-product --product-arn arn:aws:securityhub:::product/aquasecurity/aquasecurity The findings are formatted for the API with a key of Findings and a value of the array of findings. In order to upload via the CLI the outer wrapping must be removed being left with only the array of findings. The easiest way of doing this is with the jq library using the command cat report.asff | jq '.Findings' Then, you can upload it with AWS CLI. $ aws securityhub batch-import-findings --findings file://report.asff","title":"Upload findings to Security Hub"},{"location":"tutorials/integrations/aws-security-hub/#note","text":"The batch-import-findings command limits the number of findings uploaded to 100 per request. The best known workaround to this problem is using jq to run the following command jq '.[:100]' report.asff 1> short_report.asff","title":"Note"},{"location":"tutorials/integrations/aws-security-hub/#customize","text":"You can customize asff.tpl $ export AWS_REGION=us-west-1 $ export AWS_ACCOUNT_ID=123456789012 $ trivy image --format template --template \"@your-asff.tpl\" -o report.asff golang:1.12-alpine","title":"Customize"},{"location":"tutorials/integrations/aws-security-hub/#reference","text":"aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/","title":"Reference"},{"location":"tutorials/integrations/azure-devops/","text":"Azure Devops Here is the Azure DevOps Pipelines Task for Trivy Use ImageCleaner to clean up stale images on your Azure Kubernetes Service cluster It's common to use pipelines to build and deploy images on Azure Kubernetes Service (AKS) clusters. While great for image creation, this process often doesn't account for the stale images left behind and can lead to image bloat on cluster nodes. These images can present security issues as they may contain vulnerabilities. By cleaning these unreferenced images, you can remove an area of risk in your clusters. When done manually, this process can be time intensive, which ImageCleaner can mitigate via automatic image identification and removal. Vulnerability is determined based on a trivy scan, after which images with a LOW, MEDIUM, HIGH, or CRITICAL classification are flagged. An updated ImageList will be automatically generated by ImageCleaner based on a set time interval, and can also be supplied manually. Microsoft Defender for container registries and Trivy This blog explains how to scan your Azure Container Registry-based container images with the integrated vulnerability scanner when they're built as part of your GitHub workflows. To set up the scanner, you'll need to enable Microsoft Defender for Containers and the CI/CD integration. When your CI/CD workflows push images to your registries, you can view registry scan results and a summary of CI/CD scan results. The findings of the CI/CD scans are an enrichment to the existing registry scan findings by Qualys. Defender for Cloud's CI/CD scanning is powered by Aqua Trivy","title":"Azure"},{"location":"tutorials/integrations/azure-devops/#azure-devops","text":"Here is the Azure DevOps Pipelines Task for Trivy","title":"Azure Devops"},{"location":"tutorials/integrations/azure-devops/#use-imagecleaner-to-clean-up-stale-images-on-your-azure-kubernetes-service-cluster","text":"It's common to use pipelines to build and deploy images on Azure Kubernetes Service (AKS) clusters. While great for image creation, this process often doesn't account for the stale images left behind and can lead to image bloat on cluster nodes. These images can present security issues as they may contain vulnerabilities. By cleaning these unreferenced images, you can remove an area of risk in your clusters. When done manually, this process can be time intensive, which ImageCleaner can mitigate via automatic image identification and removal. Vulnerability is determined based on a trivy scan, after which images with a LOW, MEDIUM, HIGH, or CRITICAL classification are flagged. An updated ImageList will be automatically generated by ImageCleaner based on a set time interval, and can also be supplied manually.","title":"Use ImageCleaner to clean up stale images on your Azure Kubernetes Service cluster"},{"location":"tutorials/integrations/azure-devops/#microsoft-defender-for-container-registries-and-trivy","text":"This blog explains how to scan your Azure Container Registry-based container images with the integrated vulnerability scanner when they're built as part of your GitHub workflows. To set up the scanner, you'll need to enable Microsoft Defender for Containers and the CI/CD integration. When your CI/CD workflows push images to your registries, you can view registry scan results and a summary of CI/CD scan results. The findings of the CI/CD scans are an enrichment to the existing registry scan findings by Qualys. Defender for Cloud's CI/CD scanning is powered by Aqua Trivy","title":"Microsoft Defender for container registries and Trivy"},{"location":"tutorials/integrations/bitbucket/","text":"Bitbucket Pipelines See trivy-pipe for the details.","title":"Bitbucket Pipelines"},{"location":"tutorials/integrations/bitbucket/#bitbucket-pipelines","text":"See trivy-pipe for the details.","title":"Bitbucket Pipelines"},{"location":"tutorials/integrations/circleci/","text":"CircleCI $ cat .circleci/config.yml jobs: build: docker: - image: docker:stable-git steps: - checkout - setup_remote_docker - run: name: Build image command: docker build -t trivy-ci-test:${CIRCLE_SHA1} . - run: name: Install trivy command: | apk add --update-cache --upgrade curl curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - run: name: Scan the local image with trivy command: trivy image --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1} workflows: version: 2 release: jobs: - build Example Repository","title":"CircleCI"},{"location":"tutorials/integrations/circleci/#circleci","text":"$ cat .circleci/config.yml jobs: build: docker: - image: docker:stable-git steps: - checkout - setup_remote_docker - run: name: Build image command: docker build -t trivy-ci-test:${CIRCLE_SHA1} . - run: name: Install trivy command: | apk add --update-cache --upgrade curl curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - run: name: Scan the local image with trivy command: trivy image --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1} workflows: version: 2 release: jobs: - build Example Repository","title":"CircleCI"},{"location":"tutorials/integrations/github-actions/","text":"GitHub Actions Here is the Trivy GitHub Action The Microsoft Azure team have written a container-scan action that uses Trivy and Dockle For full control over the options specified to Trivy, this blog post describes adding Trivy into your own GitHub action workflows","title":"GitHub Actions"},{"location":"tutorials/integrations/github-actions/#github-actions","text":"Here is the Trivy GitHub Action The Microsoft Azure team have written a container-scan action that uses Trivy and Dockle For full control over the options specified to Trivy, this blog post describes adding Trivy into your own GitHub action workflows","title":"GitHub Actions"},{"location":"tutorials/integrations/gitlab-ci/","text":"GitLab CI GitLab 15.0 includes free integration with Trivy. To configure container scanning with Trivy in GitLab , simply include the CI template in your .gitlab-ci.yml file: include : - template : Security/Container-Scanning.gitlab-ci.yml If you're a GitLab 14.x Ultimate customer, you can use the same configuration above. Alternatively, you can always use the example configurations below. stages : - test trivy : stage : test image : docker:stable services : - name : docker:dind entrypoint : [ \"env\" , \"-u\" , \"DOCKER_HOST\" ] command : [ \"dockerd-entrypoint.sh\" ] variables : DOCKER_HOST : tcp://docker:2375/ DOCKER_DRIVER : overlay2 # See https://github.com/docker-library/docker/pull/166 DOCKER_TLS_CERTDIR : \"\" IMAGE : trivy-ci-test:$CI_COMMIT_SHA TRIVY_NO_PROGRESS : \"true\" TRIVY_CACHE_DIR : \".trivycache/\" before_script : - export TRIVY_VERSION=$(wget -qO - \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/') - echo $TRIVY_VERSION - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - allow_failure : true script : # Build image - docker build -t $IMAGE . # Build report - ./trivy image --exit-code 0 --format template --template \"@contrib/gitlab.tpl\" -o gl-container-scanning-report.json $IMAGE # Print report - ./trivy image --exit-code 0 --severity HIGH $IMAGE # Fail on severe vulnerabilities - ./trivy image --exit-code 1 --severity CRITICAL $IMAGE cache : paths : - .trivycache/ # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold) artifacts : reports : container_scanning : gl-container-scanning-report.json Example Repository GitLab CI using Trivy container To scan a previously built image that has already been pushed into the GitLab container registry the following CI job manifest can be used. Note that entrypoint needs to be unset for the script section to work. In case of a non-public GitLab project Trivy additionally needs to authenticate to the registry to be able to pull your application image. Finally, it is not necessary to clone the project repo as we only work with the container image. container_scanning : image : name : docker.io/aquasec/trivy:latest entrypoint : [ \"\" ] variables : # No need to clone the repo, we exclusively work on artifacts. See # https://docs.gitlab.com/ee/ci/runners/README.html#git-strategy GIT_STRATEGY : none TRIVY_USERNAME : \"$CI_REGISTRY_USER\" TRIVY_PASSWORD : \"$CI_REGISTRY_PASSWORD\" TRIVY_AUTH_URL : \"$CI_REGISTRY\" TRIVY_NO_PROGRESS : \"true\" TRIVY_CACHE_DIR : \".trivycache/\" FULL_IMAGE_NAME : $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG script : - trivy --version # cache cleanup is needed when scanning images with the same tags, it does not remove the database - time trivy image --clear-cache # update vulnerabilities db - time trivy image --download-db-only # Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there - time trivy image --exit-code 0 --format template --template \"@/contrib/gitlab.tpl\" --output \"$CI_PROJECT_DIR/gl-container-scanning-report.json\" \"$FULL_IMAGE_NAME\" # Prints full report - time trivy image --exit-code 0 \"$FULL_IMAGE_NAME\" # Fail on critical vulnerabilities - time trivy image --exit-code 1 --severity CRITICAL \"$FULL_IMAGE_NAME\" cache : paths : - .trivycache/ # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold) artifacts : when : always reports : container_scanning : gl-container-scanning-report.json tags : - docker-runner GitLab CI alternative template Depending on the edition of gitlab you have or your desired workflow, the container scanning template may not meet your needs. As an addition to the above container scanning template, a template for code climate has been included. The key things to update from the above examples are the template and report type. An updated example is below. stages : - test trivy : stage : test image : docker:stable services : - name : docker:dind entrypoint : [ \"env\" , \"-u\" , \"DOCKER_HOST\" ] command : [ \"dockerd-entrypoint.sh\" ] variables : DOCKER_HOST : tcp://docker:2375/ DOCKER_DRIVER : overlay2 # See https://github.com/docker-library/docker/pull/166 DOCKER_TLS_CERTDIR : \"\" IMAGE : trivy-ci-test:$CI_COMMIT_SHA TRIVY_NO_PROGRESS : \"true\" TRIVY_CACHE_DIR : \".trivycache/\" before_script : - export TRIVY_VERSION=$(wget -qO - \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/') - echo $TRIVY_VERSION - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - allow_failure : true script : # Build image - docker build -t $IMAGE . # Image report - ./trivy image --exit-code 0 --format template --template \"@contrib/gitlab-codequality.tpl\" -o gl-codeclimate-image.json $IMAGE # Filesystem report - ./trivy filesystem --scanners config,vuln --exit-code 0 --format template --template \"@contrib/gitlab-codequality.tpl\" -o gl-codeclimate-fs.json . # Combine report - apk update && apk add jq - jq -s 'add' gl-codeclimate-image.json gl-codeclimate-fs.json > gl-codeclimate.json cache : paths : - .trivycache/ # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold) artifacts : paths : - gl-codeclimate.json reports : codequality : gl-codeclimate.json Currently gitlab only supports a single code quality report. There is an open feature request to support multiple reports. Until this has been implemented, if you already have a code quality report in your pipeline, you can use jq to combine reports. Depending on how you name your artifacts, it may be necessary to rename the artifact if you want to reuse the name. To then combine the previous artifact with the output of trivy, the following jq command can be used, jq -s 'add' prev-codeclimate.json trivy-codeclimate.json > gl-codeclimate.json . GitLab CI alternative template example report You'll be able to see a full report in the GitLab pipeline code quality UI, where filesystem vulnerabilities and misconfigurations include links to the flagged files and image vulnerabilities report the image/os or runtime/library that the vulnerability originates from instead.","title":"GitLab CI"},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci","text":"GitLab 15.0 includes free integration with Trivy. To configure container scanning with Trivy in GitLab , simply include the CI template in your .gitlab-ci.yml file: include : - template : Security/Container-Scanning.gitlab-ci.yml If you're a GitLab 14.x Ultimate customer, you can use the same configuration above. Alternatively, you can always use the example configurations below. stages : - test trivy : stage : test image : docker:stable services : - name : docker:dind entrypoint : [ \"env\" , \"-u\" , \"DOCKER_HOST\" ] command : [ \"dockerd-entrypoint.sh\" ] variables : DOCKER_HOST : tcp://docker:2375/ DOCKER_DRIVER : overlay2 # See https://github.com/docker-library/docker/pull/166 DOCKER_TLS_CERTDIR : \"\" IMAGE : trivy-ci-test:$CI_COMMIT_SHA TRIVY_NO_PROGRESS : \"true\" TRIVY_CACHE_DIR : \".trivycache/\" before_script : - export TRIVY_VERSION=$(wget -qO - \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/') - echo $TRIVY_VERSION - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - allow_failure : true script : # Build image - docker build -t $IMAGE . # Build report - ./trivy image --exit-code 0 --format template --template \"@contrib/gitlab.tpl\" -o gl-container-scanning-report.json $IMAGE # Print report - ./trivy image --exit-code 0 --severity HIGH $IMAGE # Fail on severe vulnerabilities - ./trivy image --exit-code 1 --severity CRITICAL $IMAGE cache : paths : - .trivycache/ # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold) artifacts : reports : container_scanning : gl-container-scanning-report.json Example Repository","title":"GitLab CI"},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci-using-trivy-container","text":"To scan a previously built image that has already been pushed into the GitLab container registry the following CI job manifest can be used. Note that entrypoint needs to be unset for the script section to work. In case of a non-public GitLab project Trivy additionally needs to authenticate to the registry to be able to pull your application image. Finally, it is not necessary to clone the project repo as we only work with the container image. container_scanning : image : name : docker.io/aquasec/trivy:latest entrypoint : [ \"\" ] variables : # No need to clone the repo, we exclusively work on artifacts. See # https://docs.gitlab.com/ee/ci/runners/README.html#git-strategy GIT_STRATEGY : none TRIVY_USERNAME : \"$CI_REGISTRY_USER\" TRIVY_PASSWORD : \"$CI_REGISTRY_PASSWORD\" TRIVY_AUTH_URL : \"$CI_REGISTRY\" TRIVY_NO_PROGRESS : \"true\" TRIVY_CACHE_DIR : \".trivycache/\" FULL_IMAGE_NAME : $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG script : - trivy --version # cache cleanup is needed when scanning images with the same tags, it does not remove the database - time trivy image --clear-cache # update vulnerabilities db - time trivy image --download-db-only # Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there - time trivy image --exit-code 0 --format template --template \"@/contrib/gitlab.tpl\" --output \"$CI_PROJECT_DIR/gl-container-scanning-report.json\" \"$FULL_IMAGE_NAME\" # Prints full report - time trivy image --exit-code 0 \"$FULL_IMAGE_NAME\" # Fail on critical vulnerabilities - time trivy image --exit-code 1 --severity CRITICAL \"$FULL_IMAGE_NAME\" cache : paths : - .trivycache/ # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold) artifacts : when : always reports : container_scanning : gl-container-scanning-report.json tags : - docker-runner","title":"GitLab CI using Trivy container"},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci-alternative-template","text":"Depending on the edition of gitlab you have or your desired workflow, the container scanning template may not meet your needs. As an addition to the above container scanning template, a template for code climate has been included. The key things to update from the above examples are the template and report type. An updated example is below. stages : - test trivy : stage : test image : docker:stable services : - name : docker:dind entrypoint : [ \"env\" , \"-u\" , \"DOCKER_HOST\" ] command : [ \"dockerd-entrypoint.sh\" ] variables : DOCKER_HOST : tcp://docker:2375/ DOCKER_DRIVER : overlay2 # See https://github.com/docker-library/docker/pull/166 DOCKER_TLS_CERTDIR : \"\" IMAGE : trivy-ci-test:$CI_COMMIT_SHA TRIVY_NO_PROGRESS : \"true\" TRIVY_CACHE_DIR : \".trivycache/\" before_script : - export TRIVY_VERSION=$(wget -qO - \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/') - echo $TRIVY_VERSION - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - allow_failure : true script : # Build image - docker build -t $IMAGE . # Image report - ./trivy image --exit-code 0 --format template --template \"@contrib/gitlab-codequality.tpl\" -o gl-codeclimate-image.json $IMAGE # Filesystem report - ./trivy filesystem --scanners config,vuln --exit-code 0 --format template --template \"@contrib/gitlab-codequality.tpl\" -o gl-codeclimate-fs.json . # Combine report - apk update && apk add jq - jq -s 'add' gl-codeclimate-image.json gl-codeclimate-fs.json > gl-codeclimate.json cache : paths : - .trivycache/ # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold) artifacts : paths : - gl-codeclimate.json reports : codequality : gl-codeclimate.json Currently gitlab only supports a single code quality report. There is an open feature request to support multiple reports. Until this has been implemented, if you already have a code quality report in your pipeline, you can use jq to combine reports. Depending on how you name your artifacts, it may be necessary to rename the artifact if you want to reuse the name. To then combine the previous artifact with the output of trivy, the following jq command can be used, jq -s 'add' prev-codeclimate.json trivy-codeclimate.json > gl-codeclimate.json .","title":"GitLab CI alternative template"},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci-alternative-template-example-report","text":"You'll be able to see a full report in the GitLab pipeline code quality UI, where filesystem vulnerabilities and misconfigurations include links to the flagged files and image vulnerabilities report the image/os or runtime/library that the vulnerability originates from instead.","title":"GitLab CI alternative template example report"},{"location":"tutorials/integrations/travis-ci/","text":"Travis CI $ cat .travis.yml services: - docker env: global: - COMMIT=${TRAVIS_COMMIT::8} before_install: - docker build -t trivy-ci-test:${COMMIT} . - export VERSION=$(curl --silent \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/') - wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz script: - ./trivy image --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT} - ./trivy image --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT} cache: directories: - $HOME/.cache/trivy Example Repository","title":"Travis CI"},{"location":"tutorials/integrations/travis-ci/#travis-ci","text":"$ cat .travis.yml services: - docker env: global: - COMMIT=${TRAVIS_COMMIT::8} before_install: - docker build -t trivy-ci-test:${COMMIT} . - export VERSION=$(curl --silent \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/') - wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz script: - ./trivy image --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT} - ./trivy image --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT} cache: directories: - $HOME/.cache/trivy Example Repository","title":"Travis CI"},{"location":"tutorials/kubernetes/cluster-scanning/","text":"Kubernetes Scanning Tutorial Prerequisites To test the following commands yourself, make sure that you\u2019re connected to a Kubernetes cluster. A simple kind, a Docker-Desktop or microk8s cluster will do. In our case, we\u2019ll use a one-node kind cluster. Pro tip: The output of the commands will be even more interesting if you have some workloads running in your cluster. Cluster Scanning Trivy K8s is great to get an overview of all the vulnerabilities and misconfiguration issues or to scan specific workloads that are running in your cluster. You would want to use the Trivy K8s command either on your own local cluster or in your CI/CD pipeline post deployments. The Trivy K8s command is part of the Trivy CLI: With the following command, we can scan our entire Kubernetes cluster for vulnerabilities and get a summary of the scan: trivy k8s --report=summary To get detailed information for all your resources, just replace \u2018summary\u2019 with \u2018all\u2019: trivy k8s --report=all However, we recommend displaying all information only in case you scan a specific namespace or resource since you can get overwhelmed with additional details. Furthermore, we can specify the namespace that Trivy is supposed to scan to focus on specific resources in the scan result: trivy k8s -n kube-system --report=summary Again, if you\u2019d like to receive additional details, use the \u2018--report=all\u2019 flag: trivy k8s -n kube-system --report=all Like with scanning for vulnerabilities, we can also filter in-cluster security issues by severity of the vulnerabilities: trivy k8s --severity=CRITICAL --report=summary Note that you can use any of the Trivy flags on the Trivy K8s command. With the Trivy K8s command, you can also scan specific workloads that are running within your cluster, such as our deployment: trivy k8s \u2013n app --report=summary deployments/react-application Trivy Operator The Trivy K8s command is an imperative model to scan resources. We wouldn\u2019t want to manually scan each resource across different environments. The larger the cluster and the more workloads are running in it, the more error-prone this process would become. With the Trivy Operator, we can automate the scanning process after the deployment. The Trivy Operator follows the Kubernetes Operator Model. Operators automate human actions, and the result of the task is saved as custom resource definitions (CRDs) within your cluster. This has several benefits: Trivy Operator is installed CRDs in our cluster. As a result, all our resources, including our security scanner and its scan results, are Kubernetes resources. This makes it much easier to integrate the Trivy Operator directly into our existing processes, such as connecting Trivy with Prometheus, a monitoring system. The Trivy Operator will automatically scan your resources every six hours. You can set up automatic alerting in case new critical security issues are discovered. The CRDs can be both machine and human-readable depending on which applications consume the CRDs. This allows for more versatile applications of the Trivy operator. There are several ways that you can install the Trivy Operator in your cluster. In this guide, we\u2019re going to use the Helm installation based on the following documentation. Please follow the Trivy Operator documentation for further information on: Installation of the Trivy Operator Getting started guide","title":"Cluster Scanning"},{"location":"tutorials/kubernetes/cluster-scanning/#kubernetes-scanning-tutorial","text":"","title":"Kubernetes Scanning Tutorial"},{"location":"tutorials/kubernetes/cluster-scanning/#prerequisites","text":"To test the following commands yourself, make sure that you\u2019re connected to a Kubernetes cluster. A simple kind, a Docker-Desktop or microk8s cluster will do. In our case, we\u2019ll use a one-node kind cluster. Pro tip: The output of the commands will be even more interesting if you have some workloads running in your cluster.","title":"Prerequisites"},{"location":"tutorials/kubernetes/cluster-scanning/#cluster-scanning","text":"Trivy K8s is great to get an overview of all the vulnerabilities and misconfiguration issues or to scan specific workloads that are running in your cluster. You would want to use the Trivy K8s command either on your own local cluster or in your CI/CD pipeline post deployments. The Trivy K8s command is part of the Trivy CLI: With the following command, we can scan our entire Kubernetes cluster for vulnerabilities and get a summary of the scan: trivy k8s --report=summary To get detailed information for all your resources, just replace \u2018summary\u2019 with \u2018all\u2019: trivy k8s --report=all However, we recommend displaying all information only in case you scan a specific namespace or resource since you can get overwhelmed with additional details. Furthermore, we can specify the namespace that Trivy is supposed to scan to focus on specific resources in the scan result: trivy k8s -n kube-system --report=summary Again, if you\u2019d like to receive additional details, use the \u2018--report=all\u2019 flag: trivy k8s -n kube-system --report=all Like with scanning for vulnerabilities, we can also filter in-cluster security issues by severity of the vulnerabilities: trivy k8s --severity=CRITICAL --report=summary Note that you can use any of the Trivy flags on the Trivy K8s command. With the Trivy K8s command, you can also scan specific workloads that are running within your cluster, such as our deployment: trivy k8s \u2013n app --report=summary deployments/react-application","title":"Cluster Scanning"},{"location":"tutorials/kubernetes/cluster-scanning/#trivy-operator","text":"The Trivy K8s command is an imperative model to scan resources. We wouldn\u2019t want to manually scan each resource across different environments. The larger the cluster and the more workloads are running in it, the more error-prone this process would become. With the Trivy Operator, we can automate the scanning process after the deployment. The Trivy Operator follows the Kubernetes Operator Model. Operators automate human actions, and the result of the task is saved as custom resource definitions (CRDs) within your cluster. This has several benefits: Trivy Operator is installed CRDs in our cluster. As a result, all our resources, including our security scanner and its scan results, are Kubernetes resources. This makes it much easier to integrate the Trivy Operator directly into our existing processes, such as connecting Trivy with Prometheus, a monitoring system. The Trivy Operator will automatically scan your resources every six hours. You can set up automatic alerting in case new critical security issues are discovered. The CRDs can be both machine and human-readable depending on which applications consume the CRDs. This allows for more versatile applications of the Trivy operator. There are several ways that you can install the Trivy Operator in your cluster. In this guide, we\u2019re going to use the Helm installation based on the following documentation. Please follow the Trivy Operator documentation for further information on: Installation of the Trivy Operator Getting started guide","title":"Trivy Operator"},{"location":"tutorials/kubernetes/gitops/","text":"Installing the Trivy-Operator through GitOps This tutorial shows you how to install the Trivy Operator through GitOps platforms, namely ArgoCD and FluxCD. ArgoCD Make sure to have ArgoCD installed and running in your Kubernetes cluster. You can either deploy the Trivy Operator through the argocd CLI or by applying a Kubernetes manifest. ArgoCD command: > kubectl create ns trivy-system > argocd app create trivy-operator --repo https://github.com/aquasecurity/trivy-operator --path deploy/helm --dest-server https://kubernetes.default.svc --dest-namespace trivy-system Note that this installation is directly related to our official Helm Chart. If you want to change any of the value, we'd suggest you to create a separate values.yaml file. Kubernetes manifest trivy-operator.yaml : apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: trivy-operator namespace: argocd spec: project: default source: chart: trivy-operator repoURL: https://aquasecurity.github.io/helm-charts/ targetRevision: 0.0.3 helm: values: | trivy: ignoreUnfixed: true destination: server: https://kubernetes.default.svc namespace: trivy-system syncPolicy: automated: prune: true selfHeal: true The apply the Kubernetes manifest. If you have the manifest locally, you can use the following command through kubectl: > kubectl apply -f trivy-operator.yaml application.argoproj.io/trivy-operator created If you have the manifest in a Git repository, you can apply it to your cluster through the following command: > kubectl apply -n argocd -f https://raw.githubusercontent.com/AnaisUrlichs/argocd-starboard/main/starboard/argocd-starboard.yaml The latter command would allow you to make changes to the YAML manifest that ArgoCD would register automatically. Once deployed, you want to tell ArgoCD to sync the application from the actual state to the desired state: argocd app sync trivy-operator Now you can see the deployment in the ArgoCD UI. Have a look at the ArgoCD documentation to know how to access the UI. Note that ArgoCD is unable to show the Trivy CRDs as synced. FluxCD Make sure to have FluxCD installed and running in your Kubernetes cluster. You can either deploy the Trivy Operator through the Flux CLI or by applying a Kubernetes manifest. Flux command: > kubectl create ns trivy-system > flux create source helm trivy-operator --url https://aquasecurity.github.io/helm-charts --namespace trivy-system > flux create helmrelease trivy-operator --chart trivy-operator --source HelmRepository/trivy-operator --chart-version 0.0.3 --namespace trivy-system Kubernetes manifest trivy-operator.yaml : apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: trivy-operator namespace: flux-system spec: interval: 60m url: https://aquasecurity.github.io/helm-charts/ --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: trivy-operator namespace: trivy-system spec: chart: spec: chart: trivy-operator sourceRef: kind: HelmRepository name: trivy-operator namespace: flux-system version: 0.10.1 interval: 60m values: trivy: ignoreUnfixed: true install: crds: CreateReplace createNamespace: true You can then apply the file to your Kubernetes cluster: kubectl apply -f trivy-operator.yaml After the installation After the install, you want to check that the Trivy operator is running in the trivy-system namespace: kubectl get deployment -n trivy-system","title":"GitOps"},{"location":"tutorials/kubernetes/gitops/#installing-the-trivy-operator-through-gitops","text":"This tutorial shows you how to install the Trivy Operator through GitOps platforms, namely ArgoCD and FluxCD.","title":"Installing the Trivy-Operator through GitOps"},{"location":"tutorials/kubernetes/gitops/#argocd","text":"Make sure to have ArgoCD installed and running in your Kubernetes cluster. You can either deploy the Trivy Operator through the argocd CLI or by applying a Kubernetes manifest. ArgoCD command: > kubectl create ns trivy-system > argocd app create trivy-operator --repo https://github.com/aquasecurity/trivy-operator --path deploy/helm --dest-server https://kubernetes.default.svc --dest-namespace trivy-system Note that this installation is directly related to our official Helm Chart. If you want to change any of the value, we'd suggest you to create a separate values.yaml file. Kubernetes manifest trivy-operator.yaml : apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: trivy-operator namespace: argocd spec: project: default source: chart: trivy-operator repoURL: https://aquasecurity.github.io/helm-charts/ targetRevision: 0.0.3 helm: values: | trivy: ignoreUnfixed: true destination: server: https://kubernetes.default.svc namespace: trivy-system syncPolicy: automated: prune: true selfHeal: true The apply the Kubernetes manifest. If you have the manifest locally, you can use the following command through kubectl: > kubectl apply -f trivy-operator.yaml application.argoproj.io/trivy-operator created If you have the manifest in a Git repository, you can apply it to your cluster through the following command: > kubectl apply -n argocd -f https://raw.githubusercontent.com/AnaisUrlichs/argocd-starboard/main/starboard/argocd-starboard.yaml The latter command would allow you to make changes to the YAML manifest that ArgoCD would register automatically. Once deployed, you want to tell ArgoCD to sync the application from the actual state to the desired state: argocd app sync trivy-operator Now you can see the deployment in the ArgoCD UI. Have a look at the ArgoCD documentation to know how to access the UI. Note that ArgoCD is unable to show the Trivy CRDs as synced.","title":"ArgoCD"},{"location":"tutorials/kubernetes/gitops/#fluxcd","text":"Make sure to have FluxCD installed and running in your Kubernetes cluster. You can either deploy the Trivy Operator through the Flux CLI or by applying a Kubernetes manifest. Flux command: > kubectl create ns trivy-system > flux create source helm trivy-operator --url https://aquasecurity.github.io/helm-charts --namespace trivy-system > flux create helmrelease trivy-operator --chart trivy-operator --source HelmRepository/trivy-operator --chart-version 0.0.3 --namespace trivy-system Kubernetes manifest trivy-operator.yaml : apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: trivy-operator namespace: flux-system spec: interval: 60m url: https://aquasecurity.github.io/helm-charts/ --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: trivy-operator namespace: trivy-system spec: chart: spec: chart: trivy-operator sourceRef: kind: HelmRepository name: trivy-operator namespace: flux-system version: 0.10.1 interval: 60m values: trivy: ignoreUnfixed: true install: crds: CreateReplace createNamespace: true You can then apply the file to your Kubernetes cluster: kubectl apply -f trivy-operator.yaml","title":"FluxCD"},{"location":"tutorials/kubernetes/gitops/#after-the-installation","text":"After the install, you want to check that the Trivy operator is running in the trivy-system namespace: kubectl get deployment -n trivy-system","title":"After the installation"},{"location":"tutorials/kubernetes/kyverno/","text":"Attesting Image Scans With Kyverno This tutorial is based on the following blog post by Chip Zoller: Attesting Image Scans With Kyverno This tutorial details Verify the container image has an attestation with Kyverno Prerequisites Attestation of the vulnerability scan uploaded A running Kubernetes cluster that kubectl is connected to Kyverno Policy to check attestation The following policy ensures that the attestation is no older than 168h: vuln-attestation.yaml apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: check-vulnerabilities spec: validationFailureAction: enforce webhookTimeoutSeconds: 10 failurePolicy: Fail rules: - name: not-older-than-one-week match: any: - resources: kinds: - Pod verifyImages: - imageReferences: - \"CONTAINER-REGISTRY/*:*\" attestations: - predicateType: cosign.sigstore.dev/attestation/vuln/v1 conditions: - all: - key: \"{{ time_since('','{{metadata.scanFinishedOn}}','') }}\" operator: LessThanOrEquals value: \"168h\" Apply the policy to your Kubernetes cluster Ensure that you have Kyverno already deployed and running on your cluster -- for instance through he Kyverno Helm Chart. Next, apply the above policy: kubectl apply -f vuln-attestation.yaml To ensure that the policy worked, we can deploye an example deployment file with our container image: deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: cns-website namespace: app spec: replicas: 2 selector: matchLabels: run: cns-website template: metadata: labels: run: cns-website spec: containers: - name: cns-website image: docker.io/anaisurlichs/cns-website:0.0.6 ports: - containerPort: 80 imagePullPolicy: Always resources: limits: memory: 512Mi cpu: 200m securityContext: allowPrivilegeEscalation: false Once we apply the deployment, it should pass since our attestation is available: kubectl apply -f deployment.yaml -n app deployment.apps/cns-website created However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with docker.io/anaisurlichs/cns-website:0.0.5 and applying the deployment: kubectl apply -f deployment-two.yaml Resource: \"apps/v1, Resource=deployments\", GroupVersionKind: \"apps/v1, Kind=Deployment\" Name: \"cns-website\", Namespace: \"app\" for: \"deployment-two.yaml\": admission webhook \"mutate.kyverno.svc-fail\" denied the request: resource Deployment/app/cns-website was blocked due to the following policies check-image: autogen-check-image: | failed to verify signature for docker.io/anaisurlichs/cns-website:0.0.5: .attestors[0].entries[0].keys: no matching signatures:","title":"Kyverno"},{"location":"tutorials/kubernetes/kyverno/#attesting-image-scans-with-kyverno","text":"This tutorial is based on the following blog post by Chip Zoller: Attesting Image Scans With Kyverno This tutorial details Verify the container image has an attestation with Kyverno","title":"Attesting Image Scans With Kyverno"},{"location":"tutorials/kubernetes/kyverno/#prerequisites","text":"Attestation of the vulnerability scan uploaded A running Kubernetes cluster that kubectl is connected to","title":"Prerequisites"},{"location":"tutorials/kubernetes/kyverno/#kyverno-policy-to-check-attestation","text":"The following policy ensures that the attestation is no older than 168h: vuln-attestation.yaml apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: check-vulnerabilities spec: validationFailureAction: enforce webhookTimeoutSeconds: 10 failurePolicy: Fail rules: - name: not-older-than-one-week match: any: - resources: kinds: - Pod verifyImages: - imageReferences: - \"CONTAINER-REGISTRY/*:*\" attestations: - predicateType: cosign.sigstore.dev/attestation/vuln/v1 conditions: - all: - key: \"{{ time_since('','{{metadata.scanFinishedOn}}','') }}\" operator: LessThanOrEquals value: \"168h\"","title":"Kyverno Policy to check attestation"},{"location":"tutorials/kubernetes/kyverno/#apply-the-policy-to-your-kubernetes-cluster","text":"Ensure that you have Kyverno already deployed and running on your cluster -- for instance through he Kyverno Helm Chart. Next, apply the above policy: kubectl apply -f vuln-attestation.yaml To ensure that the policy worked, we can deploye an example deployment file with our container image: deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: cns-website namespace: app spec: replicas: 2 selector: matchLabels: run: cns-website template: metadata: labels: run: cns-website spec: containers: - name: cns-website image: docker.io/anaisurlichs/cns-website:0.0.6 ports: - containerPort: 80 imagePullPolicy: Always resources: limits: memory: 512Mi cpu: 200m securityContext: allowPrivilegeEscalation: false Once we apply the deployment, it should pass since our attestation is available: kubectl apply -f deployment.yaml -n app deployment.apps/cns-website created However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with docker.io/anaisurlichs/cns-website:0.0.5 and applying the deployment: kubectl apply -f deployment-two.yaml Resource: \"apps/v1, Resource=deployments\", GroupVersionKind: \"apps/v1, Kind=Deployment\" Name: \"cns-website\", Namespace: \"app\" for: \"deployment-two.yaml\": admission webhook \"mutate.kyverno.svc-fail\" denied the request: resource Deployment/app/cns-website was blocked due to the following policies check-image: autogen-check-image: | failed to verify signature for docker.io/anaisurlichs/cns-website:0.0.5: .attestors[0].entries[0].keys: no matching signatures:","title":"Apply the policy to your Kubernetes cluster"},{"location":"tutorials/shell/shell-completion/","text":"Enable shell completion Below is example steps to enable shell completion feature for trivy cli: 1. Know your current shell $ echo $SHELL /bin/zsh # For this example it is zsh, but will be vary depend on your $SHELL, maybe /bin/bash or /bin/fish 2. Run completion command to get sub-commands $ trivy completion zsh -h Generate the autocompletion script for the zsh shell. If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once: echo \"autoload -U compinit; compinit\" >> ~/.zshrc To load completions in your current shell session: source < ( trivy completion zsh ) ; compdef _trivy trivy To load completions for every new session, execute once: #### Linux: trivy completion zsh > \" ${ fpath [1] } /_trivy\" #### macOS: trivy completion zsh > $( brew --prefix ) /share/zsh/site-functions/_trivy You will need to start a new shell for this setup to take effect. 3. Run the sub-commands following the instruction echo \"autoload -U compinit; compinit\" >> ~/.zshrc source < ( trivy completion zsh ) ; compdef _trivy trivy trivy completion zsh > \" ${ fpath [1] } /_trivy\" 4. Start a new shell and you can see the shell completion $ trivy [ tab ] aws -- scan aws account completion -- Generate the autocompletion script for the specified shell config -- Scan config files for misconfigurations filesystem -- Scan local filesystem help -- Help about any command image -- Scan a container image kubernetes -- scan kubernetes cluster module -- Manage modules plugin -- Manage plugins repository -- Scan a remote repository rootfs -- Scan rootfs sbom -- Scan SBOM for vulnerabilities server -- Server mode version -- Print the version","title":"Completion"},{"location":"tutorials/shell/shell-completion/#enable-shell-completion","text":"Below is example steps to enable shell completion feature for trivy cli:","title":"Enable shell completion"},{"location":"tutorials/shell/shell-completion/#1-know-your-current-shell","text":"$ echo $SHELL /bin/zsh # For this example it is zsh, but will be vary depend on your $SHELL, maybe /bin/bash or /bin/fish","title":"1. Know your current shell"},{"location":"tutorials/shell/shell-completion/#2-run-completion-command-to-get-sub-commands","text":"$ trivy completion zsh -h Generate the autocompletion script for the zsh shell. If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once: echo \"autoload -U compinit; compinit\" >> ~/.zshrc To load completions in your current shell session: source < ( trivy completion zsh ) ; compdef _trivy trivy To load completions for every new session, execute once: #### Linux: trivy completion zsh > \" ${ fpath [1] } /_trivy\" #### macOS: trivy completion zsh > $( brew --prefix ) /share/zsh/site-functions/_trivy You will need to start a new shell for this setup to take effect.","title":"2. Run completion command to get sub-commands"},{"location":"tutorials/shell/shell-completion/#3-run-the-sub-commands-following-the-instruction","text":"echo \"autoload -U compinit; compinit\" >> ~/.zshrc source < ( trivy completion zsh ) ; compdef _trivy trivy trivy completion zsh > \" ${ fpath [1] } /_trivy\"","title":"3. Run the sub-commands following the instruction"},{"location":"tutorials/shell/shell-completion/#4-start-a-new-shell-and-you-can-see-the-shell-completion","text":"$ trivy [ tab ] aws -- scan aws account completion -- Generate the autocompletion script for the specified shell config -- Scan config files for misconfigurations filesystem -- Scan local filesystem help -- Help about any command image -- Scan a container image kubernetes -- scan kubernetes cluster module -- Manage modules plugin -- Manage plugins repository -- Scan a remote repository rootfs -- Scan rootfs sbom -- Scan SBOM for vulnerabilities server -- Server mode version -- Print the version","title":"4. Start a new shell and you can see the shell completion"},{"location":"tutorials/signing/vuln-attestation/","text":"Vulnerability Scan Record Attestation This tutorial details Scan your container image for vulnerabilities Generate an attestation with Cosign Prerequisites Trivy CLI installed Cosign installed Scan Container Image for vulnerabilities Scan your container image for vulnerabilities and save the scan result to a scan.json file: trivy image --ignore-unfixed --format json --output scan.json anaisurlichs/cns-website:0.0.6 --ignore-unfixed: Ensures that only the vulnerabilities are displayed that have a already a fix available --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal. Note: Replace the container image with the container image that you would like to scan. Attestation of the vulnerability scan with Cosign The following command generates an attestation for the vulnerability scan and uploads it to our container image: cosign attest --replace --predicate scan.json --type vuln anaisurlichs/cns-website:0.0.6 Note: Replace the container image with the container image that you would like to scan. See here for more details.","title":"Vulnerability Scan Record Attestation"},{"location":"tutorials/signing/vuln-attestation/#vulnerability-scan-record-attestation","text":"This tutorial details Scan your container image for vulnerabilities Generate an attestation with Cosign","title":"Vulnerability Scan Record Attestation"},{"location":"tutorials/signing/vuln-attestation/#prerequisites","text":"Trivy CLI installed Cosign installed","title":"Prerequisites"},{"location":"tutorials/signing/vuln-attestation/#scan-container-image-for-vulnerabilities","text":"Scan your container image for vulnerabilities and save the scan result to a scan.json file: trivy image --ignore-unfixed --format json --output scan.json anaisurlichs/cns-website:0.0.6 --ignore-unfixed: Ensures that only the vulnerabilities are displayed that have a already a fix available --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal. Note: Replace the container image with the container image that you would like to scan.","title":"Scan Container Image for vulnerabilities"},{"location":"tutorials/signing/vuln-attestation/#attestation-of-the-vulnerability-scan-with-cosign","text":"The following command generates an attestation for the vulnerability scan and uploads it to our container image: cosign attest --replace --predicate scan.json --type vuln anaisurlichs/cns-website:0.0.6 Note: Replace the container image with the container image that you would like to scan. See here for more details.","title":"Attestation of the vulnerability scan with Cosign"}]} \ No newline at end of file diff --git a/test/sitemap.xml b/test/sitemap.xml deleted file mode 100644 index 89dcba7ea41c..000000000000 --- a/test/sitemap.xml +++ /dev/null @@ -1,558 +0,0 @@ - - - - https://aquasecurity.github.io/trivy/test/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/community/contribute/discussion/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/community/contribute/issue/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/community/contribute/pr/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/community/maintainer/help-wanted/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/community/maintainer/triage/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/air-gap/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/modules/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/plugins/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/container/embed-in-dockerfile/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/container/unpacked-filesystem/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/private-registries/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/private-registries/acr/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/private-registries/docker-hub/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/private-registries/ecr/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/private-registries/gcr/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/advanced/private-registries/self/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/compliance/compliance/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/cache/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/db/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/filtering/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/others/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/reporting/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/configuration/skipping/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/troubleshooting/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/config-file/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_aws/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_config/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_filesystem/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_image/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_kubernetes/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_module/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_module_install/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_module_uninstall/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin_info/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin_install/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin_list/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin_run/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin_uninstall/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_plugin_update/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_repository/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_rootfs/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_sbom/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_server/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_version/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/configuration/cli/trivy_vm/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/modes/client-server/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/references/modes/standalone/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/license/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/secret/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/combine/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/data/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/debug/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/schema/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/selectors/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/custom/testing/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/policy/builtin/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/misconfiguration/policy/exceptions/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/os/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/golang/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/java/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/nodejs/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/php/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/python/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/scanner/vulnerability/language/rust/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/supply-chain/sbom/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/supply-chain/vex/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/supply-chain/attestation/rekor/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/supply-chain/attestation/sbom/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/supply-chain/attestation/vuln/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/aws/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/container_image/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/filesystem/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/git-repository/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/kubernetes/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/rootfs/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/sbom/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/docs/target/vm/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/ecosystem/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/ecosystem/cicd/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/ecosystem/ide/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/ecosystem/prod/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/ecosystem/security/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/getting-started/faq/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/getting-started/installation/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/overview/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/additional-resources/cks/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/additional-resources/community/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/additional-resources/references/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/aws-codepipeline/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/aws-security-hub/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/azure-devops/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/bitbucket/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/circleci/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/github-actions/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/gitlab-ci/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/integrations/travis-ci/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/kubernetes/cluster-scanning/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/kubernetes/gitops/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/kubernetes/kyverno/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/shell/shell-completion/ - 2023-05-16 - daily - - - https://aquasecurity.github.io/trivy/test/tutorials/signing/vuln-attestation/ - 2023-05-16 - daily - - \ No newline at end of file diff --git a/test/sitemap.xml.gz b/test/sitemap.xml.gz deleted file mode 100644 index d5d4976859c1..000000000000 Binary files a/test/sitemap.xml.gz and /dev/null differ diff --git a/test/tutorials/additional-resources/cks/index.html b/test/tutorials/additional-resources/cks/index.html deleted file mode 100644 index 0958bcded2d3..000000000000 --- a/test/tutorials/additional-resources/cks/index.html +++ /dev/null @@ -1,3083 +0,0 @@ - - - - - - - - - - - - - - - - - - - - CKS Reference - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    CKS preparation resources

    -

    The Certified Kubernetes Security Specialist (CKS) Exam is offered by The Linux Foundation. It provides assurance that a CKS has the skills, knowledge, and competence on a broad range of best practices for securing container-based applications and Kubernetes platforms during build, deployment and runtime. CKA certification is required to sit for this exam.

    -

    Community Resources

    - -

    Aqua Security Blog posts to learn more

    - -

    If you know of interesting resources, please start a PR to add those to the list.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/additional-resources/community/index.html b/test/tutorials/additional-resources/community/index.html deleted file mode 100644 index 3dfae5d96833..000000000000 --- a/test/tutorials/additional-resources/community/index.html +++ /dev/null @@ -1,3186 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Community References - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/additional-resources/references/index.html b/test/tutorials/additional-resources/references/index.html deleted file mode 100644 index bd4e68a90785..000000000000 --- a/test/tutorials/additional-resources/references/index.html +++ /dev/null @@ -1,3174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Additional Resources - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/aws-codepipeline/index.html b/test/tutorials/integrations/aws-codepipeline/index.html deleted file mode 100644 index 0cfe60327058..000000000000 --- a/test/tutorials/integrations/aws-codepipeline/index.html +++ /dev/null @@ -1,3009 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AWS CodePipeline - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    AWS CodePipeline

    -

    See this blog post for an example of using Trivy within AWS CodePipeline.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/aws-security-hub/index.html b/test/tutorials/integrations/aws-security-hub/index.html deleted file mode 100644 index d15710ecad95..000000000000 --- a/test/tutorials/integrations/aws-security-hub/index.html +++ /dev/null @@ -1,3141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AWS Security Hub - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    AWS Security Hub

    -

    Amazon Security Hub

    -

    Upload findings to Security Hub

    -

    In the following example using the template asff.tpl, ASFF file can be generated.

    -
    $ AWS_REGION=us-west-1 AWS_ACCOUNT_ID=123456789012 trivy image --format template --template "@contrib/asff.tpl" -o report.asff golang:1.12-alpine
    -
    -

    ASFF template needs AWS_REGION and AWS_ACCOUNT_ID from environment variables.

    -

    The Product ARN field follows the pattern below to match what AWS requires for the product resource type.

    -
    "ProductArn": "arn:aws:securityhub:{{ env "AWS_REGION" }}::product/aquasecurity/aquasecurity",
    -
    -

    In order to upload results you must first run enable-import-findings-for-product like:

    -
    aws securityhub enable-import-findings-for-product --product-arn arn:aws:securityhub:<AWS_REGION>::product/aquasecurity/aquasecurity
    -
    -

    The findings are formatted for the API with a key of Findings and a value of the array of findings. -In order to upload via the CLI the outer wrapping must be removed being left with only the array of findings. -The easiest way of doing this is with the jq library using the command

    -
    cat report.asff | jq '.Findings'
    -
    -

    Then, you can upload it with AWS CLI.

    -
    $ aws securityhub batch-import-findings --findings file://report.asff
    -
    -

    Note

    -

    The batch-import-findings command limits the number of findings uploaded to 100 per request. -The best known workaround to this problem is using jq to run the following command

    -
    jq '.[:100]' report.asff 1> short_report.asff
    -
    -

    Customize

    -

    You can customize asff.tpl

    -
    $ export AWS_REGION=us-west-1
    -$ export AWS_ACCOUNT_ID=123456789012
    -$ trivy image --format template --template "@your-asff.tpl" -o report.asff golang:1.12-alpine
    -
    -

    Reference

    -

    aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/azure-devops/index.html b/test/tutorials/integrations/azure-devops/index.html deleted file mode 100644 index e688f2943c7a..000000000000 --- a/test/tutorials/integrations/azure-devops/index.html +++ /dev/null @@ -1,3079 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Azure - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Azure Devops

    - -

    trivy-azure

    -

    Use ImageCleaner to clean up stale images on your Azure Kubernetes Service cluster

    -

    It's common to use pipelines to build and deploy images on Azure Kubernetes Service (AKS) clusters. While great for image creation, this process often doesn't account for the stale images left behind and can lead to image bloat on cluster nodes. These images can present security issues as they may contain vulnerabilities. By cleaning these unreferenced images, you can remove an area of risk in your clusters. When done manually, this process can be time intensive, which ImageCleaner can mitigate via automatic image identification and removal.

    -

    Vulnerability is determined based on a trivy scan, after which images with a LOW, MEDIUM, HIGH, or CRITICAL classification are flagged. An updated ImageList will be automatically generated by ImageCleaner based on a set time interval, and can also be supplied manually.

    -

    Microsoft Defender for container registries and Trivy

    -

    This blog explains how to scan your Azure Container Registry-based container images with the integrated vulnerability scanner when they're built as part of your GitHub workflows.

    -

    To set up the scanner, you'll need to enable Microsoft Defender for Containers and the CI/CD integration. When your CI/CD workflows push images to your registries, you can view registry scan results and a summary of CI/CD scan results.

    -

    The findings of the CI/CD scans are an enrichment to the existing registry scan findings by Qualys. Defender for Cloud's CI/CD scanning is powered by Aqua Trivy

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/bitbucket/index.html b/test/tutorials/integrations/bitbucket/index.html deleted file mode 100644 index 0e6f6a3be68c..000000000000 --- a/test/tutorials/integrations/bitbucket/index.html +++ /dev/null @@ -1,3009 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Bitbucket Pipelines - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Bitbucket Pipelines

    -

    See trivy-pipe for the details.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/circleci/index.html b/test/tutorials/integrations/circleci/index.html deleted file mode 100644 index c761aa425eac..000000000000 --- a/test/tutorials/integrations/circleci/index.html +++ /dev/null @@ -1,3035 +0,0 @@ - - - - - - - - - - - - - - - - - - - - CircleCI - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    CircleCI

    -
    $ cat .circleci/config.yml
    -jobs:
    -  build:
    -    docker:
    -      - image: docker:stable-git
    -    steps:
    -      - checkout
    -      - setup_remote_docker
    -      - run:
    -          name: Build image
    -          command: docker build -t trivy-ci-test:${CIRCLE_SHA1} .
    -      - run:
    -          name: Install trivy
    -          command: |
    -            apk add --update-cache --upgrade curl
    -            curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
    -      - run:
    -          name: Scan the local image with trivy
    -          command: trivy image --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1}
    -workflows:
    -  version: 2
    -  release:
    -    jobs:
    -      - build
    -
    -

    Example -Repository

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/github-actions/index.html b/test/tutorials/integrations/github-actions/index.html deleted file mode 100644 index 798897611c74..000000000000 --- a/test/tutorials/integrations/github-actions/index.html +++ /dev/null @@ -1,3013 +0,0 @@ - - - - - - - - - - - - - - - - - - - - GitHub Actions - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    GitHub Actions

    -
      -
    • Here is the Trivy GitHub Action
    • -
    • The Microsoft Azure team have written a container-scan action that uses Trivy and Dockle
    • -
    • For full control over the options specified to Trivy, this blog post describes adding Trivy into your own GitHub action workflows
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/gitlab-ci/index.html b/test/tutorials/integrations/gitlab-ci/index.html deleted file mode 100644 index 8c5b9a4b56c8..000000000000 --- a/test/tutorials/integrations/gitlab-ci/index.html +++ /dev/null @@ -1,3238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - GitLab CI - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    GitLab CI

    -

    GitLab 15.0 includes free integration with Trivy.

    -

    To configure container scanning with Trivy in GitLab, simply include the CI template in your .gitlab-ci.yml file:

    -
    include:
    -  - template: Security/Container-Scanning.gitlab-ci.yml
    -
    -

    If you're a GitLab 14.x Ultimate customer, you can use the same configuration above.

    -

    Alternatively, you can always use the example configurations below.

    -
    stages:
    -  - test
    -
    -trivy:
    -  stage: test
    -  image: docker:stable
    -  services:
    -    - name: docker:dind
    -      entrypoint: ["env", "-u", "DOCKER_HOST"]
    -      command: ["dockerd-entrypoint.sh"]
    -  variables:
    -    DOCKER_HOST: tcp://docker:2375/
    -    DOCKER_DRIVER: overlay2
    -    # See https://github.com/docker-library/docker/pull/166
    -    DOCKER_TLS_CERTDIR: ""
    -    IMAGE: trivy-ci-test:$CI_COMMIT_SHA
    -    TRIVY_NO_PROGRESS: "true"
    -    TRIVY_CACHE_DIR: ".trivycache/"
    -  before_script:
    -    - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    -    - echo $TRIVY_VERSION
    -    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
    -  allow_failure: true
    -  script:
    -    # Build image
    -    - docker build -t $IMAGE .
    -    # Build report
    -    - ./trivy image --exit-code 0 --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
    -    # Print report
    -    - ./trivy image --exit-code 0 --severity HIGH $IMAGE
    -    # Fail on severe vulnerabilities
    -    - ./trivy image --exit-code 1 --severity CRITICAL $IMAGE
    -  cache:
    -    paths:
    -      - .trivycache/
    -  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
    -  artifacts:
    -    reports:
    -      container_scanning: gl-container-scanning-report.json
    -
    -

    Example -Repository

    -

    GitLab CI using Trivy container

    -

    To scan a previously built image that has already been pushed into the -GitLab container registry the following CI job manifest can be used. -Note that entrypoint needs to be unset for the script section to work. -In case of a non-public GitLab project Trivy additionally needs to -authenticate to the registry to be able to pull your application image. -Finally, it is not necessary to clone the project repo as we only work -with the container image.

    -
    container_scanning:
    -  image:
    -    name: docker.io/aquasec/trivy:latest
    -    entrypoint: [""]
    -  variables:
    -    # No need to clone the repo, we exclusively work on artifacts.  See
    -    # https://docs.gitlab.com/ee/ci/runners/README.html#git-strategy
    -    GIT_STRATEGY: none
    -    TRIVY_USERNAME: "$CI_REGISTRY_USER"
    -    TRIVY_PASSWORD: "$CI_REGISTRY_PASSWORD"
    -    TRIVY_AUTH_URL: "$CI_REGISTRY"
    -    TRIVY_NO_PROGRESS: "true"
    -    TRIVY_CACHE_DIR: ".trivycache/"
    -    FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
    -  script:
    -    - trivy --version
    -    # cache cleanup is needed when scanning images with the same tags, it does not remove the database
    -    - time trivy image --clear-cache
    -    # update vulnerabilities db
    -    - time trivy image --download-db-only
    -    # Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
    -    - time trivy image --exit-code 0 --format template --template "@/contrib/gitlab.tpl"
    -        --output "$CI_PROJECT_DIR/gl-container-scanning-report.json" "$FULL_IMAGE_NAME"
    -    # Prints full report
    -    - time trivy image --exit-code 0 "$FULL_IMAGE_NAME"
    -    # Fail on critical vulnerabilities
    -    - time trivy image --exit-code 1 --severity CRITICAL "$FULL_IMAGE_NAME"
    -  cache:
    -    paths:
    -      - .trivycache/
    -  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
    -  artifacts:
    -    when:                          always
    -    reports:
    -      container_scanning:          gl-container-scanning-report.json
    -  tags:
    -    - docker-runner
    -
    -

    GitLab CI alternative template

    -

    Depending on the edition of gitlab you have or your desired workflow, the -container scanning template may not meet your needs. As an addition to the -above container scanning template, a template for -code climate -has been included. The key things to update from the above examples are -the template and report type. An updated example is below.

    -
    stages:
    -  - test
    -
    -trivy:
    -  stage: test
    -  image: docker:stable
    -  services:
    -    - name: docker:dind
    -      entrypoint: ["env", "-u", "DOCKER_HOST"]
    -      command: ["dockerd-entrypoint.sh"]
    -  variables:
    -    DOCKER_HOST: tcp://docker:2375/
    -    DOCKER_DRIVER: overlay2
    -    # See https://github.com/docker-library/docker/pull/166
    -    DOCKER_TLS_CERTDIR: ""
    -    IMAGE: trivy-ci-test:$CI_COMMIT_SHA
    -    TRIVY_NO_PROGRESS: "true"
    -    TRIVY_CACHE_DIR: ".trivycache/"
    -  before_script:
    -    - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    -    - echo $TRIVY_VERSION
    -    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
    -  allow_failure: true
    -  script:
    -    # Build image
    -    - docker build -t $IMAGE .
    -    # Image report
    -    - ./trivy image --exit-code 0 --format template --template "@contrib/gitlab-codequality.tpl" -o gl-codeclimate-image.json $IMAGE
    -    # Filesystem report
    -    - ./trivy filesystem --scanners config,vuln --exit-code 0 --format template --template "@contrib/gitlab-codequality.tpl" -o gl-codeclimate-fs.json .
    -    # Combine report
    -    - apk update && apk add jq
    -    - jq -s 'add' gl-codeclimate-image.json gl-codeclimate-fs.json > gl-codeclimate.json
    -  cache:
    -    paths:
    -      - .trivycache/
    -  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
    -  artifacts:
    -    paths:
    -      - gl-codeclimate.json
    -    reports:
    -      codequality: gl-codeclimate.json
    -
    -

    Currently gitlab only supports a single code quality report. There is an -open feature request -to support multiple reports. Until this has been implemented, if you -already have a code quality report in your pipeline, you can use -jq to combine reports. Depending on how you name your artifacts, it may -be necessary to rename the artifact if you want to reuse the name. To then -combine the previous artifact with the output of trivy, the following jq -command can be used, jq -s 'add' prev-codeclimate.json trivy-codeclimate.json > gl-codeclimate.json.

    -

    GitLab CI alternative template example report

    -

    You'll be able to see a full report in the GitLab pipeline code quality UI, where filesystem vulnerabilities and misconfigurations include links to the flagged files and image vulnerabilities report the image/os or runtime/library that the vulnerability originates from instead.

    -

    codequality

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/index.html b/test/tutorials/integrations/index.html deleted file mode 100644 index 7d92d9edfdf6..000000000000 --- a/test/tutorials/integrations/index.html +++ /dev/null @@ -1,3009 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Integrations

    -

    Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify --exit-code 0.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/integrations/travis-ci/index.html b/test/tutorials/integrations/travis-ci/index.html deleted file mode 100644 index c043eccd85b4..000000000000 --- a/test/tutorials/integrations/travis-ci/index.html +++ /dev/null @@ -1,3030 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Travis CI - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Travis CI

    -
    $ cat .travis.yml
    -services:
    -  - docker
    -
    -env:
    -  global:
    -    - COMMIT=${TRAVIS_COMMIT::8}
    -
    -before_install:
    -  - docker build -t trivy-ci-test:${COMMIT} .
    -  - export VERSION=$(curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    -  - wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
    -  - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
    -script:
    -  - ./trivy image --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT}
    -  - ./trivy image --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT}
    -cache:
    -  directories:
    -    - $HOME/.cache/trivy
    -
    -

    Example -Repository

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/kubernetes/cluster-scanning/index.html b/test/tutorials/kubernetes/cluster-scanning/index.html deleted file mode 100644 index 074d5c8b1580..000000000000 --- a/test/tutorials/kubernetes/cluster-scanning/index.html +++ /dev/null @@ -1,3129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Cluster Scanning - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Kubernetes Scanning Tutorial

    -

    Prerequisites

    -

    To test the following commands yourself, make sure that you’re connected to a Kubernetes cluster. A simple kind, a Docker-Desktop or microk8s cluster will do. In our case, we’ll use a one-node kind cluster.

    -

    Pro tip: The output of the commands will be even more interesting if you have some workloads running in your cluster.

    -

    Cluster Scanning

    -

    Trivy K8s is great to get an overview of all the vulnerabilities and misconfiguration issues or to scan specific workloads that are running in your cluster. You would want to use the Trivy K8s command either on your own local cluster or in your CI/CD pipeline post deployments.

    -

    The Trivy K8s command is part of the Trivy CLI:

    -

    With the following command, we can scan our entire Kubernetes cluster for vulnerabilities and get a summary of the scan:

    -
    trivy k8s --report=summary 
    -
    -

    To get detailed information for all your resources, just replace ‘summary’ with ‘all’:

    -
    trivy k8s --report=all 
    -
    -

    However, we recommend displaying all information only in case you scan a specific namespace or resource since you can get overwhelmed with additional details.

    -

    Furthermore, we can specify the namespace that Trivy is supposed to scan to focus on specific resources in the scan result:

    -
    trivy k8s -n kube-system --report=summary 
    -
    -

    Again, if you’d like to receive additional details, use the ‘--report=all’ flag:

    -
    trivy k8s -n kube-system --report=all 
    -
    -

    Like with scanning for vulnerabilities, we can also filter in-cluster security issues by severity of the vulnerabilities:

    -
    trivy k8s --severity=CRITICAL --report=summary 
    -
    -

    Note that you can use any of the Trivy flags on the Trivy K8s command.

    -

    With the Trivy K8s command, you can also scan specific workloads that are running within your cluster, such as our deployment:

    -
    trivy k8s –n app --report=summary deployments/react-application
    -
    -

    Trivy Operator

    -

    The Trivy K8s command is an imperative model to scan resources. We wouldn’t want to manually scan each resource across different environments. The larger the cluster and the more workloads are running in it, the more error-prone this process would become. With the Trivy Operator, we can automate the scanning process after the deployment.

    -

    The Trivy Operator follows the Kubernetes Operator Model. Operators automate human actions, and the result of the task is saved as custom resource definitions (CRDs) within your cluster.

    -

    This has several benefits:

    -
      -
    • -

      Trivy Operator is installed CRDs in our cluster. As a result, all our resources, including our security scanner and its scan results, are Kubernetes resources. This makes it much easier to integrate the Trivy Operator directly into our existing processes, such as connecting Trivy with Prometheus, a monitoring system.

      -
    • -
    • -

      The Trivy Operator will automatically scan your resources every six hours. You can set up automatic alerting in case new critical security issues are discovered.

      -
    • -
    • -

      The CRDs can be both machine and human-readable depending on which applications consume the CRDs. This allows for more versatile applications of the Trivy operator.

      -
    • -
    -

    There are several ways that you can install the Trivy Operator in your cluster. In this guide, we’re going to use the Helm installation based on the following documentation.

    -

    Please follow the Trivy Operator documentation for further information on:

    - - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/kubernetes/gitops/index.html b/test/tutorials/kubernetes/gitops/index.html deleted file mode 100644 index 211c28160760..000000000000 --- a/test/tutorials/kubernetes/gitops/index.html +++ /dev/null @@ -1,3181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - GitOps - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Installing the Trivy-Operator through GitOps

    -

    This tutorial shows you how to install the Trivy Operator through GitOps platforms, namely ArgoCD and FluxCD.

    -

    ArgoCD

    -

    Make sure to have ArgoCD installed and running in your Kubernetes cluster.

    -

    You can either deploy the Trivy Operator through the argocd CLI or by applying a Kubernetes manifest.

    -

    ArgoCD command: -

    > kubectl create ns trivy-system
    -> argocd app create trivy-operator --repo https://github.com/aquasecurity/trivy-operator --path deploy/helm --dest-server https://kubernetes.default.svc --dest-namespace trivy-system
    -
    -Note that this installation is directly related to our official Helm Chart. If you want to change any of the value, we'd suggest you to create a separate values.yaml file.

    -

    Kubernetes manifest trivy-operator.yaml: -

    apiVersion: argoproj.io/v1alpha1
    -kind: Application
    -metadata:
    -  name: trivy-operator
    -  namespace: argocd
    -spec:
    -  project: default
    -  source:
    -    chart: trivy-operator
    -    repoURL: https://aquasecurity.github.io/helm-charts/
    -    targetRevision: 0.0.3
    -    helm:
    -      values: |
    -        trivy:
    -          ignoreUnfixed: true
    -  destination:
    -    server: https://kubernetes.default.svc
    -    namespace: trivy-system
    -  syncPolicy:
    -    automated:
    -      prune: true
    -      selfHeal: true
    -

    -

    The apply the Kubernetes manifest. If you have the manifest locally, you can use the following command through kubectl: -

    > kubectl apply -f trivy-operator.yaml
    -
    -application.argoproj.io/trivy-operator created
    -

    -

    If you have the manifest in a Git repository, you can apply it to your cluster through the following command: -

    > kubectl apply -n argocd -f https://raw.githubusercontent.com/AnaisUrlichs/argocd-starboard/main/starboard/argocd-starboard.yaml
    -
    -The latter command would allow you to make changes to the YAML manifest that ArgoCD would register automatically.

    -

    Once deployed, you want to tell ArgoCD to sync the application from the actual state to the desired state: -

    argocd app sync trivy-operator
    -

    -

    Now you can see the deployment in the ArgoCD UI. Have a look at the ArgoCD documentation to know how to access the UI.

    -

    ArgoCD UI after deploying the Trivy Operator

    -

    Note that ArgoCD is unable to show the Trivy CRDs as synced.

    -

    FluxCD

    -

    Make sure to have FluxCD installed and running in your Kubernetes cluster.

    -

    You can either deploy the Trivy Operator through the Flux CLI or by applying a Kubernetes manifest.

    -

    Flux command: -

    > kubectl create ns trivy-system
    -> flux create source helm trivy-operator --url https://aquasecurity.github.io/helm-charts --namespace trivy-system
    -> flux create helmrelease trivy-operator --chart trivy-operator
    -  --source HelmRepository/trivy-operator
    -  --chart-version 0.0.3
    -  --namespace trivy-system
    -

    -

    Kubernetes manifest trivy-operator.yaml: -

    apiVersion: source.toolkit.fluxcd.io/v1beta2
    -kind: HelmRepository
    -metadata:
    -  name: trivy-operator
    -  namespace: flux-system
    -spec:
    -  interval: 60m
    -  url: https://aquasecurity.github.io/helm-charts/
    -
    ----
    -apiVersion: helm.toolkit.fluxcd.io/v2beta1
    -kind: HelmRelease
    -metadata:
    -  name: trivy-operator
    -  namespace: trivy-system
    -spec:
    -  chart:
    -    spec:
    -      chart: trivy-operator
    -      sourceRef:
    -        kind: HelmRepository
    -        name: trivy-operator
    -        namespace: flux-system
    -      version: 0.10.1
    -  interval: 60m
    -  values:
    -    trivy:
    -      ignoreUnfixed: true
    -  install:
    -    crds: CreateReplace
    -    createNamespace: true
    -

    -

    You can then apply the file to your Kubernetes cluster: -

    kubectl apply -f trivy-operator.yaml
    -

    -

    After the installation

    -

    After the install, you want to check that the Trivy operator is running in the trivy-system namespace: -

    kubectl get deployment -n trivy-system
    -

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/kubernetes/kyverno/index.html b/test/tutorials/kubernetes/kyverno/index.html deleted file mode 100644 index 0ec4596cd851..000000000000 --- a/test/tutorials/kubernetes/kyverno/index.html +++ /dev/null @@ -1,3173 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Kyverno - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Attesting Image Scans With Kyverno

    -

    This tutorial is based on the following blog post by Chip Zoller: Attesting Image Scans With Kyverno

    -

    This tutorial details

    -
      -
    • Verify the container image has an attestation with Kyverno
    • -
    -

    Prerequisites

    -
      -
    1. Attestation of the vulnerability scan uploaded
    2. -
    3. A running Kubernetes cluster that kubectl is connected to
    4. -
    -

    Kyverno Policy to check attestation

    -

    The following policy ensures that the attestation is no older than 168h:

    -

    vuln-attestation.yaml

    -
    apiVersion: kyverno.io/v1
    -kind: ClusterPolicy
    -metadata:
    -  name: check-vulnerabilities
    -spec:
    -  validationFailureAction: enforce
    -  webhookTimeoutSeconds: 10
    -  failurePolicy: Fail
    -  rules:
    -    - name: not-older-than-one-week
    -      match:
    -        any:
    -        - resources:
    -            kinds:
    -              - Pod
    -      verifyImages:
    -      - imageReferences:
    -        - "CONTAINER-REGISTRY/*:*"
    -        attestations:
    -        - predicateType: cosign.sigstore.dev/attestation/vuln/v1
    -          conditions:
    -          - all:
    -            - key: "{{ time_since('','{{metadata.scanFinishedOn}}','') }}"
    -              operator: LessThanOrEquals
    -              value: "168h"
    -
    -

    Apply the policy to your Kubernetes cluster

    -

    Ensure that you have Kyverno already deployed and running on your cluster -- for instance through he Kyverno Helm Chart.

    -

    Next, apply the above policy: -

    kubectl apply -f vuln-attestation.yaml
    -

    -

    To ensure that the policy worked, we can deploye an example deployment file with our container image:

    -

    deployment.yaml -

    apiVersion: apps/v1
    -kind: Deployment
    -metadata:
    -  name: cns-website
    -  namespace: app
    -spec:
    -  replicas: 2
    -  selector:
    -    matchLabels:
    -      run: cns-website
    -  template:
    -    metadata:
    -      labels:
    -        run: cns-website
    -    spec:
    -      containers:
    -      - name: cns-website
    -        image: docker.io/anaisurlichs/cns-website:0.0.6
    -        ports:
    -          - containerPort: 80
    -        imagePullPolicy: Always
    -        resources:
    -          limits:
    -            memory: 512Mi
    -            cpu: 200m
    -        securityContext:
    -          allowPrivilegeEscalation: false
    -

    -

    Once we apply the deployment, it should pass since our attestation is available: -

    kubectl apply -f deployment.yaml -n app
    -deployment.apps/cns-website created
    -

    -

    However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with docker.io/anaisurlichs/cns-website:0.0.5 and applying the deployment: -

    kubectl apply -f deployment-two.yaml
    -
    -Resource: "apps/v1, Resource=deployments", GroupVersionKind: "apps/v1, Kind=Deployment"
    -Name: "cns-website", Namespace: "app"
    -for: "deployment-two.yaml": admission webhook "mutate.kyverno.svc-fail" denied the request: 
    -
    -resource Deployment/app/cns-website was blocked due to the following policies
    -
    -check-image:
    -  autogen-check-image: |
    -    failed to verify signature for docker.io/anaisurlichs/cns-website:0.0.5: .attestors[0].entries[0].keys: no matching signatures:
    -

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/overview/index.html b/test/tutorials/overview/index.html deleted file mode 100644 index ffb8a42507c6..000000000000 --- a/test/tutorials/overview/index.html +++ /dev/null @@ -1,3063 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Tutorials

    -

    In this section you can find step-by-step guides that help you accomplish specific tasks.

    -

    👈 Please use the side-navigation on the left in order to browse the different topics.

    -

    Adding tutorials

    -

    You are welcome to create tutorials and showcase them here. Tutorials can be either included in here as full articles, or included as external links under external community resources. -Before sending PR, please first create an issue (of kind "Documentation") and describe the suggestion, if it's external link or article, and what category it's under.

    -

    Guidelines:

    -
      -
    • Focus on a specific use case. Start by clearly describing the use case and when/who it is relevant for.
    • -
    • Provide an end-to-end set of instructions. Make sure anyone can easily follow.
    • -
    • Describe the expected outcome after each step. Include examples as much as possible.
    • -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/shell/shell-completion/index.html b/test/tutorials/shell/shell-completion/index.html deleted file mode 100644 index ef2c9cda6024..000000000000 --- a/test/tutorials/shell/shell-completion/index.html +++ /dev/null @@ -1,3148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Completion - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - - - - -
    -
    - - - - -

    Enable shell completion

    -

    Below is example steps to enable shell completion feature for trivy cli:

    -

    1. Know your current shell

    -
    $ echo $SHELL
    -/bin/zsh # For this example it is zsh, but will be vary depend on your $SHELL, maybe /bin/bash or /bin/fish
    -
    -

    2. Run completion command to get sub-commands

    -
    $ trivy completion zsh -h
    -Generate the autocompletion script for the zsh shell.
    -
    -If shell completion is not already enabled in your environment you will need
    -to enable it.  You can execute the following once:
    -
    -    echo "autoload -U compinit; compinit" >> ~/.zshrc
    -
    -To load completions in your current shell session:
    -
    -    source <(trivy completion zsh); compdef _trivy trivy
    -
    -To load completions for every new session, execute once:
    -
    -#### Linux:
    -
    -    trivy completion zsh > "${fpath[1]}/_trivy"
    -
    -#### macOS:
    -
    -    trivy completion zsh > $(brew --prefix)/share/zsh/site-functions/_trivy
    -
    -You will need to start a new shell for this setup to take effect.
    -
    -

    3. Run the sub-commands following the instruction

    -
    echo "autoload -U compinit; compinit" >> ~/.zshrc
    -source <(trivy completion zsh); compdef _trivy trivy
    -trivy completion zsh > "${fpath[1]}/_trivy"
    -
    -

    4. Start a new shell and you can see the shell completion

    -
    $ trivy [tab]
    -aws         -- scan aws account
    -completion  -- Generate the autocompletion script for the specified shell
    -config      -- Scan config files for misconfigurations
    -filesystem  -- Scan local filesystem
    -help        -- Help about any command
    -image       -- Scan a container image
    -kubernetes  -- scan kubernetes cluster
    -module      -- Manage modules
    -plugin      -- Manage plugins
    -repository  -- Scan a remote repository
    -rootfs      -- Scan rootfs
    -sbom        -- Scan SBOM for vulnerabilities
    -server      -- Server mode
    -version     -- Print the version
    -
    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/test/tutorials/signing/vuln-attestation/index.html b/test/tutorials/signing/vuln-attestation/index.html deleted file mode 100644 index fc5e3982364f..000000000000 --- a/test/tutorials/signing/vuln-attestation/index.html +++ /dev/null @@ -1,3107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Vulnerability Scan Record Attestation - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    - - - - -

    Vulnerability Scan Record Attestation

    -

    This tutorial details

    -
      -
    • Scan your container image for vulnerabilities
    • -
    • Generate an attestation with Cosign
    • -
    -

    Prerequisites

    -
      -
    1. Trivy CLI installed
    2. -
    3. Cosign installed
    4. -
    -

    Scan Container Image for vulnerabilities

    -

    Scan your container image for vulnerabilities and save the scan result to a scan.json file: -

    trivy image --ignore-unfixed --format json --output scan.json anaisurlichs/cns-website:0.0.6
    -

    -
      -
    • --ignore-unfixed: Ensures that only the vulnerabilities are displayed that have a already a fix available
    • -
    • --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal.
    • -
    -

    Note: Replace the container image with the container image that you would like to scan.

    -

    Attestation of the vulnerability scan with Cosign

    -

    The following command generates an attestation for the vulnerability scan and uploads it to our container image: -

    cosign attest --replace --predicate scan.json --type vuln anaisurlichs/cns-website:0.0.6
    -

    -

    Note: Replace the container image with the container image that you would like to scan.

    -

    See here for more details.

    - - -
    -
    -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/404.html b/v0.58.0/404.html deleted file mode 100644 index d3c9fa874cc3..000000000000 --- a/v0.58.0/404.html +++ /dev/null @@ -1,7651 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - -

    404 - Not found

    - -
    -
    - - - - - -
    - -
    - -
    - - - - -
    - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/assets/css/trivy_v1_homepage.min.css b/v0.58.0/assets/css/trivy_v1_homepage.min.css deleted file mode 100644 index 0b9ef16d1976..000000000000 --- a/v0.58.0/assets/css/trivy_v1_homepage.min.css +++ /dev/null @@ -1 +0,0 @@ -body{font-family:"Inter",sans-serif}.trivy_v1_homepage_wrap{position:relative;z-index:3}.trivy_v1_homepage_wrap *{transition:all .2s ease !important}.trivy_v1_homepage_wrap .container{width:100%;margin:0 auto;max-width:1440px}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .container{padding:0 24px;max-width:769px}}.trivy_v1_homepage_wrap .button{background-color:#ebf3fa;border:1px solid #dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(.5em - 1px);text-align:center;white-space:nowrap;border-radius:4px;transition:all .2s ease;font-size:16px;display:inline-block;font-weight:700}.trivy_v1_homepage_wrap .button.is-seafoam{background-color:#00ffe4;border-color:#00ffe4;color:#07242d}.trivy_v1_homepage_wrap .button.is-seafoam.is-outlined{background-color:rgba(0,0,0,0);border-color:#00ffe4;color:#00ffe4;border-width:2px}.trivy_v1_homepage_wrap .button.is-seafoam.is-outlined:hover{background-color:#00ffe4;color:#07242d}.trivy_v1_homepage_wrap .button.large_btn{font-size:22px;padding:16px 27px;margin-right:12px}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .button.large_btn{font-size:18px}}.trivy_v1_homepage_wrap .button.solidseafoamarrowbutton{background-color:#00ffe4;font-weight:700;border:2px solid #00ffe4;font-size:22px;padding:16px 27px;color:#07242d}.trivy_v1_homepage_wrap .button.solidseafoamarrowbutton:after{content:"";border:solid #07242d;border-width:0 2px 2px 0;display:inline-block;padding:4px;transform:rotate(-45deg);margin-left:30px;vertical-align:middle;transition:all .2s}.trivy_v1_homepage_wrap .margin-bottom-20{margin-bottom:20px}.trivy_v1_homepage_wrap .hero_wrap{background-color:#0a0b23;background-image:radial-gradient(1600px at 70% 120%, #031145 10%, #0a0b23 100%);min-height:1050px;position:relative;z-index:10}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap{position:absolute;left:0px;top:0px;width:100%;height:100%;z-index:1;pointer-events:none}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .stars_wrap{position:absolute;left:0px;top:0px;width:100%;height:100%;z-index:1;overflow:hidden}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .stars_wrap .stars_bg{position:absolute;width:400vw;height:400vh;top:50%;left:50%;margin-top:-200vh;margin-left:-200vw;animation:stars_ani 240s linear infinite;background-size:240px;backface-visibility:visible;background-image:url(../images/homepage_hero_stars_02.svg);background-repeat:repeat}@keyframes stars_ani{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .terrain_wrap{position:absolute;left:0px;bottom:0px;width:100%;height:680px;background-image:url(../images/homepage_hero_terrain_08.svg);background-repeat:no-repeat;background-position:center top;background-size:cover;z-index:2}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .beams_wrap{position:absolute;left:0px;bottom:0px;width:100%;height:100%;z-index:3;overflow:hidden}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .beams_wrap .beam{position:absolute;right:200px;top:270px;width:3px;height:350%;background:rgba(62,171,255,.6);box-shadow:0px 0px 55px 0px #3eabff;transform-origin:0 0;animation:beam_ani 10s infinite}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .beams_wrap .beam.num2{animation:beam_ani 11s infinite}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .beams_wrap .beam.num3{animation:beam_ani 12s infinite}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .beams_wrap .beam.num4{animation:beam_ani 13s infinite}@keyframes beam_ani{0%{transform:rotate(75deg)}50%{transform:rotate(-15deg)}100%{transform:rotate(75deg)}}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .beams_wrap .sphere{z-index:999;position:absolute;top:60px;right:50px;width:280px;height:280px;background-image:url(../images/homepage_hero_orb_03.png);background-position:center center;background-repeat:no-repeat}.trivy_v1_homepage_wrap .hero_wrap .homepage_background_image_wrap .person_wrap{position:absolute;left:0px;bottom:0px;width:100%;height:595px;background-image:url(../images/homepage_v1_hero_person_01.png);background-repeat:no-repeat;background-position:center bottom;z-index:4}.trivy_v1_homepage_wrap .hero .hero-body{padding:80px 0px}.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap{width:50%;position:relative;z-index:3}.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap .page_title{color:#fff;font-weight:700;font-size:48px;line-height:1.3}.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap .page_subtitle{color:#fff;font-weight:400;font-size:24px;line-height:1.3;margin-bottom:30px}@media screen and (max-width: 1216px),print{.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap{width:70%}}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap{width:100%}.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap .page_title{font-size:32px}.trivy_v1_homepage_wrap .hero .hero-body .header_title_wrap .header_title_content_wrap .page_subtitle{font-size:18px}}@media screen and (min-width: 769px),print{.trivy_v1_homepage_wrap .hero .hero-body{padding:48px 24px}}.trivy_v1_homepage_wrap .homepage_community_wrap{position:relative;background-color:#0a0b23;color:#fff;z-index:5;padding-top:60px;padding-bottom:20px}.trivy_v1_homepage_wrap .homepage_community_wrap .container.wide_container{max-width:1640px;padding-left:20px;padding-right:20px;display:flex;flex-direction:row;flex-wrap:wrap}.trivy_v1_homepage_wrap .homepage_community_wrap .community_titles_column{width:33.3333%;padding-right:32px}@media screen and (max-width: 1024px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_titles_column{width:41.6666666667%}}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_titles_column{width:100%}}.trivy_v1_homepage_wrap .homepage_community_wrap .community_slider_column{width:66.6666%}@media screen and (max-width: 1024px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_slider_column{width:58.3333333333%}}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_slider_column{width:100%}}.trivy_v1_homepage_wrap .homepage_community_wrap .community_title{color:#00ffe4;font-size:60px;font-weight:700;margin-bottom:24px;line-height:1.2}.trivy_v1_homepage_wrap .homepage_community_wrap .community_subtitle{color:#fff;font-size:26px;margin-bottom:24px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_cta_wrap .button{font-weight:700;margin-right:10px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap{position:relative}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes{column-count:3;column-gap:20px}@media screen and (max-width: 1216px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes{column-count:2}}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes{column-count:1}}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item_wrap{display:inline-block;margin:0px 0px 20px 0px;width:100%}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item{display:block;position:relative;color:#fff;border:1px solid rgba(0,255,228,.2);background-color:rgba(0,255,228,.05);border-radius:4px;padding:25px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item .quote_name{font-size:16px;font-weight:600}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item .quote_twitter_handle{opacity:.6;font-size:13px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item .quote_company{opacity:.6;font-size:13px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item .quote_text{font-size:16px;font-weight:400;line-height:1.3}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item .quote_avatar{display:block;position:absolute;top:25px;left:25px;width:40px;height:40px;border-radius:50%;background-repeat:no-repeat;background-position:center center;background-size:cover}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item.is_tweet .quote_text{padding-top:10px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item.is_tweet.has_avatar .quote_name,.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item.is_tweet.has_avatar .quote_twitter_handle{padding-left:50px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item.is_quote .quote_text{position:relative;padding-top:40px;padding-bottom:10px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_quotes_wrap .community_quotes .quote_item.is_quote .quote_text:before{content:"";display:block;position:absolute;top:-10px;left:0px;width:56px;height:42px;background-image:url(../images/community_quote.png);background-position:center center;background-repeat:no-repeat}@media screen and (max-width: 769px),print{.trivy_v1_homepage_wrap .homepage_community_wrap .community_title{font-size:32px}.trivy_v1_homepage_wrap .homepage_community_wrap .community_subtitle{font-size:18px}}.slick-slider{position:relative;display:block;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:rgba(0,0,0,0)}.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}.slick-list:focus{outline:none}.slick-list.dragging{cursor:hand}.slick-slider .slick-track,.slick-slider .slick-list{transform:translate3d(0, 0, 0)}.slick-track{position:relative;top:0;left:0;display:block;margin-left:auto;margin-right:auto}.slick-track:before,.slick-track:after{display:table;content:""}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{display:none;float:left;height:100%;min-height:1px}.slick-slide:focus{outline:none}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid rgba(0,0,0,0)}.slick-arrow.slick-hidden{display:none}.slick-arrow{display:block;background-color:rgba(0,0,0,0);border:none;color:rgba(0,0,0,0);cursor:pointer;position:absolute;top:0px;height:330px;width:80px;z-index:20;outline:none}.slick-arrow:focus,.slick-arrow:active{outline:none}.slick-arrow.slick-prev{left:0px;background-image:linear-gradient(to right, #ebf3fa 0%, rgba(235, 243, 250, 0) 100%)}.slick-arrow.slick-next{right:0px;background-image:linear-gradient(to left, #ebf3fa 0%, rgba(235, 243, 250, 0) 100%)}.slick-arrow:before{content:"";display:block;position:absolute;left:0px;top:0px;width:100%;height:100%;z-index:21;background-repeat:no-repeat}.slick-arrow.slick-prev:before{background-image:url(../images/arrow_left.png);background-position:center left}.slick-arrow.slick-next:before{background-image:url(../images/arrow_right.png);background-position:center right}.slick-dotted.slick-slider{margin-bottom:0px}.slick-dots{position:relative;display:block;width:100%;padding:0;margin:0;list-style:none;text-align:center}.slick-dots li{position:relative;display:inline-block;width:24px;height:24px;margin:0px 4px;padding:0;cursor:pointer}.slick-dots li button{font-size:0;line-height:0;display:block;width:24px;height:24px;padding:0px;cursor:pointer;color:rgba(0,0,0,0);border:0;outline:none;background:rgba(0,0,0,0)}.slick-dots li button:before{position:relative;top:0px;left:0px;width:20px;height:20px;content:"";background-color:rgba(0,0,0,0);border:2px solid #00ffe4;border-radius:50%;display:block;opacity:.7}.slick-dots li button:after{position:absolute;top:7px;left:5px;width:10px;height:10px;content:"";background-color:#00ffe4;border-radius:50%;display:block;opacity:0;transition:.2s ease-out}.slick-dots li button:hover,.slick-dots li button:focus{outline:none}.slick-dots li button:hover:after,.slick-dots li button:focus:after{opacity:1}.slick-dots li.slick-active button:after{opacity:1} diff --git a/v0.58.0/assets/css/trivy_v1_homepage.scss b/v0.58.0/assets/css/trivy_v1_homepage.scss deleted file mode 100644 index 7dd40ba43a11..000000000000 --- a/v0.58.0/assets/css/trivy_v1_homepage.scss +++ /dev/null @@ -1,693 +0,0 @@ -/* trivy homepage */ - -//aqua brand colors -$aq-royal-blue: #1904da; -$aq-legacy-blue: #08b1d5; -$aq-coral-red: #ff445f; -$aq-starfish-yellow: #ffc900; -$aq-dark-abyss: #07242d; -$aq-deep-sea-blue: #183278; -$aq-ocean-ash: #405a75; -$aq-sea-foam: #00ffe4; - -$aq-neo-background: #ebf3fa; -$aq-neo-background-hover: #f0f8ff; - - -$aq-royal-blue-dark: #1503ba; - -$aq-trivy-dark: #0a0b23; - - -$weight-normal: 400; -$weight-semibold: 600; -$weight-bold: 700; - - - -$gap: 32px; -// 960, 1152, and 1344 have been chosen because they are divisible by both 12 and 16 -$tablet: 769px; - -// 960px container + 4rem -$desktop: 960px + 2 * $gap; - -// 1152px container + 4rem -$widescreen: 1152px + 2 * $gap; -$widescreen-enabled: true; - -// 1344px container + 4rem -$fullhd: 1344px + 2 * $gap; -$fullhd-enabled: true; - - - -body { - - font-family: "Inter", sans-serif; -} - -.trivy_v1_homepage_wrap { - position: relative; - z-index: 3; - - * { - transition: all 0.2s ease !important; - } - - .container { - width: 100%; - margin: 0 auto; - max-width: 1440px; - - @media screen and (max-width: $tablet), print { //769 - padding: 0 24px; - max-width: $tablet; //769 - } //until tablet - } - - .button { - - background-color: #ebf3fa; - border: 1px solid #dbdbdb; - border-width: 1px; - color: #363636; - cursor: pointer; - justify-content: center; - padding-bottom: calc(.5em - 1px); - padding-left: 1em; - padding-right: 1em; - padding-top: calc(.5em - 1px); - text-align: center; - white-space: nowrap; - border-radius: 4px; - transition: all .2s ease; - font-size: 16px; - display: inline-block; - font-weight: 700; - - &.is-seafoam { - background-color: $aq-sea-foam; - border-color: $aq-sea-foam; - color: $aq-dark-abyss; - - - &.is-outlined { - background-color: rgba(0,0,0,0); - border-color: $aq-sea-foam; - color: $aq-sea-foam; - border-width: 2px; - - &:hover { - background-color: $aq-sea-foam; - color: $aq-dark-abyss; - } - } //is-outlines - - } //is-seafoam - - &.large_btn { - font-size: 22px; - padding: 16px 27px; - margin-right: 12px; - - @media screen and (max-width: $tablet), print { - font-size: 18px; - } //until tablet - } - - - - &.solidseafoamarrowbutton { - - background-color: $aq-sea-foam; - font-weight: 700; - border: 2px solid $aq-sea-foam; - font-size: 22px; //1.375rem; //1.125rem; - padding: 16px 27px; - color: $aq-dark-abyss; - - - &:after { - content: ""; - border: solid $aq-dark-abyss; - border-width: 0 2px 2px 0; - display: inline-block; - padding: 4px; - transform: rotate(-45deg); - margin-left: 30px; - vertical-align: middle; - transition: all .2s; - } - } //solidseafoamarrowbutton - - } //button - - .margin-bottom-20 { - margin-bottom: 20px; - } - - .hero_wrap { - background-color: $aq-trivy-dark; - background-image: radial-gradient(1600px at 70% 120%, #031145 10%, $aq-trivy-dark 100%); - min-height: 1050px; - position: relative; - z-index: 10; - - - - - - - .homepage_background_image_wrap { - position: absolute; - left: 0px; - top: 0px; - width: 100%; - height: 100%; - z-index: 1; - pointer-events: none; - - - .stars_wrap { - position: absolute; - left: 0px; - top: 0px; - width: 100%; - height: 100%; - z-index: 1; - overflow: hidden; - - .stars_bg { - position: absolute; - width: 400vw; - height: 400vh; - top: 50%; - left: 50%; - margin-top: -200vh; - margin-left: -200vw; - animation: stars_ani 240s linear infinite; - background-size: 240px; - backface-visibility: visible; - background-image:url(../images/homepage_hero_stars_02.svg); - background-repeat: repeat; - - } - - - @keyframes stars_ani { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } - } - - } //stars_wrap - - .terrain_wrap { - position: absolute; - left: 0px; - bottom: 0px; - width: 100%; - height: 680px; - background-image:url(../images/homepage_hero_terrain_08.svg); - background-repeat: no-repeat; - background-position: center top; - background-size: cover; - z-index: 2; - } // terrain_wrap - - - .beams_wrap { - position: absolute; - left: 0px; - bottom: 0px; - width: 100%; - height: 100%; - z-index: 3; - overflow: hidden; - - .beam { - position: absolute; - right: 200px; - top: 270px; - width: 3px; - height: 350%; - background: rgba(#3eabff,0.6); - box-shadow: 0px 0px 55px 0px rgba(#3eabff,1); - transform-origin: 0 0; - animation: beam_ani 10s infinite; - - &.num2 {animation: beam_ani 11s infinite;} - &.num3 {animation: beam_ani 12s infinite;} - &.num4 {animation: beam_ani 13s infinite;} - } //beam - - @keyframes beam_ani { - 0% { transform: rotate(75deg); } - 50% { transform: rotate(-15deg); } - 100% { transform: rotate(75deg); } - } - - .sphere { - z-index:999; - position: absolute; - top: 60px; - right: 50px; - width: 280px; - height: 280px; - background-image:url(../images/homepage_hero_orb_03.png); - background-position: center center; - background-repeat: no-repeat; - } - - } //beams_wrap - - - .person_wrap { - position: absolute; - left: 0px; - bottom: 0px; - width: 100%; - height: 595px; - background-image:url(../images/homepage_v1_hero_person_01.png); - background-repeat: no-repeat; - background-position: center bottom; - z-index: 4; - - } // person_wrap - - - - } //hero_background_image_wrap - } - - - - .hero { - - - .hero-body { - padding: 80px 0px; - // border: 1px solid red; - - .header_title_wrap { - .header_title_content_wrap { - - width: 50%; - position: relative; - z-index: 3; - - .page_title { - color: #ffffff; - font-weight: $weight-bold; - font-size: 48px; //3rem; - line-height: 1.3; - }//page_title - - .page_subtitle { - color: #ffffff; - font-weight: $weight-normal; - font-size: 24px; //1.5rem; - line-height: 1.3; - margin-bottom: 30px; - } //page_subtitle - - - @media screen and (max-width: $widescreen), print { - width: 70%; - } //until widescreen - - @media screen and (max-width: $tablet), print { //769 - - width: 100%; - - .page_title { - font-size: 32px; //2rem; - }//page_title - - .page_subtitle { - font-size: 18px; //1.125rem; - }//page_subtitle - - } //until tablet - - - } //header_title_content_wrap - - } //header_title_wrap - - @media screen and (min-width: $tablet), print { //769 - padding: 48px 24px; //3rem 1.5rem; - } - } - - } //hero - - - - - - // } //page-trivy_homepage - - - - - /* homepage_community */ - .homepage_community_wrap { - position: relative; - background-color: $aq-trivy-dark; - color: #ffffff; - z-index: 5; - padding-top: 60px; - padding-bottom: 20px; - - - .container.wide_container { - max-width: 1640px; - padding-left: 20px; - padding-right: 20px; - display: flex; - flex-direction: row; - flex-wrap: wrap; - } - - - .community_titles_column { - width: 33.3333%; - padding-right: 32px; - - @media screen and (max-width: $desktop), print { - width: 41.6666666667%; - } //until desktop - - @media screen and (max-width: $tablet), print { - width: 100%; - } //until tablet - } - - .community_slider_column { - width: 66.6666%; - - @media screen and (max-width: $desktop), print { - width: 58.3333333333%; - } //until desktop - - @media screen and (max-width: $tablet), print { - width: 100%; - } //until tablet - } - - - .community_title { - color: $aq-sea-foam; - font-size: 60px; //3.75rem; - font-weight: $weight-bold; - margin-bottom: 24px; ////1.5rem; - line-height: 1.2; - - - } - - .community_subtitle { - color: #ffffff; - font-size: 26px; //1.625rem; - margin-bottom: 24px; ////1.5rem; - - - } - - .community_cta_wrap { - - .button { - font-weight: $weight-bold; - margin-right: 10px; - } - - } - - .community_quotes_wrap { - position: relative; - - - .community_quotes { - column-count: 3; - column-gap: 20px; - - @media screen and (max-width: $widescreen), print { //1216 - column-count: 2; - } - - @media screen and (max-width: $tablet), print { //769 - column-count: 1; - } - - .quote_item_wrap { - display: inline-block; - margin: 0px 0px 20px 0px; - width: 100%; - } - - .quote_item { - - display: block; - position: relative; - color: #ffffff; - border: 1px solid rgba($aq-sea-foam,0.2); - background-color: rgba($aq-sea-foam,0.05); - border-radius: 4px; - padding: 25px; - - .quote_name { - font-size: 16px; //1rem; - font-weight: $weight-semibold; - } - - .quote_twitter_handle { - opacity: 0.6; - font-size: 13px; //0.8125rem; - } - - .quote_company { - opacity: 0.6; - font-size: 13px; //0.8125rem; - } - - .quote_text { - font-size: 16px; //1rem; - font-weight: $weight-normal; - line-height: 1.3; - } - - .quote_avatar { - display: block; - position: absolute; - top: 25px; - left: 25px; - width: 40px; - height: 40px; - border-radius: 50%; - background-repeat: no-repeat; - background-position: center center; - background-size: cover; - - } - - &.is_tweet { - - .quote_text { - padding-top: 10px; - } - - - &.has_avatar { - .quote_name, - .quote_twitter_handle { - padding-left: 50px; - } - } //has_avatar - - } //&is_tweet - - &.is_quote { - - .quote_text { - position: relative; - padding-top: 40px; - padding-bottom: 10px; - - &:before { - content: ""; - display: block; - position: absolute; - top: -10px; - left: 0px; - width: 56px; - height: 42px; - background-image: url(../images/community_quote.png); - background-position: center center; - background-repeat: no-repeat; - } - } //quote_text - - } //&is_quote - - } //quote_item - - } - - } //community_quotes_wrap - - @media screen and (max-width: $tablet), print { //tablet - - .community_title { - font-size: 32px; //2rem; - } - .community_subtitle { - font-size: 18px; //1.125rem; - } - - } //until - - - } //homepage_community_wrap - -} //trivy_homepage_wrap - - - - - -/* Slider */ -.slick-slider{position:relative;display:block;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent;} -.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0;} -.slick-list:focus{outline:none;} -.slick-list.dragging{cursor:hand;} -.slick-slider .slick-track,.slick-slider .slick-list{transform:translate3d(0,0,0);} -.slick-track{position:relative;top:0;left:0;display:block;margin-left:auto;margin-right:auto;} -.slick-track:before,.slick-track:after{display:table;content:'';} -.slick-track:after{clear:both;} -.slick-loading .slick-track{visibility:hidden;} -.slick-slide{display:none;float:left;height:100%;min-height:1px;} -.slick-slide:focus{outline:none;} -.slick-slide img{display:block;} -.slick-slide.slick-loading img{display:none;} -.slick-slide.dragging img{pointer-events:none;} -.slick-initialized .slick-slide{display:block;} -.slick-loading .slick-slide{visibility:hidden;} -.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent;} -.slick-arrow.slick-hidden{display:none;} - -.slick-arrow {display:block;background-color:transparent;border:none;color:transparent;cursor:pointer;position:absolute;top:0px;height:330px;width:80px;z-index:20;outline:none;} -.slick-arrow:focus, .slick-arrow:active {outline:none;} -.slick-arrow.slick-prev {left:0px;background-image:linear-gradient(to right, rgba($aq-neo-background,1) 0%, rgba($aq-neo-background,0) 100%);} -.slick-arrow.slick-next {right:0px;background-image:linear-gradient(to left, rgba($aq-neo-background,1) 0%, rgba($aq-neo-background,0) 100%);} -.slick-arrow:before {content:"";display:block;position:absolute;left:0px;top:0px;width:100%;height:100%;z-index:21;background-repeat:no-repeat;} -.slick-arrow.slick-prev:before {background-image:url(../images/arrow_left.png);background-position:center left;} -.slick-arrow.slick-next:before {background-image:url(../images/arrow_right.png);background-position:center right;} - - - -/* dots */ -.slick-dotted.slick-slider -{ - margin-bottom: 0px; -} - - -.slick-dots -{ - //position: absolute; - //bottom: -25px; - position: relative; - display: block; - - width: 100%; - padding: 0; - margin: 0; - - list-style: none; - - text-align: center; -} - - -.slick-dots li { - position: relative; - display: inline-block; - width: 24px; - height: 24px; - margin: 0px 4px; - padding: 0; - cursor: pointer; -} - -.slick-dots li button -{ - font-size: 0; - line-height: 0; - - display: block; - - width: 24px; - height: 24px; - padding: 0px; - - cursor: pointer; - - color: transparent; - border: 0; - outline: none; - background: transparent; - - &:before { - - position: relative; - top: 0px; - left: 0px; - width: 20px; - height: 20px; - content: ""; - background-color: transparent; - border: 2px solid $aq-sea-foam; - border-radius: 50%; - display: block; - opacity: 0.7; - } - - &:after { - - position: absolute; - top: 7px; - left: 5px; - width: 10px; - height: 10px; - content: ""; - background-color: $aq-sea-foam; - //border: 1px solid #666; - border-radius: 50%; - //box-shadow: inset 1px 1px 1px #888; - display: block; - opacity: 0; - transition: 0.2s ease-out; - - } - - - - -} -.slick-dots li button:hover, -.slick-dots li button:focus -{ - outline: none; - &:after { - opacity: 1; - } -} - -.slick-dots li.slick-active button:after { - opacity: 1; -} - - - - diff --git a/v0.58.0/assets/images/favicon.png b/v0.58.0/assets/images/favicon.png deleted file mode 100644 index 1cf13b9f9d97..000000000000 Binary files a/v0.58.0/assets/images/favicon.png and /dev/null differ diff --git a/v0.58.0/assets/images/homepage_hero_orb_03.png b/v0.58.0/assets/images/homepage_hero_orb_03.png deleted file mode 100644 index 261f40f49073..000000000000 Binary files a/v0.58.0/assets/images/homepage_hero_orb_03.png and /dev/null differ diff --git a/v0.58.0/assets/images/homepage_hero_stars_02.svg b/v0.58.0/assets/images/homepage_hero_stars_02.svg deleted file mode 100644 index d0e4570eb467..000000000000 --- a/v0.58.0/assets/images/homepage_hero_stars_02.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/v0.58.0/assets/images/homepage_hero_terrain_08.svg b/v0.58.0/assets/images/homepage_hero_terrain_08.svg deleted file mode 100644 index fe2236c99569..000000000000 --- a/v0.58.0/assets/images/homepage_hero_terrain_08.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/v0.58.0/assets/images/homepage_v1_hero_person_01.png b/v0.58.0/assets/images/homepage_v1_hero_person_01.png deleted file mode 100644 index 2901ed862e5d..000000000000 Binary files a/v0.58.0/assets/images/homepage_v1_hero_person_01.png and /dev/null differ diff --git a/v0.58.0/assets/images/trivy_logo_horizontal_white.svg b/v0.58.0/assets/images/trivy_logo_horizontal_white.svg deleted file mode 100644 index 287eb199f1e8..000000000000 --- a/v0.58.0/assets/images/trivy_logo_horizontal_white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/bundle.203fd0bc.min.js b/v0.58.0/assets/javascripts/bundle.203fd0bc.min.js deleted file mode 100644 index 6ff9630a6ca5..000000000000 --- a/v0.58.0/assets/javascripts/bundle.203fd0bc.min.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict";(()=>{var Zi=Object.create;var _r=Object.defineProperty;var ea=Object.getOwnPropertyDescriptor;var ta=Object.getOwnPropertyNames,Gt=Object.getOwnPropertySymbols,ra=Object.getPrototypeOf,Ar=Object.prototype.hasOwnProperty,bo=Object.prototype.propertyIsEnumerable;var ho=(e,t,r)=>t in e?_r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,R=(e,t)=>{for(var r in t||(t={}))Ar.call(t,r)&&ho(e,r,t[r]);if(Gt)for(var r of Gt(t))bo.call(t,r)&&ho(e,r,t[r]);return e};var vo=(e,t)=>{var r={};for(var o in e)Ar.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Gt)for(var o of Gt(e))t.indexOf(o)<0&&bo.call(e,o)&&(r[o]=e[o]);return r};var Cr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var oa=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ta(t))!Ar.call(e,n)&&n!==r&&_r(e,n,{get:()=>t[n],enumerable:!(o=ea(t,n))||o.enumerable});return e};var Rt=(e,t,r)=>(r=e!=null?Zi(ra(e)):{},oa(t||!e||!e.__esModule?_r(r,"default",{value:e,enumerable:!0}):r,e));var go=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var xo=Cr((kr,yo)=>{(function(e,t){typeof kr=="object"&&typeof yo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(kr,function(){"use strict";function e(r){var o=!0,n=!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(k){return!!(k&&k!==document&&k.nodeName!=="HTML"&&k.nodeName!=="BODY"&&"classList"in k&&"contains"in k.classList)}function c(k){var ut=k.type,je=k.tagName;return!!(je==="INPUT"&&s[ut]&&!k.readOnly||je==="TEXTAREA"&&!k.readOnly||k.isContentEditable)}function p(k){k.classList.contains("focus-visible")||(k.classList.add("focus-visible"),k.setAttribute("data-focus-visible-added",""))}function l(k){k.hasAttribute("data-focus-visible-added")&&(k.classList.remove("focus-visible"),k.removeAttribute("data-focus-visible-added"))}function f(k){k.metaKey||k.altKey||k.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(k){o=!1}function d(k){a(k.target)&&(o||c(k.target))&&p(k.target)}function v(k){a(k.target)&&(k.target.classList.contains("focus-visible")||k.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(k.target))}function S(k){document.visibilityState==="hidden"&&(n&&(o=!0),X())}function X(){document.addEventListener("mousemove",ee),document.addEventListener("mousedown",ee),document.addEventListener("mouseup",ee),document.addEventListener("pointermove",ee),document.addEventListener("pointerdown",ee),document.addEventListener("pointerup",ee),document.addEventListener("touchmove",ee),document.addEventListener("touchstart",ee),document.addEventListener("touchend",ee)}function re(){document.removeEventListener("mousemove",ee),document.removeEventListener("mousedown",ee),document.removeEventListener("mouseup",ee),document.removeEventListener("pointermove",ee),document.removeEventListener("pointerdown",ee),document.removeEventListener("pointerup",ee),document.removeEventListener("touchmove",ee),document.removeEventListener("touchstart",ee),document.removeEventListener("touchend",ee)}function ee(k){k.target.nodeName&&k.target.nodeName.toLowerCase()==="html"||(o=!1,re())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",S,!0),X(),r.addEventListener("focus",d,!0),r.addEventListener("blur",v,!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 ro=Cr((Uy,Pn)=>{"use strict";var qa=/["'&<>]/;Pn.exports=Ka;function Ka(e){var t=""+e,r=qa.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i{(function(t,r){typeof zt=="object"&&typeof io=="object"?io.exports=r():typeof define=="function"&&define.amd?define([],r):typeof zt=="object"?zt.ClipboardJS=r():t.ClipboardJS=r()})(zt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Xi}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(q){try{return document.execCommand(q)}catch(C){return!1}}var d=function(C){var _=f()(C);return u("cut"),_},v=d;function S(q){var C=document.documentElement.getAttribute("dir")==="rtl",_=document.createElement("textarea");_.style.fontSize="12pt",_.style.border="0",_.style.padding="0",_.style.margin="0",_.style.position="absolute",_.style[C?"right":"left"]="-9999px";var W=window.pageYOffset||document.documentElement.scrollTop;return _.style.top="".concat(W,"px"),_.setAttribute("readonly",""),_.value=q,_}var X=function(C,_){var W=S(C);_.container.appendChild(W);var N=f()(W);return u("copy"),W.remove(),N},re=function(C){var _=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},W="";return typeof C=="string"?W=X(C,_):C instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(C==null?void 0:C.type)?W=X(C.value,_):(W=f()(C),u("copy")),W},ee=re;function k(q){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?k=function(_){return typeof _}:k=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},k(q)}var ut=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},_=C.action,W=_===void 0?"copy":_,N=C.container,G=C.target,De=C.text;if(W!=="copy"&&W!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(G!==void 0)if(G&&k(G)==="object"&&G.nodeType===1){if(W==="copy"&&G.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(W==="cut"&&(G.hasAttribute("readonly")||G.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(De)return ee(De,{container:N});if(G)return W==="cut"?v(G):ee(G,{container:N})},je=ut;function P(q){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?P=function(_){return typeof _}:P=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},P(q)}function se(q,C){if(!(q instanceof C))throw new TypeError("Cannot call a class as a function")}function ce(q,C){for(var _=0;_0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof N.action=="function"?N.action:this.defaultAction,this.target=typeof N.target=="function"?N.target:this.defaultTarget,this.text=typeof N.text=="function"?N.text:this.defaultText,this.container=P(N.container)==="object"?N.container:document.body}},{key:"listenClick",value:function(N){var G=this;this.listener=p()(N,"click",function(De){return G.onClick(De)})}},{key:"onClick",value:function(N){var G=N.delegateTarget||N.currentTarget,De=this.action(G)||"copy",Bt=je({action:De,container:this.container,target:this.target(G),text:this.text(G)});this.emit(Bt?"success":"error",{action:De,text:Bt,trigger:G,clearSelection:function(){G&&G.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(N){return Mr("action",N)}},{key:"defaultTarget",value:function(N){var G=Mr("target",N);if(G)return document.querySelector(G)}},{key:"defaultText",value:function(N){return Mr("text",N)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(N){var G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return ee(N,G)}},{key:"cut",value:function(N){return v(N)}},{key:"isSupported",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],G=typeof N=="string"?[N]:N,De=!!document.queryCommandSupported;return G.forEach(function(Bt){De=De&&!!document.queryCommandSupported(Bt)}),De}}]),_}(a()),Xi=Ji},828:function(o){var n=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!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,d,v){var S=p.apply(this,arguments);return l.addEventListener(u,S,v),{destroy:function(){l.removeEventListener(u,S,v)}}}function c(l,f,u,d,v){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(S){return a(S,f,u,d,v)}))}function p(l,f,u,d){return function(v){v.delegateTarget=s(v.target,f),v.delegateTarget&&d.call(l,v)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.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||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,d,v){if(!u&&!d&&!v)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(v))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,d,v);if(s.nodeList(u))return l(u,d,v);if(s.string(u))return f(u,d,v);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,d,v){return u.addEventListener(d,v),{destroy:function(){u.removeEventListener(d,v)}}}function l(u,d,v){return Array.prototype.forEach.call(u,function(S){S.addEventListener(d,v)}),{destroy:function(){Array.prototype.forEach.call(u,function(S){S.removeEventListener(d,v)})}}}function f(u,d,v){return a(document.body,u,d,v)}o.exports=c},817:function(o){function n(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(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.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 p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function K(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function B(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||c(d,S)})},v&&(n[d]=v(n[d])))}function c(d,v){try{p(o[d](v))}catch(S){u(i[0][3],S)}}function p(d){d.value instanceof dt?Promise.resolve(d.value.v).then(l,f):u(i[0][2],d)}function l(d){c("next",d)}function f(d){c("throw",d)}function u(d,v){d(v),i.shift(),i.length&&c(i[0][0],i[0][1])}}function To(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 Oe=="function"?Oe(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function I(e){return typeof e=="function"}function yt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Xt=yt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: -`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` - `):"",this.name="UnsubscriptionError",this.errors=r}});function Ze(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var qe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Oe(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(S){t={error:S}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(I(l))try{l()}catch(S){i=S instanceof Xt?S.errors:[S]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Oe(f),d=u.next();!d.done;d=u.next()){var v=d.value;try{So(v)}catch(S){i=i!=null?i:[],S instanceof Xt?i=B(B([],K(i)),K(S.errors)):i.push(S)}}}catch(S){o={error:S}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Xt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)So(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)&&Ze(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ze(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var $r=qe.EMPTY;function Zt(e){return e instanceof qe||e&&"closed"in e&&I(e.remove)&&I(e.add)&&I(e.unsubscribe)}function So(e){I(e)?e():e.unsubscribe()}var We={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var xt={setTimeout:function(e,t){for(var r=[],o=2;o0},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 o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?$r:(this.currentObservers=null,a.push(r),new qe(function(){o.currentObservers=null,Ze(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,o){return new Ho(r,o)},t}(F);var Ho=function(e){ie(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:$r},t}(T);var jr=function(e){ie(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(T);var It={now:function(){return(It.delegate||Date).now()},delegate:void 0};var Ft=function(e){ie(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=It);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(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 o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(St);var Po=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(Ot);var Wr=new Po(Ro);var Io=function(e){ie(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=Tt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(Tt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(St);var Fo=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 o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(Ot);var ye=new Fo(Io);var y=new F(function(e){return e.complete()});function rr(e){return e&&I(e.schedule)}function Vr(e){return e[e.length-1]}function pt(e){return I(Vr(e))?e.pop():void 0}function Fe(e){return rr(Vr(e))?e.pop():void 0}function or(e,t){return typeof Vr(e)=="number"?e.pop():t}var Lt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function nr(e){return I(e==null?void 0:e.then)}function ir(e){return I(e[wt])}function ar(e){return Symbol.asyncIterator&&I(e==null?void 0:e[Symbol.asyncIterator])}function sr(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 fa(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var cr=fa();function pr(e){return I(e==null?void 0:e[cr])}function lr(e){return wo(this,arguments,function(){var r,o,n,i;return Jt(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,dt(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,dt(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,dt(n)];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 mr(e){return I(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(ir(e))return ua(e);if(Lt(e))return da(e);if(nr(e))return ha(e);if(ar(e))return jo(e);if(pr(e))return ba(e);if(mr(e))return va(e)}throw sr(e)}function ua(e){return new F(function(t){var r=e[wt]();if(I(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function da(e){return new F(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?g(function(n,i){return e(n,i,o)}):be,Ee(1),r?Qe(t):tn(function(){return new ur}))}}function Yr(e){return e<=0?function(){return y}:E(function(t,r){var o=[];t.subscribe(w(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new T}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,d=0,v=!1,S=!1,X=function(){f==null||f.unsubscribe(),f=void 0},re=function(){X(),l=u=void 0,v=S=!1},ee=function(){var k=l;re(),k==null||k.unsubscribe()};return E(function(k,ut){d++,!S&&!v&&X();var je=u=u!=null?u:r();ut.add(function(){d--,d===0&&!S&&!v&&(f=Br(ee,c))}),je.subscribe(ut),!l&&d>0&&(l=new bt({next:function(P){return je.next(P)},error:function(P){S=!0,X(),f=Br(re,n,P),je.error(P)},complete:function(){v=!0,X(),f=Br(re,s),je.complete()}}),U(k).subscribe(l))})(p)}}function Br(e,t){for(var r=[],o=2;oe.next(document)),e}function M(e,t=document){return Array.from(t.querySelectorAll(e))}function j(e,t=document){let r=ue(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ue(e,t=document){return t.querySelector(e)||void 0}function Ne(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var Pa=L(h(document.body,"focusin"),h(document.body,"focusout")).pipe(Ae(1),Q(void 0),m(()=>Ne()||document.body),Z(1));function Ye(e){return Pa.pipe(m(t=>e.contains(t)),Y())}function it(e,t){return H(()=>L(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ut(r=>He(+!r*t)):be,Q(e.matches(":hover"))))}function sn(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)sn(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)sn(o,n);return o}function br(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function At(e){let t=x("script",{src:e});return H(()=>(document.head.appendChild(t),L(h(t,"load"),h(t,"error").pipe(b(()=>Nr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),Ee(1))))}var cn=new T,Ia=H(()=>typeof ResizeObserver=="undefined"?At("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>cn.next(t)))),b(e=>L(tt,$(e)).pipe(A(()=>e.disconnect()))),Z(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Le(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return Ia.pipe(O(r=>r.observe(t)),b(r=>cn.pipe(g(o=>o.target===t),A(()=>r.unobserve(t)))),m(()=>de(e)),Q(de(e)))}function Ct(e){return{width:e.scrollWidth,height:e.scrollHeight}}function vr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function pn(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Be(e){return{x:e.offsetLeft,y:e.offsetTop}}function ln(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function mn(e){return L(h(window,"load"),h(window,"resize")).pipe($e(0,ye),m(()=>Be(e)),Q(Be(e)))}function gr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ge(e){return L(h(e,"scroll"),h(window,"scroll"),h(window,"resize")).pipe($e(0,ye),m(()=>gr(e)),Q(gr(e)))}var fn=new T,Fa=H(()=>$(new IntersectionObserver(e=>{for(let t of e)fn.next(t)},{threshold:0}))).pipe(b(e=>L(tt,$(e)).pipe(A(()=>e.disconnect()))),Z(1));function mt(e){return Fa.pipe(O(t=>t.observe(e)),b(t=>fn.pipe(g(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function un(e,t=16){return Ge(e).pipe(m(({y:r})=>{let o=de(e),n=Ct(e);return r>=n.height-o.height-t}),Y())}var yr={drawer:j("[data-md-toggle=drawer]"),search:j("[data-md-toggle=search]")};function dn(e){return yr[e].checked}function at(e,t){yr[e].checked!==t&&yr[e].click()}function Je(e){let t=yr[e];return h(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function ja(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 Ua(){return L(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function hn(){let e=h(window,"keydown").pipe(g(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:dn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),g(({mode:t,type:r})=>{if(t==="global"){let o=Ne();if(typeof o!="undefined")return!ja(o,r)}return!0}),le());return Ua().pipe(b(t=>t?y:e))}function we(){return new URL(location.href)}function st(e,t=!1){if(V("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function bn(){return new T}function vn(){return location.hash.slice(1)}function gn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Zr(e){return L(h(window,"hashchange"),e).pipe(m(vn),Q(vn()),g(t=>t.length>0),Z(1))}function yn(e){return Zr(e).pipe(m(t=>ue(`[id="${t}"]`)),g(t=>typeof t!="undefined"))}function Wt(e){let t=matchMedia(e);return dr(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function xn(){let e=matchMedia("print");return L(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function eo(e,t){return e.pipe(b(r=>r?t():y))}function to(e,t){return new F(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function ze(e,t){return to(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),Z(1))}function xr(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),Z(1))}function En(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),Z(1))}function wn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Tn(){return L(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(wn),Q(wn()))}function Sn(){return{width:innerWidth,height:innerHeight}}function On(){return h(window,"resize",{passive:!0}).pipe(m(Sn),Q(Sn()))}function Ln(){return z([Tn(),On()]).pipe(m(([e,t])=>({offset:e,size:t})),Z(1))}function Er(e,{viewport$:t,header$:r}){let o=t.pipe(ne("size")),n=z([o,r]).pipe(m(()=>Be(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function Da(e){return h(e,"message",t=>t.data)}function Wa(e){let t=new T;return t.subscribe(r=>e.postMessage(r)),t}function Mn(e,t=new Worker(e)){let r=Da(t),o=Wa(t),n=new T;n.subscribe(o);let i=o.pipe(oe(),ae(!0));return n.pipe(oe(),Ve(r.pipe(D(i))),le())}var Va=j("#__config"),kt=JSON.parse(Va.textContent);kt.base=`${new URL(kt.base,we())}`;function Te(){return kt}function V(e){return kt.features.includes(e)}function Me(e,t){return typeof t!="undefined"?kt.translations[e].replace("#",t.toString()):kt.translations[e]}function Ce(e,t=document){return j(`[data-md-component=${e}]`,t)}function me(e,t=document){return M(`[data-md-component=${e}]`,t)}function Na(e){let t=j(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>j(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function _n(e){if(!V("announce.dismiss")||!e.childElementCount)return y;if(!e.hidden){let t=j(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new T;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Na(e).pipe(O(r=>t.next(r)),A(()=>t.complete()),m(r=>R({ref:e},r)))})}function za(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function An(e,t){let r=new T;return r.subscribe(({hidden:o})=>{e.hidden=o}),za(e,t).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))}function Vt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function wr(...e){return x("div",{class:"md-tooltip2",role:"dialog"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function Cn(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function kn(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Vt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Vt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function Hn(e){return x("button",{class:"md-code__button",title:Me("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function $n(){return x("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function Rn(){return x("nav",{class:"md-code__nav"})}var In=Rt(ro());function oo(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,x("del",null,(0,In.default)(p))," "],[]).slice(0,-1),i=Te(),s=new URL(e.location,i.base);V("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=Te();return x("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&x("nav",{class:"md-tags"},e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${p}`},c)})),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Me("search.result.term.missing"),": ",...n)))}function Fn(e){let t=e[0].score,r=[...e],o=Te(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scoreoo(l,1)),...c.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,c.length>0&&c.length===1?Me("search.result.more.one"):Me("search.result.more.other",c.length))),...c.map(l=>oo(l,1)))]:[]];return x("li",{class:"md-search-result__item"},p)}function jn(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?br(r):r)))}function no(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function Un(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function Qa(e){var o;let t=Te(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function Dn(e,t){var o;let r=Te();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Me("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map(Qa)))}var Ya=0;function Ba(e,t=250){let r=z([Ye(e),it(e,t)]).pipe(m(([n,i])=>n||i),Y()),o=H(()=>pn(e)).pipe(J(Ge),gt(1),Re(r),m(()=>ln(e)));return r.pipe(Pe(n=>n),b(()=>z([r,o])),m(([n,i])=>({active:n,offset:i})),le())}function Nt(e,t,r=250){let{content$:o,viewport$:n}=t,i=`__tooltip2_${Ya++}`;return H(()=>{let s=new T,a=new jr(!1);s.pipe(oe(),ae(!1)).subscribe(a);let c=a.pipe(Ut(l=>He(+!l*250,Wr)),Y(),b(l=>l?o:y),O(l=>l.id=i),le());z([s.pipe(m(({active:l})=>l)),c.pipe(b(l=>it(l,250)),Q(!1))]).pipe(m(l=>l.some(f=>f))).subscribe(a);let p=a.pipe(g(l=>l),te(c,n),m(([l,f,{size:u}])=>{let d=e.getBoundingClientRect(),v=d.width/2;if(f.role==="tooltip")return{x:v,y:8+d.height};if(d.y>=u.height/2){let{height:S}=de(f);return{x:v,y:-16-S}}else return{x:v,y:16+d.height}}));return z([c,s,p]).subscribe(([l,{offset:f},u])=>{l.style.setProperty("--md-tooltip-host-x",`${f.x}px`),l.style.setProperty("--md-tooltip-host-y",`${f.y}px`),l.style.setProperty("--md-tooltip-x",`${u.x}px`),l.style.setProperty("--md-tooltip-y",`${u.y}px`),l.classList.toggle("md-tooltip2--top",u.y<0),l.classList.toggle("md-tooltip2--bottom",u.y>=0)}),a.pipe(g(l=>l),te(c,(l,f)=>f),g(l=>l.role==="tooltip")).subscribe(l=>{let f=de(j(":scope > *",l));l.style.setProperty("--md-tooltip-width",`${f.width}px`),l.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(Y(),xe(ye),te(c)).subscribe(([l,f])=>{f.classList.toggle("md-tooltip2--active",l)}),z([a.pipe(g(l=>l)),c]).subscribe(([l,f])=>{f.role==="dialog"?(e.setAttribute("aria-controls",i),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",i)}),a.pipe(g(l=>!l)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Ba(e,r).pipe(O(l=>s.next(l)),A(()=>s.complete()),m(l=>R({ref:e},l)))})}function Xe(e,{viewport$:t},r=document.body){return Nt(e,{content$:new F(o=>{let n=e.title,i=Cn(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t},0)}function Ga(e,t){let r=H(()=>z([mn(e),Ge(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=de(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return Ye(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),Ee(+!o||1/0))))}function Wn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new T,s=i.pipe(oe(),ae(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),mt(e).pipe(D(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),L(i.pipe(g(({active:a})=>a)),i.pipe(Ae(250),g(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe($e(16,ye)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(gt(125,ye),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(D(s),g(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),h(n,"mousedown").pipe(D(s),te(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Ne())==null||p.blur()}}),r.pipe(D(s),g(a=>a===o),nt(125)).subscribe(()=>e.focus()),Ga(e,t).pipe(O(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))})}function Ja(e){let t=Te();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(typeof t.annotate!="undefined"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return M(r.join(", "),e)}function Xa(e){let t=[];for(let r of Ja(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function Vn(e,t){t.append(...Array.from(e.childNodes))}function Tr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Xa(t)){let[,c]=a.textContent.match(/\((\d+)\)/);ue(`:scope > li:nth-child(${c})`,e)&&(s.set(c,kn(c,i)),a.replaceWith(s.get(c)))}return s.size===0?y:H(()=>{let a=new T,c=a.pipe(oe(),ae(!0)),p=[];for(let[l,f]of s)p.push([j(".md-typeset",f),j(`:scope > li:nth-child(${l})`,e)]);return o.pipe(D(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?Vn(f,u):Vn(u,f)}),L(...[...s].map(([,l])=>Wn(l,t,{target$:r}))).pipe(A(()=>a.complete()),le())})}function Nn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Nn(t)}}function zn(e,t){return H(()=>{let r=Nn(e);return typeof r!="undefined"?Tr(r,e,t):y})}var Kn=Rt(ao());var Za=0,qn=L(h(window,"keydown").pipe(m(()=>!0)),L(h(window,"keyup"),h(window,"contextmenu")).pipe(m(()=>!1))).pipe(Q(!1),Z(1));function Qn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Qn(t)}}function es(e){return Le(e).pipe(m(({width:t})=>({scrollable:Ct(e).width>t})),ne("scrollable"))}function Yn(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new T,i=n.pipe(Yr(1));n.subscribe(({scrollable:d})=>{d&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[],a=e.closest("pre"),c=a.closest("[id]"),p=c?c.id:Za++;a.id=`__code_${p}`;let l=[],f=e.closest(".highlight");if(f instanceof HTMLElement){let d=Qn(f);if(typeof d!="undefined"&&(f.classList.contains("annotate")||V("content.code.annotate"))){let v=Tr(d,e,t);l.push(Le(f).pipe(D(i),m(({width:S,height:X})=>S&&X),Y(),b(S=>S?v:y)))}}let u=M(":scope > span[id]",e);if(u.length&&(e.classList.add("md-code__content"),e.closest(".select")||V("content.code.select")&&!e.closest(".no-select"))){let d=+u[0].id.split("-").pop(),v=$n();s.push(v),V("content.tooltips")&&l.push(Xe(v,{viewport$}));let S=h(v,"click").pipe(Dt(P=>!P,!1),O(()=>v.blur()),le());S.subscribe(P=>{v.classList.toggle("md-code__button--active",P)});let X=fe(u).pipe(J(P=>it(P).pipe(m(se=>[P,se]))));S.pipe(b(P=>P?X:y)).subscribe(([P,se])=>{let ce=ue(".hll.select",P);if(ce&&!se)ce.replaceWith(...Array.from(ce.childNodes));else if(!ce&&se){let he=document.createElement("span");he.className="hll select",he.append(...Array.from(P.childNodes).slice(1)),P.append(he)}});let re=fe(u).pipe(J(P=>h(P,"mousedown").pipe(O(se=>se.preventDefault()),m(()=>P)))),ee=S.pipe(b(P=>P?re:y),te(qn),m(([P,se])=>{var he;let ce=u.indexOf(P)+d;if(se===!1)return[ce,ce];{let Se=M(".hll",e).map(Ue=>u.indexOf(Ue.parentElement)+d);return(he=window.getSelection())==null||he.removeAllRanges(),[Math.min(ce,...Se),Math.max(ce,...Se)]}})),k=Zr(y).pipe(g(P=>P.startsWith(`__codelineno-${p}-`)));k.subscribe(P=>{let[,,se]=P.split("-"),ce=se.split(":").map(Se=>+Se-d+1);ce.length===1&&ce.push(ce[0]);for(let Se of M(".hll:not(.select)",e))Se.replaceWith(...Array.from(Se.childNodes));let he=u.slice(ce[0]-1,ce[1]);for(let Se of he){let Ue=document.createElement("span");Ue.className="hll",Ue.append(...Array.from(Se.childNodes).slice(1)),Se.append(Ue)}}),k.pipe(Ee(1),xe(pe)).subscribe(P=>{if(P.includes(":")){let se=document.getElementById(P.split(":")[0]);se&&setTimeout(()=>{let ce=se,he=-64;for(;ce!==document.body;)he+=ce.offsetTop,ce=ce.offsetParent;window.scrollTo({top:he})},1)}});let je=fe(M('a[href^="#__codelineno"]',f)).pipe(J(P=>h(P,"click").pipe(O(se=>se.preventDefault()),m(()=>P)))).pipe(D(i),te(qn),m(([P,se])=>{let he=+j(`[id="${P.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(se===!1)return[he,he];{let Se=M(".hll",e).map(Ue=>+Ue.parentElement.id.split("-").pop());return[Math.min(he,...Se),Math.max(he,...Se)]}}));L(ee,je).subscribe(P=>{let se=`#__codelineno-${p}-`;P[0]===P[1]?se+=P[0]:se+=`${P[0]}:${P[1]}`,history.replaceState({},"",se),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+se,oldURL:window.location.href}))})}if(Kn.default.isSupported()&&(e.closest(".copy")||V("content.code.copy")&&!e.closest(".no-copy"))){let d=Hn(a.id);s.push(d),V("content.tooltips")&&l.push(Xe(d,{viewport$}))}if(s.length){let d=Rn();d.append(...s),a.insertBefore(d,e)}return es(e).pipe(O(d=>n.next(d)),A(()=>n.complete()),m(d=>R({ref:e},d)),Ve(L(...l).pipe(D(i))))});return V("content.lazy")?mt(e).pipe(g(n=>n),Ee(1),b(()=>o)):o}function ts(e,{target$:t,print$:r}){let o=!0;return L(t.pipe(m(n=>n.closest("details:not([open])")),g(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(g(n=>n||!o),O(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Bn(e,t){return H(()=>{let r=new T;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),ts(e,t).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))})}var Gn=0;function rs(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],o=e.nextElementSibling;for(;o&&!(o instanceof HTMLHeadingElement);)r.push(o),o=o.nextElementSibling;return r}function os(e,t){for(let r of M("[href], [src]",e))for(let o of["href","src"]){let n=r.getAttribute(o);if(n&&!/^(?:[a-z]+:)?\/\//i.test(n)){r[o]=new URL(r.getAttribute(o),t).toString();break}}for(let r of M("[name^=__], [for]",e))for(let o of["id","for","name"]){let n=r.getAttribute(o);n&&r.setAttribute(o,`${n}$preview_${Gn}`)}return Gn++,$(e)}function Jn(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return y;if(!(V("navigation.instant.preview")||e.hasAttribute("data-preview")))return y;let o=z([Ye(e),it(e)]).pipe(m(([i,s])=>i||s),Y(),g(i=>i));return rt([r,o]).pipe(b(([i])=>{let s=new URL(e.href);return s.search=s.hash="",i.has(`${s}`)?$(s):y}),b(i=>xr(i).pipe(b(s=>os(s,i)))),b(i=>{let s=e.hash?`article [id="${e.hash.slice(1)}"]`:"article h1",a=ue(s,i);return typeof a=="undefined"?y:$(rs(a))})).pipe(b(i=>{let s=new F(a=>{let c=wr(...i);return a.next(c),document.body.append(c),()=>c.remove()});return Nt(e,R({content$:s},t))}))}var Xn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel p,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel p{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var so,is=0;function as(){return typeof mermaid=="undefined"||mermaid instanceof Element?At("https://unpkg.com/mermaid@11/dist/mermaid.min.js"):$(void 0)}function Zn(e){return e.classList.remove("mermaid"),so||(so=as().pipe(O(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Xn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),Z(1))),so.subscribe(()=>go(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${is++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),so.pipe(m(()=>({ref:e})))}var ei=x("table");function ti(e){return e.replaceWith(ei),ei.replaceWith(Un(e)),$({ref:e})}function ss(e){let t=e.find(r=>r.checked)||e[0];return L(...e.map(r=>h(r,"change").pipe(m(()=>j(`label[for="${r.id}"]`))))).pipe(Q(j(`label[for="${t.id}"]`)),m(r=>({active:r})))}function ri(e,{viewport$:t,target$:r}){let o=j(".tabbed-labels",e),n=M(":scope > input",e),i=no("prev");e.append(i);let s=no("next");return e.append(s),H(()=>{let a=new T,c=a.pipe(oe(),ae(!0));z([a,Le(e),mt(e)]).pipe(D(c),$e(1,ye)).subscribe({next([{active:p},l]){let f=Be(p),{width:u}=de(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=gr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([Ge(o),Le(o)]).pipe(D(c)).subscribe(([p,l])=>{let f=Ct(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),L(h(i,"click").pipe(m(()=>-1)),h(s,"click").pipe(m(()=>1))).pipe(D(c)).subscribe(p=>{let{width:l}=de(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(D(c),g(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=j(`label[for="${p.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(D(c),g(f=>!(f.metaKey||f.ctrlKey)),O(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return V("content.tabs.link")&&a.pipe(Ie(1),te(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let v of M("[data-tabs]"))for(let S of M(":scope > input",v)){let X=j(`label[for="${S.id}"]`);if(X!==p&&X.innerText.trim()===f){X.setAttribute("data-md-switching",""),S.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),a.pipe(D(c)).subscribe(()=>{for(let p of M("audio, video",e))p.pause()}),ss(n).pipe(O(p=>a.next(p)),A(()=>a.complete()),m(p=>R({ref:e},p)))}).pipe(et(pe))}function oi(e,t){let{viewport$:r,target$:o,print$:n}=t;return L(...M(".annotate:not(.highlight)",e).map(i=>zn(i,{target$:o,print$:n})),...M("pre:not(.mermaid) > code",e).map(i=>Yn(i,{target$:o,print$:n})),...M("a:not([title])",e).map(i=>Jn(i,t)),...M("pre.mermaid",e).map(i=>Zn(i)),...M("table:not([class])",e).map(i=>ti(i)),...M("details",e).map(i=>Bn(i,{target$:o,print$:n})),...M("[data-tabs]",e).map(i=>ri(i,{viewport$:r,target$:o})),...M("[title]",e).filter(()=>V("content.tooltips")).map(i=>Xe(i,{viewport$:r})),...M(".footnote-ref",e).filter(()=>V("content.footnote.tooltips")).map(i=>Nt(i,{content$:new F(s=>{let a=new URL(i.href).hash.slice(1),c=Array.from(document.getElementById(a).cloneNode(!0).children),p=wr(...c);return s.next(p),document.body.append(p),()=>p.remove()}),viewport$:r})))}function cs(e,{alert$:t}){return t.pipe(b(r=>L($(!0),$(!1).pipe(nt(2e3))).pipe(m(o=>({message:r,active:o})))))}function ni(e,t){let r=j(".md-typeset",e);return H(()=>{let o=new T;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),cs(e,t).pipe(O(n=>o.next(n)),A(()=>o.complete()),m(n=>R({ref:e},n)))})}var ps=0;function ls(e,t){document.body.append(e);let{width:r}=de(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=vr(t),n=typeof o!="undefined"?Ge(o):$({x:0,y:0}),i=L(Ye(t),it(t)).pipe(Y());return z([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Be(t),l=de(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function ii(e){let t=e.title;if(!t.length)return y;let r=`__tooltip_${ps++}`,o=Vt(r,"inline"),n=j(".md-typeset",o);return n.innerHTML=t,H(()=>{let i=new T;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),L(i.pipe(g(({active:s})=>s)),i.pipe(Ae(250),g(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe($e(16,ye)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(gt(125,ye),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),ls(o,e).pipe(O(s=>i.next(s)),A(()=>i.complete()),m(s=>R({ref:e},s)))}).pipe(et(pe))}function ms({viewport$:e}){if(!V("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),ot(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=Je("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),Q(!1))}function ai(e,t){return H(()=>z([Le(e),ms(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),Z(1))}function si(e,{header$:t,main$:r}){return H(()=>{let o=new T,n=o.pipe(oe(),ae(!0));o.pipe(ne("active"),Re(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(M("[title]",e)).pipe(g(()=>V("content.tooltips")),J(s=>ii(s)));return r.subscribe(o),t.pipe(D(n),m(s=>R({ref:e},s)),Ve(i.pipe(D(n))))})}function fs(e,{viewport$:t,header$:r}){return Er(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=de(e);return{active:o>=n}}),ne("active"))}function ci(e,t){return H(()=>{let r=new T;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=ue(".md-content h1");return typeof o=="undefined"?y:fs(o,t).pipe(O(n=>r.next(n)),A(()=>r.complete()),m(n=>R({ref:e},n)))})}function pi(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Le(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ne("bottom"))));return z([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function us(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(J(o=>h(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),Z(1))}function li(e){let t=M("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Wt("(prefers-color-scheme: light)");return H(()=>{let i=new T;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;as.key==="Enter"),te(i,(s,a)=>a)).subscribe(({index:s})=>{s=(s+1)%t.length,t[s].click(),t[s].focus()}),i.pipe(m(()=>{let s=Ce("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(xe(pe)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),us(t).pipe(D(n.pipe(Ie(1))),vt(),O(s=>i.next(s)),A(()=>i.complete()),m(s=>R({ref:e},s)))})}function mi(e,{progress$:t}){return H(()=>{let r=new T;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(O(o=>r.next({value:o})),A(()=>r.complete()),m(o=>({ref:e,value:o})))})}function fi(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function ds(e,t){let r=new Map;for(let o of M("url",e)){let n=j("loc",o),i=[fi(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of M("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(fi(new URL(a),t))}}return r}function Ht(e){return En(new URL("sitemap.xml",e)).pipe(m(t=>ds(t,new URL(e))),ve(()=>$(new Map)),le())}function ui({document$:e}){let t=new Map;e.pipe(b(()=>M("link[rel=alternate]")),m(r=>new URL(r.href)),g(r=>!t.has(r.toString())),J(r=>Ht(r).pipe(m(o=>[r,o]),ve(()=>y)))).subscribe(([r,o])=>{t.set(r.toString().replace(/\/$/,""),o)}),h(document.body,"click").pipe(g(r=>!r.metaKey&&!r.ctrlKey),b(r=>{if(r.target instanceof Element){let o=r.target.closest("a");if(o&&!o.target){let n=[...t].find(([f])=>o.href.startsWith(`${f}/`));if(typeof n=="undefined")return y;let[i,s]=n,a=we();if(a.href.startsWith(i))return y;let c=Te(),p=a.href.replace(c.base,"");p=`${i}/${p}`;let l=s.has(p.split("#")[0])?new URL(p,c.base):new URL(i);return r.preventDefault(),$(l)}}return y})).subscribe(r=>st(r,!0))}var co=Rt(ao());function hs(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function di({alert$:e}){co.default.isSupported()&&new F(t=>{new co.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||hs(j(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(O(t=>{t.trigger.focus()}),m(()=>Me("clipboard.copied"))).subscribe(e)}function hi(e,t){if(!(e.target instanceof Element))return y;let r=e.target.closest("a");if(r===null)return y;if(r.target||e.metaKey||e.ctrlKey)return y;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(r)):y}function bi(e){let t=new Map;for(let r of M(":scope > *",e.head))t.set(r.outerHTML,r);return t}function vi(e){for(let t of M("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function bs(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...V("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=ue(o),i=ue(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=bi(document);for(let[o,n]of bi(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Ce("container");return Ke(M("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new F(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),y}),oe(),ae(document))}function gi({sitemap$:e,location$:t,viewport$:r,progress$:o}){if(location.protocol==="file:")return y;$(document).subscribe(vi);let n=h(document.body,"click").pipe(Re(e),b(([a,c])=>hi(a,c)),m(({href:a})=>new URL(a)),le()),i=h(window,"popstate").pipe(m(we),le());n.pipe(te(r)).subscribe(([a,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",a)}),L(n,i).subscribe(t);let s=t.pipe(ne("pathname"),b(a=>xr(a,{progress$:o}).pipe(ve(()=>(st(a,!0),y)))),b(vi),b(bs),le());return L(s.pipe(te(t,(a,c)=>c)),s.pipe(b(()=>t),ne("pathname"),b(()=>t),ne("hash")),t.pipe(Y((a,c)=>a.pathname===c.pathname&&a.hash===c.hash),b(()=>n),O(()=>history.back()))).subscribe(a=>{var c,p;history.state!==null||!a.hash?window.scrollTo(0,(p=(c=history.state)==null?void 0:c.y)!=null?p:0):(history.scrollRestoration="auto",gn(a.hash),history.scrollRestoration="manual")}),t.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),r.pipe(ne("offset"),Ae(100)).subscribe(({offset:a})=>{history.replaceState(a,"")}),V("navigation.instant.prefetch")&&L(h(document.body,"mousemove"),h(document.body,"focusin")).pipe(Re(e),b(([a,c])=>hi(a,c)),Ae(25),Qr(({href:a})=>a),hr(a=>{let c=document.createElement("link");return c.rel="prefetch",c.href=a.toString(),document.head.appendChild(c),h(c,"load").pipe(m(()=>c),Ee(1))})).subscribe(a=>a.remove()),s}var yi=Rt(ro());function xi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,yi.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function qt(e){return e.type===1}function Sr(e){return e.type===3}function Ei(e,t){let r=Mn(e);return L($(location.protocol!=="file:"),Je("search")).pipe(Pe(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:V("search.suggest")}}})),r}function wi(e){var l;let{selectedVersionSitemap:t,selectedVersionBaseURL:r,currentLocation:o,currentBaseURL:n}=e,i=(l=po(n))==null?void 0:l.pathname;if(i===void 0)return;let s=ys(o.pathname,i);if(s===void 0)return;let a=Es(t.keys());if(!t.has(a))return;let c=po(s,a);if(!c||!t.has(c.href))return;let p=po(s,r);if(p)return p.hash=o.hash,p.search=o.search,p}function po(e,t){try{return new URL(e,t)}catch(r){return}}function ys(e,t){if(e.startsWith(t))return e.slice(t.length)}function xs(e,t){let r=Math.min(e.length,t.length),o;for(o=0;oy)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>h(document.body,"click").pipe(g(i=>!i.metaKey&&!i.ctrlKey),te(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?y:(i.preventDefault(),$(new URL(c)))}}return y}),b(i=>Ht(i).pipe(m(s=>{var a;return(a=wi({selectedVersionSitemap:s,selectedVersionBaseURL:i,currentLocation:we(),currentBaseURL:t.base}))!=null?a:i})))))).subscribe(n=>st(n,!0)),z([r,o]).subscribe(([n,i])=>{j(".md-header__topic").appendChild(Dn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of me("outdated"))a.hidden=!1})}function ws(e,{worker$:t}){let{searchParams:r}=we();r.has("q")&&(at("search",!0),e.value=r.get("q"),e.focus(),Je("search").pipe(Pe(i=>!i)).subscribe(()=>{let i=we();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Ye(e),n=L(t.pipe(Pe(qt)),h(e,"keyup"),o).pipe(m(()=>e.value),Y());return z([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),Z(1))}function Si(e,{worker$:t}){let r=new T,o=r.pipe(oe(),ae(!0));z([t.pipe(Pe(qt)),r],(i,s)=>s).pipe(ne("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ne("focus")).subscribe(({focus:i})=>{i&&at("search",i)}),h(e.form,"reset").pipe(D(o)).subscribe(()=>e.focus());let n=j("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),ws(e,{worker$:t}).pipe(O(i=>r.next(i)),A(()=>r.complete()),m(i=>R({ref:e},i)),Z(1))}function Oi(e,{worker$:t,query$:r}){let o=new T,n=un(e.parentElement).pipe(g(Boolean)),i=e.parentElement,s=j(":scope > :first-child",e),a=j(":scope > :last-child",e);Je("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(te(r),Gr(t.pipe(Pe(qt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?Me("search.result.none"):Me("search.result.placeholder");break;case 1:s.textContent=Me("search.result.one");break;default:let u=br(l.length);s.textContent=Me("search.result.other",u)}});let c=o.pipe(O(()=>a.innerHTML=""),b(({items:l})=>L($(...l.slice(0,10)),$(...l.slice(10)).pipe(ot(4),Xr(n),b(([f])=>f)))),m(Fn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(J(l=>{let f=ue("details",l);return typeof f=="undefined"?y:h(f,"toggle").pipe(D(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(g(Sr),m(({data:l})=>l)).pipe(O(l=>o.next(l)),A(()=>o.complete()),m(l=>R({ref:e},l)))}function Ts(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=we();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Li(e,t){let r=new T,o=r.pipe(oe(),ae(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(D(o)).subscribe(n=>n.preventDefault()),Ts(e,t).pipe(O(n=>r.next(n)),A(()=>r.complete()),m(n=>R({ref:e},n)))}function Mi(e,{worker$:t,keyboard$:r}){let o=new T,n=Ce("search-query"),i=L(h(n,"keydown"),h(n,"focus")).pipe(xe(pe),m(()=>n.value),Y());return o.pipe(Re(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(g(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(g(Sr),m(({data:a})=>a)).pipe(O(a=>o.next(a)),A(()=>o.complete()),m(()=>({ref:e})))}function _i(e,{index$:t,keyboard$:r}){let o=Te();try{let n=Ei(o.search,t),i=Ce("search-query",e),s=Ce("search-result",e);h(e,"click").pipe(g(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>at("search",!1)),r.pipe(g(({mode:c})=>c==="search")).subscribe(c=>{let p=Ne();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of M(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}c.claim()}break;case"Escape":case"Tab":at("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...M(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Ne()&&i.focus()}}),r.pipe(g(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=Si(i,{worker$:n});return L(a,Oi(s,{worker$:n,query$:a})).pipe(Ve(...me("search-share",e).map(c=>Li(c,{query$:a})),...me("search-suggest",e).map(c=>Mi(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,tt}}function Ai(e,{index$:t,location$:r}){return z([t,r.pipe(Q(we()),g(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>xi(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=x("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ss(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function lo(e,o){var n=o,{header$:t}=n,r=vo(n,["header$"]);let i=j(".md-sidebar__scrollwrap",e),{y:s}=Be(i);return H(()=>{let a=new T,c=a.pipe(oe(),ae(!0)),p=a.pipe($e(0,ye));return p.pipe(te(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(Pe()).subscribe(()=>{for(let l of M(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2})}}}),fe(M("label[tabindex]",e)).pipe(J(l=>h(l,"click").pipe(xe(pe),m(()=>l),D(c)))).subscribe(l=>{let f=j(`[id="${l.htmlFor}"]`);j(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),V("content.tooltips")&&fe(M("abbr[title]",e)).pipe(J(l=>Xe(l,{viewport$})),D(c)).subscribe(),Ss(e,r).pipe(O(l=>a.next(l)),A(()=>a.complete()),m(l=>R({ref:e},l)))})}function Ci(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return rt(ze(`${r}/releases/latest`).pipe(ve(()=>y),m(o=>({version:o.tag_name})),Qe({})),ze(r).pipe(ve(()=>y),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Qe({}))).pipe(m(([o,n])=>R(R({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return ze(r).pipe(m(o=>({repositories:o.public_repos})),Qe({}))}}function ki(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return rt(ze(`${r}/releases/permalink/latest`).pipe(ve(()=>y),m(({tag_name:o})=>({version:o})),Qe({})),ze(r).pipe(ve(()=>y),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Qe({}))).pipe(m(([o,n])=>R(R({},o),n)))}function Hi(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return Ci(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ki(r,o)}return y}var Os;function Ls(e){return Os||(Os=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(me("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return y}return Hi(e.href).pipe(O(o=>__md_set("__source",o,sessionStorage)))}).pipe(ve(()=>y),g(t=>Object.keys(t).length>0),m(t=>({facts:t})),Z(1)))}function $i(e){let t=j(":scope > :last-child",e);return H(()=>{let r=new T;return r.subscribe(({facts:o})=>{t.appendChild(jn(o)),t.classList.add("md-source__repository--active")}),Ls(e).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))})}function Ms(e,{viewport$:t,header$:r}){return Le(document.body).pipe(b(()=>Er(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ne("hidden"))}function Ri(e,t){return H(()=>{let r=new T;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(V("navigation.tabs.sticky")?$({hidden:!1}):Ms(e,t)).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))})}function _s(e,{viewport$:t,header$:r}){let o=new Map,n=M(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=ue(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(ne("height"),m(({height:a})=>{let c=Ce("main"),p=j(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Le(document.body).pipe(ne("height"),b(a=>H(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),Re(i),b(([c,p])=>t.pipe(Dt(([l,f],{offset:{y:u},size:d})=>{let v=u+d.height>=Math.floor(a.height);for(;f.length;){let[,S]=f[0];if(S-p=u&&!v)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),Q({prev:[],next:[]}),ot(2,1),m(([a,c])=>a.prev.length{let i=new T,s=i.pipe(oe(),ae(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),V("toc.follow")){let a=L(t.pipe(Ae(1),m(()=>{})),t.pipe(Ae(250),m(()=>"smooth")));i.pipe(g(({prev:c})=>c.length>0),Re(o.pipe(xe(pe))),te(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=vr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2,behavior:p})}}})}return V("navigation.tracking")&&t.pipe(D(s),ne("offset"),Ae(250),Ie(1),D(n.pipe(Ie(1))),vt({delay:250}),te(i)).subscribe(([,{prev:a}])=>{let c=we(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),_s(e,{viewport$:t,header$:r}).pipe(O(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))})}function As(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),ot(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return z([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),D(o.pipe(Ie(1))),ae(!0),vt({delay:250}),m(s=>({hidden:s})))}function Ii(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new T,s=i.pipe(oe(),ae(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(D(s),ne("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),h(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),As(e,{viewport$:t,main$:o,target$:n}).pipe(O(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))}function Fi({document$:e,viewport$:t}){e.pipe(b(()=>M(".md-ellipsis")),J(r=>mt(r).pipe(D(e.pipe(Ie(1))),g(o=>o),m(()=>r),Ee(1))),g(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,V("content.tooltips")?Xe(n,{viewport$:t}).pipe(D(e.pipe(Ie(1))),A(()=>n.removeAttribute("title"))):y})).subscribe(),V("content.tooltips")&&e.pipe(b(()=>M(".md-status")),J(r=>Xe(r,{viewport$:t}))).subscribe()}function ji({document$:e,tablet$:t}){e.pipe(b(()=>M(".md-toggle--indeterminate")),O(r=>{r.indeterminate=!0,r.checked=!1}),J(r=>h(r,"change").pipe(Jr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),te(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Cs(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Ui({document$:e}){e.pipe(b(()=>M("[data-md-scrollfix]")),O(t=>t.removeAttribute("data-md-scrollfix")),g(Cs),J(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Di({viewport$:e,tablet$:t}){z([Je("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(nt(r?400:100))),te(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ks(){return location.protocol==="file:"?At(`${new URL("search/search_index.js",Or.base)}`).pipe(m(()=>__index),Z(1)):ze(new URL("search/search_index.json",Or.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ct=an(),Qt=bn(),$t=yn(Qt),mo=hn(),ke=Ln(),Lr=Wt("(min-width: 960px)"),Vi=Wt("(min-width: 1220px)"),Ni=xn(),Or=Te(),zi=document.forms.namedItem("search")?ks():tt,fo=new T;di({alert$:fo});ui({document$:ct});var uo=new T,qi=Ht(Or.base);V("navigation.instant")&&gi({sitemap$:qi,location$:Qt,viewport$:ke,progress$:uo}).subscribe(ct);var Wi;((Wi=Or.version)==null?void 0:Wi.provider)==="mike"&&Ti({document$:ct});L(Qt,$t).pipe(nt(125)).subscribe(()=>{at("drawer",!1),at("search",!1)});mo.pipe(g(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ue("link[rel=prev]");typeof t!="undefined"&&st(t);break;case"n":case".":let r=ue("link[rel=next]");typeof r!="undefined"&&st(r);break;case"Enter":let o=Ne();o instanceof HTMLLabelElement&&o.click()}});Fi({viewport$:ke,document$:ct});ji({document$:ct,tablet$:Lr});Ui({document$:ct});Di({viewport$:ke,tablet$:Lr});var ft=ai(Ce("header"),{viewport$:ke}),Kt=ct.pipe(m(()=>Ce("main")),b(e=>pi(e,{viewport$:ke,header$:ft})),Z(1)),Hs=L(...me("consent").map(e=>An(e,{target$:$t})),...me("dialog").map(e=>ni(e,{alert$:fo})),...me("palette").map(e=>li(e)),...me("progress").map(e=>mi(e,{progress$:uo})),...me("search").map(e=>_i(e,{index$:zi,keyboard$:mo})),...me("source").map(e=>$i(e))),$s=H(()=>L(...me("announce").map(e=>_n(e)),...me("content").map(e=>oi(e,{sitemap$:qi,viewport$:ke,target$:$t,print$:Ni})),...me("content").map(e=>V("search.highlight")?Ai(e,{index$:zi,location$:Qt}):y),...me("header").map(e=>si(e,{viewport$:ke,header$:ft,main$:Kt})),...me("header-title").map(e=>ci(e,{viewport$:ke,header$:ft})),...me("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?eo(Vi,()=>lo(e,{viewport$:ke,header$:ft,main$:Kt})):eo(Lr,()=>lo(e,{viewport$:ke,header$:ft,main$:Kt}))),...me("tabs").map(e=>Ri(e,{viewport$:ke,header$:ft})),...me("toc").map(e=>Pi(e,{viewport$:ke,header$:ft,main$:Kt,target$:$t})),...me("top").map(e=>Ii(e,{viewport$:ke,header$:ft,main$:Kt,target$:$t})))),Ki=ct.pipe(b(()=>$s),Ve(Hs),Z(1));Ki.subscribe();window.document$=ct;window.location$=Qt;window.target$=$t;window.keyboard$=mo;window.viewport$=ke;window.tablet$=Lr;window.screen$=Vi;window.print$=Ni;window.alert$=fo;window.progress$=uo;window.component$=Ki;})(); diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.ar.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.ar.min.js deleted file mode 100644 index 9b06c26c1fc3..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.ar.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.de.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.de.min.js deleted file mode 100644 index f3b5c108c9ee..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.de.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `German` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.du.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.du.min.js deleted file mode 100644 index 49a0f3f0ac17..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.du.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Dutch` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.el.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.el.min.js deleted file mode 100644 index ace017bd650d..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.el.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.el=function(){this.pipeline.reset(),void 0===this.searchPipeline&&this.pipeline.add(e.el.trimmer,e.el.normilizer),this.pipeline.add(e.el.stopWordFilter,e.el.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.el.stemmer))},e.el.wordCharacters="A-Za-zΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσςΤτΥυΦφΧχΨψΩωΆάΈέΉήΊίΌόΎύΏώΪΐΫΰΐΰ",e.el.trimmer=e.trimmerSupport.generateTrimmer(e.el.wordCharacters),e.Pipeline.registerFunction(e.el.trimmer,"trimmer-el"),e.el.stemmer=function(){function e(e){return s.test(e)}function t(e){return/[ΑΕΗΙΟΥΩ]$/.test(e)}function r(e){return/[ΑΕΗΙΟΩ]$/.test(e)}function n(n){var s=n;if(n.length<3)return s;if(!e(n))return s;if(i.indexOf(n)>=0)return s;var u=new RegExp("(.*)("+Object.keys(l).join("|")+")$"),o=u.exec(s);return null!==o&&(s=o[1]+l[o[2]]),null!==(o=/^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|ΠΕΘΕΡ|ΜΟΥΣΑΜ|ΚΑΠΛΑΜ|ΠΑΡ|ΨΑΡ|ΤΖΟΥΡ|ΤΑΜΠΟΥΡ|ΓΑΛΑΤ|ΦΑΦΛΑΤ)$/.test(o[1])||(s+="ΑΔ")),null!==(o=/^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/.test(o[1])&&(s+="ΕΔ")),null!==(o=/^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/.exec(s))&&(s=o[1],/(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|ΣΠ|ΤΡΑΓ|ΦΕ)$/.test(o[1])&&(s+="ΟΥΔ")),null!==(o=/^(.+?)(ΕΩΣ|ΕΩΝ|ΕΑΣ|ΕΑ)$/.exec(s))&&(s=o[1],/^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ|ΣΤΕΡ|ΟΡΦ|ΑΝΔΡ|ΑΝΤΡ)$/.test(o[1])&&(s+="Ε")),null!==(o=/^(.+?)(ΕΙΟ|ΕΙΟΣ|ΕΙΟΙ|ΕΙΑ|ΕΙΑΣ|ΕΙΕΣ|ΕΙΟΥ|ΕΙΟΥΣ|ΕΙΩΝ)$/.exec(s))&&o[1].length>4&&(s=o[1]),null!==(o=/^(.+?)(ΙΟΥΣ|ΙΑΣ|ΙΕΣ|ΙΟΣ|ΙΟΥ|ΙΟΙ|ΙΩΝ|ΙΟΝ|ΙΑ|ΙΟ)$/.exec(s))&&(s=o[1],(t(s)||s.length<2||/^(ΑΓ|ΑΓΓΕΛ|ΑΓΡ|ΑΕΡ|ΑΘΛ|ΑΚΟΥΣ|ΑΞ|ΑΣ|Β|ΒΙΒΛ|ΒΥΤ|Γ|ΓΙΑΓ|ΓΩΝ|Δ|ΔΑΝ|ΔΗΛ|ΔΗΜ|ΔΟΚΙΜ|ΕΛ|ΖΑΧΑΡ|ΗΛ|ΗΠ|ΙΔ|ΙΣΚ|ΙΣΤ|ΙΟΝ|ΙΩΝ|ΚΙΜΩΛ|ΚΟΛΟΝ|ΚΟΡ|ΚΤΗΡ|ΚΥΡ|ΛΑΓ|ΛΟΓ|ΜΑΓ|ΜΠΑΝ|ΜΠΡ|ΝΑΥΤ|ΝΟΤ|ΟΠΑΛ|ΟΞ|ΟΡ|ΟΣ|ΠΑΝΑΓ|ΠΑΤΡ|ΠΗΛ|ΠΗΝ|ΠΛΑΙΣ|ΠΟΝΤ|ΡΑΔ|ΡΟΔ|ΣΚ|ΣΚΟΡΠ|ΣΟΥΝ|ΣΠΑΝ|ΣΤΑΔ|ΣΥΡ|ΤΗΛ|ΤΙΜ|ΤΟΚ|ΤΟΠ|ΤΡΟΧ|ΦΙΛ|ΦΩΤ|Χ|ΧΙΛ|ΧΡΩΜ|ΧΩΡ)$/.test(o[1]))&&(s+="Ι"),/^(ΠΑΛ)$/.test(o[1])&&(s+="ΑΙ")),null!==(o=/^(.+?)(ΙΚΟΣ|ΙΚΟΝ|ΙΚΕΙΣ|ΙΚΟΙ|ΙΚΕΣ|ΙΚΟΥΣ|ΙΚΗ|ΙΚΗΣ|ΙΚΟ|ΙΚΑ|ΙΚΟΥ|ΙΚΩΝ|ΙΚΩΣ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΑΔ|ΑΛ|ΑΜΑΝ|ΑΜΕΡ|ΑΜΜΟΧΑΛ|ΑΝΗΘ|ΑΝΤΙΔ|ΑΠΛ|ΑΤΤ|ΑΦΡ|ΒΑΣ|ΒΡΩΜ|ΓΕΝ|ΓΕΡ|Δ|ΔΙΚΑΝ|ΔΥΤ|ΕΙΔ|ΕΝΔ|ΕΞΩΔ|ΗΘ|ΘΕΤ|ΚΑΛΛΙΝ|ΚΑΛΠ|ΚΑΤΑΔ|ΚΟΥΖΙΝ|ΚΡ|ΚΩΔ|ΛΟΓ|Μ|ΜΕΡ|ΜΟΝΑΔ|ΜΟΥΛ|ΜΟΥΣ|ΜΠΑΓΙΑΤ|ΜΠΑΝ|ΜΠΟΛ|ΜΠΟΣ|ΜΥΣΤ|Ν|ΝΙΤ|ΞΙΚ|ΟΠΤ|ΠΑΝ|ΠΕΤΣ|ΠΙΚΑΝΤ|ΠΙΤΣ|ΠΛΑΣΤ|ΠΛΙΑΤΣ|ΠΟΝΤ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΗΜΑΝΤ|ΣΤΑΤ|ΣΥΝΑΔ|ΣΥΝΟΜΗΛ|ΤΕΛ|ΤΕΧΝ|ΤΡΟΠ|ΤΣΑΜ|ΥΠΟΔ|Φ|ΦΙΛΟΝ|ΦΥΛΟΔ|ΦΥΣ|ΧΑΣ)$/.test(o[1])||/(ΦΟΙΝ)$/.test(o[1]))&&(s+="ΙΚ")),"ΑΓΑΜΕ"===s&&(s="ΑΓΑΜ"),null!==(o=/^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΑΜΕ)$/.exec(s))&&(s=o[1],/^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|ΣΙΧ|Χ)$/.test(o[1])&&(s+="ΑΜ")),null!==(o=/^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/.exec(s))&&(s=o[1],/^(ΤΡ|ΤΣ)$/.test(o[1])&&(s+="ΑΓΑΝ")),null!==(o=/^(.+?)(ΑΝΕ)$/.exec(s))&&(s=o[1],(r(s)||/^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜΑΝ|ΟΥΛ|Π|ΠΕΛΕΚ|ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|ΛΟΥΘΗΡ|ΜΑΙΝΤ|ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|ΘΥΣ|ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/.test(o[1]))&&(s+="ΑΝ")),null!==(o=/^(.+?)(ΗΣΕΤΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΕΤΕ)$/.exec(s))&&(s=o[1],(r(s)||/(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/.test(o[1])||/^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/.test(o[1]))&&(s+="ΕΤ")),null!==(o=/^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/.exec(s))&&(s=o[1],/^ΑΡΧ$/.test(o[1])&&(s+="ΟΝΤ"),/ΚΡΕ$/.test(o[1])&&(s+="ΩΝΤ")),null!==(o=/^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/.exec(s))&&(s=o[1],/^ΟΝ$/.test(o[1])&&(s+="ΟΜΑΣΤ")),null!==(o=/^(.+?)(ΙΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/.test(o[1])&&(s+="ΙΕΣΤ")),null!==(o=/^(.+?)(ΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΠΡΟ|ΝΙΣ)$/.test(o[1])&&(s+="ΕΣΤ")),null!==(o=/^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/.exec(s))&&(s=o[1],(/(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/.test(o[1])||/^(ΔΙΑΘ|Θ|ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ)$/.test(o[1]))&&(s+="ΗΚ")),null!==(o=/^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ)$/.test(o[1])||/(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/.test(o[1]))&&(s+="ΟΥΣ")),null!==(o=/^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/.exec(s))&&(s=o[1],(/^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|ΠΡΟΣΩΠΟΠ|ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/.test(o[1])||/(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/.test(o[1])&&!/^(ΨΟΦ|ΝΑΥΛΟΧ)$/.test(o[1])||/(ΚΟΛΛ)$/.test(o[1]))&&(s+="ΑΓ")),null!==(o=/^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/.exec(s))&&(s=o[1],/^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ|Ι)$/.test(o[1])&&(s+="ΗΣ")),null!==(o=/^(.+?)(ΗΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|ΠΑΛΙΜΨ)$/.test(o[1])&&(s+="ΗΣΤ")),null!==(o=/^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/.exec(s))&&(s=o[1],/^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/.test(o[1])&&(s+="ΟΥΝ")),null!==(o=/^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/.exec(s))&&(s=o[1],/^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/.test(o[1])&&(s+="ΟΥΜ")),null!=(o=/^(.+?)(ΜΑΤΟΙ|ΜΑΤΟΥΣ|ΜΑΤΟ|ΜΑΤΑ|ΜΑΤΩΣ|ΜΑΤΩΝ|ΜΑΤΟΣ|ΜΑΤΕΣ|ΜΑΤΗ|ΜΑΤΗΣ|ΜΑΤΟΥ)$/.exec(s))&&(s=o[1]+"Μ",/^(ΓΡΑΜ)$/.test(o[1])?s+="Α":/^(ΓΕ|ΣΤΑ)$/.test(o[1])&&(s+="ΑΤ")),null!==(o=/^(.+?)(ΟΥΑ)$/.exec(s))&&(s=o[1]+"ΟΥ"),n.length===s.length&&null!==(o=/^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|ΙΟΜΟΥΝΑ|ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ||ΥΑ|ΥΣ|Ω|ΩΝ|ΟΙΣ)$/.exec(s))&&(s=o[1]),null!=(o=/^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/.exec(s))&&(/^(ΕΞ|ΕΣ|ΑΝ|ΚΑΤ|Κ|ΠΡ)$/.test(o[1])||(s=o[1]),/^(ΚΑ|Μ|ΕΛΕ|ΛΕ|ΔΕ)$/.test(o[1])&&(s+="ΥΤ")),s}var l={"ΦΑΓΙΑ":"ΦΑ","ΦΑΓΙΟΥ":"ΦΑ","ΦΑΓΙΩΝ":"ΦΑ","ΣΚΑΓΙΑ":"ΣΚΑ","ΣΚΑΓΙΟΥ":"ΣΚΑ","ΣΚΑΓΙΩΝ":"ΣΚΑ","ΣΟΓΙΟΥ":"ΣΟ","ΣΟΓΙΑ":"ΣΟ","ΣΟΓΙΩΝ":"ΣΟ","ΤΑΤΟΓΙΑ":"ΤΑΤΟ","ΤΑΤΟΓΙΟΥ":"ΤΑΤΟ","ΤΑΤΟΓΙΩΝ":"ΤΑΤΟ","ΚΡΕΑΣ":"ΚΡΕ","ΚΡΕΑΤΟΣ":"ΚΡΕ","ΚΡΕΑΤΑ":"ΚΡΕ","ΚΡΕΑΤΩΝ":"ΚΡΕ","ΠΕΡΑΣ":"ΠΕΡ","ΠΕΡΑΤΟΣ":"ΠΕΡ","ΠΕΡΑΤΑ":"ΠΕΡ","ΠΕΡΑΤΩΝ":"ΠΕΡ","ΤΕΡΑΣ":"ΤΕΡ","ΤΕΡΑΤΟΣ":"ΤΕΡ","ΤΕΡΑΤΑ":"ΤΕΡ","ΤΕΡΑΤΩΝ":"ΤΕΡ","ΦΩΣ":"ΦΩ","ΦΩΤΟΣ":"ΦΩ","ΦΩΤΑ":"ΦΩ","ΦΩΤΩΝ":"ΦΩ","ΚΑΘΕΣΤΩΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΟΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΑ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΩΝ":"ΚΑΘΕΣΤ","ΓΕΓΟΝΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΑ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΩΝ":"ΓΕΓΟΝ","ΕΥΑ":"ΕΥ"},i=["ΑΚΡΙΒΩΣ","ΑΛΑ","ΑΛΛΑ","ΑΛΛΙΩΣ","ΑΛΛΟΤΕ","ΑΜΑ","ΑΝΩ","ΑΝΑ","ΑΝΑΜΕΣΑ","ΑΝΑΜΕΤΑΞΥ","ΑΝΕΥ","ΑΝΤΙ","ΑΝΤΙΠΕΡΑ","ΑΝΤΙΟ","ΑΞΑΦΝΑ","ΑΠΟ","ΑΠΟΨΕ","ΑΡΑ","ΑΡΑΓΕ","ΑΥΡΙΟ","ΑΦΟΙ","ΑΦΟΥ","ΑΦΟΤΟΥ","ΒΡΕ","ΓΕΙΑ","ΓΙΑ","ΓΙΑΤΙ","ΓΡΑΜΜΑ","ΔΕΗ","ΔΕΝ","ΔΗΛΑΔΗ","ΔΙΧΩΣ","ΔΥΟ","ΕΑΝ","ΕΓΩ","ΕΔΩ","ΕΔΑ","ΕΙΘΕ","ΕΙΜΑΙ","ΕΙΜΑΣΤΕ","ΕΙΣΑΙ","ΕΙΣΑΣΤΕ","ΕΙΝΑΙ","ΕΙΣΤΕ","ΕΙΤΕ","ΕΚΕΙ","ΕΚΟ","ΕΛΑ","ΕΜΑΣ","ΕΜΕΙΣ","ΕΝΤΕΛΩΣ","ΕΝΤΟΣ","ΕΝΤΩΜΕΤΑΞΥ","ΕΝΩ","ΕΞΙ","ΕΞΙΣΟΥ","ΕΞΗΣ","ΕΞΩ","ΕΟΚ","ΕΠΑΝΩ","ΕΠΕΙΔΗ","ΕΠΕΙΤΑ","ΕΠΙ","ΕΠΙΣΗΣ","ΕΠΟΜΕΝΩΣ","ΕΠΤΑ","ΕΣΑΣ","ΕΣΕΙΣ","ΕΣΤΩ","ΕΣΥ","ΕΣΩ","ΕΤΣΙ","ΕΥΓΕ","ΕΦΕ","ΕΦΕΞΗΣ","ΕΧΤΕΣ","ΕΩΣ","ΗΔΗ","ΗΜΙ","ΗΠΑ","ΗΤΟΙ","ΘΕΣ","ΙΔΙΩΣ","ΙΔΗ","ΙΚΑ","ΙΣΩΣ","ΚΑΘΕ","ΚΑΘΕΤΙ","ΚΑΘΟΛΟΥ","ΚΑΘΩΣ","ΚΑΙ","ΚΑΝ","ΚΑΠΟΤΕ","ΚΑΠΟΥ","ΚΑΤΑ","ΚΑΤΙ","ΚΑΤΟΠΙΝ","ΚΑΤΩ","ΚΕΙ","ΚΙΧ","ΚΚΕ","ΚΟΛΑΝ","ΚΥΡΙΩΣ","ΚΩΣ","ΜΑΚΑΡΙ","ΜΑΛΙΣΤΑ","ΜΑΛΛΟΝ","ΜΑΙ","ΜΑΟ","ΜΑΟΥΣ","ΜΑΣ","ΜΕΘΑΥΡΙΟ","ΜΕΣ","ΜΕΣΑ","ΜΕΤΑ","ΜΕΤΑΞΥ","ΜΕΧΡΙ","ΜΗΔΕ","ΜΗΝ","ΜΗΠΩΣ","ΜΗΤΕ","ΜΙΑ","ΜΙΑΣ","ΜΙΣ","ΜΜΕ","ΜΟΛΟΝΟΤΙ","ΜΟΥ","ΜΠΑ","ΜΠΑΣ","ΜΠΟΥΦΑΝ","ΜΠΡΟΣ","ΝΑΙ","ΝΕΣ","ΝΤΑ","ΝΤΕ","ΞΑΝΑ","ΟΗΕ","ΟΚΤΩ","ΟΜΩΣ","ΟΝΕ","ΟΠΑ","ΟΠΟΥ","ΟΠΩΣ","ΟΣΟ","ΟΤΑΝ","ΟΤΕ","ΟΤΙ","ΟΥΤΕ","ΟΧΙ","ΠΑΛΙ","ΠΑΝ","ΠΑΝΟ","ΠΑΝΤΟΤΕ","ΠΑΝΤΟΥ","ΠΑΝΤΩΣ","ΠΑΝΩ","ΠΑΡΑ","ΠΕΡΑ","ΠΕΡΙ","ΠΕΡΙΠΟΥ","ΠΙΑ","ΠΙΟ","ΠΙΣΩ","ΠΛΑΙ","ΠΛΕΟΝ","ΠΛΗΝ","ΠΟΤΕ","ΠΟΥ","ΠΡΟ","ΠΡΟΣ","ΠΡΟΧΤΕΣ","ΠΡΟΧΘΕΣ","ΡΟΔΙ","ΠΩΣ","ΣΑΙ","ΣΑΣ","ΣΑΝ","ΣΕΙΣ","ΣΙΑ","ΣΚΙ","ΣΟΙ","ΣΟΥ","ΣΡΙ","ΣΥΝ","ΣΥΝΑΜΑ","ΣΧΕΔΟΝ","ΤΑΔΕ","ΤΑΞΙ","ΤΑΧΑ","ΤΕΙ","ΤΗΝ","ΤΗΣ","ΤΙΠΟΤΑ","ΤΙΠΟΤΕ","ΤΙΣ","ΤΟΝ","ΤΟΤΕ","ΤΟΥ","ΤΟΥΣ","ΤΣΑ","ΤΣΕ","ΤΣΙ","ΤΣΟΥ","ΤΩΝ","ΥΠΟ","ΥΠΟΨΗ","ΥΠΟΨΙΝ","ΥΣΤΕΡΑ","ΦΕΤΟΣ","ΦΙΣ","ΦΠΑ","ΧΑΦ","ΧΘΕΣ","ΧΤΕΣ","ΧΩΡΙΣ","ΩΣ","ΩΣΑΝ","ΩΣΟΤΟΥ","ΩΣΠΟΥ","ΩΣΤΕ","ΩΣΤΟΣΟ"],s=new RegExp("^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ]+$");return function(e){return"function"==typeof e.update?e.update(function(e){return n(e.toUpperCase()).toLowerCase()}):n(e.toUpperCase()).toLowerCase()}}(),e.Pipeline.registerFunction(e.el.stemmer,"stemmer-el"),e.el.stopWordFilter=e.generateStopWordFilter("αλλα αν αντι απο αυτα αυτεσ αυτη αυτο αυτοι αυτοσ αυτουσ αυτων για δε δεν εαν ειμαι ειμαστε ειναι εισαι ειστε εκεινα εκεινεσ εκεινη εκεινο εκεινοι εκεινοσ εκεινουσ εκεινων ενω επι η θα ισωσ κ και κατα κι μα με μετα μη μην να ο οι ομωσ οπωσ οσο οτι παρα ποια ποιεσ ποιο ποιοι ποιοσ ποιουσ ποιων που προσ πωσ σε στη στην στο στον τα την τησ το τον τοτε του των ωσ".split(" ")),e.Pipeline.registerFunction(e.el.stopWordFilter,"stopWordFilter-el"),e.el.normilizer=function(){var e={"Ά":"Α","ά":"α","Έ":"Ε","έ":"ε","Ή":"Η","ή":"η","Ί":"Ι","ί":"ι","Ό":"Ο","ο":"ο","Ύ":"Υ","ύ":"υ","Ώ":"Ω","ώ":"ω","Ϊ":"Ι","ϊ":"ι","Ϋ":"Υ","ϋ":"υ","ΐ":"ι","ΰ":"υ"};return function(t){if("function"==typeof t.update)return t.update(function(t){for(var r="",n=0;n=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.fi.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.fi.min.js deleted file mode 100644 index 29f5dfcea8f3..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.fi.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Finnish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.fr.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.fr.min.js deleted file mode 100644 index 68cd0094ae03..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.fr.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `French` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.he.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.he.min.js deleted file mode 100644 index b863d3eae0a3..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.he.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHebrewCharacters=function(){return e.word=e.word.replace("ך","כ"),e.word=e.word.replace("ם","מ"),e.word=e.word.replace("ן","נ"),e.word=e.word.replace("ף","פ"),e.word=e.word.replace("ץ","צ"),!1},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}}(),e.Pipeline.registerFunction(e.he.stemmer,"stemmer-he"),e.he.stopWordFilter=e.generateStopWordFilter("אבל או אולי אותו אותי אותך אותם אותן אותנו אז אחר אחרות אחרי אחריכן אחרים אחרת אי איזה איך אין איפה אל אלה אלו אם אנחנו אני אף אפשר את אתה אתכם אתכן אתם אתן באיזה באיזו בגלל בין בלבד בעבור בעזרת בכל בכן בלי במידה במקום שבו ברוב בשביל בשעה ש בתוך גם דרך הוא היא היה היי היכן היתה היתי הם הן הנה הסיבה שבגללה הרי ואילו ואת זאת זה זות יהיה יוכל יוכלו יותר מדי יכול יכולה יכולות יכולים יכל יכלה יכלו יש כאן כאשר כולם כולן כזה כי כיצד כך כל כלל כמו כן כפי כש לא לאו לאיזותך לאן לבין לה להיות להם להן לו לזה לזות לי לך לכם לכן למה למעלה למעלה מ למטה למטה מ למעט למקום שבו למרות לנו לעבר לעיכן לפיכך לפני מאד מאחורי מאיזו סיבה מאין מאיפה מבלי מבעד מדוע מה מהיכן מול מחוץ מי מידע מכאן מכל מכן מלבד מן מנין מסוגל מעט מעטים מעל מצד מקום בו מתחת מתי נגד נגר נו עד עז על עלי עליו עליה עליהם עליך עלינו עם עצמה עצמהם עצמהן עצמו עצמי עצמם עצמן עצמנו פה רק שוב של שלה שלהם שלהן שלו שלי שלך שלכה שלכם שלכן שלנו שם תהיה תחת".split(" ")),e.Pipeline.registerFunction(e.he.stopWordFilter,"stopWordFilter-he")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.hi.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.hi.min.js deleted file mode 100644 index 7dbc41402cf3..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.hi.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.hu.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.hu.min.js deleted file mode 100644 index ed9d909f7344..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.hu.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Hungarian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.hy.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.hy.min.js deleted file mode 100644 index b37f79298555..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.hy.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.it.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.it.min.js deleted file mode 100644 index 344b6a3c0cf8..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.it.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Italian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.ja.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.ja.min.js deleted file mode 100644 index 5f254ebe91fa..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.ja.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.no.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.no.min.js deleted file mode 100644 index 92bc7e4e8944..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.no.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Norwegian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.pt.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.pt.min.js deleted file mode 100644 index 6c16996d6509..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.pt.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Portuguese` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.ro.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.ro.min.js deleted file mode 100644 index 727714018182..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.ro.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Romanian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.ru.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.ru.min.js deleted file mode 100644 index 186cc485c238..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.ru.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Russian` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.sv.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.sv.min.js deleted file mode 100644 index 3e5eb6400026..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.sv.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Swedish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.ta.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.ta.min.js deleted file mode 100644 index a644bed22809..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.ta.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.te.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.te.min.js deleted file mode 100644 index 9fa7a93b9913..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.te.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.th.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.th.min.js deleted file mode 100644 index dee3aac6e5cb..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.th.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.tr.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.tr.min.js deleted file mode 100644 index 563f6ec1f525..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.tr.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * Lunr languages, `Turkish` language - * https://github.com/MihaiValentin/lunr-languages - * - * Copyright 2014, Mihai Valentin - * http://www.mozilla.org/MPL/ - */ -/*! - * based on - * Snowball JavaScript Library v0.3 - * http://code.google.com/p/urim/ - * http://snowball.tartarus.org/ - * - * Copyright 2010, Oleg Mazko - * http://www.mozilla.org/MPL/ - */ - -!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.vi.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.vi.min.js deleted file mode 100644 index 22aed28c49b8..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.vi.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/min/lunr.zh.min.js b/v0.58.0/assets/javascripts/lunr/min/lunr.zh.min.js deleted file mode 100644 index fda66e9c5725..000000000000 --- a/v0.58.0/assets/javascripts/lunr/min/lunr.zh.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/tinyseg.js b/v0.58.0/assets/javascripts/lunr/tinyseg.js deleted file mode 100644 index 167fa6dd69e0..000000000000 --- a/v0.58.0/assets/javascripts/lunr/tinyseg.js +++ /dev/null @@ -1,206 +0,0 @@ -/** - * export the module via AMD, CommonJS or as a browser global - * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js - */ -;(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(factory) - } else if (typeof exports === 'object') { - /** - * Node. Does not work with strict CommonJS, but - * only CommonJS-like environments that support module.exports, - * like Node. - */ - module.exports = factory() - } else { - // Browser globals (root is window) - factory()(root.lunr); - } -}(this, function () { - /** - * Just return a value to define the module export. - * This example returns an object, but the module - * can return a function as the exported value. - */ - - return function(lunr) { - // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript - // (c) 2008 Taku Kudo - // TinySegmenter is freely distributable under the terms of a new BSD licence. - // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt - - function TinySegmenter() { - var patterns = { - "[一二三四五六七八九十百千万億兆]":"M", - "[一-龠々〆ヵヶ]":"H", - "[ぁ-ん]":"I", - "[ァ-ヴーア-ン゙ー]":"K", - "[a-zA-Za-zA-Z]":"A", - "[0-90-9]":"N" - } - this.chartype_ = []; - for (var i in patterns) { - var regexp = new RegExp(i); - this.chartype_.push([regexp, patterns[i]]); - } - - this.BIAS__ = -332 - this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; - this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; - this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; - this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; - this.BP2__ = {"BO":60,"OO":-1762}; - this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; - this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; - this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; - this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; - this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; - this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; - this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; - this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; - this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; - this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; - this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; - this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; - this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; - this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; - this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; - this.TW1__ = {"につい":-4681,"東京都":2026}; - this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; - this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; - this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; - this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; - this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; - this.UC3__ = {"A":-1370,"I":2311}; - this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; - this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; - this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; - this.UP1__ = {"O":-214}; - this.UP2__ = {"B":69,"O":935}; - this.UP3__ = {"B":189}; - this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; - this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; - this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; - this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; - this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; - this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; - this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; - this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; - this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; - - return this; - } - TinySegmenter.prototype.ctype_ = function(str) { - for (var i in this.chartype_) { - if (str.match(this.chartype_[i][0])) { - return this.chartype_[i][1]; - } - } - return "O"; - } - - TinySegmenter.prototype.ts_ = function(v) { - if (v) { return v; } - return 0; - } - - TinySegmenter.prototype.segment = function(input) { - if (input == null || input == undefined || input == "") { - return []; - } - var result = []; - var seg = ["B3","B2","B1"]; - var ctype = ["O","O","O"]; - var o = input.split(""); - for (i = 0; i < o.length; ++i) { - seg.push(o[i]); - ctype.push(this.ctype_(o[i])) - } - seg.push("E1"); - seg.push("E2"); - seg.push("E3"); - ctype.push("O"); - ctype.push("O"); - ctype.push("O"); - var word = seg[3]; - var p1 = "U"; - var p2 = "U"; - var p3 = "U"; - for (var i = 4; i < seg.length - 3; ++i) { - var score = this.BIAS__; - var w1 = seg[i-3]; - var w2 = seg[i-2]; - var w3 = seg[i-1]; - var w4 = seg[i]; - var w5 = seg[i+1]; - var w6 = seg[i+2]; - var c1 = ctype[i-3]; - var c2 = ctype[i-2]; - var c3 = ctype[i-1]; - var c4 = ctype[i]; - var c5 = ctype[i+1]; - var c6 = ctype[i+2]; - score += this.ts_(this.UP1__[p1]); - score += this.ts_(this.UP2__[p2]); - score += this.ts_(this.UP3__[p3]); - score += this.ts_(this.BP1__[p1 + p2]); - score += this.ts_(this.BP2__[p2 + p3]); - score += this.ts_(this.UW1__[w1]); - score += this.ts_(this.UW2__[w2]); - score += this.ts_(this.UW3__[w3]); - score += this.ts_(this.UW4__[w4]); - score += this.ts_(this.UW5__[w5]); - score += this.ts_(this.UW6__[w6]); - score += this.ts_(this.BW1__[w2 + w3]); - score += this.ts_(this.BW2__[w3 + w4]); - score += this.ts_(this.BW3__[w4 + w5]); - score += this.ts_(this.TW1__[w1 + w2 + w3]); - score += this.ts_(this.TW2__[w2 + w3 + w4]); - score += this.ts_(this.TW3__[w3 + w4 + w5]); - score += this.ts_(this.TW4__[w4 + w5 + w6]); - score += this.ts_(this.UC1__[c1]); - score += this.ts_(this.UC2__[c2]); - score += this.ts_(this.UC3__[c3]); - score += this.ts_(this.UC4__[c4]); - score += this.ts_(this.UC5__[c5]); - score += this.ts_(this.UC6__[c6]); - score += this.ts_(this.BC1__[c2 + c3]); - score += this.ts_(this.BC2__[c3 + c4]); - score += this.ts_(this.BC3__[c4 + c5]); - score += this.ts_(this.TC1__[c1 + c2 + c3]); - score += this.ts_(this.TC2__[c2 + c3 + c4]); - score += this.ts_(this.TC3__[c3 + c4 + c5]); - score += this.ts_(this.TC4__[c4 + c5 + c6]); - // score += this.ts_(this.TC5__[c4 + c5 + c6]); - score += this.ts_(this.UQ1__[p1 + c1]); - score += this.ts_(this.UQ2__[p2 + c2]); - score += this.ts_(this.UQ3__[p3 + c3]); - score += this.ts_(this.BQ1__[p2 + c2 + c3]); - score += this.ts_(this.BQ2__[p2 + c3 + c4]); - score += this.ts_(this.BQ3__[p3 + c2 + c3]); - score += this.ts_(this.BQ4__[p3 + c3 + c4]); - score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); - score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); - score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); - score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); - var p = "O"; - if (score > 0) { - result.push(word); - word = ""; - p = "B"; - } - p1 = p2; - p2 = p3; - p3 = p; - word += seg[i]; - } - result.push(word); - - return result; - } - - lunr.TinySegmenter = TinySegmenter; - }; - -})); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/lunr/wordcut.js b/v0.58.0/assets/javascripts/lunr/wordcut.js deleted file mode 100644 index 0d898c9ed144..000000000000 --- a/v0.58.0/assets/javascripts/lunr/wordcut.js +++ /dev/null @@ -1,6708 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; - }) - this.addWords(words, false) - } - if(finalize){ - this.finalizeDict(); - } - }, - - dictSeek: function (l, r, ch, strOffset, pos) { - var ans = null; - while (l <= r) { - var m = Math.floor((l + r) / 2), - dict_item = this.dict[m], - len = dict_item.length; - if (len <= strOffset) { - l = m + 1; - } else { - var ch_ = dict_item[strOffset]; - if (ch_ < ch) { - l = m + 1; - } else if (ch_ > ch) { - r = m - 1; - } else { - ans = m; - if (pos == LEFT) { - r = m - 1; - } else { - l = m + 1; - } - } - } - } - return ans; - }, - - isFinal: function (acceptor) { - return this.dict[acceptor.l].length == acceptor.strOffset; - }, - - createAcceptor: function () { - return { - l: 0, - r: this.dict.length - 1, - strOffset: 0, - isFinal: false, - dict: this, - transit: function (ch) { - return this.dict.transit(this, ch); - }, - isError: false, - tag: "DICT", - w: 1, - type: "DICT" - }; - }, - - transit: function (acceptor, ch) { - var l = this.dictSeek(acceptor.l, - acceptor.r, - ch, - acceptor.strOffset, - LEFT); - if (l !== null) { - var r = this.dictSeek(l, - acceptor.r, - ch, - acceptor.strOffset, - RIGHT); - acceptor.l = l; - acceptor.r = r; - acceptor.strOffset++; - acceptor.isFinal = this.isFinal(acceptor); - } else { - acceptor.isError = true; - } - return acceptor; - }, - - sortuniq: function(a){ - return a.sort().filter(function(item, pos, arr){ - return !pos || item != arr[pos - 1]; - }) - }, - - flatten: function(a){ - //[[1,2],[3]] -> [1,2,3] - return [].concat.apply([], a); - } -}; -module.exports = WordcutDict; - -}).call(this,"/dist/tmp") -},{"glob":16,"path":22}],3:[function(require,module,exports){ -var WordRule = { - createAcceptor: function(tag) { - if (tag["WORD_RULE"]) - return null; - - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - var lch = ch.toLowerCase(); - if (lch >= "a" && lch <= "z") { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "WORD_RULE", - type: "WORD_RULE", - w: 1}; - } -}; - -var NumberRule = { - createAcceptor: function(tag) { - if (tag["NUMBER_RULE"]) - return null; - - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (ch >= "0" && ch <= "9") { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "NUMBER_RULE", - type: "NUMBER_RULE", - w: 1}; - } -}; - -var SpaceRule = { - tag: "SPACE_RULE", - createAcceptor: function(tag) { - - if (tag["SPACE_RULE"]) - return null; - - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || - ch == "\u00A0" || ch=="\u2003"//nbsp and emsp - ) { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: SpaceRule.tag, - w: 1, - type: "SPACE_RULE"}; - } -} - -var SingleSymbolRule = { - tag: "SINSYM", - createAcceptor: function(tag) { - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { - this.isFinal = true; - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "SINSYM", - w: 1, - type: "SINSYM"}; - } -} - - -var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; - -module.exports = LatinRules; - -},{}],4:[function(require,module,exports){ -var _ = require("underscore") - , WordcutCore = require("./wordcut_core"); -var PathInfoBuilder = { - - /* - buildByPartAcceptors: function(path, acceptors, i) { - var - var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { - - }, []); - - return genInfos; - } - */ - - buildByAcceptors: function(path, finalAcceptors, i) { - var self = this; - var infos = finalAcceptors.map(function(acceptor) { - var p = i - acceptor.strOffset + 1 - , _info = path[p]; - - var info = {p: p, - mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), - w: acceptor.w + _info.w, - unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, - type: acceptor.type}; - - if (acceptor.type == "PART") { - for(var j = p + 1; j <= i; j++) { - path[j].merge = p; - } - info.merge = p; - } - - return info; - }); - return infos.filter(function(info) { return info; }); - }, - - fallback: function(path, leftBoundary, text, i) { - var _info = path[leftBoundary]; - if (text[i].match(/[\u0E48-\u0E4E]/)) { - if (leftBoundary != 0) - leftBoundary = path[leftBoundary].p; - return {p: leftBoundary, - mw: 0, - w: 1 + _info.w, - unk: 1 + _info.unk, - type: "UNK"}; -/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { - leftBoundary = path[leftBoundary].p; - return {p: leftBoundary, - w: 1 + _info.w, - unk: 1 + _info.unk, - type: "UNK"}; */ - } else { - return {p: leftBoundary, - mw: _info.mw, - w: 1 + _info.w, - unk: 1 + _info.unk, - type: "UNK"}; - } - }, - - build: function(path, finalAcceptors, i, leftBoundary, text) { - var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); - if (basicPathInfos.length > 0) { - return basicPathInfos; - } else { - return [this.fallback(path, leftBoundary, text, i)]; - } - } -}; - -module.exports = function() { - return _.clone(PathInfoBuilder); -} - -},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ -var _ = require("underscore"); - - -var PathSelector = { - selectPath: function(paths) { - var path = paths.reduce(function(selectedPath, path) { - if (selectedPath == null) { - return path; - } else { - if (path.unk < selectedPath.unk) - return path; - if (path.unk == selectedPath.unk) { - if (path.mw < selectedPath.mw) - return path - if (path.mw == selectedPath.mw) { - if (path.w < selectedPath.w) - return path; - } - } - return selectedPath; - } - }, null); - return path; - }, - - createPath: function() { - return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; - } -}; - -module.exports = function() { - return _.clone(PathSelector); -}; - -},{"underscore":25}],6:[function(require,module,exports){ -function isMatch(pat, offset, ch) { - if (pat.length <= offset) - return false; - var _ch = pat[offset]; - return _ch == ch || - (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || - (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || - (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); -} - -var Rule0 = { - pat: "เหก็ม", - createAcceptor: function(tag) { - return {strOffset: 0, - isFinal: false, - transit: function(ch) { - if (isMatch(Rule0.pat, this.strOffset,ch)) { - this.isFinal = (this.strOffset + 1 == Rule0.pat.length); - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "THAI_RULE", - type: "THAI_RULE", - w: 1}; - } -}; - -var PartRule = { - createAcceptor: function(tag) { - return {strOffset: 0, - patterns: [ - "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" - ], - isFinal: false, - transit: function(ch) { - var offset = this.strOffset; - this.patterns = this.patterns.filter(function(pat) { - return isMatch(pat, offset, ch); - }); - - if (this.patterns.length > 0) { - var len = 1 + offset; - this.isFinal = this.patterns.some(function(pat) { - return pat.length == len; - }); - this.strOffset++; - } else { - this.isError = true; - } - return this; - }, - isError: false, - tag: "PART", - type: "PART", - unk: 1, - w: 1}; - } -}; - -var ThaiRules = [Rule0, PartRule]; - -module.exports = ThaiRules; - -},{}],7:[function(require,module,exports){ -var sys = require("sys") - , WordcutDict = require("./dict") - , WordcutCore = require("./wordcut_core") - , PathInfoBuilder = require("./path_info_builder") - , PathSelector = require("./path_selector") - , Acceptors = require("./acceptors") - , latinRules = require("./latin_rules") - , thaiRules = require("./thai_rules") - , _ = require("underscore"); - - -var Wordcut = Object.create(WordcutCore); -Wordcut.defaultPathInfoBuilder = PathInfoBuilder; -Wordcut.defaultPathSelector = PathSelector; -Wordcut.defaultAcceptors = Acceptors; -Wordcut.defaultLatinRules = latinRules; -Wordcut.defaultThaiRules = thaiRules; -Wordcut.defaultDict = WordcutDict; - - -Wordcut.initNoDict = function(dict_path) { - var self = this; - self.pathInfoBuilder = new self.defaultPathInfoBuilder; - self.pathSelector = new self.defaultPathSelector; - self.acceptors = new self.defaultAcceptors; - self.defaultLatinRules.forEach(function(rule) { - self.acceptors.creators.push(rule); - }); - self.defaultThaiRules.forEach(function(rule) { - self.acceptors.creators.push(rule); - }); -}; - -Wordcut.init = function(dict_path, withDefault, additionalWords) { - withDefault = withDefault || false; - this.initNoDict(); - var dict = _.clone(this.defaultDict); - dict.init(dict_path, withDefault, additionalWords); - this.acceptors.creators.push(dict); -}; - -module.exports = Wordcut; - -},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ -var WordcutCore = { - - buildPath: function(text) { - var self = this - , path = self.pathSelector.createPath() - , leftBoundary = 0; - self.acceptors.reset(); - for (var i = 0; i < text.length; i++) { - var ch = text[i]; - self.acceptors.transit(ch); - - var possiblePathInfos = self - .pathInfoBuilder - .build(path, - self.acceptors.getFinalAcceptors(), - i, - leftBoundary, - text); - var selectedPath = self.pathSelector.selectPath(possiblePathInfos) - - path.push(selectedPath); - if (selectedPath.type !== "UNK") { - leftBoundary = i; - } - } - return path; - }, - - pathToRanges: function(path) { - var e = path.length - 1 - , ranges = []; - - while (e > 0) { - var info = path[e] - , s = info.p; - - if (info.merge !== undefined && ranges.length > 0) { - var r = ranges[ranges.length - 1]; - r.s = info.merge; - s = r.s; - } else { - ranges.push({s:s, e:e}); - } - e = s; - } - return ranges.reverse(); - }, - - rangesToText: function(text, ranges, delimiter) { - return ranges.map(function(r) { - return text.substring(r.s, r.e); - }).join(delimiter); - }, - - cut: function(text, delimiter) { - var path = this.buildPath(text) - , ranges = this.pathToRanges(path); - return this - .rangesToText(text, ranges, - (delimiter === undefined ? "|" : delimiter)); - }, - - cutIntoRanges: function(text, noText) { - var path = this.buildPath(text) - , ranges = this.pathToRanges(path); - - if (!noText) { - ranges.forEach(function(r) { - r.text = text.substring(r.s, r.e); - }); - } - return ranges; - }, - - cutIntoArray: function(text) { - var path = this.buildPath(text) - , ranges = this.pathToRanges(path); - - return ranges.map(function(r) { - return text.substring(r.s, r.e) - }); - } -}; - -module.exports = WordcutCore; - -},{}],9:[function(require,module,exports){ -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -// when used in node, this will actually load the util module we depend on -// versus loading the builtin util module as happens otherwise -// this is a bug in node module loading as far as I am concerned -var util = require('util/'); - -var pSlice = Array.prototype.slice; -var hasOwn = Object.prototype.hasOwnProperty; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } - else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = stackStartFunction.name; - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function replacer(key, value) { - if (util.isUndefined(value)) { - return '' + value; - } - if (util.isNumber(value) && !isFinite(value)) { - return value.toString(); - } - if (util.isFunction(value) || util.isRegExp(value)) { - return value.toString(); - } - return value; -} - -function truncate(s, n) { - if (util.isString(s)) { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} - -function getMessage(self) { - return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + - self.operator + ' ' + - truncate(JSON.stringify(self.expected, replacer), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (util.isBuffer(actual) && util.isBuffer(expected)) { - if (actual.length != expected.length) return false; - - for (var i = 0; i < actual.length; i++) { - if (actual[i] !== expected[i]) return false; - } - - return true; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!util.isObject(actual) && !util.isObject(expected)) { - return actual == expected; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b) { - if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) { - return a === b; - } - var aIsArgs = isArguments(a), - bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - var ka = objectKeys(a), - kb = objectKeys(b), - key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key])) return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } else if (actual instanceof expected) { - return true; - } else if (expected.call({}, actual) === true) { - return true; - } - - return false; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (util.isString(expected)) { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - if (!shouldThrow && expectedException(actual, expected)) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function(err) { if (err) {throw err;}}; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -},{"util/":28}],10:[function(require,module,exports){ -'use strict'; -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} - -},{}],11:[function(require,module,exports){ -var concatMap = require('concat-map'); -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - - -},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ - -},{}],13:[function(require,module,exports){ -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -},{}],14:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); - } - } - - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} - -},{}],15:[function(require,module,exports){ -(function (process){ -exports.alphasort = alphasort -exports.alphasorti = alphasorti -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") -var Minimatch = minimatch.Minimatch - -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) -} - -function alphasort (a, b) { - return a.localeCompare(b) -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern) - } - - return { - matcher: new Minimatch(pattern), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = options.cwd - self.changedCwd = path.resolve(options.cwd) !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - self.nomount = !!options.nomount - - // disable comments and negation unless the user explicitly - // passes in false as the option. - options.nonegate = options.nonegate === false ? false : true - options.nocomment = options.nocomment === false ? false : true - deprecationWarning(options) - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -// TODO(isaacs): remove entirely in v6 -// exported to reset in tests -exports.deprecationWarned -function deprecationWarning(options) { - if (!options.nonegate || !options.nocomment) { - if (process.noDeprecation !== true && !exports.deprecationWarned) { - var msg = 'glob WARNING: comments and negation will be disabled in v6' - if (process.throwDeprecation) - throw new Error(msg) - else if (process.traceDeprecation) - console.trace(msg) - else - console.error(msg) - - exports.deprecationWarned = true - } - } -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - return !(/\/$/.test(e)) - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -}).call(this,require('_process')) -},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ -(function (process){ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var fs = require('fs') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var globSync = require('./sync.js') -var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -glob.hasMagic = function (pattern, options_) { - var options = util._extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - var n = this.minimatch.set.length - this._processing = 0 - this.matches = new Array(n) - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - - function done () { - --self._processing - if (self._processing <= 0) - self._finish() - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - fs.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (this.matches[index][e]) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = this._makeAbs(e) - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - if (this.mark) - e = this._mark(e) - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er) - return cb() - - var isSym = lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - this.cache[this._makeAbs(f)] = 'FILE' - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && !stat.isDirectory()) - return cb(null, false, stat) - - var c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c !== 'DIR') - return cb() - - return cb(null, c, stat) -} - -}).call(this,require('_process')) -},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ -(function (process){ -module.exports = globSync -globSync.GlobSync = GlobSync - -var fs = require('fs') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = fs.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this.matches[index][e] = true - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - var abs = this._makeAbs(e) - if (this.mark) - e = this._mark(e) - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[this._makeAbs(e)] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - // lstat failed, doesn't exist - return null - } - - var isSym = lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - this.cache[this._makeAbs(f)] = 'FILE' - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this.matches[index][prefix] = true -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - return false - } - - if (lstat.isSymbolicLink()) { - try { - stat = fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c !== 'DIR') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -}).call(this,require('_process')) -},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ -(function (process){ -var wrappy = require('wrappy') -var reqs = Object.create(null) -var once = require('once') - -module.exports = wrappy(inflight) - -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) - } -} - -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) - - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] - } - } - }) -} - -function slice (args) { - var length = args.length - var array = [] - - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} - -}).call(this,require('_process')) -},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - -},{}],20:[function(require,module,exports){ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = { sep: '/' } -try { - path = require('path') -} catch (er) {} - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - // "" only matches "" - if (pattern.trim() === '') return p === '' - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd - } - - // should be unreachable. - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} - -},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ -var wrappy = require('wrappy') -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) - -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) - -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f -} - -},{"wrappy":29}],22:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":24}],23:[function(require,module,exports){ -(function (process){ -'use strict'; - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; - -}).call(this,require('_process')) -},{"_process":24}],24:[function(require,module,exports){ -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],25:[function(require,module,exports){ -// Underscore.js 1.8.3 -// http://underscorejs.org -// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `exports` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var - push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind, - nativeCreate = Object.create; - - // Naked function reference for surrogate-prototype-swapping. - var Ctor = function(){}; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.8.3'; - - // Internal function that returns an efficient (for current engines) version - // of the passed-in callback, to be repeatedly applied in other Underscore - // functions. - var optimizeCb = function(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - case 2: return function(value, other) { - return func.call(context, value, other); - }; - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; - }; - - // A mostly-internal function to generate callbacks that can be applied - // to each element in a collection, returning the desired result — either - // identity, an arbitrary callback, a property matcher, or a property accessor. - var cb = function(value, context, argCount) { - if (value == null) return _.identity; - if (_.isFunction(value)) return optimizeCb(value, context, argCount); - if (_.isObject(value)) return _.matcher(value); - return _.property(value); - }; - _.iteratee = function(value, context) { - return cb(value, context, Infinity); - }; - - // An internal function for creating assigner functions. - var createAssigner = function(keysFunc, undefinedOnly) { - return function(obj) { - var length = arguments.length; - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; - } - } - return obj; - }; - }; - - // An internal function for creating a new object that inherits from another. - var baseCreate = function(prototype) { - if (!_.isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; - }; - - var property = function(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; - }; - - // Helper for collection methods to determine whether a collection - // should be iterated as an array or as an object - // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength - // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 - var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - var getLength = property('length'); - var isArrayLike = function(collection) { - var length = getLength(collection); - return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; - }; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles raw objects in addition to array-likes. Treats all - // sparse array-likes as if they were dense. - _.each = _.forEach = function(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var keys = _.keys(obj); - for (i = 0, length = keys.length; i < length; i++) { - iteratee(obj[keys[i]], keys[i], obj); - } - } - return obj; - }; - - // Return the results of applying the iteratee to each element. - _.map = _.collect = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Create a reducing function iterating left or right. - function createReduce(dir) { - // Optimized iterator function as using arguments.length - // in the main function will deoptimize the, see #1991. - function iterator(obj, iteratee, memo, keys, index, length) { - for (; index >= 0 && index < length; index += dir) { - var currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - } - - return function(obj, iteratee, memo, context) { - iteratee = optimizeCb(iteratee, context, 4); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length, - index = dir > 0 ? 0 : length - 1; - // Determine the initial value if none is provided. - if (arguments.length < 3) { - memo = obj[keys ? keys[index] : index]; - index += dir; - } - return iterator(obj, iteratee, memo, keys, index, length); - }; - } - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. - _.reduce = _.foldl = _.inject = createReduce(1); - - // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = createReduce(-1); - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, predicate, context) { - var key; - if (isArrayLike(obj)) { - key = _.findIndex(obj, predicate, context); - } else { - key = _.findKey(obj, predicate, context); - } - if (key !== void 0 && key !== -1) return obj[key]; - }; - - // Return all the elements that pass a truth test. - // Aliased as `select`. - _.filter = _.select = function(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - _.each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(cb(predicate)), context); - }; - - // Determine whether all of the elements match a truth test. - // Aliased as `all`. - _.every = _.all = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; - }; - - // Determine if at least one element in the object matches a truth test. - // Aliased as `any`. - _.some = _.any = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = !isArrayLike(obj) && _.keys(obj), - length = (keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = keys ? keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; - }; - - // Determine if the array or object contains a given item (using `===`). - // Aliased as `includes` and `include`. - _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return _.indexOf(obj, item, fromIndex) >= 0; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - var func = isFunc ? method : value[method]; - return func == null ? func : func.apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, _.property(key)); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs) { - return _.filter(obj, _.matcher(attrs)); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.find(obj, _.matcher(attrs)); - }; - - // Return the maximum element (or element-based computation). - _.max = function(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { - result = value; - lastComputed = computed; - } - }); - } - return result; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = isArrayLike(obj) ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed < lastComputed || computed === Infinity && result === Infinity) { - result = value; - lastComputed = computed; - } - }); - } - return result; - }; - - // Shuffle a collection, using the modern version of the - // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). - _.shuffle = function(obj) { - var set = isArrayLike(obj) ? obj : _.values(obj); - var length = set.length; - var shuffled = Array(length); - for (var index = 0, rand; index < length; index++) { - rand = _.random(0, index); - if (rand !== index) shuffled[index] = shuffled[rand]; - shuffled[rand] = set[index]; - } - return shuffled; - }; - - // Sample **n** random values from a collection. - // If **n** is not specified, returns a single random element. - // The internal `guard` argument allows it to work with `map`. - _.sample = function(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = _.values(obj); - return obj[_.random(obj.length - 1)]; - } - return _.shuffle(obj).slice(0, Math.max(0, n)); - }; - - // Sort the object's values by a criterion produced by an iteratee. - _.sortBy = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value: value, - index: index, - criteria: iteratee(value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(behavior) { - return function(obj, iteratee, context) { - var result = {}; - iteratee = cb(iteratee, context); - _.each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = group(function(result, value, key) { - if (_.has(result, key)) result[key].push(value); else result[key] = [value]; - }); - - // Indexes the object's values by a criterion, similar to `groupBy`, but for - // when you know that your index values will be unique. - _.indexBy = group(function(result, value, key) { - result[key] = value; - }); - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = group(function(result, value, key) { - if (_.has(result, key)) result[key]++; else result[key] = 1; - }); - - // Safely create a real, live array from anything iterable. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (isArrayLike(obj)) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : _.keys(obj).length; - }; - - // Split a collection into two arrays: one whose elements all satisfy the given - // predicate, and one whose elements all do not satisfy the predicate. - _.partition = function(obj, predicate, context) { - predicate = cb(predicate, context); - var pass = [], fail = []; - _.each(obj, function(value, key, obj) { - (predicate(value, key, obj) ? pass : fail).push(value); - }); - return [pass, fail]; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - if (n == null || guard) return array[0]; - return _.initial(array, array.length - n); - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. - _.initial = function(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if (n == null || guard) return array[array.length - 1]; - return _.rest(array, Math.max(0, array.length - n)); - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, startIndex) { - var output = [], idx = 0; - for (var i = startIndex || 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { - //flatten current level of array or arguments object - if (!shallow) value = flatten(value, shallow, strict); - var j = 0, len = value.length; - output.length += len; - while (j < len) { - output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; - } - } - return output; - }; - - // Flatten out an array, either recursively (by default), or just one level. - _.flatten = function(array, shallow) { - return flatten(array, shallow, false); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iteratee, context) { - if (!_.isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!_.contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!_.contains(result, value)) { - result.push(value); - } - } - return result; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(flatten(arguments, true, true)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (_.contains(result, item)) continue; - for (var j = 1; j < argsLength; j++) { - if (!_.contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = flatten(arguments, true, true, 1); - return _.filter(array, function(value){ - return !_.contains(rest, value); - }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - return _.unzip(arguments); - }; - - // Complement of _.zip. Unzip accepts an array of arrays and groups - // each array's elements on shared indices - _.unzip = function(array) { - var length = array && _.max(array, getLength).length || 0; - var result = Array(length); - - for (var index = 0; index < length; index++) { - result[index] = _.pluck(array, index); - } - return result; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // Generator function to create the findIndex and findLastIndex functions - function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; - }; - } - - // Returns the first index on an array-like that passes a predicate test - _.findIndex = createPredicateIndexFinder(1); - _.findLastIndex = createPredicateIndexFinder(-1); - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - - // Generator function to create the indexOf and lastIndexOf functions - function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; - } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), _.isNaN); - return idx >= 0 ? idx + i : -1; - } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; - } - return -1; - }; - } - - // Return the position of the first occurrence of an item in an array, - // or -1 if the item is not included in the array. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); - _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - step = step || 1; - - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); - - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Determines whether to execute a function as a constructor - // or a normal function with the provided arguments - var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (_.isObject(result)) return result; - return self; - }; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - var args = slice.call(arguments, 2); - var bound = function() { - return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); - }; - return bound; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. _ acts - // as a placeholder, allowing any combination of arguments to be pre-filled. - _.partial = function(func) { - var boundArgs = slice.call(arguments, 1); - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; - }; - - // Bind a number of an object's methods to that object. Remaining arguments - // are the method names to be bound. Useful for ensuring that all callbacks - // defined on an object belong to it. - _.bindAll = function(obj) { - var i, length = arguments.length, key; - if (length <= 1) throw new Error('bindAll must be passed function names'); - for (i = 1; i < length; i++) { - key = arguments[i]; - obj[key] = _.bind(obj[key], obj); - } - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ - return func.apply(null, args); - }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = _.partial(_.delay, _, 1); - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. Normally, the throttled function will run - // as much as it can, without ever going more than once per `wait` duration; - // but if you'd like to disable the execution on the leading edge, pass - // `{leading: false}`. To disable execution on the trailing edge, ditto. - _.throttle = function(func, wait, options) { - var context, args, result; - var timeout = null; - var previous = 0; - if (!options) options = {}; - var later = function() { - previous = options.leading === false ? 0 : _.now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - return function() { - var now = _.now(); - if (!previous && options.leading === false) previous = now; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, args, context, timestamp, result; - - var later = function() { - var last = _.now() - timestamp; - - if (last < wait && last >= 0) { - timeout = setTimeout(later, wait - last); - } else { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - if (!timeout) context = args = null; - } - } - }; - - return function() { - context = this; - args = arguments; - timestamp = _.now(); - var callNow = immediate && !timeout; - if (!timeout) timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - context = args = null; - } - - return result; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return _.partial(wrapper, func); - }; - - // Returns a negated version of the passed-in predicate. - _.negate = function(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; - }; - - // Returns a function that will only be executed on and after the Nth call. - _.after = function(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Returns a function that will only be executed up to (but not including) the Nth call. - _.before = function(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); - } - if (times <= 1) func = null; - return memo; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = _.partial(_.before, 2); - - // Object Functions - // ---------------- - - // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. - var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); - var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - - function collectNonEnumProps(obj, keys) { - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; - - // Constructor is a special case. - var prop = 'constructor'; - if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); - - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { - keys.push(prop); - } - } - } - - // Retrieve the names of an object's own properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve all the property names of an object. - _.allKeys = function(obj) { - if (!_.isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - }; - - // Returns the results of applying the iteratee to each element of the object - // In contrast to _.map it returns an object - _.mapObject = function(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var keys = _.keys(obj), - length = keys.length, - results = {}, - currentKey; - for (var index = 0; index < length; index++) { - currentKey = keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [keys[i], obj[keys[i]]]; - } - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - result[obj[keys[i]]] = keys[i]; - } - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = createAssigner(_.allKeys); - - // Assigns a given object with all the own properties in the passed-in object(s) - // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) - _.extendOwn = _.assign = createAssigner(_.keys); - - // Returns the first key on an object that passes a predicate test - _.findKey = function(obj, predicate, context) { - predicate = cb(predicate, context); - var keys = _.keys(obj), key; - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (predicate(obj[key], key, obj)) return key; - } - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(object, oiteratee, context) { - var result = {}, obj = object, iteratee, keys; - if (obj == null) return result; - if (_.isFunction(oiteratee)) { - keys = _.allKeys(obj); - iteratee = optimizeCb(oiteratee, context); - } else { - keys = flatten(arguments, false, false, 1); - iteratee = function(value, key, obj) { return key in obj; }; - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj, iteratee, context) { - if (_.isFunction(iteratee)) { - iteratee = _.negate(iteratee); - } else { - var keys = _.map(flatten(arguments, false, false, 1), String); - iteratee = function(value, key) { - return !_.contains(keys, key); - }; - } - return _.pick(obj, iteratee, context); - }; - - // Fill in a given object with default properties. - _.defaults = createAssigner(_.allKeys, true); - - // Creates an object that inherits from the given prototype object. - // If additional properties are provided then they will be added to the - // created object. - _.create = function(prototype, props) { - var result = baseCreate(prototype); - if (props) _.extendOwn(result, props); - return result; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Returns whether an object has a given set of `key:value` pairs. - _.isMatch = function(object, attrs) { - var keys = _.keys(attrs), length = keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; - }; - - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - } - - var areArrays = className === '[object Array]'; - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var keys = _.keys(a), key; - length = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (_.keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = keys[length]; - if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; - return _.keys(obj).length === 0; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) === '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) === '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE < 9), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return _.has(obj, 'callee'); - }; - } - - // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, - // IE 11 (#1621), and in Safari 8 (#1929). - if (typeof /./ != 'function' && typeof Int8Array != 'object') { - _.isFunction = function(obj) { - return typeof obj == 'function' || false; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj !== +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iteratees. - _.identity = function(value) { - return value; - }; - - // Predicate-generating functions. Often useful outside of Underscore. - _.constant = function(value) { - return function() { - return value; - }; - }; - - _.noop = function(){}; - - _.property = property; - - // Generates a function for a given object that returns a given property. - _.propertyOf = function(obj) { - return obj == null ? function(){} : function(key) { - return obj[key]; - }; - }; - - // Returns a predicate for checking whether an object has a given set of - // `key:value` pairs. - _.matcher = _.matches = function(attrs) { - attrs = _.extendOwn({}, attrs); - return function(obj) { - return _.isMatch(obj, attrs); - }; - }; - - // Run a function **n** times. - _.times = function(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // A (possibly faster) way to get the current timestamp as an integer. - _.now = Date.now || function() { - return new Date().getTime(); - }; - - // List of HTML entities for escaping. - var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - var unescapeMap = _.invert(escapeMap); - - // Functions for escaping and unescaping strings to/from HTML interpolation. - var createEscaper = function(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped - var source = '(?:' + _.keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; - }; - _.escape = createEscaper(escapeMap); - _.unescape = createEscaper(unescapeMap); - - // If the value of the named `property` is a function then invoke it with the - // `object` as context; otherwise, return it. - _.result = function(object, property, fallback) { - var value = object == null ? void 0 : object[property]; - if (value === void 0) { - value = fallback; - } - return _.isFunction(value) ? value.call(object) : value; - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\u2028|\u2029/g; - - var escapeChar = function(match) { - return '\\' + escapes[match]; - }; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - // NB: `oldSettings` only exists for backwards compatibility. - _.template = function(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escaper, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offest. - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - try { - var render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled source as a convenience for precompilation. - var argument = settings.variable || 'obj'; - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function. Start chaining a wrapped Underscore object. - _.chain = function(obj) { - var instance = _(obj); - instance._chain = true; - return instance; - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(instance, obj) { - return instance._chain ? _(obj).chain() : obj; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - _.each(_.functions(obj), function(name) { - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result(this, func.apply(_, args)); - }; - }); - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return result(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - _.each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result(this, method.apply(this._wrapped, arguments)); - }; - }); - - // Extracts the result from a wrapped and chained object. - _.prototype.value = function() { - return this._wrapped; - }; - - // Provide unwrapping proxy for some methods used in engine operations - // such as arithmetic and JSON stringification. - _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; - - _.prototype.toString = function() { - return '' + this._wrapped; - }; - - // AMD registration happens at the end for compatibility with AMD loaders - // that may not enforce next-turn semantics on modules. Even though general - // practice for AMD registration is to be anonymous, underscore registers - // as a named module because, like jQuery, it is a base library that is - // popular enough to be bundled in a third party lib, but not be part of - // an AMD load request. Those cases could generate an error when an - // anonymous define() is called outside of a loader request. - if (typeof define === 'function' && define.amd) { - define('underscore', [], function() { - return _; - }); - } -}.call(this)); - -},{}],26:[function(require,module,exports){ -arguments[4][19][0].apply(exports,arguments) -},{"dup":19}],27:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],28:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} - -},{}]},{},[7])(7) -}); \ No newline at end of file diff --git a/v0.58.0/assets/javascripts/trivy_v1_homepage.js b/v0.58.0/assets/javascripts/trivy_v1_homepage.js deleted file mode 100644 index 2fdfba9a8a00..000000000000 --- a/v0.58.0/assets/javascripts/trivy_v1_homepage.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0Previous',nextArrow:'',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i(' - - - -
    -
    -
    -
    - Initializing search -
    - -
    -
    -
    - - - - - - - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Aqua Security is the home of Trivy

    -

    Trivy is proudly maintained by Aqua Security. -If you liked Trivy, you will love Aqua which builds on top of Trivy to provide even more enhanced capabilities for a complete security management offering.
    -In this page you can find a high level comparison between Trivy Open Source and Aqua's commercial product. -If you'd like to learn more or request a demo, click here to contact us.

    -

    User experience

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    InterfaceCLI toolCLI tool
    Enterprise-grade web application
    SaaS or on-prem
    Search & Discover-Easily search for security issues across all workloads and infrastructure in your organization
    Visually discover risks across your organization
    User management-Multi account
    Granular permissions (RBAC)
    Single Sign On (SSO)
    SupportSome skills required for setup and integration
    Best effort community support
    Personal onboarding by Aqua Customer Success
    SLA backed professional support
    Scalability & AvailabilitySingle scan at a timeCentralized scanning service supports concurrent scans efficiently
    Highly available production grade architecture
    Rate limitingAssets hosted on public free infrastructure and could be rate limitedAssets hosted on Aqua infrastructure and does not have limitations
    -

    Vulnerability scanning

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Vulnerabilities sourcesBased on open source vulnerability feedsBased on open source and commercial vulnerability feeds
    New Vulnerabilities SLANo SLACommercial level SLA
    Package managersFind packages in lock filesFind packages in lock files or reconstructed lock files
    Vulnerability managementManually ignore specific vulnerabilities by ID or propertyAdvanced vulnerability management solution
    Vulnerability tracking and suppression
    Incident lifecycle management
    Vulnerability prioritizationManually triage by severityMultiple prioritization tools:
    Accessibility of the affected resources
    Exploitability of the vulnerability
    Open Source packages health and trustworthiness score
    Affected image layers
    Reachability analysis-Analyze source code to eliminate vulnerabilities of unused dependencies
    Contextual vulnerabilities-Reduce irrelevant vulnerabilities based on environmental factors (e.g. Spring4Shell not relevant due to JDK version)
    Compiled binariesFind embedded dependencies in Go and Rust binaries
    Find SBOM by hash in public Sigstore
    In addition, identify popular applications
    -

    Container scanning

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Windows containers-Support scanning windows containers
    Scan container registries-Connect to any container registries and automatically scan it
    Private registriesStandard registry authenticationCloud authentication with ECR, GCR, ACRSupports registry specific authentication schemes
    Layer cacheLocal cache directoryScalable Cloud cache
    -

    Advanced scanning

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Malware scanning-Scan container images for malware
    Sandbox scanning-Use DTA (Dynamic threat analysis) to run and test container images' behavior to detect sophisticated threats
    SAST (code scanning)-Analyze source code for security issues and vulnerabilities
    -

    Policy and enforcement

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Kubernetes admission-Validating Kubernetes Admission based on automatic or user defined policy
    CI/CD policiesCan fail the entire build on any findingGranular policies to fail builds based on custom criteria
    Container engine-Block incompliant images from running at container engine level
    Block vulnerable packages-vShield – monitor and block usage of vulnerable packages
    -

    Secrets scanning

    - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Detected patternsBasic patternsAdvanced patterns
    Leaked secrets validation-Automatically checks if leaked secrets are valid and usable
    -

    IaC/CSPM scanning

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Infrastructure as Code (IaC)Many popular languages as detailed hereIn addition, Build Pipeline configuration scanning
    Checks customizationCreate custom checks with RegoCreate custom checks in no-code interface
    Customize existing checks with organizational preferences
    Cloud scanningAWS (subset of services)AWS, Azure, GCP, Alibaba Cloud, Oracle Cloud
    Compliance frameworksCIS, NSA, vendor guidesMore than 25 compliance programs
    Custom complianceCreate in YAMLCreate in a web UI
    Remediation adviceBasicAI powered specialized remediation guides
    -

    Kubernetes scanning

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FeatureTrivy OSSAqua
    Scan initiationCLI / Kubernetes OperatorKubernetes Operator / Management web application
    Results consumptionkubectl / CRD / Prometheus exporterIn addition, Advanced UI dashboards, Automatic notifications and incident management flows
    Cluster discoveryKubeconfigAutomatic discovery thorough cloud onboarding
    Workload image scanningScanning in cluster, requires capacity planningScanning offloaded to Aqua service, little impact on scanned clusters
    Cluster scanningCIS, NSA, PSSMore than 25 compliance programs
    ScopeSingle clusterMulti cluster, Cloud relationship
    ScalabilityReports limited by in-cluster etcd storage (size and number of reports)Cloud-based storage (unlimited scalability)
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/commercial/contact/index.html b/v0.58.0/commercial/contact/index.html deleted file mode 100644 index 6066d8822156..000000000000 --- a/v0.58.0/commercial/contact/index.html +++ /dev/null @@ -1,7738 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Contact Us - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Contact Us

    - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/contribute/checks/overview/index.html b/v0.58.0/community/contribute/checks/overview/index.html deleted file mode 100644 index 278bd25cb03d..000000000000 --- a/v0.58.0/community/contribute/checks/overview/index.html +++ /dev/null @@ -1,8167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Contribute Rego Checks

    -

    The following guide provides an overview of contributing checks to the default checks in Trivy.

    -

    All of the checks in Trivy can be found in the trivy-checks repository on GitHub. Before you begin writing a check, ensure:

    -
      -
    1. The check does not already exist as part of the default checks in the trivy-checks repository.
    2. -
    3. The pull requests in the trivy-checks repository to see whether someone else is already contributing the check that you wanted to add.
    4. -
    5. The issues in Trivy to see whether any specific checks are missing in Trivy that you can contribute.
    6. -
    -

    If anything is unclear, please start a discussion and we will do our best to help.

    -

    Check structure

    -

    Checks are written in Rego and follow a particular structure in Trivy. Below is an example check for AWS:

    -
    # METADATA
    -# title: "RDS IAM Database Authentication Disabled"
    -# description: "Ensure IAM Database Authentication is enabled for RDS database instances to manage database access"
    -# scope: package
    -# schemas:
    -# - input: schema["aws"]
    -# related_resources:
    -# - https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth.html
    -# custom:
    -#   id: AVD-AWS-0176
    -#   avd_id: AVD-AWS-0176
    -#   provider: aws
    -#   service: rds
    -#   severity: MEDIUM
    -#   short_code: enable-iam-auth
    -#   recommended_action: "Modify the PostgreSQL and MySQL type RDS instances to enable IAM database authentication."
    -#   input:
    -#     selector:
    -#     - type: cloud
    -#       subtypes:
    -#         - service: rds
    -#           provider: aws
    -
    -package builtin.aws.rds.aws0176
    -
    -deny[res] {
    -    instance := input.aws.rds.instances[_]
    -    instance.engine.value == ["postgres", "mysql"][_]
    -    not instance.iamauthenabled.value
    -    res := result.new("Instance does not have IAM Authentication enabled", instance.iamauthenabled)
    -}
    -
    -

    Verify the provider and service exists

    -

    Every check for a cloud service references a cloud provider. The list of providers are found in the Trivy repository.

    -

    Before writing a new check for a cloud provider, you need to verify if the cloud provider or resource type that your check targets is supported by Trivy. If it's not, you'll need to add support for it. Additionally, if the provider that you want to target exists, you need to check whether the service your policy will target is supported. As a reference you can take a look at the AWS provider here.

    -
    -Note -

    New Kubernetes and Dockerfile checks do not require any additional provider definitions. You can find an example of a Dockerfile check here and a Kubernetes check here.

    -
    -

    Add Support for a New Service in an existing Provider

    -

    Please reference the documentation on adding Support for a New Service.

    -

    This guide also showcases how to add new properties for an existing Service.

    -

    Create a new .rego file

    -

    The following directory in the trivy-checks repository contains all of our custom checks. Depending on what type of check you want to create, you will need to nest a new .rego file in either of the subdirectories:

    -
      -
    • cloud: All checks related to cloud providers and their services
    • -
    • docker: Docker specific checks
    • -
    • kubernetes: Kubernetes specific checks
    • -
    -

    Check Package name

    -

    Have a look at the existing package names in the built in checks.

    -

    The package name should be in the format builtin.PROVIDER.SERVICE.ID, e.g. builtin.aws.rds.aws0176.

    -

    Generating an ID

    -

    Every check has a custom ID that is referenced throughout the metadata of the check to uniquely identify the check. If you plan to contribue your check back into the trivy-checks repository, it will require a valid ID.

    -

    Running make id in the root of the trivy-checks repository will provide you with the next available ID for your rule.

    -

    Check Schemas

    -

    Rego Checks for Trivy can utilise Schemas to map the input to specific objects. The schemas available are listed here..

    -

    More information on using the builtin schemas is provided in the main documentation.

    -

    Check Metadata

    -

    The metadata is the top section that starts with # METADATA, and has to be placed on top of the check. You can copy and paste from another check as a starting point. This format is effectively yaml within a Rego comment, and is defined as part of Rego itself.

    -

    For detailed information on each component of the Check Metadata, please refer to the main documentation.

    -

    Note that while the Metadata is optional in your own custom checks for Trivy, if you are contributing your check to the Trivy builtin checks, the Metadata section will be required.

    -

    Writing Rego Rules

    -

    Rules are defined using OPA Rego. You can find a number of examples in the checks directory (Link). The OPA documentation is a great place to start learning Rego. You can also check out the Rego Playground to experiment with Rego, and join the OPA Slack.

    -
    deny[res] {
    -    instance := input.aws.rds.instances[_]
    -    instance.engine.value == ["postgres", "mysql"][_]
    -    not instance.iamauthenabled.value
    -    res := result.new("Instance does not have IAM Authentication enabled", instance.iamauthenabled)
    -}
    -
    -

    The rule should return a result, which can be created using result.new. This function does not need to be imported, it is defined internally and provided at runtime. The first argument is the message to display and the second argument is the resource that the issue was detected on.

    -

    It is possible to pass any rego variable that references a field of the input document.

    -

    Generate docs

    -

    Finally, you'll want to generate documentation for your newly added rule. Please run make docs in the trivy-checks directory to generate the documentation for your new policy and submit a PR for us to take a look at.

    -

    Adding Tests

    -

    All Rego checks need to have tests. There are many examples of these in the checks directory for each check (Link). More information on how to write tests for Rego checks is provided in the custom misconfiguration section of the docs.

    -

    Example PR

    -

    You can see a full example PR for a new rule being added here: https://github.com/aquasecurity/defsec/pull/1000.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/contribute/checks/service-support/index.html b/v0.58.0/community/contribute/checks/service-support/index.html deleted file mode 100644 index c156a5efa406..000000000000 --- a/v0.58.0/community/contribute/checks/service-support/index.html +++ /dev/null @@ -1,7965 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Add Service Support - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Add Service Support

    -

    A service refers to a service by a cloud provider. This section details how to add a new service to an existing provider. All contributions need to be made to the trivy repository.

    -

    Prerequisites

    -

    Before you begin, verify that the provider does not already have the service that you plan to add.

    -

    Adding a new service to an existing provider

    -

    Adding a new service involves two steps. The service will need a data structure to store information about the required resources that will be scanned. Additionally, the service will require one or more adapters to convert the scan targetes as input(s) into the aforementioned data structure.

    -

    Create a new file in the provider directory

    -

    In this example, we are adding the CodeBuild service to the AWS provider.

    -

    First, create a new directory and file for your new service under the provider directory: e.g. aws/codebuild/codebuild.go

    -

    The CodeBuild service will require a structure struct to hold the information on the input that is scanned. The input is the CodeBuild resource that a user configured and wants to scan for misconfiguration.

    -
    type CodeBuild struct {
    -    Projects []Project
    -}
    -
    -

    The CodeBuild service manages Project resources. The Project struct has been added to hold information about each Project resources; Project Resources in turn manage ArtifactSettings:

    -
    type Project struct {
    -    Metadata                  iacTypes.Metadata
    -    ArtifactSettings          ArtifactSettings
    -    SecondaryArtifactSettings []ArtifactSettings
    -}
    -
    -type ArtifactSettings struct {
    -    Metadata          iacTypes.Metadata
    -    EncryptionEnabled iacTypes.BoolValue
    -}
    -
    -

    The iacTypes.Metadata struct is embedded in all of the Trivy types and provides a common set of metadata for all resources. This includes the file and line number where the resource was defined and the name of the resource.

    -

    A resource in this example Project can have a name and can optionally be encrypted. Instead of using raw string and bool types respectively, we use the trivy types iacTypes.Metadata and iacTypes.BoolValue. These types wrap the raw values and provide additional metadata about the value. For instance, whether it was set by the user and the file and line number where the resource was defined.

    -

    Have a look at the other providers and services in the iac/providers directory in Trivy.

    -

    Next you'll need to add a reference to your new service struct in the provider struct at pkg/iac/providers/aws/aws.go:

    -
    type AWS struct {
    -    ...
    -    CodeBuild      codebuild.CodeBuild
    -    ...
    -}
    -
    -

    Update Adapters

    -

    Now you'll need to update all of the adapters which populate the struct of the provider that you have been using. Following the example above, if you want to add support for CodeBuild in Terraform, you'll need to update the Terraform AWS adatper as shown here: trivy/pkg/iac/adapters/terraform/aws/codebuild/adapt.go.

    -

    Another example for updating the adapters is provided in the following PR. Additionally, please refer to the respective Terraform documentation on the provider to which you are adding the service. For instance, the Terraform documentation for AWS CodeBuild is provided here.

    -

    Create a new Schema for your provider

    -

    Once the new service has been added to the provider, you need to create the schema for the service as part of the provider schema.

    -

    This process has been automated with mage commands. In the Trivy root directory run mage schema:generate to generate the schema for your new service and mage schema:verify.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/contribute/discussion/index.html b/v0.58.0/community/contribute/discussion/index.html deleted file mode 100644 index a6cb5b959441..000000000000 --- a/v0.58.0/community/contribute/discussion/index.html +++ /dev/null @@ -1,7951 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Discussions - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Discussions

    -

    Thank you for taking interest in contributing to Trivy!

    -

    Trivy uses GitHub Discussion for bug reports, feature requests, and questions. -If maintainers decide to accept a new feature or confirm that it is a bug, they will close the discussion and create a GitHub Issue associated with that discussion.

    -
      -
    • Feel free to open discussions for any reason. When you open a new discussion, you'll have to select a discussion category as described below.
    • -
    • Please spend a small amount of time giving due diligence to the issue/discussion tracker. Your discussion might be a duplicate. If it is, please add your comment to the existing issue/discussion.
    • -
    • Remember that users might search for your issue/discussion in the future, so please give it a meaningful title to help others.
    • -
    • The issue should clearly explain the reason for opening, the proposal if you have any, and any relevant technical information.
    • -
    -

    There are 4 categories:

    -
      -
    • 💡 Ideas
        -
      • Share ideas for new features
      • -
      -
    • -
    • 🔎 False Detection
        -
      • Report false positives/negatives
      • -
      -
    • -
    • 🐛 Bugs
        -
      • Report something that is not working as expected
      • -
      -
    • -
    • 🙏 Q&A
        -
      • Ask the community for help
      • -
      -
    • -
    -
    -

    Note

    -

    If you find any false positives or false negatives, please make sure to report them under the "False Detection" category, not "Bugs".

    -
    -

    False detection

    -

    Trivy depends on multiple data sources. -Sometime these databases contain mistakes.

    -

    If Trivy can't detect any CVE-IDs or shows false positive result, at first please follow the next steps:

    -
      -
    1. Run Trivy with -f json that shows data sources.
    2. -
    3. According to the shown data source, make sure that the security advisory in the data source is correct.
    4. -
    -

    If the data source is correct and Trivy shows wrong results, please raise an issue on Trivy.

    -

    GitHub Advisory Database

    -

    Visit here and search CVE-ID.

    -

    If you find a problem, it'll be nice to fix it: How to contribute to a GitHub security advisory

    -

    GitLab Advisory Database

    -

    Visit here and search CVE-ID.

    -

    If you find a problem, it'll be nice to fix it: Create an issue to GitLab Advisory Database

    -

    Red Hat CVE Database

    -

    Visit here and search CVE-ID.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/contribute/issue/index.html b/v0.58.0/community/contribute/issue/index.html deleted file mode 100644 index c4b5cc4a2711..000000000000 --- a/v0.58.0/community/contribute/issue/index.html +++ /dev/null @@ -1,7764 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Issues - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Issues

    -

    Thank you for taking interest in contributing to Trivy!

    -

    Trivy uses GitHub Discussion for bug reports, feature requests, and questions.

    -
    -

    Warning

    -

    Issues created by non-maintainers will be immediately closed.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/contribute/pr/index.html b/v0.58.0/community/contribute/pr/index.html deleted file mode 100644 index dbde332b236f..000000000000 --- a/v0.58.0/community/contribute/pr/index.html +++ /dev/null @@ -1,8244 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pull Requests - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Pull Requests

    - -

    Thank you for taking interest in contributing to Trivy!

    -
      -
    1. Every Pull Request should have an associated GitHub issue link in the PR description. Note that issues are created by Trivy maintainers based on feedback provided in a GitHub discussion. Please refer to the issue and discussion pages for explanation about this process. If you think your change is trivial enough, you can skip the issue and instead add justification and explanation in the PR description.
    2. -
    3. Your PR is more likely to be accepted if it focuses on just one change.
    4. -
    5. There's no need to add or tag reviewers.
    6. -
    7. If a reviewer commented on your code or asked for changes, please remember to respond with comment. Do not mark discussion as resolved. It's up to reviewer to mark it resolved (in case if suggested fix addresses problem properly). PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).
    8. -
    9. Please include a comment with the results before and after your change.
    10. -
    11. Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!).
    12. -
    13. If your PR affects the user experience in some way, please update the README.md and the CLI help accordingly.
    14. -
    -

    Development

    -

    Install the necessary tools for development by following their respective installation instructions.

    - -

    Build

    -

    After making changes to the Go source code, build the project with the following command:

    -
    $ mage build
    -$ ./trivy -h
    -
    -

    Lint

    -

    You must pass the linter checks:

    -
    $ mage lint:run
    -
    -

    Additionally, you need to have run go mod tidy, so execute the following command as well:

    -
    $ mage tidy
    -
    -

    To autofix linters use the following command: -

    $ mage lint:fix
    -

    -

    Unit tests

    -

    Your PR must pass all the unit tests. You can test it as below.

    -
    $ mage test:unit
    -
    -

    Integration tests

    -

    Your PR must pass all the integration tests. You can test it as below.

    -
    $ mage test:integration
    -
    -

    Documentation

    -

    If you update CLI flags, you need to generate the CLI references. -The test will fail if they are not up-to-date.

    -
    $ mage docs:generate
    -
    -

    You can build the documents as below and view it at http://localhost:8000.

    -
    $ mage docs:serve
    -
    -

    Title

    -

    It is not that strict, but we use the title conventions in this repository. -Each commit message doesn't have to follow the conventions as long as it is clear and descriptive since it will be squashed and merged.

    -

    Format of the title

    -
    <type>(<scope>): <subject>
    -
    -

    The type and scope should always be lowercase as shown below.

    -

    Allowed <type> values:

    -
      -
    • feat for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version.
    • -
    • fix for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version.
    • -
    • perf for performance improvements. Such commit will trigger a release bumping a PATCH version.
    • -
    • docs for changes to the documentation.
    • -
    • style for formatting changes, missing semicolons, etc.
    • -
    • refactor for refactoring production code, e.g. renaming a variable.
    • -
    • test for adding missing tests, refactoring tests; no production code change.
    • -
    • build for updating build configuration, development tools or other changes irrelevant to the user.
    • -
    • chore for updates that do not apply to the above, such as dependency updates.
    • -
    • ci for changes to CI configuration files and scripts
    • -
    • revert for revert to a previous commit
    • -
    -

    Allowed <scope> values:

    -

    checks:

    -
      -
    • vuln
    • -
    • misconf
    • -
    • secret
    • -
    • license
    • -
    -

    mode:

    -
      -
    • image
    • -
    • fs
    • -
    • repo
    • -
    • sbom
    • -
    • k8s
    • -
    • server
    • -
    • aws
    • -
    • vm
    • -
    • plugin
    • -
    -

    os:

    -
      -
    • alpine
    • -
    • redhat
    • -
    • alma
    • -
    • rocky
    • -
    • azure
    • -
    • oracle
    • -
    • debian
    • -
    • ubuntu
    • -
    • amazon
    • -
    • suse
    • -
    • photon
    • -
    • distroless
    • -
    -

    language:

    -
      -
    • ruby
    • -
    • php
    • -
    • python
    • -
    • nodejs
    • -
    • rust
    • -
    • dotnet
    • -
    • java
    • -
    • go
    • -
    • elixir
    • -
    • dart
    • -
    • julia
    • -
    -

    vuln:

    -
      -
    • os
    • -
    • lang
    • -
    -

    config:

    -
      -
    • kubernetes
    • -
    • dockerfile
    • -
    • terraform
    • -
    • cloudformation
    • -
    -

    container

    -
      -
    • docker
    • -
    • podman
    • -
    • containerd
    • -
    • oci
    • -
    -

    cli:

    -
      -
    • cli
    • -
    • flag
    • -
    -

    SBOM:

    -
      -
    • cyclonedx
    • -
    • spdx
    • -
    • purl
    • -
    -

    others:

    -
      -
    • helm
    • -
    • report
    • -
    • db
    • -
    • parser
    • -
    • deps
    • -
    -

    The <scope> can be empty (e.g. if the change is a global or difficult to assign to a single component), in which case the parentheses are omitted.

    -

    Breaking changes

    -

    A PR, introducing a breaking API change, needs to append a ! after the type/scope.

    -

    Example titles

    -
    feat(alma): add support for AlmaLinux
    -
    -
    feat(vuln)!: delete the existing CLI flag
    -
    -
    fix(oracle): handle advisories with ksplice versions
    -
    -
    docs(misconf): add comparison with Conftest and TFsec
    -
    -
    chore(deps): bump go.uber.org/zap from 1.19.1 to 1.20.0
    -
    -

    NOTE: please do not use chore(deps): update fanal and something like that if you add new features or fix bugs in Trivy-related projects. -The PR title should describe what the PR adds or fixes even though it just updates the dependency in Trivy.

    -

    Commits

    -

    Understand where your pull request belongs

    -

    Trivy is composed of several repositories that work together:

    -
      -
    • Trivy is the client-side, user-facing, command line tool.
    • -
    • vuln-list is a vulnerability database, aggregated from different sources, and normalized for easy consumption. Think of this as the "server" side of the trivy command line tool. There should be no pull requests to this repo
    • -
    • vuln-list-update is the code that maintains the vuln-list database.
    • -
    • trivy-db maintains the vulnerability database pulled by Trivy CLI.
    • -
    • go-dep-parser is a library for parsing lock files such as package-lock.json and Gemfile.lock.
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/maintainer/backporting/index.html b/v0.58.0/community/maintainer/backporting/index.html deleted file mode 100644 index 2bd852e6a6b1..000000000000 --- a/v0.58.0/community/maintainer/backporting/index.html +++ /dev/null @@ -1,7952 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Backporting - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Backporting Process

    -

    This document outlines the backporting process for Trivy, including when to create patch releases and how to perform the backporting.

    -

    When to Create Patch Releases

    -

    In general, small changes should not be backported and should be included in the next minor release. -However, patch releases should be made in the following cases:

    -
      -
    • Fixes for HIGH or CRITICAL vulnerabilities in Trivy itself or Trivy's dependencies
    • -
    • Fixes for bugs that cause panic during Trivy execution or otherwise interfere with normal usage
    • -
    -

    In these cases, the fixes should be backported using the procedure described below. -At the maintainer's discretion, other bug fixes may be included in the patch release containing these hotfixes.

    -

    Versioning

    -

    Trivy follows Semantic Versioning, using version numbers in the format MAJOR.MINOR.PATCH. -When creating a patch release, the PATCH part of the version number is incremented. -For example, if a fix is being distributed for v0.50.0, the patch release would be v0.50.1.

    -

    Backporting Procedure

    -
      -
    1. A release branch (e.g., release/v0.50) is automatically created when a new minor version is released.
    2. -
    3. Create a pull request (PR) against the main branch with the necessary fixes. If the fixes are already merged into the main branch, skip this step.
    4. -
    5. Once the PR with the fixes is merged, comment @aqua-bot backport <release-branch> on the PR (e.g., @aqua-bot backport release/v0.50). This will trigger the automated backporting process using GitHub Actions.
    6. -
    7. The automated process will create a new PR with the backported changes. Ensure that all tests pass for this PR.
    8. -
    9. Once the tests pass, merge the automatically created PR into the release branch.
    10. -
    11. Merge a release PR on the release branch and release the patch version.
    12. -
    -
    -

    Note

    -

    Even if a conflict occurs, a PR is created by forceful commit, in which case the conflict should be resolved manually. -If you want to re-run a backport of the same PR, close the existing PR, delete the branch and re-run it.

    -
    -

    Example

    -

    To better understand the backporting procedure, let's walk through an example using the releases of v0.50.

    -
    gitGraph:
    -  commit id:"Feature 1"
    -  commit id:"v0.50.0 release" tag:"v0.50.0"
    -
    -  branch "release/v0.50"
    -
    -  checkout main
    -  commit id:"Bugfix 1"
    -
    -  checkout "release/v0.50"
    -  cherry-pick id:"Bugfix 1"
    -
    -  checkout main
    -  commit id:"Feature 2"
    -  commit id:"Bugfix 2"
    -  commit id:"Feature 3"
    -
    -  checkout "release/v0.50"
    -  cherry-pick id:"Bugfix 2"
    -  commit id:"v0.50.1 release" tag:"v0.50.1"
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/maintainer/help-wanted/index.html b/v0.58.0/community/maintainer/help-wanted/index.html deleted file mode 100644 index 5dcf86c846a8..000000000000 --- a/v0.58.0/community/maintainer/help-wanted/index.html +++ /dev/null @@ -1,7914 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Help Wanted - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Overview

    -

    We use two labels help wanted and good first -issue to identify issues that have been specially groomed -for new contributors. The good first issue label is a subset of help wanted -label, indicating that members have committed to providing extra assistance for -new contributors. All good first issue items also have the help wanted -label.

    -

    Help Wanted

    -

    Items marked with the help wanted label need to ensure that they are:

    -
      -
    • Low Barrier to Entry
    • -
    -

    It should be tractable for new contributors. Documentation on how that type of - change should be made should already exist.

    -
      -
    • Clear Task
    • -
    -

    The task is agreed upon and does not require further discussions in the - community. Call out if that area of code is untested and requires new - fixtures.

    -

    API / CLI behavior is decided and included in the OP issue, for example: "The - new command syntax is trivy --format yaml IMAGE_NAME"_ with - expected validations called out.

    -
      -
    • Goldilocks priority
    • -
    -

    Not too high that a core contributor should do it, but not too low that it - isn't useful enough for a core contributor to spend time to review it, answer - questions, help get it into a release, etc.

    -
      -
    • Up-To-Date
    • -
    -

    Often these issues become obsolete and have already been done, are no longer - desired, no longer make sense, have changed priority or difficulty , etc.

    -

    Good First Issue

    -

    Items marked with the good first issue label are intended for first-time -contributors. It indicates that members will keep an eye out for these pull -requests and shepherd it through our processes.

    -

    These items need to ensure that they follow the guidelines for help wanted -labels (above) in addition to meeting the following criteria:

    -
      -
    • No Barrier to Entry
    • -
    -

    The task is something that a new contributor can tackle without advanced - setup, or domain knowledge.

    -
      -
    • Solution Explained
    • -
    -

    The recommended solution is clearly described in the issue.

    -
      -
    • Provides Context
    • -
    -

    If background knowledge is required, this should be explicitly mentioned and a - list of suggested readings included.

    -
      -
    • Gives Examples
    • -
    -

    Link to examples of similar implementations so new contributors have a - reference guide for their changes.

    -
      -
    • Identifies Relevant Code
    • -
    -

    The relevant code and tests to be changed should be linked in the issue.

    -
      -
    • Ready to Test
    • -
    -

    There should be existing tests that can be modified, or existing test cases - fit to be copied. If the area of code doesn't have tests, before labeling the - issue, add a test fixture. This prep often makes a great help wanted task!

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/maintainer/release-flow/index.html b/v0.58.0/community/maintainer/release-flow/index.html deleted file mode 100644 index 5dc4155af13c..000000000000 --- a/v0.58.0/community/maintainer/release-flow/index.html +++ /dev/null @@ -1,8052 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Release Flow - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Release Flow

    -

    Overview

    -

    Trivy adopts conventional commit messages, and Release Please automatically creates a release PR based on the messages of the merged commits. -This release PR is automatically updated every time a new commit is added to the release branch.

    -

    If a commit has the prefix feat:, a PR is automatically created to increment the minor version, and if a commit has the prefix fix:, a PR is created to increment the patch version. -When the PR is merged, GitHub Actions automatically creates a version tag and the release is performed. -For detailed behavior, please refer to the GitHub Actions configuration.

    -
    -

    Note

    -

    Commits with prefixes like chore or build are not considered releasable, and no release PR is created. -To include such commits in a release, you need to either include commits with feat or fix prefixes or perform a manual release as described below.

    -
    -

    Flow

    -

    The release flow consists of the following main steps:

    -
      -
    1. Creating the release PR (automatically or manually)
    2. -
    3. Drafting the release notes in GitHub Discussions
    4. -
    5. Merging the release PR
    6. -
    7. Updating the release notes in GitHub Discussions
    8. -
    9. Navigating to the release notes in GitHub Releases page
    10. -
    -

    Automatic Release PR Creation

    -

    When a releasable commit (a commit with feat or fix prefix) is merged, a release PR is automatically created. -These Release PRs are kept up-to-date as additional work is merged. -When it's ready to tag a release, simply merge the release PR. -See the Release Please documentation for more information.

    -

    The title of the PR will be in the format release: v${version} [${branch}] (e.g., release: v0.51.0 [main]). -The format of the PR title is important for identifying the release commit, so it should not be changed.

    -

    The release/vX.Y release branches are also subject to automatic release PR creation for patch releases. -The PR title will be like release: v0.51.1 [release/v0.51].

    -

    Manual Release PR Creation

    -

    If you want to release commits like chore, a release PR is not automatically created, so you need to manually trigger the creation of a release PR. -The Release Please workflow supports workflow_dispatch and can be triggered manually. -Click "Run workflow" in the top right corner and specify the release branch. -In Trivy, the following branches are the release branches.

    -
      -
    • main
    • -
    • release/vX.Y (e.g. release/v0.51)
    • -
    -

    Specify the release version (without the v prefix) and click "Run workflow" to create a release PR for the specified version.

    -

    Drafting the Release Notes

    -

    Next, create release notes for this version. -Draft a new post in GitHub Discussions, and maintainers edit these release notes (e.g., https://github.com/aquasecurity/trivy/discussions/6605). -Currently, the creation of this draft is done manually. -For patch version updates, this step can be skipped since they only involve bug fixes.

    -

    Merging the Release PR

    -

    Once the draft of the release notes is complete, merge the release PR. -When the PR is merged, a tag is automatically created, and GoReleaser releases binaries, container images, etc.

    -

    Updating the Release Notes

    -

    If the release completes without errors, a page for the release notes is created in GitHub Discussions (e.g., https://github.com/aquasecurity/trivy/discussions/6622). -Copy the draft release notes, adjust the formatting, and finalize the release notes.

    - -

    To navigate to the release highlights and summary in GitHub Discussions, place a link in the GitHub Releases page as below:

    -
    ## ⚡Release highlights and summary⚡
    -
    -👉 https://github.com/aquasecurity/trivy/discussions/6838
    -
    -## Changelog
    -https://github.com/aquasecurity/trivy/blob/main/CHANGELOG.md#0520-2024-06-03
    -
    -

    Replace URLs with appropriate ones.

    -

    Example: https://github.com/aquasecurity/trivy/releases/tag/v0.52.0

    -

    The release is now complete.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/maintainer/triage/index.html b/v0.58.0/community/maintainer/triage/index.html deleted file mode 100644 index fb82d7dedffa..000000000000 --- a/v0.58.0/community/maintainer/triage/index.html +++ /dev/null @@ -1,7905 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Triage - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Triage

    -

    Triage is an important part of maintaining the health of the trivy repo. -A well organized repo allows maintainers to prioritize feature requests, fix bugs, and respond to users facing difficulty with the tool as quickly as possible.

    -

    Triage includes:

    -
      -
    • Labeling issues
    • -
    • Responding to issues
    • -
    • Closing issues
    • -
    -

    Daily Triage

    -

    Daily triage has two goals:

    -
      -
    1. Responsiveness for new issues
    2. -
    3. Responsiveness when explicitly requested information was provided
    4. -
    -

    It covers:

    -
      -
    1. Issues without a kind/ or triage/ label
    2. -
    3. Issues without a priority/ label
    4. -
    5. triage/needs-information issues which the user has followed up on, and now require a response.
    6. -
    -

    Categorization

    -

    The most important level of categorizing the issue is defining what type it is. -We typically want at least one of the following labels on every issue, and some issues may fall into multiple categories:

    -
      -
    • triage/support - The default for most incoming issues
    • -
    • kind/bug - When it’s a bug or we aren’t delivering the best user experience
    • -
    -

    Other possibilities: -- kind/feature- Identify new feature requests -- kind/testing - Update or fix unit/integration tests -- kind/cleanup - Cleaning up/refactoring the codebase -- kind/documentation - Updates or additions to trivy documentation

    -

    If the issue is specific to a driver for OS packages or libraries:

    -

    co/[driver for OS packages]

    -
      -
    • co/alpine
    • -
    • co/amazon
    • -
    • co/debian
    • -
    • co/oracle
    • -
    • co/photon
    • -
    • co/redhat
    • -
    • co/suse
    • -
    • co/ubuntu
    • -
    -

    co/[driver for libraries of programming languages]

    -
      -
    • co/bundler
    • -
    • co/cargo
    • -
    • co/composer
    • -
    • co/npm
    • -
    • co/yarn
    • -
    • co/pipenv
    • -
    • co/poetry
    • -
    -

    Help wanted?

    -

    Good First Issue - bug has a proposed solution, can be implemented w/o further discussion.

    -

    Help wanted - if the bug could use help from a contributor

    -

    Prioritization

    -

    If the issue is not triage/support, it needs a priority label.

    -

    priority/critical-urgent - someones top priority ASAP, such as security issue, user-visible bug, or build breakage. Rarely used.

    -

    priority/important-soon: in time for the next two releases. It should be attached to a milestone.

    -

    priority/important-longterm: 2-4 releases from now

    -

    priority/backlog: agreed that this would be good to have, but no one is available at the moment. Consider tagging as help wanted

    -

    priority/awaiting-more-evidence: may be useful, but there is not yet enough support.

    -

    Weekly Triage

    -

    Weekly triage has three goals:

    -
      -
    1. Catching up on unresponded issues
    2. -
    3. Reviewing and closing PR’s
    4. -
    5. Closing stale issues
    6. -
    -

    Post-Release Triage

    -

    Post-release triage occurs after a major release (around every 4-6 weeks). -It focuses on:

    -
      -
    1. Closing bugs that have been resolved by the release
    2. -
    3. Reprioritizing bugs that have not been resolved by the release
    4. -
    5. Letting users know if we believe that there is still an issue
    6. -
    -

    This includes reviewing:

    -
      -
    1. Every issue that hasn’t been touched in the last 2 days
    2. -
    3. Re-evaluation of long-term issues
    4. -
    5. Re-evaluation of short-term issues
    6. -
    -

    Responding to Issues

    -

    Needs More Information

    -

    A sample response to ask for more info:

    -
    -

    I don’t yet have a clear way to replicate this issue. Do you mind adding some additional details. Here is additional information that would be helpful:

    -

    * The exact trivy command line used

    -

    * The exact image you want to scan

    -

    * The full output of the trivy command, preferably with --debug for extra logging.

    -

    Thank you for sharing your experience!

    -
    -

    Then: Label with triage/needs-information.

    -

    Issue might be resolved

    -

    If you think a release may have resolved an issue, ask the author to see if their issue has been resolved:

    -
    -

    Could you please check to see if trivy addresses this issue? We've made some changes with how this is handled, and improved the trivy logs output to help us debug tricky cases like this.

    -
    -

    Then: Label with triage/needs-information.

    -

    Closing with Care

    -

    Issues typically need to be closed for the following reasons:

    -
      -
    • The issue has been addressed
    • -
    • The issue is a duplicate of an existing issue
    • -
    • There has been a lack of information over a long period of time
    • -
    -

    In any of these situations, we aim to be kind when closing the issue, and offer the author action items should they need to reopen their issue or still require a solution.

    -

    Samples responses for these situations include:

    -

    Issue has been addressed

    -
    -

    @author: I believe this issue is now addressed by trivy v1.0.0, as it . If you still see this issue with trivy v1.0 or higher, please reopen this issue.

    -

    Thank you for reporting this issue!

    -
    -

    Then: Close the issue

    -

    Duplicate Issue

    -
    -

    This issue appears to be a duplicate of #X, do you mind if we move the conversation there?

    -

    This way we can centralize the content relating to the issue. If you feel that this issue is not in fact a duplicate, please re-open it. If you have additional information to share, please add it to the new issue.

    -

    Thank you for reporting this!

    -
    -

    Then: Label with triage/duplicate and close the issue.

    -

    Lack of Information

    -

    If an issue hasn't been active for more than four weeks, and the author has been pinged at least once, then the issue can be closed.

    -
    -

    Hey @author -- hopefully it's OK if I close this - there wasn't enough information to make it actionable, and some time has already passed. If you are able to provide additional details, you may reopen it at any point.

    -

    Here is additional information that may be helpful to us:

    -

    * Whether the issue occurs with the latest trivy release

    -

    * The exact trivy command line used

    -

    * The exact image you want to scan

    -

    * The full output of the trivy command, preferably with --debug for extra logging.

    -

    Thank you for sharing your experience!

    -
    -

    Then: Close the issue.

    -

    Help Wanted issues

    -

    We use two labels help wanted -and good first issue -to identify issues that have been specially groomed for new contributors.

    -

    We have specific guidelines -for how to use these labels. If you see an issue that satisfies these -guidelines, you can add the help wanted label and the good first issue label. -Please note that adding the good first issue label must also -add the help wanted label.

    -

    If an issue has these labels but does not satisfy the guidelines, please -ask for more details to be added to the issue or remove the labels.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/community/principles/index.html b/v0.58.0/community/principles/index.html deleted file mode 100644 index 64397b7ecc68..000000000000 --- a/v0.58.0/community/principles/index.html +++ /dev/null @@ -1,8079 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Principles - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Trivy Project Principles

    -

    This document outlines the guiding principles and governance framework for the Trivy project.

    -

    Core Principles

    -

    Trivy is a security scanner focused on static analysis and designed with simplicity and security at its core. -All new proposals to the project must adhere to the following principles.

    -

    Static Analysis (No Runtime Required)

    -

    Trivy operates without requiring container or VM image startups, eliminating the need for Docker or similar runtimes, except for scanning images stored within a container runtime. -This approach enhances security and efficiency by minimizing dependencies.

    -

    External Dependency Free (Single Binary)

    -

    Operating as a single binary, Trivy is independent of external environments and avoids executing external OS commands or processes. -If specific functionality, like Maven's, is needed, Trivy opts for internal reimplementations or processing outputs of the tool without direct execution of external tools.

    -

    This approach obviously requires more effort but significantly reduces security risks associated with executing OS commands and dependency errors due to external environment versions. -Simplifying the scanner's use by making it operational immediately upon binary download facilitates easier initiation of scans.

    -

    No Setup Required

    -

    Trivy must be ready to use immediately after installation. -It's unacceptable for Trivy not to function without setting up a database or writing configuration files by default. -Such setups should only be necessary for users requiring specific customizations.

    -

    Security often isn't a top priority for many organizations and can be easily deferred. -Trivy aims to lower the barrier to entry by simplifying the setup process, making it easier for users to start securing their projects.

    -

    Security Focus

    -

    Trivy prioritizes the identification of security issues, excluding features unrelated to security, such as performance metrics or content listings of container images. -It can, however, produce and output intermediate representations like SBOMs for comprehensive security assessments.

    -

    Trivy serves as a tool with opinions on security, used to warn users about potential issues.

    -

    Detecting Unintended States

    -

    Trivy is designed to detect unintended vulnerable states in projects, such as the use of vulnerable versions of dependencies or misconfigurations in Infrastructure as Code (IaC) that may unintentionally expose servers to the internet. -The focus is on identifying developer mistakes or undesirable states, not on detecting intentional attacks, such as malicious images and malware.

    -

    Out of Scope Features

    -

    Aqua Security offers a premium version with several features not available in the open-source Trivy project. -While detailed information can be found here, it's beneficial to highlight specific functionalities frequently inquired about:

    -

    Runtime Security

    -

    As mentioned in the Core Principles, Trivy is a static analysis security scanner, making runtime security outside its scope. -Runtime security needs are addressed by Tracee or the commercial version of Aqua Security.

    -

    Intentional Attacks

    -

    As mentioned in the Core Principles, detection of intentional attacks, such as malware or malicious container images, is not covered by Trivy and is supported in the commercial version.

    -

    User Interface

    -

    Trivy primarily operates via CLI for displaying results, with a richer UI available in the commercial version.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/air-gap/index.html b/v0.58.0/docs/advanced/air-gap/index.html deleted file mode 100644 index 4ae7f62edaee..000000000000 --- a/v0.58.0/docs/advanced/air-gap/index.html +++ /dev/null @@ -1,8172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Connectivity and Network considerations - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Connectivity and Network considerations

    -

    Trivy requires internet connectivity in order to function normally. If your organizations blocks or restricts network traffic, that could prevent Trivy from working correctly. -This document explains Trivy's network connectivity requirements, and how to configure Trivy to work in restricted networks environments, including completely air-gapped environments.

    -

    The following table lists all external resources that are required by Trivy:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    External ResourceFeatureDetails
    Vulnerability DatabaseVulnerability scanningTrivy DB
    Java Vulnerability DatabaseJava vulnerability scanningTrivy Java DB
    Checks BundleMisconfigurations scanningTrivy Checks
    VEX HubVEX HubVEX Hub
    Maven Central / Remote RepositoriesJava vulnerability scanningJava Scanner/Remote Repositories
    -
    -

    Note

    -

    Trivy is an open source project that relies on public free infrastructure. In case of extreme load, you may encounter rate limiting when Trivy attempts to connect to external resources.

    -
    -

    The rest of this document details each resource's connectivity requirements and network related considerations.

    -

    OCI Databases

    -

    Trivy's Vulnerability, Java, and Checks Bundle are packaged as OCI images and stored in public container registries.

    -

    Connectivity requirements

    -

    The specific registries and locations are detailed in the databases document.

    -

    Communication with OCI Registries follows the OCI Distribution spec.

    -

    The following hosts are known to be used by the default container registries:

    - - - - - - - - - - - - - - - - - - - - -
    RegistryHostsAdditional info
    Google Artifact Registry
    • mirror.gcr.io
    • googlecode.l.googleusercontent.com
    Google's IP addresses
    GitHub Container Registry
    • ghcr.io
    • pkg-containers.githubusercontent.com
    GitHub's IP addresses
    -

    Self-hosting

    -

    You can host Trivy's databases in your own container registry. Please refer to Self-hosting document for a detailed guide.

    -

    Embedded Checks

    -

    Checks Bundle is embedded in the Trivy binary (at build time), and will be used as a fallback if the external database is not available. This means that you can still scan for misconfigurations in an air-gapped environment using the database from the time of the Trivy release you are using.

    -

    VEX Hub

    -

    Connectivity Requirements

    -

    VEX Hub is hosted as at https://github.com/aquasecurity/vexhub.

    -

    Trivy is fetching VEX Hub GitHub Repository directly using simple HTTPS requests.

    -

    The following hosts are known to be used by GitHub's services:

    -
      -
    • api.github.com
    • -
    • codeload.github.com
    • -
    -

    For more information about GitHub connectivity (including specific IP addresses), please refer to GitHub's connectivity troubleshooting guide.

    -

    Self-hosting

    -

    You can host a copy of VEX Hub on your own internal server. Please refer to the self-hosting document for a detailed guide.

    -

    Maven Central / Remote Repositories

    -

    Trivy might call out to Maven central or other remote repositories to fetch in order to correctly identify Java packages during a vulnerability scan.

    -

    Connectivity requirements

    -

    Trivy might attempt to connect (over HTTPS) to the following URLs:

    -
      -
    • https://repo.maven.apache.org/maven2
    • -
    -

    Offline mode

    -

    There's no way to leverage Maven Central in a network-restricted environment, but you can prevent Trivy from trying to connect to it by using the --offline-scan flag.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/container/embed-in-dockerfile/index.html b/v0.58.0/docs/advanced/container/embed-in-dockerfile/index.html deleted file mode 100644 index b5a257fe7b69..000000000000 --- a/v0.58.0/docs/advanced/container/embed-in-dockerfile/index.html +++ /dev/null @@ -1,7799 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Embed in Dockerfile - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Embed in Dockerfile

    -

    Scan your image as part of the build process by embedding Trivy in the -Dockerfile. This approach can be used to update Dockerfiles currently using -Aqua’s Microscanner.

    -

    $ cat Dockerfile
    -FROM alpine:3.7
    -
    -RUN apk add curl \
    -    && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \
    -    && trivy rootfs --exit-code 1 --no-progress /
    -
    -$ docker build -t vulnerable-image .
    -
    -Alternatively you can use Trivy in a multistage build. Thus avoiding the -insecure curl | sh. Also the image is not changed. -
    [...]
    -# Run vulnerability scan on build image
    -FROM build AS vulnscan
    -COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy
    -RUN trivy rootfs --exit-code 1 --no-progress /
    -[...]
    -

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/container/unpacked-filesystem/index.html b/v0.58.0/docs/advanced/container/unpacked-filesystem/index.html deleted file mode 100644 index 05d7a85603fe..000000000000 --- a/v0.58.0/docs/advanced/container/unpacked-filesystem/index.html +++ /dev/null @@ -1,7887 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Unpacked container image filesystem - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Unpacked Filesystem

    -

    Scan an unpacked container image filesystem.

    -

    In this case, Trivy works the same way when scanning containers

    -
    $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
    -$ trivy rootfs /tmp/rootfs
    -
    -
    -Result - -
    2021-03-08T05:22:26.378Z        INFO    Need to update DB
    -2021-03-08T05:22:26.380Z        INFO    Downloading DB...
    -20.37 MiB / 20.37 MiB [-------------------------------------------------------------------------------------------------------------------------------------] 100.00% 8.24 MiB p/s 2s
    -2021-03-08T05:22:30.134Z        INFO    Detecting Alpine vulnerabilities...
    -
    -/tmp/rootfs (alpine 3.10.2)
    -===========================
    -Total: 20 (UNKNOWN: 0, LOW: 2, MEDIUM: 10, HIGH: 8, CRITICAL: 0)
    -
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| libcrypto1.1 | CVE-2020-1967    | HIGH     | 1.1.1c-r0         | 1.1.1g-r0     | openssl: Segmentation                 |
    -|              |                  |          |                   |               | fault in SSL_check_chain              |
    -|              |                  |          |                   |               | causes denial of service              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1967  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2021-23839   |          |                   | 1.1.1j-r0     | openssl: incorrect SSLv2              |
    -|              |                  |          |                   |               | rollback protection                   |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23839 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23840   |          |                   |               | openssl: integer                      |
    -|              |                  |          |                   |               | overflow in CipherUpdate              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23840 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23841   |          |                   |               | openssl: NULL pointer dereference     |
    -|              |                  |          |                   |               | in X509_issuer_and_serial_hash()      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23841 |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1547    | MEDIUM   |                   | 1.1.1d-r0     | openssl: side-channel weak            |
    -|              |                  |          |                   |               | encryption vulnerability              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1547  |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2019-1549    |          |                   |               | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in fork()                  |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1549  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2019-1551    |          |                   | 1.1.1d-r2     | openssl: Integer overflow in RSAZ     |
    -|              |                  |          |                   |               | modular exponentiation on x86_64      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1551  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2020-1971    |          |                   | 1.1.1i-r0     | openssl: EDIPARTYNAME                 |
    -|              |                  |          |                   |               | NULL pointer de-reference             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1971  |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1563    | LOW      |                   | 1.1.1d-r0     | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in PKCS7_dataDecode        |
    -|              |                  |          |                   |               | and CMS_decrypt_set1_pkey             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1563  |
    -+--------------+------------------+----------+                   +---------------+---------------------------------------+
    -| libssl1.1    | CVE-2020-1967    | HIGH     |                   | 1.1.1g-r0     | openssl: Segmentation                 |
    -|              |                  |          |                   |               | fault in SSL_check_chain              |
    -|              |                  |          |                   |               | causes denial of service              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1967  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2021-23839   |          |                   | 1.1.1j-r0     | openssl: incorrect SSLv2              |
    -|              |                  |          |                   |               | rollback protection                   |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23839 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23840   |          |                   |               | openssl: integer                      |
    -|              |                  |          |                   |               | overflow in CipherUpdate              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23840 |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2021-23841   |          |                   |               | openssl: NULL pointer dereference     |
    -|              |                  |          |                   |               | in X509_issuer_and_serial_hash()      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23841 |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1547    | MEDIUM   |                   | 1.1.1d-r0     | openssl: side-channel weak            |
    -|              |                  |          |                   |               | encryption vulnerability              |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1547  |
    -+              +------------------+          +                   +               +---------------------------------------+
    -|              | CVE-2019-1549    |          |                   |               | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in fork()                  |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1549  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2019-1551    |          |                   | 1.1.1d-r2     | openssl: Integer overflow in RSAZ     |
    -|              |                  |          |                   |               | modular exponentiation on x86_64      |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1551  |
    -+              +------------------+          +                   +---------------+---------------------------------------+
    -|              | CVE-2020-1971    |          |                   | 1.1.1i-r0     | openssl: EDIPARTYNAME                 |
    -|              |                  |          |                   |               | NULL pointer de-reference             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1971  |
    -+              +------------------+----------+                   +---------------+---------------------------------------+
    -|              | CVE-2019-1563    | LOW      |                   | 1.1.1d-r0     | openssl: information                  |
    -|              |                  |          |                   |               | disclosure in PKCS7_dataDecode        |
    -|              |                  |          |                   |               | and CMS_decrypt_set1_pkey             |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1563  |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| musl         | CVE-2020-28928   | MEDIUM   | 1.1.22-r3         | 1.1.22-r4     | In musl libc through 1.2.1,           |
    -|              |                  |          |                   |               | wcsnrtombs mishandles particular      |
    -|              |                  |          |                   |               | combinations of destination buffer... |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-28928 |
    -+--------------+                  +          +                   +               +                                       +
    -| musl-utils   |                  |          |                   |               |                                       |
    -|              |                  |          |                   |               |                                       |
    -|              |                  |          |                   |               |                                       |
    -|              |                  |          |                   |               |                                       |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -
    - -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/modules/index.html b/v0.58.0/docs/advanced/modules/index.html deleted file mode 100644 index ceaa0948ed31..000000000000 --- a/v0.58.0/docs/advanced/modules/index.html +++ /dev/null @@ -1,8441 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Modules - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Modules

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy provides a module feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. -It changes the behavior during scanning by WebAssembly.

    -

    Overview

    -

    Trivy modules are add-on tools that integrate seamlessly with Trivy. -They provide a way to extend the core feature set of Trivy, but without updating the Trivy binary.

    -
      -
    • They can be added and removed from a Trivy installation without impacting the core Trivy tool.
    • -
    • They can be written in any programming language supporting WebAssembly.
    • -
    • It supports only TinyGo at the moment.
    • -
    -

    You can write your own detection logic.

    -
      -
    • Evaluate complex vulnerability conditions like Spring4Shell
    • -
    • Detect a shell script communicating with malicious domains
    • -
    • Detect malicious python install script (setup.py)
    • -
    • Even detect misconfigurations in WordPress setting
    • -
    • etc.
    • -
    -

    Then, you can update the scan result however you want.

    -
      -
    • Change a severity
    • -
    • Remove a vulnerability
    • -
    • Add a new vulnerability
    • -
    • etc.
    • -
    -

    Modules should be distributed in OCI registries like GitHub Container Registry.

    -
    -

    Warning

    -

    WebAssembly doesn't allow file access and network access by default. -Modules can read required files only, but cannot overwrite them. -WebAssembly is sandboxed and secure by design, but Trivy modules available in public are not audited for security. -You should install and run third-party modules at your own risk even though

    -
    -

    Under the hood Trivy leverages wazero to run WebAssembly modules without CGO.

    -

    Installing a Module

    -

    A module can be installed using the trivy module install command. -This command takes an url. It will download the module and install it in the module cache.

    -

    Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. -Trivy will now search XDG_DATA_HOME for the location of the Trivy modules cache. -The preference order is as follows:

    -
      -
    • XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir
    • -
    • $HOME/.trivy/plugins
    • -
    -

    For example, to download the WebAssembly module, you can execute the following command:

    -
    $ trivy module install ghcr.io/aquasecurity/trivy-module-spring4shell
    -
    -

    Using Modules

    -

    Once the module is installed, Trivy will load all available modules in the cache on the start of the next Trivy execution. -The modules may inject custom logic into scanning and change the result. -You can run Trivy as usual and modules are loaded automatically.

    -

    You will see the log messages about WASM modules.

    -
    $ trivy image ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8
    -2022-06-12T12:57:13.210+0300    INFO    Loading ghcr.io/aquasecurity/trivy-module-spring4shell/spring4shell.wasm...
    -2022-06-12T12:57:13.596+0300    INFO    Registering WASM module: spring4shell@v1
    -...
    -2022-06-12T12:57:14.865+0300    INFO    Module spring4shell: Java Version: 8, Tomcat Version: 8.5.77
    -2022-06-12T12:57:14.865+0300    INFO    Module spring4shell: change CVE-2022-22965 severity from CRITICAL to LOW
    -
    -Java (jar)
    -
    -Total: 9 (UNKNOWN: 1, LOW: 3, MEDIUM: 2, HIGH: 3, CRITICAL: 0)
    -
    -┌──────────────────────────────────────────────────────────────┬─────────────────────┬──────────┬───────────────────┬────────────────────────┬────────────────────────────────────────────────────────────┐
    -│                           Library                                Vulnerability     Severity  Installed Version      Fixed Version                                 Title                            │
    -├──────────────────────────────────────────────────────────────┼─────────────────────┼──────────┼───────────────────┼────────────────────────┼────────────────────────────────────────────────────────────┤
    -│ org.springframework.boot:spring-boot (helloworld.war)         CVE-2022-22965       LOW       2.6.3              2.5.12, 2.6.6           spring-framework: RCE via Data Binding on JDK 9+           │
    -│                                                                                                                                         https://avd.aquasec.com/nvd/cve-2022-22965                 │
    -├──────────────────────────────────────────────────────────────┼─────────────────────┼──────────┼───────────────────┼────────────────────────┼────────────────────────────────────────────────────────────┤
    -...(snip)...
    -
    -

    In the above example, the Spring4Shell module changed the severity from CRITICAL to LOW because the application doesn't satisfy one of conditions.

    -

    Uninstalling Modules

    -

    Specify a module repository with trivy module uninstall command.

    -
    $ trivy module uninstall ghcr.io/aquasecurity/trivy-module-spring4shell
    -
    -

    Building Modules

    -

    It supports TinyGo only at the moment.

    -

    TinyGo

    -

    Trivy provides Go SDK including three interfaces. -Your own module needs to implement either or both Analyzer and PostScanner in addition to Module.

    -
    type Module interface {
    -    Version() int
    -    Name() string
    -}
    -
    -type Analyzer interface {
    -    RequiredFiles() []string
    -    Analyze(filePath string) (*serialize.AnalysisResult, error)
    -}
    -
    -type PostScanner interface {
    -    PostScanSpec() serialize.PostScanSpec
    -    PostScan(serialize.Results) (serialize.Results, error)
    -}
    -
    -

    In the following tutorial, it creates a WordPress module that detects a WordPress version and a critical vulnerability accordingly.

    -
    -

    Tips

    -

    You can use logging functions such as Debug and Info for debugging. -See examples for the detail.

    -
    -

    Initialize your module

    -

    Replace the repository name with yours.

    -
    $ go mod init github.com/aquasecurity/trivy-module-wordpress
    -
    -

    Module interface

    -

    Version() returns your module version and should be incremented after updates. -Name() returns your module name.

    -
    package main
    -
    -const (
    -    version = 1
    -    name = "wordpress-module"
    -)
    -
    -type WordpressModule struct{
    -    // Cannot define fields as modules can't keep state.
    -}
    -
    -func (WordpressModule) Version() int {
    -    return version
    -}
    -
    -func (WordpressModule) Name() string {
    -    return name
    -}
    -
    -
    -

    Info

    -

    A struct cannot have any fields. Each method invocation is performed in different states.

    -
    -

    Analyzer interface

    -

    If you implement the Analyzer interface, Analyze method is called when the file path is matched to file patterns returned by RequiredFiles(). -A file pattern must be a regular expression. The syntax detail is here.

    -

    Analyze takes the matched file path, then the file can be opened by os.Open().

    -
    const typeWPVersion = "wordpress-version"
    -
    -func (WordpressModule) RequiredFiles() []string {
    -    return []string{
    -        `wp-includes\/version.php`,
    -    }
    -}
    -
    -func (WordpressModule) Analyze(filePath string) (*serialize.AnalysisResult, error) {
    -    f, err := os.Open(filePath) // e.g. filePath: /usr/src/wordpress/wp-includes/version.php
    -    if err != nil {
    -        return nil, err
    -    }
    -    defer f.Close()
    -
    -    var wpVersion string
    -    scanner := bufio.NewScanner(f)
    -    for scanner.Scan() {
    -        line := scanner.Text()
    -        if !strings.HasPrefix(line, "$wp_version=") {
    -            continue
    -        }
    -
    -        ss := strings.Split(line, "=")
    -        if len(ss) != 2 {
    -            return nil, fmt.Errorf("invalid wordpress version: %s", line)
    -        }
    -
    -        // NOTE: it is an example; you actually need to handle comments, etc
    -        ss[1] = strings.TrimSpace(ss[1])
    -        wpVersion = strings.Trim(ss[1], `";`)
    -    }
    -
    -    if err = scanner.Err(); err != nil {
    -        return nil, err
    -    }
    -
    -    return &serialize.AnalysisResult{
    -        CustomResources: []serialize.CustomResource{
    -            {
    -                Type:     typeWPVersion,
    -                FilePath: filePath,
    -                Data:     wpVersion,
    -            },
    -        },
    -    }, nil
    -}
    -
    -
    -

    Tips

    -

    Trivy caches analysis results according to the module version. -We'd recommend cleaning the cache or changing the module version every time you update Analyzer.

    -
    -

    PostScanner interface

    -

    PostScan is called after scanning and takes the scan result as an argument from Trivy. -In post scanning, your module can perform one of three actions:

    -
      -
    • Insert
        -
      • Add a new security finding
      • -
      • e.g. Add a new vulnerability and misconfiguration
      • -
      -
    • -
    • Update
        -
      • Update the detected vulnerability and misconfiguration
      • -
      • e.g. Change a severity
      • -
      -
    • -
    • Delete
        -
      • Delete the detected vulnerability and misconfiguration
      • -
      • e.g. Remove Spring4Shell because it is not actually affected.
      • -
      -
    • -
    -

    PostScanSpec() returns which action the module does. -If it is Update or Delete, it also needs to return IDs such as CVE-ID and misconfiguration ID, which your module wants to update or delete.

    -

    serialize.Results contains the filtered results matching IDs you specified. -Also, it includes CustomResources with the values your Analyze returns, so you can modify the scan result according to the custom resources.

    -
    func (WordpressModule) PostScanSpec() serialize.PostScanSpec {
    -    return serialize.PostScanSpec{
    -        Action: api.ActionInsert, // Add new vulnerabilities
    -    }
    -}
    -
    -func (WordpressModule) PostScan(results serialize.Results) (serialize.Results, error) {
    -    // e.g. results
    -    // [
    -    //   {
    -    //     "Target": "",
    -    //     "Class": "custom",
    -    //     "CustomResources": [
    -    //       {
    -    //         "Type": "wordpress-version",
    -    //         "FilePath": "/usr/src/wordpress/wp-includes/version.php",
    -    //         "Layer": {
    -    //           "DiffID": "sha256:057649e61046e02c975b84557c03c6cca095b8c9accd3bd20eb4e432f7aec887"
    -    //         },
    -    //         "Data": "5.7.1"
    -    //       }
    -    //     ]
    -    //   }
    -    // ]   
    -    var wpVersion int
    -    for _, result := range results {
    -        if result.Class != types.ClassCustom {
    -            continue
    -        }
    -
    -        for _, c := range result.CustomResources {
    -            if c.Type != typeWPVersion {
    -                continue
    -            }
    -            wpVersion = c.Data.(string)
    -            wasm.Info(fmt.Sprintf("WordPress Version: %s", wpVersion))
    -
    -            ...snip...
    -
    -            if affectedVersion.Check(ver) {
    -                vulnerable = true
    -            }
    -            break
    -        }
    -    }
    -
    -    if vulnerable {
    -        // Add CVE-2020-36326
    -        results = append(results, serialize.Result{
    -            Target: wpPath,
    -            Class:  types.ClassLangPkg,
    -            Type:   "wordpress",
    -            Vulnerabilities: []types.DetectedVulnerability {
    -                {
    -                    VulnerabilityID:  "CVE-2020-36326",
    -                    PkgName:          "wordpress",
    -                    InstalledVersion: wpVersion,
    -                    FixedVersion:     "5.7.2",
    -                    Vulnerability: dbTypes.Vulnerability{
    -                        Title:    "PHPMailer 6.1.8 through 6.4.0 allows object injection through Phar Deserialization via addAttachment with a UNC pathname.",
    -                        Severity: "CRITICAL",
    -                    },
    -                },
    -            },
    -        })
    -    }
    -    return results, nil
    -}
    -
    -

    The new vulnerability will be added to the scan results. -This example shows how the module inserts a new finding. -If you are interested in Update, you can see an example of Spring4Shell.

    -

    In the Delete action, PostScan needs to return results you want to delete. -If PostScan returns an empty, Trivy will not delete anything.

    -

    Build

    -

    Follow the install guide and install TinyGo.

    -
    $ tinygo build -o wordpress.wasm -scheduler=none -target=wasi --no-debug wordpress.go
    -
    -

    Put the built binary to the module directory that is under the home directory by default.

    -
    $ mkdir -p ~/.trivy/modules
    -$ cp wordpress.wasm ~/.trivy/modules
    -
    -

    Distribute Your Module

    -

    You can distribute your own module in OCI registries. Please follow the oras installation instruction.

    -
    oras push ghcr.io/aquasecurity/trivy-module-wordpress:latest wordpress.wasm:application/vnd.module.wasm.content.layer.v1+wasm
    -Uploading 3daa3dac086b wordpress.wasm
    -Pushed ghcr.io/aquasecurity/trivy-module-wordpress:latest
    -Digest: sha256:6416d0199d66ce52ced19f01d75454b22692ff3aa7737e45f7a189880840424f
    -
    -

    Examples

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/private-registries/acr/index.html b/v0.58.0/docs/advanced/private-registries/acr/index.html deleted file mode 100644 index aecf4ea5c745..000000000000 --- a/v0.58.0/docs/advanced/private-registries/acr/index.html +++ /dev/null @@ -1,7798 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACR (Azure Container Registry) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Requirements

    -

    None, Trivy uses Azure SDK for Go. You don't need to install az command.

    -

    Privileges

    -

    Service principal must have the AcrPull permissions.

    -

    Creation of a service principal

    -
    export SP_DATA=$(az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.ContainerRegistry/registries/<registry_name>")
    -
    -

    Usage

    -
    # must set TRIVY_USERNAME empty char
    -export AZURE_CLIENT_ID=$(echo $SP_DATA | jq -r '.appId')
    -export AZURE_CLIENT_SECRET=$(echo $SP_DATA | jq -r '.password')
    -export AZURE_TENANT_ID=$(echo $SP_DATA | jq -r '.tenant')
    -
    -

    Testing

    -

    You can test credentials in the following manner.

    -
    docker run -it --rm -v /tmp:/tmp \
    -  -e AZURE_CLIENT_ID -e AZURE_CLIENT_SECRET -e AZURE_TENANT_ID \
    -  aquasec/trivy image your_special_project.azurecr.io/your_special_image:your_special_tag
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/private-registries/docker-hub/index.html b/v0.58.0/docs/advanced/private-registries/docker-hub/index.html deleted file mode 100644 index 05b55e76cfd5..000000000000 --- a/v0.58.0/docs/advanced/private-registries/docker-hub/index.html +++ /dev/null @@ -1,7774 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Docker Hub - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Docker Hub

    - -

    See here for the detail. -You don't need to provide a credential when download from public repository.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/private-registries/ecr/index.html b/v0.58.0/docs/advanced/private-registries/ecr/index.html deleted file mode 100644 index ebce0ab82138..000000000000 --- a/v0.58.0/docs/advanced/private-registries/ecr/index.html +++ /dev/null @@ -1,7920 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AWS ECR (Elastic Container Registry) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    AWS ECR (Elastic Container Registry)

    - -

    Trivy uses AWS SDK. You don't need to install aws CLI tool. -You can use AWS CLI's ENV Vars.

    -

    AWS private registry permissions

    -

    You may need to grant permissions to allow Trivy to pull images from private ECR.

    -

    It depends on how you want to provide AWS Role to trivy.

    - -

    IAM Role Service account

    -

    Add the AWS role in trivy's service account annotations:

    -
    trivy:
    -
    -  serviceAccount:
    -    annotations: {}
    -      # eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
    -
    -

    Kube2iam or Kiam

    -

    Add the AWS role to pod's annotations:

    -
    podAnnotations: {}
    -  ## kube2iam/kiam annotation
    -  # iam.amazonaws.com/role: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/private-registries/gcr/index.html b/v0.58.0/docs/advanced/private-registries/gcr/index.html deleted file mode 100644 index 5fc8f7e1522b..000000000000 --- a/v0.58.0/docs/advanced/private-registries/gcr/index.html +++ /dev/null @@ -1,7810 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GCR (Google Container Registry) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Requirements

    -

    None, Trivy uses Google Cloud SDK. You don't need to install gcloud command.

    -

    Privileges

    -

    Credential file must have the roles/storage.objectViewer permissions. -More information can be found in Google's documentation

    -

    JSON File Format

    -

    The JSON file specified should have the following format provided by google's service account mechanisms:

    -
    {
    -  "type": "service_account",
    -  "project_id": "your_special_project",
    -  "private_key_id": "XXXXXXXXXXXXXXXXXXXXxx",
    -  "private_key": "-----BEGIN PRIVATE KEY-----\nNONONONO\n-----END PRIVATE KEY-----\n",
    -  "client_email": "somedude@your_special_project.iam.gserviceaccount.com",
    -  "client_id": "1234567890",
    -  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    -  "token_uri": "https://oauth2.googleapis.com/token",
    -  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    -  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/somedude%40your_special_project.iam.gserviceaccount.com"
    -}
    -
    -

    Usage

    -

    If you want to use target project's repository, you can set them via GOOGLE_APPLICATION_CREDENTIALS. -

    # must set TRIVY_USERNAME empty char
    -export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json
    -

    -

    Testing

    -

    You can test credentials in the following manner (assuming they are in /tmp on host machine).

    -
    docker run -it --rm -v /tmp:/tmp\
    -  -e GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json\
    -  aquasec/trivy image gcr.io/your_special_project/your_special_image:your_special_tag
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/private-registries/index.html b/v0.58.0/docs/advanced/private-registries/index.html deleted file mode 100644 index 8b301ed75378..000000000000 --- a/v0.58.0/docs/advanced/private-registries/index.html +++ /dev/null @@ -1,7909 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Overview

    - -

    Trivy can download images from a private registry without the need for installing Docker or any other 3rd party tools. -This makes it easy to run within a CI process.

    -

    Login

    -

    You can log in to a private registry using the trivy registry login command. -It uses the Docker configuration file (~/.docker/config.json) to store the credentials under the hood, and the configuration file path can be configured by DOCKER_CONFIG environment variable.

    -
    $ cat ~/my_password.txt | trivy registry login --username foo --password-stdin ghcr.io
    -$ trivy image ghcr.io/your/private_image
    -
    -

    Passing Credentials

    -

    You can also provide your credentials when scanning.

    -
    $ TRIVY_USERNAME=YOUR_USERNAME TRIVY_PASSWORD=YOUR_PASSWORD trivy image YOUR_PRIVATE_IMAGE
    -
    -
    -

    Warning

    -

    When passing credentials via environment variables or CLI flags, Trivy will attempt to use these credentials for all registries encountered during scanning, regardless of the target registry. -This can potentially lead to unintended credential exposure. -To mitigate this risk:

    -
      -
    1. Set credentials cautiously and only when necessary.
    2. -
    3. Prefer using trivy registry login to pre-configure credentials with specific registries, which ensures credentials are only sent to appropriate registries.
    4. -
    -
    -

    Trivy also supports providing credentials through CLI flags:

    -
    $ TRIVY_PASSWORD=YOUR_PASSWORD trivy image --username YOUR_USERNAME YOUR_PRIVATE_IMAGE
    -
    -
    -

    Warning

    -

    The CLI flag --password is available, but its use is not recommended for security reasons.

    -
    -

    You can also store your credentials in trivy.yaml. -For more information, please refer to the documentation.

    -

    It can handle multiple sets of credentials as well:

    -
    $ export TRIVY_USERNAME=USERNAME1,USERNAME2
    -$ export TRIVY_PASSWORD=PASSWORD1,PASSWORD2
    -$ trivy image YOUR_PRIVATE_IMAGE
    -
    -

    In the example above, Trivy attempts to use two pairs of credentials:

    -
      -
    • USERNAME1/PASSWORD1
    • -
    • USERNAME2/PASSWORD2
    • -
    -

    Please note that the number of usernames and passwords must be the same.

    -
    -

    Note

    -

    --password-stdin doesn't support comma-separated passwords.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/private-registries/self/index.html b/v0.58.0/docs/advanced/private-registries/self/index.html deleted file mode 100644 index 155443d1c2df..000000000000 --- a/v0.58.0/docs/advanced/private-registries/self/index.html +++ /dev/null @@ -1,7779 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Self-Hosted - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Self-Hosted

    - -

    BasicAuth server needs TRIVY_USERNAME and TRIVY_PASSWORD.

    -
    export TRIVY_USERNAME={USERNAME}
    -export TRIVY_PASSWORD={PASSWORD}
    -
    -# if you want to use 80 port, use NonSSL
    -export TRIVY_NON_SSL=true
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/advanced/self-hosting/index.html b/v0.58.0/docs/advanced/self-hosting/index.html deleted file mode 100644 index 9dff1305b290..000000000000 --- a/v0.58.0/docs/advanced/self-hosting/index.html +++ /dev/null @@ -1,8258 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Self-Hosting Trivy's Databases - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Self-Hosting Trivy's Databases

    -

    This document explains how to host Trivy's external dependencies in your own infrastructure to prevent external network access. If you haven't already, please familiarize yourself with the Databases document that explains about the different databases used by Trivy and the different configuration options that control them. This guide assumes you are already familiar with the concepts explained there.

    -

    OCI databases

    -

    The following Trivy Databases are packaged as OCI images:

    -
      -
    • trivy-db
    • -
    • trivy-java-db
    • -
    • trivy-checks
    • -
    -

    To host these databases in your own infrastructure:

    -

    Make a local copy

    -

    Use any container registry manipulation tool (e.g , crane to copy the images to your destination registry.

    -
    -

    Note

    -

    You will need to keep the databases updated in order to maintain relevant scanning results over time.

    -
    -

    Configure Trivy

    -

    Use the appropriate database location flags to change the db-repository location:

    -
      -
    • --db-repository
    • -
    • --java-db-repository
    • -
    • --checks-bundle-repository
    • -
    -

    Authentication

    -

    If the registry requires authentication, you can configure it as described in the private registry authentication document.

    -

    OCI Media Types

    -

    When serving, proxying, or manipulating Trivy's databases, note that the media type of the OCI layer is not a standard container image type:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    DBMedia TypeReference
    trivy-dbapplication/vnd.aquasec.trivy.db.layer.v1.tar+gziphttps://github.com/aquasecurity/trivy-db/pkgs/container/trivy-db
    trivy-java-dbapplication/vnd.aquasec.trivy.javadb.layer.v1.tar+gziphttps://github.com/aquasecurity/trivy-java-db/pkgs/container/trivy-java-db
    trivy-checksapplication/vnd.oci.image.manifest.v1+jsonhttps://github.com/aquasecurity/trivy-checks/pkgs/container/trivy-checks
    -

    Manual cache population

    -

    Trivy uses a local cache directory to store the database files, as described in the cache document. -You can download the databases files and surgically populate the Trivy cache directory with them.

    -

    Downloading the DB files

    -

    On a machine with internet access, pull the database container archive from the public registry into your local workspace:

    -

    Note that these examples operate in the current working directory.

    -
    -
    -
    -

    This example uses ORAS, but you can use any other container registry manipulation tool.

    -
    oras pull ghcr.io/aquasecurity/trivy-db:2
    -
    -

    You should now have a file called db.tar.gz. Next, extract it to reveal the db files:

    -
    tar -xzf db.tar.gz
    -
    -
    -
    -

    This example uses Trivy to pull the database container archive. The --cache-dir flag makes Trivy download the database files into our current working directory. The --download-db-only flag tells Trivy to only download the database files, not to scan any images.

    -
    trivy image --cache-dir . --download-db-only
    -
    -
    -
    -
    -

    You should now have 2 new files, metadata.json and trivy.db. These are the Trivy DB files, copy them over to the air-gapped environment.

    -

    Populating the Trivy Cache

    -

    In order to populate the cache, you need to identify the location of the cache directory. If it is under the default location, you can run the following command to find it:

    -
    trivy -h | grep cache
    -
    -

    For the example, we will assume the TRIVY_CACHE_DIR variable holds the cache location:

    -
    TRIVY_CACHE_DIR=/home/user/.cache/trivy
    -
    -

    Put the Trivy DB files in the Trivy cache directory under a db subdirectory:

    -
    # ensure cache db directory exists
    -mkdir -p ${TRIVY_CACHE_DIR}/db
    -# copy the db files
    -cp /path/to/trivy.db /path/to/metadata.json ${TRIVY_CACHE_DIR}/db/
    -
    -

    Java DB adaptations

    -

    For Java DB the process is the same, except for the following:

    -
      -
    1. Image location is ghcr.io/aquasecurity/trivy-java-db:1
    2. -
    3. Archive file name is javadb.tar.gz
    4. -
    5. DB file name is trivy-java.db
    6. -
    -

    VEX Hub

    -

    Make a local copy

    -

    To make a copy of VEX Hub in a location that is accessible to Trivy.

    -
      -
    1. Download the VEX Hub archive from: https://github.com/aquasecurity/vexhub/archive/refs/heads/main.zip.
    2. -
    3. Download the VEX Hub Repository Manifest file from: https://github.com/aquasecurity/vexhub/blob/main/vex-repository.json.
    4. -
    5. Create or identify an internal HTTP server that can serve the VEX Hub repository in your environment (e.g https://server.local).
    6. -
    7. Make the downloaded archive file available for serving from your server (e.g https://server.local/main.zip).
    8. -
    9. Modify the downloaded manifest file's Location URL field to the URL of the archive file on your server (e.g url: https://server.local/main.zip).
    10. -
    11. Make the manifest file available for serving from your server under the /.well-known path (e.g https://server.local/.well-known/vex-repository.json).
    12. -
    -

    Configure Trivy

    -

    To configure Trivy to use the local VEX Repository:

    -
      -
    1. Locate your Trivy VEX configuration file by running trivy vex repo init. Make the following changes to the file.
    2. -
    3. Disable the default VEX Hub repo (enabled: false)
    4. -
    5. Add your internal VEX Hub repository as a custom repository with the URL pointing to your local server (e.g url: https://server.local).
    6. -
    -

    Authentication

    -

    If your server requires authentication, you can configure it as described in the VEX Repository Authentication document.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/compliance/compliance/index.html b/v0.58.0/docs/compliance/compliance/index.html deleted file mode 100644 index f760491922cc..000000000000 --- a/v0.58.0/docs/compliance/compliance/index.html +++ /dev/null @@ -1,8564 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Built-in Compliance - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Built-in Compliance Reports

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy’s compliance flag lets you curate a specific set of checks into a report. In a typical Trivy scan, there are hundreds of different checks for many different components and configurations, but sometimes you already know which specific checks you are interested in. Often this would be an industry accepted set of checks such as CIS, or some vendor specific guideline, or your own organization policy that you want to comply with. These are all possible using the flexible compliance infrastructure that's built into Trivy. Compliance reports are defined as simple YAML documents that select checks to include in the report.

    -

    Usage

    -

    Compliance report is currently supported in the following targets (trivy sub-commands):

    -
      -
    • trivy image
    • -
    • trivy k8s
    • -
    -

    Add the --compliance flag to the command line, and set it's value to desired report. -For example: trivy k8s cluster --compliance k8s-nsa (see below for built-in and custom reports)

    -

    Options

    -

    The following flags are compatible with --compliance flag and allows customizing it's output:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    flageffect
    --report summaryshows a summary of the results. for every control shows the number of failed checks.
    --report allshows fully detailed results. for every control shows where it failed and why.
    --format tableshows results in textual table format (good for human readability).
    --format jsonshows results in json format (good for machine readability).
    -

    Built-in compliance

    -

    Trivy has a number of built-in compliance reports that you can asses right out of the box. -to specify a built-in compliance report, select it by ID like trivy --compliance <compliance_id>.

    -

    For the list of built-in compliance reports, please see the relevant section:

    - -

    Contribute a Built-in Compliance Report

    -

    Define a Compliance spec, based on CIS benchmark or other specs

    -

    Here is an example for CIS compliance report:

    -
    ---
    -spec:
    -  id: k8s-cis-1.23
    -  title: CIS Kubernetes Benchmarks v1.23
    -  description: CIS Kubernetes Benchmarks
    -  platform: k8s
    -  type: cis
    -  version: '1.23'
    -  relatedResources:
    -  - https://www.cisecurity.org/benchmark/kubernetes
    -  controls:
    -  - id: 1.1.1
    -    name: Ensure that the API server pod specification file permissions are set to
    -      600 or more restrictive
    -    description: Ensure that the API server pod specification file has permissions
    -      of 600 or more restrictive
    -    checks:
    -    - id: AVD-KCV-0073
    -    commands:
    -    - id: CMD-0001
    -    severity: HIGH
    -
    -

    Compliance ID

    -

    ID field is the name used to execute the compliance scan via trivy -example:

    -
    trivy k8s --compliance k8s-cis-1.23
    -
    -

    ID naming convention: {platform}-{type}-{version}

    -

    Compliance Platform

    -

    The platform field specifies the type of platform on which to run this compliance report. -Supported platforms:

    -
      -
    • k8s (native kubernetes cluster)
    • -
    • eks (elastic kubernetes service)
    • -
    • aks (azure kubernetes service)
    • -
    • gke (google kubernetes engine)
    • -
    • rke2 (rancher kubernetes engine v2)
    • -
    • ocp (OpenShift Container Platform)
    • -
    • docker (docker engine)
    • -
    • aws (amazon web services)
    • -
    -

    Compliance Type

    -

    The type field specifies the kind compliance report.

    -
      -
    • cis (Center for Internet Security)
    • -
    • nsa (National Security Agency)
    • -
    • pss (Pod Security Standards)
    • -
    -

    Compliance Version

    -

    The version field specifies the version of the compliance report.

    -
      -
    • 1.23
    • -
    -

    Compliance Check ID

    -

    Specify the check ID that needs to be evaluated based on the information collected from the command data output to assess the control.

    -

    Example of how to define check data under checks folder:

    -
    # METADATA
    -# title: "Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive"
    -# description: "Ensure that the kubelet.conf file has permissions of 600 or more restrictive."
    -# scope: package
    -# schemas:
    -# - input: schema["kubernetes"]
    -# related_resources:
    -# - https://www.cisecurity.org/benchmark/kubernetes
    -# custom:
    -#   id: KCV0073
    -#   avd_id: AVD-KCV-0073
    -#   severity: HIGH
    -#   short_code: ensure-kubelet.conf-file-permissions-600-or-more-restrictive.
    -#   recommended_action: "Change the kubelet.conf file permissions to 600 or more restrictive if exist"
    -#   input:
    -#     selector:
    -#     - type: kubernetes
    -package builtin.kubernetes.KCV0073
    -
    -import data.lib.kubernetes
    -
    -types := ["master", "worker"]
    -
    -validate_kubelet_file_permission(sp) := {"kubeletConfFilePermissions": violation} {
    - sp.kind == "NodeInfo"
    - sp.type == types[_]
    - violation := {permission | permission = sp.info.kubeletConfFilePermissions.values[_]; permission > 600}
    - count(violation) > 0
    -}
    -
    -deny[res] {
    - output := validate_kubelet_file_permission(input)
    - msg := "Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive"
    - res := result.new(msg, output)
    -}
    -
    -

    Compliance Command ID

    -

    Note: This field is not mandatory, it is relevant to k8s compliance report when node-collector is in use

    -

    Specify the command ID (#ref) that needs to be executed to collect the information required to evaluate the control.

    -

    Example of how to define command data under commands folder

    -
    ---
    -- id: CMD-0001
    -  key: kubeletConfFilePermissions
    -  title: kubelet.conf file permissions
    -  nodeType: worker
    -  audit: stat -c %a $kubelet.kubeconfig
    -  platfroms:
    -    - k8s
    -    - aks
    -
    -

    Command ID

    -

    Find the next command ID by running the command on trivy-checks project.

    -
    make command-id
    -
    -

    Command Key

    -
      -
    • Re-use an existing key or specifiy a new one (make sure key name has no spaces)
    • -
    -

    Note: The key value should match the key name evaluated by the Rego check.

    -

    Command Title

    -

    Represent the purpose of the command

    -

    Command NodeType

    -

    Specify the node type on which the command is supposed to run.

    -
      -
    • worker
    • -
    • master
    • -
    -

    Command Audit

    -

    Specify here the shell command to be used please make sure to add error supression (2>/dev/null)

    -

    Command Platforms

    -

    The list of platforms that support this command. Name should be taken from this list Platforms

    -

    Command Config Files

    -

    The commands use a configuration file that helps obtain the paths to binaries and configuration files based on different platforms (e.g., Rancher, native Kubernetes, etc.).

    -

    For example:

    -
    kubelet:
    -    bins:
    -      - kubelet
    -      - hyperkube kubelet
    -    confs:
    -      - /etc/kubernetes/kubelet-config.yaml
    -      - /var/lib/kubelet/config.yaml
    -
    -

    Commands Files Location

    -

    Currently checks files location are :https://github.com/aquasecurity/trivy-checks/tree/main/checks

    -

    Command files location: https://github.com/aquasecurity/trivy-checks/tree/main/commands -under command file

    -

    Note: command config files will be located under https://github.com/aquasecurity/trivy-checks/tree/main/commands as well

    -

    Node-collector output

    -

    The node collector will read commands and execute each command, and incorporate the output into the NodeInfo resource.

    -

    example:

    -
    {
    -  "apiVersion": "v1",
    -  "kind": "NodeInfo",
    -  "metadata": {
    -    "creationTimestamp": "2023-01-04T11:37:11+02:00"
    -  },
    -  "type": "master",
    -  "info": {
    -    "adminConfFileOwnership": {
    -      "values": [
    -        "root:root"
    -      ]
    -    },
    -    "adminConfFilePermissions": {
    -      "values": [
    -        600
    -      ]
    -    }
    -    ...
    -  }
    -}
    -
    -

    Custom compliance

    -

    You can create your own custom compliance report. A compliance report is a simple YAML document in the following format:

    -
    spec:
    -  id: "k8s-myreport" # report unique identifier. this should not container spaces.
    -  title: "My custom Kubernetes report" # report title. Any one-line title.
    -  description: "Describe your report" # description of the report. Any text.
    -  relatedResources :
    -    - https://some.url # useful references. URLs only.
    -  version: "1.0" # spec version (string)
    -  controls:
    -    - name: "Non-root containers" # Name for the control (appears in the report as is). Any one-line name.
    -      description: 'Check that container is not running as root' # Description (appears in the report as is). Any text.
    -      id: "1.0" # control identifier (string)
    -      checks:   # list of existing Trivy checks that define the control
    -        - id: AVD-KSV-0012 # check ID. Must start with `AVD-` or `CVE-` 
    -      severity: "MEDIUM" # Severity for the control (note that checks severity isn't used)
    -    - name: "Immutable container file systems"
    -      description: 'Check that container root file system is immutable'
    -      id: "1.1"
    -      checks:
    -        - id: AVD-KSV-0014
    -      severity: "LOW"
    -
    -

    The check id field (controls[].checks[].id) is referring to existing check by it's "AVD ID". This AVD ID is easily located in the check's source code metadata header, or by browsing Aqua vulnerability DB, specifically in the Misconfigurations and Vulnerabilities sections.

    -

    Once you have a compliance spec, you can select it by file path: trivy --compliance @</path/to/compliance.yaml> (note the @ indicating file path instead of report id).

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/compliance/contrib-compliance/index.html b/v0.58.0/docs/compliance/contrib-compliance/index.html deleted file mode 100644 index 51b8b20b3620..000000000000 --- a/v0.58.0/docs/compliance/contrib-compliance/index.html +++ /dev/null @@ -1,8086 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Custom Compliance - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Custom Compliance Spec

    -

    Trivy supports several different compliance specs. The details on compliance scanning with Trivy are provided in the compliance documentation. -All of the Compliance Specs currently available in Trivy can be found in the trivy-checks/pkg/specs/compliance/ directory (Link).

    -

    New checks are based on the custom compliance report detailed in the main documentation. -If you would like to create your custom compliance report, please reference the information in the main documentation. This section details how community members can contribute new Compliance Specs to Trivy.

    -

    All compliance specs in Trivy are based on formal compliance reports such as CIS Benchmarks.

    -

    Contributing new Compliance Specs

    -

    Compliance specs can be based on new compliance reports becoming available e.g. a new CIS Benchmark version, or identifying missing compliance specs that Trivy users would like to access.

    -

    Create a new Compliance Spec

    -

    The existing compliance specs in Trivy are located under the trivy-checks/pkg/specs/compliance/ directory (Link).

    -

    Create a new file under trivy-checks/specs/compliance/ and name the file in the format of "provider-resource-spectype-version.yaml". For example, the file name for AWS CIS Benchmarks for EKS version 1.4 is: aws-eks-cis-1.4.yaml. Note that if the compliance spec is not specific to a provider, the provider field can be ignored.

    -

    Minimum spec structure

    -

    The structure of the compliance spec is detailed in the main documentation.

    -

    The first section in the spec is focused on the metadata of the spec. Replace all the fields of the metadata with the information relevant to the compliance spec that will be added. This information can be taken from the official report e.g. the CIS Benchmark report.

    -

    Populating the control section

    -

    Compliance specs detail a set of checks that should pass so that the resource is compliant with the official benchmark specifications. There are two ways in which Trivy compliance checks can enforce the compliance specification:

    -
      -
    1. The check is available in Trivy, as part of the trivy-checks and can be referenced in the Compliance Spec
    2. -
    3. The check is not available in Trivy and a manual check has to be added to the Compliance Spec
    4. -
    -

    Additional information is provided below.

    -

    1. Referencing a check that is already part of Trivy

    -

    Trivy has a comprehensive list of checks as part of its misconfiguration scanning. These can be found in the trivy-checks/checks directory (Link). If the check is present, the AVD_ID and other information from the check has to be used.

    -

    Note: Take a look at the more generic compliance specs that are already available in Trivy. If you are adding new compliance spec to Kubernetes e.g. AWS EKS CIS Benchmarks, chances are high that the check you would like to add to the new spec has already been defined in the general k8s-ci-v.000.yaml compliance spec. The same applies for creating specific Cloud Provider Compliance Specs and the generic compliance specs available.

    -

    For example, the following check is detailed in the AWS EKS CIS v1.4 Benchmark: -3.1.2 Ensure that the kubelet kubeconfig file ownership is set to root:root (Manual)

    -

    This check can be found in the general K8s CIS Compliance Benchmark: k8s-cis-1.23.yaml (Link)

    -

    Thus, we can use the information already present:

    -
      - id: 3.1.2
    -    name: Ensure that the kubelet service file ownership is set to root:root (Manual)
    -    description: Ensure that the kubelet service file ownership is set to root:root
    -    checks:
    -      - id: AVD-KCV-0070
    -    severity: HIGH
    -
    -
      -
    • The ID, name, and description is taken directly from the AWS EKS CIS Benchmarks
    • -
    • The check and severity are taken from the existing complaince check in the k8s-cis-1.23.yaml
    • -
    -

    2. Referencing a check manually that is not part of the Trivy default checks

    -

    If the check does not already exist in the Aqua Vulnerability Database (AVD) and is not part of the trivy-checks, the fields in the compliance spec for the check have to be populated manually. This is done by referencing the information in the official compliance specification.

    -

    Below is the beginning of the information of the EKS CIS Benchmarks v1.4.0:

    -

    EKS Benchmarks 2.1.1

    -

    The corresponding check in the control section will look like this:

    -
      - id: 2.1.1
    -    name: Enable audit Logs (Manual)
    -    description: |
    -      Control plane logs provide visibility into operation of the EKS Control plane components systems. 
    -      The API server audit logs record all accepted and rejected requests in the cluster. 
    -      When enabled via EKS configuration the control plane logs for a cluster are exported to a CloudWatch 
    -      Log Group for persistence.
    -    checks: null
    -    severity: MEDIUM
    -
    -
      -
    • Again, the id, name and description are taken directly from the EKS CIS Benchmarks v1.4.0
    • -
    • The checks is in this case null as the check is not currently present in the AVD and does not have a check in the trivy policies repository
    • -
    • Since the check does not exist in Trivy, the severity will be MEDIUM. However, in some cases, the compliance report e.g. the CIS Benchmark report will specify the severity
    • -
    -

    Contributing new checks to trivy-checks

    -

    All of the checks in trivy-policies can be referenced in the compliance specs. -To write new Rego checks for Trivy, please take a look at the contributing documentation for checks.

    -

    Test the Compliance Spec

    -

    To test the compliance check, pass the new path into the Trivy scan through the --compliance flag. For instance, to pass the check to the Trivy Kubernetes scan use the following command structure:

    -
    trivy k8s cluster --compliance @</path/to/compliance.yaml> --report summary
    -
    -

    Note: The @ is required before the filepath.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/cache/index.html b/v0.58.0/docs/configuration/cache/index.html deleted file mode 100644 index ddcceb6b5058..000000000000 --- a/v0.58.0/docs/configuration/cache/index.html +++ /dev/null @@ -1,8058 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cache - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Cache

    -

    The cache directory includes

    - -

    The cache option is common to all scanners.

    -

    Clear Caches

    -

    trivy clean subcommand removes caches.

    -
    $ trivy clean --scan-cache
    -
    -
    -Result - -
    2024-06-21T21:58:21+04:00       INFO    Removing scan cache...
    -
    - -
    - -

    If you want to delete cached vulnerability databases, use --vuln-db. -You can also delete all caches with --all. -See trivy clean --help for details.

    -

    Cache Directory

    -

    Specify where the cache is stored with --cache-dir.

    -
    $ trivy --cache-dir /tmp/trivy/ image python:3.4-alpine3.9
    -
    -

    Scan Cache Backend

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy utilizes a scan cache to store analysis results, such as package lists. -It supports three types of backends for this cache:

    -
      -
    • Local File System (fs)
        -
      • The cache path can be specified by --cache-dir
      • -
      -
    • -
    • Memory (memory)
    • -
    • Redis (redis://)
        -
      • redis://[HOST]:[PORT]
      • -
      • TTL can be configured via --cache-ttl
      • -
      -
    • -
    -

    Local File System

    -

    The local file system backend is the default choice for container and VM image scans. -When scanning container images, it stores analysis results on a per-layer basis, using layer IDs as keys. -This approach enables faster scans of the same container image or different images that share layers.

    -
    -

    Note

    -

    Internally, this backend uses BoltDB, which has an important limitation: only one process can access the cache at a time. -Subsequent processes attempting to access the cache will be locked. -For more details on this limitation, refer to the troubleshooting guide.

    -
    -

    Memory

    -

    The memory backend stores analysis results in memory, which means the cache is discarded when the process ends. -This makes it useful in scenarios where caching is not required or desired. -It serves as the default for repository, filesystem and SBOM scans and can also be employed for container image scans when caching is unnecessary.

    -

    To use the memory backend for a container image scan, you can use the following command:

    -
    $ trivy image debian:11 --cache-backend memory
    -
    -

    Redis

    -

    The Redis backend is particularly useful when you need to share the cache across multiple Trivy instances. -You can set up Trivy to use a Redis backend with a command like this:

    -
    $ trivy server --cache-backend redis://localhost:6379
    -
    -

    This approach allows for centralized caching, which can be beneficial in distributed or high-concurrency environments.

    -

    If you want to use TLS with Redis, you can enable it by specifying the --redis-tls flag.

    -
    $ trivy server --cache-backend redis://localhost:6379 --redis-tls
    -
    -

    Trivy also supports for connecting to Redis with your certificates. -You need to specify --redis-ca , --redis-cert , and --redis-key options.

    -
    $ trivy server --cache-backend redis://localhost:6379 \
    -  --redis-ca /path/to/ca-cert.pem \
    -  --redis-cert /path/to/cert.pem \
    -  --redis-key /path/to/key.pem
    -
    -
    -
    -
      -
    1. -

      Downloaded when scanning for vulnerabilities 

      -
    2. -
    3. -

      Downloaded when scanning jar/war/par/ear files 

      -
    4. -
    5. -

      Downloaded when scanning for misconfigurations 

      -
    6. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/db/index.html b/v0.58.0/docs/configuration/db/index.html deleted file mode 100644 index 7eb7ead6a5b3..000000000000 --- a/v0.58.0/docs/configuration/db/index.html +++ /dev/null @@ -1,8175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Databases - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    - -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Trivy Databases

    -

    When you install Trivy, the installed artifact contains the scanner engine but is lacking relevant security information needed to make security detections and recommendations. -These so called "databases" are automatically fetched and maintained by Trivy as needed, so normally you shouldn't notice or worry about them.
    -This document elaborates on the database management mechanism and its configuration options.

    -

    Trivy relies on the following databases:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    DBArtifact nameContentsPurpose
    Vulnerabilities DBtrivy-dbCVE information collected from various feedsused only for vulnerability scanning
    Java DBtrivy-java-dbIndex of Java artifacts and their hash digestused to identify Java artifacts only in JAR scanning
    Checks Bundletrivy-checksLogic of misconfiguration checksused only in misconfiguration/IaC scanning
    -
    -

    Note

    -

    This is not an exhaustive list of Trivy's external connectivity requirements. -There are additional external resources which may be required by specific Trivy features. -To learn about external connectivity requirements, see the Advanced Network Scenarios.

    -
    -

    Locations

    -

    Trivy's databases are published to the following locations:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    RegistryImage AddressLink
    GHCRghcr.io/aquasecurity/trivy-dbhttps://ghcr.io/aquasecurity/trivy-db
    ghcr.io/aquasecurity/trivy-java-dbhttps://ghcr.io/aquasecurity/trivy-java-db
    ghcr.io/aquasecurity/trivy-checkshttps://ghcr.io/aquasecurity/trivy-checks
    Docker Hubaquasec/trivy-dbhttps://hub.docker.com/r/aquasec/trivy-db
    aquasec/trivy-java-dbhttps://hub.docker.com/r/aquasec/trivy-java-db
    aquasec/trivy-checkshttps://hub.docker.com/r/aquasec/trivy-checks
    AWS ECRpublic.ecr.aws/aquasecurity/trivy-dbhttps://gallery.ecr.aws/aquasecurity/trivy-db
    public.ecr.aws/aquasecurity/trivy-java-dbhttps://gallery.ecr.aws/aquasecurity/trivy-java-db
    public.ecr.aws/aquasecurity/trivy-checkshttps://gallery.ecr.aws/aquasecurity/trivy-checks
    -

    In addition, images are also available via pull-through cache registries like Google Container Registry Mirror.

    -

    Default Locations

    -

    Trivy will attempt to pull images from the following registries in the order specified.

    -
      -
    1. mirror.gcr.io/aquasec
    2. -
    3. ghcr.io/aquasecurity
    4. -
    -

    You can specify additional alternative repositories as explained in the configuring database locations section.

    -

    DB Management Configuration

    -

    Database Locations

    -

    You can configure Trivy to download databases from alternative locations by using the flags:

    -
      -
    • --db-repository
    • -
    • --java-db-repository
    • -
    • --checks-bundle-repository
    • -
    -

    The value should be an image address in a container registry.

    -

    For example:

    -
    trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db alpine
    -
    -

    The flags accepts multiple values, which can be used to specify multiple alternative repository locations. In case of a transient errors (e.g. status 429 or 5xx), Trivy will fall back to alternative registries in the order specified.

    -

    For example:

    -
    trivy image --db-repository my.registry.local/trivy-db --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db alpine
    -
    -

    The Checks Bundle registry location option does not support fallback through multiple options. This is because in case of a failure pulling the Checks Bundle, Trivy will use the embedded checks as a fallback.

    -
    -

    Note

    -

    Setting the repository location flags override the default values which include the official db locations. In case you want to preserve the default locations, you should include them in the list the you set as repository locations.

    -
    -
    -

    Note

    -

    When pulling trivy-db or trivy-java-db, if image tag is not specified, Trivy defaults to the db schema number instead of the latest tag.

    -
    -

    Skip updates

    -

    You can configure Trivy to not attempt to download any or all database(s), using the flags:

    -
      -
    • --skip-db-update
    • -
    • --skip-java-db-update
    • -
    • --skip-check-update
    • -
    -

    For example:

    -
    trivy image --skip-db-update --skip-java-db-update --skip-check-update alpine
    -
    -

    Only update

    -

    You can ask Trivy to only update the database without performing a scan. This action will ensure Trivy is up to date, and populate Trivy's database cache for subsequent scans.

    -
      -
    • --download-db-only
    • -
    • --download-java-db-only
    • -
    -

    For example:

    -
    trivy image --download-db-only
    -
    -

    Note that currently there is no option to download only the Checks Bundle.

    -

    Remove Databases

    -

    trivy clean command removes caches and databases. -You can select which cache component to remove:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    optiondescription
    -a/--allremove all caches
    --checks-bundleremove checks bundle
    --java-dbremove Java database
    --scan-cacheremove scan cache (container and VM image analysis results)
    --vuln-dbremove vulnerability database
    -

    Example:

    -
    $ trivy clean --vuln-db --java-db
    -2024-06-24T11:42:31+06:00       INFO    Removing vulnerability database...
    -2024-06-24T11:42:31+06:00       INFO    Removing Java database...
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/filtering/index.html b/v0.58.0/docs/configuration/filtering/index.html deleted file mode 100644 index 7e7abedeaa59..000000000000 --- a/v0.58.0/docs/configuration/filtering/index.html +++ /dev/null @@ -1,8686 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filtering - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    - -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Filtering

    -

    Trivy provides various methods for filtering the results.

    -
    flowchart LR
    -  Issues("Detected\nIssues") --> Severity
    -
    -  subgraph Filtering
    -    subgraph Prioritization
    -        direction TB
    -        Severity("By Severity") --> Status("By Status")
    -    end
    -    subgraph Suppression
    -        Status --> Ignore("By Finding IDs")
    -        Ignore --> Rego("By Rego")
    -        Rego --> VEX("By VEX")
    -    end
    -  end
    -  VEX --> Results
    -

    Similar to the functionality of filtering results, you can also limit the sub-targets for each scanner. -For information on these settings, please refer to the scanner-specific documentation (vulnerability , misconfiguration, etc.).

    -

    Prioritization

    -

    You can filter the results by

    - -

    By Severity

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Use --severity option.

    -
    $ trivy image --severity HIGH,CRITICAL ruby:2.4.0
    -
    -
    -Result - -
    2019-05-16T01:51:46.255+0900    INFO    Updating vulnerability database...
    -2019-05-16T01:51:49.213+0900    INFO    Detecting Debian vulnerabilities...
    -
    -ruby:2.4.0 (debian 8.7)
    -=======================
    -Total: 1785 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1680, CRITICAL: 105)
    -
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -|           LIBRARY           | VULNERABILITY ID | SEVERITY |     INSTALLED VERSION     |          FIXED VERSION           |                      TITLE                      |
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -| apt                         | CVE-2019-3462    | CRITICAL | 1.0.9.8.3                 | 1.0.9.8.5                        | Incorrect sanitation of the                     |
    -|                             |                  |          |                           |                                  | 302 redirect field in HTTP                      |
    -|                             |                  |          |                           |                                  | transport method of...                          |
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -| bash                        | CVE-2019-9924    | HIGH     | 4.3-11                    | 4.3-11+deb8u2                    | bash: BASH_CMD is writable in                   |
    -|                             |                  |          |                           |                                  | restricted bash shells                          |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2016-7543    |          |                           | 4.3-11+deb8u1                    | bash: Specially crafted                         |
    -|                             |                  |          |                           |                                  | SHELLOPTS+PS4 variables allows                  |
    -|                             |                  |          |                           |                                  | command substitution                            |
    -+-----------------------------+------------------+          +---------------------------+----------------------------------+-------------------------------------------------+
    -| binutils                    | CVE-2017-8421    |          | 2.25-5                    |                                  | binutils: Memory exhaustion in                  |
    -|                             |                  |          |                           |                                  | objdump via a crafted PE file                   |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2017-14930   |          |                           |                                  | binutils: Memory leak in                        |
    -|                             |                  |          |                           |                                  | decode_line_info                                |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2017-7614    |          |                           |                                  | binutils: NULL                                  |
    -|                             |                  |          |                           |                                  | pointer dereference in                          |
    -|                             |                  |          |                           |                                  | bfd_elf_final_link function                     |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2014-9939    |          |                           |                                  | binutils: buffer overflow in                    |
    -|                             |                  |          |                           |                                  | ihex.c                                          |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2017-13716   |          |                           |                                  | binutils: Memory leak with the                  |
    -|                             |                  |          |                           |                                  | C++ symbol demangler routine                    |
    -|                             |                  |          |                           |                                  | in libiberty                                    |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2018-12699   |          |                           |                                  | binutils: heap-based buffer                     |
    -|                             |                  |          |                           |                                  | overflow in finish_stab in                      |
    -|                             |                  |          |                           |                                  | stabs.c                                         |
    -+-----------------------------+------------------+          +---------------------------+----------------------------------+-------------------------------------------------+
    -| bsdutils                    | CVE-2015-5224    |          | 2.25.2-6                  |                                  | util-linux: File name                           |
    -|                             |                  |          |                           |                                  | collision due to incorrect                      |
    -|                             |                  |          |                           |                                  | mkstemp use                                     |
    -+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+
    -|                             | CVE-2016-2779    |          |                           |                                  | util-linux: runuser tty hijack                  |
    -|                             |                  |          |                           |                                  | via TIOCSTI ioctl                               |
    -+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
    -
    - -
    - -
    trivy config --severity HIGH,CRITICAL examples/misconf/mixed
    -
    -
    -Result - -
    2022-05-16T13:50:42.718+0100    INFO    Detected config files: 3
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 17 (SUCCESSES: 16, FAILURES: 1)
    -Failures: 1 (HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Last USER command in Dockerfile should not be 'root'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - Dockerfile:3
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   3 [ USER root
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -deployment.yaml (kubernetes)
    -============================
    -Tests: 8 (SUCCESSES: 8, FAILURES: 0)
    -Failures: 0 (HIGH: 0, CRITICAL: 0)
    -
    -
    -main.tf (terraform)
    -===================
    -Tests: 1 (SUCCESSES: 0, FAILURES: 1)
    -Failures: 1 (HIGH: 0, CRITICAL: 1)
    -
    -CRITICAL: Classic resources should not be used.
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -AWS Classic resources run in a shared environment with infrastructure owned by other AWS customers. You should run
    -resources in a VPC instead.
    -
    -See https://avd.aquasec.com/misconfig/avd-aws-0081
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - main.tf:2-4
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   2  resource "aws_db_security_group" "sg" {
    -   3 │
    -   4  }
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    - -

    By Status

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Trivy supports the following vulnerability statuses:

    -
      -
    • unknown
    • -
    • not_affected: this package is not affected by this vulnerability on this platform
    • -
    • affected: this package is affected by this vulnerability on this platform, but there is no patch released yet
    • -
    • fixed: this vulnerability is fixed on this platform
    • -
    • under_investigation: it is currently unknown whether or not this vulnerability affects this package on this platform, and it is under investigation
    • -
    • will_not_fix: this package is affected by this vulnerability on this platform, but there is currently no intention to fix it (this would primarily be for flaws that are of Low or Moderate impact that pose no significant risk to customers)
    • -
    • fix_deferred: this package is affected by this vulnerability on this platform, and may be fixed in the future
    • -
    • end_of_life: this package has been identified to contain the impacted component, but analysis to determine whether it is affected or not by this vulnerability was not performed
    • -
    -

    Note that vulnerabilities with the unknown, not_affected or under_investigation status are not detected. -These are only defined for comprehensiveness, and you will not have the opportunity to specify these statuses.

    -

    Some statuses are supported in limited distributions.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OSFixedAffectedUnder InvestigationWill Not FixFix DeferredEnd of Life
    Debian
    RHEL
    Other OSes
    -

    To ignore vulnerabilities with specific statuses, use the --ignore-status <list_of_statuses> option.

    -
    $ trivy image --ignore-status affected,fixed ruby:2.4.0
    -
    -
    -Result - -
    2019-05-16T12:50:14.786+0900    INFO    Detecting Debian vulnerabilities...
    -
    -ruby:2.4.0 (debian 8.7)
    -=======================
    -Total: 527 (UNKNOWN: 0, LOW: 276, MEDIUM: 83, HIGH: 158, CRITICAL: 10)
    -
    -┌─────────────────────────────┬──────────────────┬──────────┬──────────────┬────────────────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
    -│           Library           │  Vulnerability   │ Severity │    Status    │     Installed Version      │ Fixed Version │                            Title                             │
    -├─────────────────────────────┼──────────────────┼──────────┼──────────────┼────────────────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
    -│ binutils                    │ CVE-2014-9939    │ CRITICAL │ will_not_fix │ 2.25-5                     │               │ binutils: buffer overflow in ihex.c                          │
    -│                             │                  │          │              │                            │               │ https://avd.aquasec.com/nvd/cve-2014-9939                    │
    -│                             ├──────────────────┤          │              │                            ├───────────────┼──────────────────────────────────────────────────────────────┤
    -│                             │ CVE-2017-6969    │          │              │                            │               │ binutils: Heap-based buffer over-read in readelf when        │
    -│                             │                  │          │              │                            │               │ processing corrupt RL78 binaries                             │
    -│                             │                  │          │              │                            │               │ https://avd.aquasec.com/nvd/cve-2017-6969                    │
    -│                             ├──────────────────┤          │              │                            ├───────────────┼──────────────────────────────────────────────────────────────┤
    -...
    -
    - -
    - -
    -

    Tip

    -

    To skip all unfixed vulnerabilities, you can use the --ignore-unfixed flag . -It is a shorthand of --ignore-status affected,will_not_fix,fix_deferred,end_of_life. -It displays "fixed" vulnerabilities only.

    -
    -
    $ trivy image --ignore-unfixed ruby:2.4.0
    -
    -

    Suppression

    -

    You can filter the results by

    - -

    To show the suppressed results, use the --show-suppressed flag.

    -
    -

    Note

    -

    It's exported as ExperimentalModifiedFindings in the JSON output.

    -
    -
    $ trivy image --vex debian11.csaf.vex --ignorefile .trivyignore.yaml --show-suppressed debian:11
    -...
    -
    -Suppressed Vulnerabilities (Total: 9)
    -
    -┌───────────────┬───────────────┬──────────┬──────────────┬─────────────────────────────────────────────┬───────────────────┐
    -│    Library     Vulnerability  Severity     Status                      Statement                        Source       │
    -├───────────────┼───────────────┼──────────┼──────────────┼─────────────────────────────────────────────┼───────────────────┤
    -│ libdb5.3       CVE-2019-8457  CRITICAL  not_affected  vulnerable_code_not_in_execute_path          CSAF VEX          │
    -├───────────────┼───────────────┼──────────┼──────────────┼─────────────────────────────────────────────┼───────────────────┤
    -│ bsdutils       CVE-2022-0563  LOW       ignored       Accept the risk                              .trivyignore.yaml │
    -├───────────────┤                                                                                                       │
    -│ libblkid1                                                                                                            │
    -├───────────────┤                                                                                                       │
    -│ libmount1                                                                                                            │
    -├───────────────┤                                                                                                       │
    -│ libsmartcols1                                                                                                        │
    -├───────────────┤                                                                                                       │
    -│ libuuid1                                                                                                             │
    -├───────────────┤                                                                                                       │
    -│ mount                                                                                                                │
    -├───────────────┼───────────────┤                        ├─────────────────────────────────────────────┤                   │
    -│ tar            CVE-2005-2541                          The vulnerable configuration is not enabled                    │
    -├───────────────┼───────────────┤                        ├─────────────────────────────────────────────┤                   │
    -│ util-linux     CVE-2022-0563                          Accept the risk                                                │
    -└───────────────┴───────────────┴──────────┴──────────────┴─────────────────────────────────────────────┴───────────────────┘
    -
    -

    By Finding IDs

    -

    Trivy supports the .trivyignore and .trivyignore.yaml ignore files.

    -

    .trivyignore

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ cat .trivyignore
    -# Accept the risk
    -CVE-2018-14618
    -
    -# Accept the risk until 2023-01-01
    -CVE-2019-14697 exp:2023-01-01
    -
    -# No impact in our settings
    -CVE-2019-1543
    -
    -# Ignore misconfigurations
    -AVD-DS-0002
    -
    -# Ignore secrets
    -generic-unwanted-rule
    -aws-account-id
    -
    -
    $ trivy image python:3.4-alpine3.9
    -
    -
    -Result - -
    2019-05-16T12:53:10.076+0900    INFO    Updating vulnerability database...
    -2019-05-16T12:53:28.134+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    - -
    - -

    .trivyignore.yaml

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    When the extension of the specified ignore file is either .yml or .yaml, Trivy will load the file as YAML. -For the .trivyignore.yaml file, you can set ignored IDs separately for vulnerabilities, misconfigurations, secrets, or licenses1.

    -

    Available fields:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FieldRequiredTypeDescription
    idstringThe identifier of the vulnerability, misconfiguration, secret, or license1.
    paths2string arrayThe list of file paths to ignore. If paths is not set, the ignore finding is applied to all files.
    purlsstring arrayThe list of PURLs to ignore packages. If purls is not set, the ignore finding is applied to all packages. This field is currently available only for vulnerabilities.
    expired_atdate (yyyy-mm-dd)The expiration date of the ignore finding. If expired_at is not set, the ignore finding is always valid.
    statementstringThe reason for ignoring the finding. (This field is not used for filtering.)
    -
    $ cat .trivyignore.yaml
    -vulnerabilities:
    -  - id: CVE-2022-40897
    -    paths:
    -      - "usr/local/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/METADATA"
    -    statement: Accept the risk
    -  - id: CVE-2023-2650
    -  - id: CVE-2023-3446
    -  - id: CVE-2023-3817
    -    purls:
    -      - "pkg:deb/debian/libssl1.1"
    -  - id: CVE-2023-29491
    -    expired_at: 2023-09-01
    -
    -misconfigurations:
    -  - id: AVD-DS-0001
    -  - id: AVD-DS-0002
    -    paths:
    -      - "docs/Dockerfile"
    -    statement: The image needs root privileges
    -
    -secrets:
    -  - id: aws-access-key-id
    -  - id: aws-secret-access-key
    -    paths:
    -      - "foo/bar/aws.secret"
    -
    -licenses:
    -  - id: GPL-3.0 # License name is used as ID
    -    paths:
    -      - "usr/share/gcc/python/libstdcxx/v6/__init__.py"
    -
    -

    Since this feature is experimental, you must explicitly specify the YAML file path using the --ignorefile flag. -Once this functionality is stable, the YAML file will be loaded automatically.

    -
    $ trivy image --ignorefile ./.trivyignore.yaml python:3.9.16-alpine3.16
    -
    -
    -Result - -
    2023-08-31T11:10:27.155+0600    INFO    Vulnerability scanning is enabled
    -2023-08-31T11:10:27.155+0600    INFO    Secret scanning is enabled
    -2023-08-31T11:10:27.155+0600    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
    -2023-08-31T11:10:27.155+0600    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/scanner/secret/#recommendation for faster secret detection
    -2023-08-31T11:10:29.164+0600    INFO    Detected OS: alpine
    -2023-08-31T11:10:29.164+0600    INFO    Detecting Alpine vulnerabilities...
    -2023-08-31T11:10:29.169+0600    INFO    Number of language-specific files: 1
    -2023-08-31T11:10:29.170+0600    INFO    Detecting python-pkg vulnerabilities...
    -
    -python:3.9.16-alpine3.16 (alpine 3.16.5)
    -========================================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    - -
    - -

    By Rego

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Rego is a policy language that allows you to express decision logic in a concise syntax. -Rego is part of the popular Open Policy Agent (OPA) CNCF project. -For advanced filtering, Trivy allows you to use Rego language to filter vulnerabilities.

    -

    Use the --ignore-policy flag which takes a path to a Rego file that defines the filtering policy. -The Rego package name must be trivy and it must include a "rule" named ignore which determines if each individual scan result should be excluded (ignore=true) or not (ignore=false). -The input for the evaluation is each DetectedVulnerability and DetectedMisconfiguration.

    -

    A practical way to observe the filtering policy input in your case, is to run a scan with the --format json option and look at the resulting structure:

    -
    trivy image -f json centos:7
    -
    -...
    -  "Results": [
    -    {
    -      "Target": "centos:7 (centos 7.9.2009)",
    -      "Class": "os-pkgs",
    -      "Type": "centos",
    -      "Vulnerabilities": [
    -        {
    -          "VulnerabilityID": "CVE-2015-5186",
    -          "PkgID": "audit-libs@2.8.5-4.el7.x86_64",
    -          "PkgName": "audit-libs",
    -          "InstalledVersion": "2.8.5-4.el7",
    -          "Layer": {
    -            "Digest": "sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc",
    -            "DiffID": "sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02"
    -          },
    -          "SeveritySource": "redhat",
    -          "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2015-5186",
    -          "Title": "log terminal emulator escape sequences handling",
    -          "Description": "Audit before 2.4.4 in Linux does not sanitize escape characters in filenames.",
    -          "Severity": "MEDIUM",
    -          "CweIDs": [
    -            "CWE-20"
    -          ],
    -...
    -
    -

    Each individual Vulnerability, Misconfiguration, License and Secret (under Results.Vulnerabilities, Results.Misconfigurations, -Results.Licenses, Results.Secrets) is evaluated for exclusion or inclusion by the ignore rule.

    -

    The following is a Rego ignore policy that filters out every vulnerability with a specific CWE ID (as seen in the JSON example above):

    -
    package trivy
    -
    -default ignore = false
    -
    -ignore {
    -    input.CweIDs[_] == "CWE-20"
    -}
    -
    -
    trivy image --ignore-policy examples/ignore-policies/basic.rego centos:7
    -
    -

    For more advanced use cases, there is a built-in Rego library with helper functions that you can import into your policy using: import data.lib.trivy. -More info about the helper functions are in the library here.

    -

    You can create a whitelist of checks using Rego, see the detailed example. Additional examples are available here.

    -

    By Vulnerability Exploitability Exchange (VEX)

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Please refer to the VEX documentation for the details.

    -
    -
    -
      -
    1. -

      license name is used as id for .trivyignore.yaml files. 

      -
    2. -
    3. -

      This doesn't work for os package licenses (e.g. apk, dpkg, rpm). For projects which manage dependencies through a dependency file (e.g. go.mod, yarn.lock) path should point to that particular file. 

      -
    4. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/index.html b/v0.58.0/docs/configuration/index.html deleted file mode 100644 index 093a8e183f5c..000000000000 --- a/v0.58.0/docs/configuration/index.html +++ /dev/null @@ -1,7911 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Configuration

    -

    Trivy's settings can be configured in any of the following methods, which will apply in the following precedence:

    -
      -
    1. CLI flags (overrides all other settings)
    2. -
    3. Environment variables (overrides config file settings)
    4. -
    5. Configuration file
    6. -
    -

    CLI Flags

    -

    You can view the list of available flags by adding the --help flag to a Trivy command, or by exploring the CLI reference.

    -

    Environment Variables

    -

    Any CLI option can be set as an environment variable. The environment variable name are similar to the CLI option name, with the following augmentations:

    -
      -
    • Add TRIVY_ prefix
    • -
    • All uppercase letters
    • -
    • Replace - with _
    • -
    -

    For example:

    -
      -
    • --debug => TRIVY_DEBUG
    • -
    • --cache-dir => TRIVY_CACHE_DIR
    • -
    -
    $ TRIVY_DEBUG=true TRIVY_SEVERITY=CRITICAL trivy image alpine:3.15
    -
    -

    Configuration File

    -

    Any setting can be set in a YAML file. By default, config file named trivy.yaml is read from the current directory where Trivy is run. To load configuration from a different file, use the --config flag and specify the config path to load: trivy --config /etc/trivy/myconfig.yaml.

    -

    The structure and settings of the YAML config file is documented in the Config file document.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/others/index.html b/v0.58.0/docs/configuration/others/index.html deleted file mode 100644 index 082b932ec169..000000000000 --- a/v0.58.0/docs/configuration/others/index.html +++ /dev/null @@ -1,8025 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Others - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Others

    -

    Enable/Disable Scanners

    -

    You can enable/disable scanners with the --scanners flag.

    -

    Supported values:

    -
      -
    • vuln
    • -
    • misconfig
    • -
    • secret
    • -
    • license
    • -
    -

    For example, container image scanning enables vulnerability and secret scanners by default. -If you don't need secret scanning, it can be disabled.

    -
    $ trivy image --scanners vuln alpine:3.15
    -
    -

    Exit Code

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy exits with code 0 even when security issues are detected. -Use the --exit-code option if you want to exit with a non-zero exit code.

    -
    $ trivy image --exit-code 1 python:3.4-alpine3.9
    -
    -
    -Result - -
    2019-05-16T12:51:43.500+0900    INFO    Updating vulnerability database...
    -2019-05-16T12:52:00.387+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |
    -|         |                  |          |                   |               | with long nonces               |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -
    - -
    - -

    This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found.

    -
    $ trivy image --exit-code 0 --severity MEDIUM,HIGH ruby:2.4.0
    -$ trivy image --exit-code 1 --severity CRITICAL ruby:2.4.0
    -
    -

    Exit on EOL

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Sometimes you may surprisingly get 0 vulnerabilities in an old image:

    -
      -
    • Enabling --ignore-unfixed option while all packages have no fixed versions.
    • -
    • Scanning a rather outdated OS (e.g. Ubuntu 10.04).
    • -
    -

    An OS at the end of service/life (EOL) usually gets into this situation, which is definitely full of vulnerabilities. ---exit-on-eol can fail scanning on EOL OS with a non-zero code. -This flag is available with the following targets.

    -
      -
    • Container images (trivy image)
    • -
    • Virtual machine images (trivy vm)
    • -
    • SBOM (trivy sbom)
    • -
    • Root filesystem (trivy rootfs)
    • -
    -
    $ trivy image --exit-on-eol 1 alpine:3.10
    -
    -
    -Result - -
    2023-03-01T11:07:15.455+0200    INFO    Vulnerability scanning is enabled
    -...
    -2023-03-01T11:07:17.938+0200    WARN    This OS version is no longer supported by the distribution: alpine 3.10.9
    -2023-03-01T11:07:17.938+0200    WARN    The vulnerability detection may be insufficient because security updates are not provided
    -
    -alpine:3.10 (alpine 3.10.9)
    -===========================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
    -
    -┌───────────┬────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│  Library  │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├───────────┼────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ apk-tools │ CVE-2021-36159 │ CRITICAL │ 2.10.6-r0         │ 2.10.7-r0     │ libfetch before 2021-07-26, as used in apk-tools, xbps, and │
    -│           │                │          │                   │               │ other products, mishandles...                               │
    -│           │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-36159                  │
    -└───────────┴────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -2023-03-01T11:07:17.941+0200    ERROR   Detected EOL OS: alpine 3.10.9
    -
    - -
    - -

    This option is useful for CI/CD. -The following example will fail when a critical vulnerability is found or the OS is EOSL:

    -
    $ trivy image --exit-code 1 --exit-on-eol 1 --severity CRITICAL alpine:3.16.3
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/reporting/index.html b/v0.58.0/docs/configuration/reporting/index.html deleted file mode 100644 index 0183c799ea59..000000000000 --- a/v0.58.0/docs/configuration/reporting/index.html +++ /dev/null @@ -1,8852 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reporting - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Reporting

    -

    Format

    -

    Trivy supports the following formats:

    -
      -
    • Table
    • -
    • JSON
    • -
    • SARIF
    • -
    • Template
    • -
    • SBOM
    • -
    • GitHub dependency snapshot
    • -
    -

    Table (Default)

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ trivy image -f table golang:1.12-alpine
    -
    -

    Show origins of vulnerable dependencies

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Modern software development relies on the use of third-party libraries. -Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph. -In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree. -To make this task simpler Trivy can show a dependency origin tree with the --dependency-tree flag. -This flag is only available with the --format table flag.

    -

    The following OS package managers are currently supported:

    - - - - - - - - - - - - - - - - - -
    OS Package Managers
    apk
    dpkg
    rpm
    -

    The following languages are currently supported:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LanguageFile
    Node.jspackage-lock.json
    pnpm-lock.yaml
    yarn.lock
    .NETpackages.lock.json
    Pythonpoetry.lock
    RubyGemfile.lock
    Rustcargo-auditable binaries
    Gogo.mod
    PHPcomposer.lock
    Javapom.xml
    *gradle.lockfile
    *.sbt.lock
    Dartpubspec.lock
    -

    This tree is the reverse of the dependency graph. -However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update.

    -

    In table output, it looks like:

    -
    $ trivy fs --severity HIGH,CRITICAL --dependency-tree /path/to/your_node_project
    -
    -package-lock.json (npm)
    -=======================
    -Total: 2 (HIGH: 1, CRITICAL: 1)
    -
    -┌──────────────────┬────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│     Library       Vulnerability   Severity  Installed Version  Fixed Version                            Title                            │
    -├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ follow-redirects  CVE-2022-0155   HIGH      1.14.6             1.14.7         follow-redirects: Exposure of Private Personal Information │
    -│                                                                               to an Unauthorized Actor                                   │
    -│                                                                               https://avd.aquasec.com/nvd/cve-2022-0155                  │
    -├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ glob-parent       CVE-2020-28469  CRITICAL  3.1.0              5.1.2          nodejs-glob-parent: Regular expression denial of service   │
    -│                                                                               https://avd.aquasec.com/nvd/cve-2020-28469                 │
    -└──────────────────┴────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -Dependency Origin Tree (Reversed)
    -=================================
    -package-lock.json
    -├── follow-redirects@1.14.6, (HIGH: 1, CRITICAL: 0)
    -│   └── axios@0.21.4
    -└── glob-parent@3.1.0, (HIGH: 0, CRITICAL: 1)
    -    └── chokidar@2.1.8
    -        └── watchpack-chokidar2@2.0.1
    -            └── watchpack@1.7.5
    -                └── webpack@4.46.0
    -                    └── cra-append-sw@2.7.0
    -
    -

    Vulnerable dependencies are shown in the top level of the tree. -Lower levels show how those vulnerabilities are introduced. -In the example above axios@0.21.4 included in the project directly depends on the vulnerable follow-redirects@1.14.6. -Also, glob-parent@3.1.0 with some vulnerabilities is included through chain of dependencies that is added by cra-append-sw@2.7.0.

    -

    Then, you can try to update axios@0.21.4 and cra-append-sw@2.7.0 to resolve vulnerabilities in follow-redirects@1.14.6 and glob-parent@3.1.0.

    -

    JSON

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ trivy image -f json -o results.json golang:1.12-alpine
    -
    -
    -Result - -
    2019-05-16T01:46:31.777+0900    INFO    Updating vulnerability database...
    -2019-05-16T01:47:03.007+0900    INFO    Detecting Alpine vulnerabilities...
    -
    - -
    - -
    -JSON - -
    [
    -  {
    -    "Target": "php-app/composer.lock",
    -    "Vulnerabilities": null
    -  },
    -  {
    -    "Target": "node-app/package-lock.json",
    -    "Vulnerabilities": [
    -      {
    -        "VulnerabilityID": "CVE-2018-16487",
    -        "PkgName": "lodash",
    -        "InstalledVersion": "4.17.4",
    -        "FixedVersion": "\u003e=4.17.11",
    -        "Title": "lodash: Prototype pollution in utilities function",
    -        "Description": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487",
    -        ]
    -      }
    -    ]
    -  },
    -  {
    -    "Target": "trivy-ci-test (alpine 3.7.1)",
    -    "Vulnerabilities": [
    -      {
    -        "VulnerabilityID": "CVE-2018-16840",
    -        "PkgName": "curl",
    -        "InstalledVersion": "7.61.0-r0",
    -        "FixedVersion": "7.61.1-r1",
    -        "Title": "curl: Use-after-free when closing \"easy\" handle in Curl_close()",
    -        "Description": "A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. ",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840",
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2019-3822",
    -        "PkgName": "curl",
    -        "InstalledVersion": "7.61.0-r0",
    -        "FixedVersion": "7.61.1-r2",
    -        "Title": "curl: NTLMv2 type-3 header stack buffer overflow",
    -        "Description": "libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. ",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://curl.haxx.se/docs/CVE-2019-3822.html",
    -          "https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E"
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2018-16839",
    -        "PkgName": "curl",
    -        "InstalledVersion": "7.61.0-r0",
    -        "FixedVersion": "7.61.1-r1",
    -        "Title": "curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()",
    -        "Description": "Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5",
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2018-19486",
    -        "PkgName": "git",
    -        "InstalledVersion": "2.15.2-r0",
    -        "FixedVersion": "2.15.3-r0",
    -        "Title": "git: Improper handling of PATH allows for commands to be executed from the current directory",
    -        "Description": "Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "https://usn.ubuntu.com/3829-1/",
    -        ]
    -      },
    -      {
    -        "VulnerabilityID": "CVE-2018-17456",
    -        "PkgName": "git",
    -        "InstalledVersion": "2.15.2-r0",
    -        "FixedVersion": "2.15.3-r0",
    -        "Title": "git: arbitrary code execution via .gitmodules",
    -        "Description": "Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \"git clone\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.",
    -        "Severity": "HIGH",
    -        "References": [
    -          "http://www.securitytracker.com/id/1041811",
    -        ]
    -      }
    -    ]
    -  },
    -  {
    -    "Target": "python-app/Pipfile.lock",
    -    "Vulnerabilities": null
    -  },
    -  {
    -    "Target": "ruby-app/Gemfile.lock",
    -    "Vulnerabilities": null
    -  },
    -  {
    -    "Target": "rust-app/Cargo.lock",
    -    "Vulnerabilities": null
    -  }
    -]
    -
    - -
    - -

    VulnerabilityID, PkgName, InstalledVersion, and Severity in Vulnerabilities are always filled with values, but other fields might be empty.

    -

    SARIF

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    SARIF (Static Analysis Results Interchange Format) complying with SARIF 2.1.0 OASIS standard can be generated with the --format sarif flag.

    -
    $ trivy image --format sarif -o report.sarif  golang:1.12-alpine
    -
    -

    This SARIF file can be uploaded to several platforms, including:

    - -

    GitHub dependency snapshot

    -

    Trivy supports the following packages:

    - -

    GitHub dependency snapshots can be generated with the --format github flag.

    -
    $ trivy image --format github -o report.gsbom alpine
    -
    -

    This snapshot file can be submitted to your GitHub repository.

    -

    Template

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Custom Template

    -
    $ trivy image --format template --template "{{ range . }} {{ .Target }} {{ end }}" golang:1.12-alpine
    -
    -
    -Result - -
    2020-01-02T18:02:32.856+0100    INFO    Detecting Alpine vulnerabilities...
    - golang:1.12-alpine (alpine 3.10.2)
    -
    -
    - -

    You can compute different figures within the template using sprig functions. -As an example you can summarize the different classes of issues:

    -
    $ trivy image --format template --template '{{- $critical := 0 }}{{- $high := 0 }}{{- range . }}{{- range .Vulnerabilities }}{{- if  eq .Severity "CRITICAL" }}{{- $critical = add $critical 1 }}{{- end }}{{- if  eq .Severity "HIGH" }}{{- $high = add $high 1 }}{{- end }}{{- end }}{{- end }}Critical: {{ $critical }}, High: {{ $high }}' golang:1.12-alpine
    -
    -
    -Result - -
    Critical: 0, High: 2
    -
    -
    - -

    For other features of sprig, see the official sprig documentation.

    -

    Load templates from a file

    -

    You can load templates from a file prefixing the template path with an @.

    -
    $ trivy image --format template --template "@/path/to/template" golang:1.12-alpine
    -
    -

    Default Templates

    -

    If Trivy is installed using rpm then default templates can be found at /usr/local/share/trivy/templates.

    -
    JUnit
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    In the following example using the template junit.tpl XML can be generated. -

    $ trivy image --format template --template "@contrib/junit.tpl" -o junit-report.xml  golang:1.12-alpine
    -

    -
    ASFF
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    Trivy also supports an ASFF template for reporting findings to AWS Security Hub

    -
    HTML
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -
    $ trivy image --format template --template "@contrib/html.tpl" -o report.html golang:1.12-alpine
    -
    -

    The following example shows use of default HTML template when Trivy is installed using rpm.

    -
    $ trivy image --format template --template "@/usr/local/share/trivy/templates/html.tpl" -o report.html golang:1.12-alpine
    -
    -

    SBOM

    -

    See here for details.

    -

    Output

    -

    Trivy supports the following output destinations:

    -
      -
    • File
    • -
    • Plugin
    • -
    -

    File

    -

    By specifying --output <file_path>, you can output the results to a file. -Here is an example:

    -
    $ trivy image --format json --output result.json debian:12
    -
    -

    Plugin

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Plugins capable of receiving Trivy's results via standard input, called "output plugin", can be seamlessly invoked using the --output flag.

    -
    $ trivy <target> [--format <format>] --output plugin=<plugin_name> [--output-plugin-arg <plugin_flags>] <target_name>
    -
    -

    This is useful for cases where you want to convert the output into a custom format, or when you want to send the output somewhere. -For more details, please check here.

    -

    Converting

    -

    To generate multiple reports, you can generate the JSON report first and convert it to other formats with the convert subcommand.

    -
    $ trivy image --format json -o result.json --list-all-pkgs debian:11
    -$ trivy convert --format cyclonedx --output result.cdx result.json
    -
    -
    -

    Note

    -

    Please note that if you want to convert to a format that requires a list of packages, -such as SBOM, you need to add the --list-all-pkgs flag when outputting in JSON.

    -
    -

    Filtering options such as --severity are also available with convert.

    -
    # Output all severities in JSON
    -$ trivy image --format json -o result.json --list-all-pkgs debian:11
    -
    -# Output only critical issues in table format
    -$ trivy convert --format table --severity CRITICAL result.json
    -
    -
    -

    Note

    -

    JSON reports from "trivy k8s" are not yet supported.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/configuration/skipping/index.html b/v0.58.0/docs/configuration/skipping/index.html deleted file mode 100644 index 23490e202307..000000000000 --- a/v0.58.0/docs/configuration/skipping/index.html +++ /dev/null @@ -1,8065 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Skipping Files - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Skipping Files and Directories

    -

    This section details ways to specify the files and directories that Trivy should not scan.

    -

    Skip Files

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy traverses directories and searches for all necessary files for scanning. -You can skip files that you don't maintain using the --skip-files flag, or the equivalent Trivy YAML config option.

    -

    Using the --skip-files flag: -

    $ trivy image --skip-files "/Gemfile.lock" --skip-files "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
    -

    -

    Using the Trivy YAML configuration: -

    image:
    -  skip-files:
    -    - foo
    -    - "testdata/*/bar"
    -

    -

    It's possible to specify globs as part of the value.

    -
    $ trivy image --skip-files "./testdata/*/bar" .
    -
    -

    This will skip any file named bar in the subdirectories of testdata.

    -
    $ trivy config --skip-files "./foo/**/*.tf" .
    -
    -

    This will skip any files with the extension .tf in subdirectories of foo at any depth.

    -

    Skip Directories

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License
    -

    By default, Trivy traverses directories and searches for all necessary files for scanning. -You can skip directories that you don't maintain using the --skip-dirs flag, or the equivalent Trivy YAML config option.

    -

    Using the --skip-dirs flag: -

    $ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
    -

    -

    Using the Trivy YAML configuration: -

    image:
    -  skip-dirs:
    -    - foo/bar/
    -    - "**/.terraform"
    -

    -

    It's possible to specify globs as part of the value.

    -
    $ trivy image --skip-dirs "./testdata/*" .
    -
    -

    This will skip all subdirectories of the testdata directory.

    -
    $ trivy config --skip-dirs "**/.terraform" .
    -
    -

    This will skip subdirectories at any depth named .terraform/. (Note: this will match ./foo/.terraform or -./foo/bar/.terraform, but not ./.terraform.)

    -
    -

    Tip

    -

    Glob patterns work with any trivy subcommand (image, config, etc.) and can be specified to skip both directories (with --skip-dirs) and files (with --skip-files).

    -
    -

    Advanced globbing

    -

    Trivy also supports bash style extended glob pattern matching.

    -
    $ trivy image --skip-files "**/foo" image:tag
    -
    -

    This will skip the file foo that happens to be nested under any parent(s).

    -

    File patterns

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Vulnerability
    Misconfiguration
    Secret
    License1
    -

    When a directory is given as an input, Trivy will recursively look for and test all files based on file patterns. -The default file patterns are here.

    -

    In addition to the default file patterns, the --file-patterns option takes regexp patterns to look for your files. -For example, it may be useful when your file name of Dockerfile doesn't match the default patterns.

    -

    This can be repeated for specifying multiple file patterns.

    -

    A file pattern contains the analyzer it is used for, and the pattern itself, joined by a semicolon. For example: -

    --file-patterns "dockerfile:.*.docker" --file-patterns "kubernetes:*.tpl" --file-patterns "pip:requirements-.*\.txt"
    -

    -

    The prefixes are listed here

    -
    -
    -
      -
    1. -

      Only work with the license-full flag) 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/azure-arm/index.html b/v0.58.0/docs/coverage/iac/azure-arm/index.html deleted file mode 100644 index e87675b089d8..000000000000 --- a/v0.58.0/docs/coverage/iac/azure-arm/index.html +++ /dev/null @@ -1,7921 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Azure ARM Template - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Azure ARM Template

    -

    Trivy supports the scanners listed in the table below.

    - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Misconfiguration
    Secret
    -

    It supports the following configurations:

    - - - - - - - - - - - - - - - - - -
    FormatSupported
    ARM template
    Bicep1
    -

    To scan Bicep codes, you need to convert them into ARM templates first.

    -
    az bicep build -f main.bicep
    -or
    -bicep build main.bicep
    -
    -

    Misconfiguration

    -

    Trivy recursively searches directories and scans all found Azure ARM templates.

    -

    Secret

    -

    The secret scan is performed on plain text files, with no special treatment for Azure ARM templates.

    -
    -
    -
      -
    1. -

      Bicep is not natively supported. It needs to be converted into Azure ARM templates. 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/cloudformation/index.html b/v0.58.0/docs/coverage/iac/cloudformation/index.html deleted file mode 100644 index e32fabbfc98c..000000000000 --- a/v0.58.0/docs/coverage/iac/cloudformation/index.html +++ /dev/null @@ -1,7948 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CloudFormation - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    CloudFormation

    -

    Trivy supports the scanners listed in the table below.

    - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Misconfiguration
    Secret
    -

    It supports the following formats.

    - - - - - - - - - - - - - - - - - -
    FormatSupported
    JSON
    YAML
    -

    Misconfiguration

    -

    Trivy recursively searches directories and scans all found CloudFormation files. -It evaluates properties, functions, and other elements within CloudFormation files to detect misconfigurations.

    -

    Value Overrides

    -

    You can provide cf-params with path to CloudFormation Parameters file to Trivy to scan your CloudFormation code with parameters.

    -
    trivy config --cf-params params.json ./infrastructure/cf
    -
    -

    You can check a CloudFormation Parameters Example

    -

    Secret

    -

    The secret scan is performed on plain text files, with no special treatment for CloudFormation.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/docker/index.html b/v0.58.0/docs/coverage/iac/docker/index.html deleted file mode 100644 index ff5be0abef9f..000000000000 --- a/v0.58.0/docs/coverage/iac/docker/index.html +++ /dev/null @@ -1,7912 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Docker - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Docker

    -

    Trivy supports the scanners listed in the table below.

    - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Misconfiguration
    Secret
    -

    It supports the following configurations.

    - - - - - - - - - - - - - - - - - - - - - -
    ConfigSupported
    Dockerfile
    Containerfile
    Compose-
    -

    Misconfiguration

    -

    Trivy recursively searches directories and scans all found Docker files.

    -

    Secret

    -

    The secret scan is performed on plain text files, with no special treatment for Dockerfile.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/helm/index.html b/v0.58.0/docs/coverage/iac/helm/index.html deleted file mode 100644 index faccdbcb4410..000000000000 --- a/v0.58.0/docs/coverage/iac/helm/index.html +++ /dev/null @@ -1,8054 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Helm - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Helm

    -

    Trivy supports two types of Helm scanning, templates and packaged charts. -The following scanners are supported.

    - - - - - - - - - - - - - - - - - - - - -
    FormatMisconfigurationSecret
    Template
    Chart-
    -

    Misconfiguration

    -

    Trivy recursively searches directories and scans all found Helm files.

    -

    It evaluates variables, functions, and other elements within Helm templates and resolve the chart to Kubernetes manifests then run the Kubernetes checks. -See here for more details on the built-in checks.

    -

    Value overrides

    -

    There are a number of options for overriding values in Helm charts. -When override values are passed to the Helm scanner, the values will be used during the Manifest rendering process and will become part of the scanned artifact.

    -

    Setting inline value overrides

    -

    Overrides can be set inline on the command line

    -
    trivy config --helm-set securityContext.runAsUser=0 ./charts/mySql
    -
    -

    Setting value file overrides

    -

    Overrides can be in a file that has the key=value set.

    -
    # Example override file (overrides.yaml)
    -
    -securityContext:
    -  runAsUser: 0
    -
    -
    trivy config --helm-values overrides.yaml ./charts/mySql
    -
    -

    Setting value as explicit string

    -

    the --helm-set-string is the same as --helm-set but explicitly retains the value as a string

    -
    trivy config --helm-set-string name=false ./infrastructure/tf
    -
    -

    Setting specific values from files

    -

    Specific override values can come from specific files

    -
    trivy config --helm-set-file environment=dev.values.yaml ./charts/mySql
    -
    -

    Secret

    -

    The secret scan is performed on plain text files, with no special treatment for Helm. -Secret scanning is not conducted on the contents of packaged Charts, such as tar or tar.gz.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/index.html b/v0.58.0/docs/coverage/iac/index.html deleted file mode 100644 index cf0a31b45dee..000000000000 --- a/v0.58.0/docs/coverage/iac/index.html +++ /dev/null @@ -1,7919 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Infrastructure as Code

    -

    Scanner

    -

    Trivy scans Infrastructure as Code (IaC) files for

    - -

    Supported configurations

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Config typeFile patterns
    Kubernetes*.yml, *.yaml, *.json
    DockerDockerfile, Containerfile
    Terraform*.tf, *.tf.json, *.tfvars
    Terraform Plantfplan, *.tfplan, *.json
    CloudFormation*.yml, *.yaml, *.json
    Azure ARM Template*.json
    Helm*.yaml, *.tpl, *.tar.gz, etc.
    YAML*.yaml, *.yml
    JSON*.json
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/kubernetes/index.html b/v0.58.0/docs/coverage/iac/kubernetes/index.html deleted file mode 100644 index 81ef8aa80a08..000000000000 --- a/v0.58.0/docs/coverage/iac/kubernetes/index.html +++ /dev/null @@ -1,7922 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kubernetes - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Kubernetes

    -

    Trivy supports the scanners listed in the table below.

    - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Misconfiguration
    Secret
    -

    In addition to raw YAML and JSON, it supports the following templates:

    - - - - - - - - - - - - - - - - - -
    TemplateSupported
    Helm
    Kustomize1
    -
    -

    Note

    -

    Trivy does not support Kustomize overlays, so it scans files defined in the base. -Or, you can scan the output of kustomize build.

    -
    -

    Misconfiguration

    -

    Trivy recursively searches directories and scans all found Kubernetes files.

    -

    Secret

    -

    The secret scan is performed on plain text files, with no special treatment for Kubernetes. -This means that Base64 encoded secrets are not scanned, and only secrets written in plain text are detected.

    -
    -
    -
      -
    1. -

      Kustomize is not natively supported. 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/iac/terraform/index.html b/v0.58.0/docs/coverage/iac/terraform/index.html deleted file mode 100644 index ae35a1564488..000000000000 --- a/v0.58.0/docs/coverage/iac/terraform/index.html +++ /dev/null @@ -1,8101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Terraform - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    - -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Terraform

    -

    Trivy supports the scanners listed in the table below.

    - - - - - - - - - - - - - - - - - -
    ScannerSupported
    Misconfiguration
    Secret
    -

    It supports the following formats:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    FormatSupported
    JSON
    HCL
    Plan Snapshot
    Plan JSON
    -

    Trivy can scan Terraform Plan files (snapshots) or their JSON representations. To create a Terraform Plan and scan it, run the following command: -

    terraform plan --out tfplan
    -trivy config tfplan
    -

    -

    To scan a Terraform Plan representation in JSON format, run the following command: -

    terraform show -json tfplan > tfplan.json
    -trivy config tfplan.json
    -

    -

    Misconfiguration

    -

    Trivy recursively searches directories and scans all found Terraform files. -It also evaluates variables, imports, and other elements within Terraform files to detect misconfigurations.

    -

    Value Overrides

    -

    You can provide tf-vars files to Trivy to override default values specified in the Terraform HCL code.

    -
    trivy config --tf-vars dev.terraform.tfvars ./infrastructure/tf
    -
    -

    Exclude Downloaded Terraform Modules

    -

    By default, downloaded modules are also scanned. -If you don't want to scan them, you can use the --tf-exclude-downloaded-modules flag.

    -
    trivy config --tf-exclude-downloaded-modules ./configs
    -
    -

    Secret

    -

    The secret scan is performed on plain text files, with no special treatment for Terraform.

    -

    Limitations

    -

    Terraform Plan JSON

    -

    For each and count objects in expression

    -

    The plan created by Terraform does not provide complete information about references in expressions that use each or count objects. For this reason, in some situations it is not possible to establish references between resources that are needed for checks when detecting misconfigurations. An example of such a configuration is:

    -
    locals {
    -  buckets = toset(["test"])
    -}
    -
    -resource "aws_s3_bucket" "this" {
    -  for_each = local.buckets
    -  bucket = each.key
    -}
    -
    -resource "aws_s3_bucket_acl" "this" {
    -  for_each = local.buckets
    -  bucket = aws_s3_bucket.this[each.key].id
    -  acl    = "private"
    -}
    -
    -

    With this configuration, the plan will not contain information about which attribute of the aws_s3_bucket resource is referenced by the aws_s3_bucket_acl resource.

    -

    See more here.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/index.html b/v0.58.0/docs/coverage/index.html deleted file mode 100644 index 2cefa5eb4cef..000000000000 --- a/v0.58.0/docs/coverage/index.html +++ /dev/null @@ -1,7785 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Scanning Coverage

    -

    Trivy can detect security issues in many different platforms, languages and configuration files. -This section gives a general overview of that coverage, and can help answer the frequently asked question "Does Trivy support X?". -For more detailed information about the specific platforms and languages, check the relevant documentation.

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/kubernetes/index.html b/v0.58.0/docs/coverage/kubernetes/index.html deleted file mode 100644 index 5510914c5d4a..000000000000 --- a/v0.58.0/docs/coverage/kubernetes/index.html +++ /dev/null @@ -1,7797 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kubernetes - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Kubernetes

    -

    When scanning a Kubernetes cluster, Trivy differentiates between the following:

    -
      -
    1. Cluster infrastructure (e.g api-server, kubelet, addons)
    2. -
    3. Cluster configuration (e.g Roles, ClusterRoles).
    4. -
    5. Application workloads (e.g nginx, postgresql).
    6. -
    -

    Whenever Trivy scans either of these Kubernetes resources, the container image is scanned separately to the Kubernetes resource definition (the YAML manifest) that defines the resource. -When scanning any of the above, the container image is scanned separately to the Kubernetes resource definition (the YAML manifest) that defines the resource.

    -

    Container image is scanned for:

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Exposed secrets
    • -
    -

    Kubernetes resource definition is scanned for:

    -
      -
    • Vulnerabilities - partially supported through KBOM scanning
    • -
    • Misconfigurations
    • -
    • Exposed secrets
    • -
    -

    To learn more, please see the documentation for Kubernetes scanning.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/c/index.html b/v0.58.0/docs/coverage/language/c/index.html deleted file mode 100644 index 9fbdb5b57e6a..000000000000 --- a/v0.58.0/docs/coverage/language/c/index.html +++ /dev/null @@ -1,7949 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C/C++ - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    C/C++

    -

    Trivy supports Conan C/C++ Package Manager (v1 and v2 with limitations).

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Conan1
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    Conan (lockfile v1)conan.lock2Excluded
    Conan (lockfile v2)conan.lock23Excluded-
    -

    Conan

    -

    In order to detect dependencies, Trivy searches for conan.lock1.

    -

    Licenses

    -

    The Conan lock file doesn't contain any license information. -To obtain licenses we parse the conanfile.py files from the conan v1 cache directory and conan v2 cache directory. -To correctly detection licenses, ensure that the cache directory contains all dependencies used.

    -
    -
    -
      -
    1. -

      The local cache should contain the dependencies used. See licenses

      -
    2. -
    3. -

      conan.lock is default name. To scan a custom filename use file-patterns

      -
    4. -
    5. -

      For conan.lock in version 2, indirect dependencies are included in analysis but not flagged explicitly in dependency tree 

      -
    6. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/dart/index.html b/v0.58.0/docs/coverage/language/dart/index.html deleted file mode 100644 index f23401cd0496..000000000000 --- a/v0.58.0/docs/coverage/language/dart/index.html +++ /dev/null @@ -1,7970 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dart - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Dart

    -

    Trivy supports Dart.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Dart-
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPositionDetection Priority
    Dartpubspec.lockIncluded-
    -

    Dart

    -

    In order to detect dependencies, Trivy searches for pubspec.lock.

    -

    Trivy marks indirect dependencies, but pubspec.lock file doesn't have options to separate root and dev transitive dependencies. -So Trivy includes all dependencies in report.

    -

    SDK dependencies

    -

    Dart uses version 0.0.0 for SDK dependencies (e.g. Flutter). -It is not possible to accurately determine the versions of these dependencies. -Trivy just treats them as 0.0.0.

    -

    If --detection-priority comprehensive is passed, Trivy uses the minimum version of the constraint for the SDK. -For example, in the following case, the version of flutter would be 3.3.0:

    -
    flutter:
    -  dependency: "direct main"
    -  description: flutter
    -  source: sdk
    -  version: "0.0.0"
    -sdks:
    -  dart: ">=2.18.0 <3.0.0"
    -  flutter: "^3.3.0"
    -
    -

    Dependency tree

    -

    To build dependency tree Trivy parses cache directory. Currently supported default directories and PUB_CACHE environment (absolute path only).

    -
    -

    Note

    -

    Make sure the cache directory contains all the dependencies installed in your application. To download missing dependencies, use dart pub get command.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/dotnet/index.html b/v0.58.0/docs/coverage/language/dotnet/index.html deleted file mode 100644 index d6778e402dea..000000000000 --- a/v0.58.0/docs/coverage/language/dotnet/index.html +++ /dev/null @@ -1,8077 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .NET - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    .NET

    -

    Trivy supports .NET core and NuGet package managers.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactSBOMVulnerabilityLicense
    .Net Core-
    NuGet
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    .Net Core*.deps.jsonExcluded-
    NuGetpackages.configExcluded--
    NuGet*Packages.props-Excluded--
    NuGetpackages.lock.jsonIncluded
    -

    *.deps.json

    -

    Trivy parses *.deps.json files. Trivy currently excludes dev dependencies from the report.

    -
    -

    Note

    -

    Trivy only includes runtime dependencies in the report.

    -
    -

    packages.config

    -

    Trivy only finds dependency names and versions from packages.config files. To build dependency graph, it is better to use packages.lock.json files.

    -

    *Packages.props

    -

    Trivy parses *Packages.props files. Both legacy Packages.props and modern Directory.Packages.props are supported.

    -

    license detection

    -

    packages.config files don't have information about the licenses used. -Trivy uses *.nuspec files from global packages folder to detect licenses.

    -
    -

    Note

    -

    The licenseUrl field is deprecated. Trivy doesn't parse this field and only checks the license field (license expression type only).

    -
    -

    Currently only the default path and NUGET_PACKAGES environment variable are supported.

    -

    packages.lock.json

    -

    Don't forgot to enable lock files in your project.

    -
    -

    Tip

    -

    Please make sure your lock file is up-to-date after modifying dependencies.

    -
    -

    license detection

    -

    Same as packages.config

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/elixir/index.html b/v0.58.0/docs/coverage/language/elixir/index.html deleted file mode 100644 index f41907d05446..000000000000 --- a/v0.58.0/docs/coverage/language/elixir/index.html +++ /dev/null @@ -1,7898 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Elixir - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Elixir

    -

    Trivy supports Hex repository for Elixir.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    hex-
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    hexmix.lock1Excluded-
    -

    Hex

    -

    In order to detect dependencies, Trivy searches for mix.lock1.

    -

    Configure your project to use mix.lock1 file.

    -
    -
    -
      -
    1. -

      mix.lock is default name. To scan a custom filename use file-patterns 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/golang/index.html b/v0.58.0/docs/coverage/language/golang/index.html deleted file mode 100644 index a5b67c9eb804..000000000000 --- a/v0.58.0/docs/coverage/language/golang/index.html +++ /dev/null @@ -1,8320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Go - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Go

    -

    Overview

    -

    Trivy supports two types of Go scanning, Go Modules and binaries built by Go.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactSBOMVulnerabilityLicense
    Modules
    Binaries-
    -

    The table below provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactOffline1Dev dependenciesDependency graphStdlibDetection Priority
    ModulesInclude
    BinariesExclude-Not needed
    -
    -

    Note

    -

    When scanning Go projects (go.mod or binaries built with Go), Trivy scans only dependencies of the project, and does not detect vulnerabilities of application itself. -For example, when scanning the Docker project (Docker's source code with go.mod or the Docker binary), Trivy might find vulnerabilities in Go modules that Docker depends on, but won't find vulnerabilities of Docker itself. Moreover, when scanning the Trivy project, which happens to use Docker, Docker's vulnerabilities might be detected as dependencies of Trivy.

    -
    -

    Data Sources

    -

    The data sources are listed here. -Trivy uses Go Vulnerability Database for standard library and uses GitHub Advisory Database for other Go modules.

    -

    Go Module

    -

    Depending on Go versions, the required files are different.

    - - - - - - - - - - - - - - - - - - - - -
    VersionRequired filesOffline
    >=1.17go.mod
    <1.17go.mod, go.sum
    -

    In Go 1.17+ projects, Trivy uses go.mod for direct/indirect dependencies. -On the other hand, it uses go.mod for direct dependencies and go.sum for indirect dependencies in Go 1.16 or less.

    -

    Go 1.17+ holds actually needed indirect dependencies in go.mod, and it reduces false detection. -go.sum in Go 1.16 or less contains all indirect dependencies that are even not needed for compiling. -If you want to have better detection, please consider updating the Go version in your project.

    -
    -

    Note

    -

    The Go version doesn't mean your Go tool version, but the Go version in your go.mod.

    -
    module github.com/aquasecurity/trivy
    -
    -go 1.18
    -
    -require (
    -        github.com/CycloneDX/cyclonedx-go v0.5.0
    -        ...
    -)
    -
    -

    To update the Go version in your project, you need to run the following command.

    -
    $ go mod tidy -go=1.18
    -
    -
    -

    Main Module

    -

    Trivy scans only dependencies of the project, and does not detect vulnerabilities of the main module. -For example, when scanning the Docker project (Docker's source code with go.mod), Trivy might find vulnerabilities in Go modules that Docker depends on, but won't find vulnerabilities of Docker itself. -Moreover, when scanning the Trivy project, which happens to use Docker, Docker's vulnerabilities might be detected as dependencies of Trivy.

    -

    Standard Library

    -

    Detecting the version of Go used in the project can be tricky. -The go.mod file include hints that allows Trivy to guess the Go version but it eventually depends on the Go tool version in the build environment. -Since this strategy is not fully deterministic and accurate, it is enabled only in --detection-priority comprehensive mode. -When enabled, Trivy detects stdlib version as the minimum between the go and the toolchain directives in the go.mod file. -To obtain reproducible scan results Trivy doesn't check the locally installed version of Go.

    -
    -

    Note

    -

    Trivy detects stdlib only for Go 1.21 or higher.

    -

    The version from the go line (for Go 1.20 or early) is not a minimum required version. -For details, see this.

    -
    -

    It possibly produces false positives. -See the caveat for details.

    -

    License

    -

    To identify licenses, you need to download modules to local cache beforehand, such as go mod download, go mod tidy, etc. -Trivy traverses $GOPATH/pkg/mod and collects those extra information.

    -

    Dependency Graph

    -

    Same as licenses, you need to download modules to local cache beforehand.

    -

    Go Binary

    -

    Trivy scans Go binaries when it encounters them during scans such as container images or file systems. -When scanning binaries built by Go, Trivy finds dependencies and Go version information as embedded in the binary by Go tool at build time.

    -
    $ trivy rootfs ./your_binary
    -
    -
    -

    Note

    -

    It doesn't work with UPX-compressed binaries.

    -
    -

    Main Module

    -

    Go binaries installed using the go install command contains correct (semver) version for the main module and therefor are detected by Trivy. -In other cases, Go uses the (devel) version2. -In this case, Trivy will attempt to parse any -ldflags as it's a common practice to pass versions this way. -If unsuccessful, the version will be empty3.

    -

    Standard Library

    -

    Trivy detects the Go version used to compile the binary and detects its vulnerabilities in the standard libraries. -It possibly produces false positives. -See the caveat for details.

    -

    Caveats

    -

    Stdlib Vulnerabilities

    -

    Trivy does not know if or how you use stdlib functions, therefore it is possible that stdlib vulnerabilities are not applicable to your use case. -There are a few ways to mitigate this:

    -
      -
    1. Analyze vulnerability reachability using a tool such as govulncheck. This will ensure that reported vulnerabilities are applicable to your project.
    2. -
    3. Suppress non-applicable vulnerabilities using either ignore file for self-use or VEX Hub for public use.
    4. -
    -

    Empty Version

    -

    As described in the Main Module section, the main module of Go binaries might have an empty version. -Also, dependencies replaced with local ones will have an empty version.

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/index.html b/v0.58.0/docs/coverage/language/index.html deleted file mode 100644 index 0711e57c6b1d..000000000000 --- a/v0.58.0/docs/coverage/language/index.html +++ /dev/null @@ -1,8155 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Programming Language

    -

    Trivy supports programming languages for

    - -

    Supported languages

    -

    The files analyzed vary depending on the target. -This is because Trivy primarily categorizes targets into two groups:

    -
      -
    • Pre-build
    • -
    • Post-build
    • -
    -

    If the target is a pre-build project, like a code repository, Trivy will analyze files used for building, such as lock files. -On the other hand, when the target is a post-build artifact, like a container image, Trivy will analyze installed package metadata like .gemspec, binary files, and so on.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LanguageFileImage4Rootfs5Filesystem6Repository7
    RubyGemfile.lock--
    gemspec--
    PythonPipfile.lock--
    poetry.lock--
    requirements.txt--
    egg package1--
    wheel package2--
    PHPcomposer.lock--
    installed.json--
    Node.jspackage-lock.json--
    yarn.lock--
    pnpm-lock.yaml--
    package.json--
    .NETpackages.lock.json
    packages.config
    .deps.json
    *Packages.props9
    JavaJAR/WAR/PAR/EAR3--
    pom.xml--
    *gradle.lockfile--
    *.sbt.lock--
    GoBinaries built by Go--
    go.mod--
    RustCargo.lock
    Binaries built with cargo-auditable--
    C/C++conan.lock--
    Elixirmix.lock8--
    Dartpubspec.lock--
    SwiftPodfile.lock--
    Package.resolved--
    JuliaManifest.toml
    -

    The path of these files does not matter.

    -

    Example: Dockerfile

    -
    -
    -
      -
    1. -

      *.egg-info, *.egg-info/PKG-INFO, *.egg and EGG-INFO/PKG-INFO 

      -
    2. -
    3. -

      .dist-info/META-DATA 

      -
    4. -
    5. -

      *.jar, *.war, *.par and *.ear 

      -
    6. -
    7. -

      ✅ means "enabled" and - means "disabled" in the image scanning 

      -
    8. -
    9. -

      ✅ means "enabled" and - means "disabled" in the rootfs scanning 

      -
    10. -
    11. -

      ✅ means "enabled" and - means "disabled" in the filesystem scanning 

      -
    12. -
    13. -

      ✅ means "enabled" and - means "disabled" in the git repository scanning 

      -
    14. -
    15. -

      To scan a filename other than the default filename use file-patterns 

      -
    16. -
    17. -

      Directory.Packages.props and legacy Packages.props file names are supported 

      -
    18. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/java/index.html b/v0.58.0/docs/coverage/language/java/index.html deleted file mode 100644 index 2dd2d3f2127b..000000000000 --- a/v0.58.0/docs/coverage/language/java/index.html +++ /dev/null @@ -1,8272 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Java - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Java

    -

    Trivy supports four types of Java scanning: JAR/WAR/PAR/EAR, pom.xml, *gradle.lockfile and *.sbt.lock files.

    -

    Each artifact supports the following scanners:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactSBOMVulnerabilityLicense
    JAR/WAR/PAR/EAR-
    pom.xml
    *gradle.lockfile
    *.sbt.lock-
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactInternet accessDev dependenciesDependency graphPositionDetection Priority
    JAR/WAR/PAR/EARTrivy Java DBInclude--Not needed
    pom.xmlMaven repository 1Exclude7-
    *gradle.lockfile-ExcludeNot needed
    *.sbt.lock-Exclude-Not needed
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    JAR/WAR/PAR/EAR

    -

    To find information about your JAR2 file, Trivy parses pom.properties and MANIFEST.MF files in your JAR2 file and takes required properties3.

    -

    If those files don't exist or don't contain enough information - Trivy will try to find this JAR2 file in trivy-java-db. -The Java DB will be automatically downloaded/updated when any JAR2 file is found. -It is stored in the cache directory.

    -
    -

    EXPERIMENTAL

    -

    Finding JARs in trivy-java-db is an experimental function.

    -
    -

    Base JAR2 may contain inner JARs2 within itself. -To find information about these JARs2, the same logic is used as for the base JAR2.

    -

    table format only contains the name of root JAR2 . To get the full path to inner JARs2 use the json format.

    -

    pom.xml

    -

    Trivy parses your pom.xml file and tries to find files with dependencies from these local locations.

    -
      -
    • project directory4
    • -
    • relativePath field5
    • -
    • local repository directory6.
    • -
    -

    remote repositories

    -

    If your machine doesn't have the necessary files - Trivy tries to find the information about these dependencies in the remote repositories:

    - -

    Trivy reproduces Maven's repository selection and priority:

    -
      -
    • for snapshot artifacts:
        -
      • check only snapshot repositories from pom files (if exists)
      • -
      -
    • -
    • for other artifacts:
        -
      • check release repositories from pom files (if exists)
      • -
      • check maven central
      • -
      -
    • -
    -
    -

    Note

    -

    Trivy only takes information about packages. We don't take a list of vulnerabilities for packages from the maven repository. -Information about data sources for Java you can see here.

    -
    -

    You can disable connecting to the maven repository with the --offline-scan flag. -The --offline-scan flag does not affect the Trivy database. -The vulnerability database will be downloaded anyway.

    -
    -

    Warning

    -

    Trivy may skip some dependencies (that were not found on your local machine) when the --offline-scan flag is passed.

    -
    -

    supported scopes

    -

    Trivy only scans import, compile, runtime and empty maven scopes. Other scopes and Optional dependencies are not currently being analyzed.

    -

    empty dependency version

    -

    There are cases when Trivy cannot determine the version of dependencies:

    -
      -
    • Unable to determine the version from the parent because the parent is not reachable;
    • -
    • The dependency uses a hard requirement with more than one version.
    • -
    -

    In these cases, Trivy uses an empty version for the dependency.

    -
    -

    Warning

    -

    Trivy doesn't detect child dependencies for dependencies without a version.

    -
    -

    maven-invoker-plugin

    -

    Typically, the integration tests directory (**/[src|target]/it/*/pom.xml) of maven-invoker-plugin doesn't contain actual pom.xml files and should be skipped to avoid noise.

    -

    Trivy marks dependencies from these files as the development dependencies and skip them by default. -If you need to show them, use the --include-dev-deps flag.

    -

    Gradle.lock

    -

    gradle.lock files only contain information about used dependencies.

    -
    -

    Note

    -

    All necessary files are checked locally. Gradle file scanning doesn't require internet access.

    -
    -

    Dependency-tree

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy finds child dependencies from *.pom files in the cache8 directory.

    -

    But there is no reliable way to determine direct dependencies (even using other files). -Therefore, we mark all dependencies as indirect to use logic to guess direct dependencies and build a dependency tree.

    -

    Licenses

    -

    Trity also can detect licenses for dependencies.

    -

    Make sure that you have cache8 directory to find licenses from *.pom dependency files.

    -

    SBT

    -

    build.sbt.lock files only contain information about used dependencies. This requires a lockfile generated using the -sbt-dependency-lock plugin.

    -
    -

    Note

    -

    All necessary files are checked locally. SBT file scanning doesn't require internet access.

    -
    -
    -
    -
      -
    1. -

      Uses maven repository to get information about dependencies. Internet access required. 

      -
    2. -
    3. -

      It means *.jar, *.war, *.par and *.ear file 

      -
    4. -
    5. -

      ArtifactID, GroupID and Version 

      -
    6. -
    7. -

      e.g. when parent pom.xml file has ../pom.xml path 

      -
    8. -
    9. -

      When you use dependency path in relativePath field in pom.xml file 

      -
    10. -
    11. -

      /Users/<username>/.m2/repository (for Linux and Mac) and C:/Users/<username>/.m2/repository (for Windows) by default 

      -
    12. -
    13. -

      To avoid confusion, Trivy only finds locations for direct dependencies from the base pom.xml file. 

      -
    14. -
    15. -

      The supported directories are $GRADLE_USER_HOME/caches and $HOME/.gradle/caches (%HOMEPATH%\.gradle\caches for Windows). 

      -
    16. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/julia/index.html b/v0.58.0/docs/coverage/language/julia/index.html deleted file mode 100644 index 2e357f39c690..000000000000 --- a/v0.58.0/docs/coverage/language/julia/index.html +++ /dev/null @@ -1,7939 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Julia - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Julia

    -

    Features

    -

    Trivy supports Pkg.jl, which is the Julia package manager. -The following scanners are supported.

    - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Pkg.jl--
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesLicenseDependency graphPosition
    Pkg.jlManifest.tomlExcluded1-
    -

    Pkg.jl

    -

    Trivy searches for Manifest.toml to detect dependencies.

    -

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. -Since this information is not included in Manifest.toml, Trivy parses Project.toml, which should be located next to Project.toml. -If you want to see the dependency tree, please ensure that Project.toml is present.

    -

    Scanning Manifest.toml and Project.toml together also removes developer dependencies.

    -

    Dependency extensions are currently ignored.

    -
    -
    -
      -
    1. -

      When you scan Manifest.toml and Project.toml together. 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/nodejs/index.html b/v0.58.0/docs/coverage/language/nodejs/index.html deleted file mode 100644 index 299a5115373b..000000000000 --- a/v0.58.0/docs/coverage/language/nodejs/index.html +++ /dev/null @@ -1,8181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Node.js - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Node.js

    -

    Trivy supports four types of Node.js package managers: npm, Yarn, pnpm and Bun1.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArtifactSBOMVulnerabilityLicense
    npm
    Yarn
    pnpm
    Bun
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    npmpackage-lock.jsonExcluded
    Yarnyarn.lockExcluded
    pnpmpnpm-lock.yamlExcluded-
    Bunyarn.lockExcluded
    -

    In addition, Trivy scans installed packages with package.json.

    - - - - - - - - - - - - - - - - - -
    FileDependency graphPositionLicense
    package.json--
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    Package managers

    -

    Trivy parses your files generated by package managers in filesystem/repository scanning.

    -
    -

    Tip

    -

    Please make sure your lock file is up-to-date after modifying package.json.

    -
    -

    npm

    -

    Trivy parses package-lock.json. -To identify licenses, you need to download dependencies to node_modules beforehand. -Trivy analyzes node_modules for licenses.

    -

    By default, Trivy doesn't report development dependencies. Use the --include-dev-deps flag to include them.

    -

    Yarn

    -

    Trivy parses yarn.lock, which doesn't contain information about development dependencies. -Trivy also uses package.json file to handle aliases.

    -

    To exclude devDependencies and allow aliases, package.json also needs to be present next to yarn.lock.

    -

    Trivy analyzes .yarn (Yarn 2+) or node_modules (Yarn Classic) folder next to the yarn.lock file to detect licenses.

    -

    By default, Trivy doesn't report development dependencies. Use the --include-dev-deps flag to include them.

    -

    pnpm

    -

    Trivy parses pnpm-lock.yaml, then finds production dependencies and builds a tree of dependencies with vulnerabilities. -To identify licenses, you need to download dependencies to node_modules beforehand. Trivy analyzes node_modules for licenses.

    -

    lock file v9 version

    -

    Trivy supports Dev field for pnpm-lock.yaml v9 or later. Use the --include-dev-deps flag to include the developer's dependencies in the result.

    -

    Bun

    -

    Trivy supports scanning yarn.lock files generated by Bun. You can use the command bun install -y to generate a Yarn-compatible yarn.lock.

    -
    -

    Note

    -

    bun.lockb is not supported.

    -
    -

    Packages

    -

    Trivy parses the manifest files of installed packages in container image scanning and so on.

    -

    package.json

    -

    Trivy searches for package.json files under node_modules and identifies installed packages. -It only extracts package names, versions and licenses for those packages.

    -
    -
    -
      -
    1. -

      yarn.lock must be generated 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/php/index.html b/v0.58.0/docs/coverage/language/php/index.html deleted file mode 100644 index ed873bac1d64..000000000000 --- a/v0.58.0/docs/coverage/language/php/index.html +++ /dev/null @@ -1,7924 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PHP - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    PHP

    -

    Trivy supports Composer, which is a tool for dependency management in PHP.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Composer
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    Composercomposer.lockExcluded
    Composerinstalled.jsonExcluded-
    -

    composer.lock

    -

    In order to detect dependencies, Trivy searches for composer.lock.

    -

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. -Since this information is not included in composer.lock, Trivy parses composer.json, which should be located next to composer.lock. -If you want to see the dependency tree, please ensure that composer.json is present.

    -

    installed.json

    -

    Trivy also supports dependency detection for installed.json files. By default, you can find this file at path_to_app/vendor/composer/installed.json.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/python/index.html b/v0.58.0/docs/coverage/language/python/index.html deleted file mode 100644 index 2f67295eaae1..000000000000 --- a/v0.58.0/docs/coverage/language/python/index.html +++ /dev/null @@ -1,8268 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Python - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Python

    -

    Trivy supports three types of Python package managers: pip, Pipenv and Poetry. -The following scanners are supported for package managers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    pip
    Pipenv-
    Poetry-
    -

    In addition, Trivy supports three formats of Python packages: egg, wheel and conda. -The following scanners are supported for Python packages.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    PackagingSBOMVulnerabilityLicense
    Egg
    Wheel
    Conda--
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPositionDetection Priority
    piprequirements.txt-Include-
    PipenvPipfile.lockInclude-Not needed
    Poetrypoetry.lockExclude-Not needed
    - - - - - - - - - - - - - - - - - -
    PackagingDependency graph
    Egg
    Wheel
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    Package managers

    -

    Trivy parses your files generated by package managers in filesystem/repository scanning.

    -

    pip

    -

    Dependency detection

    -

    By default, Trivy only parses version specifiers with == comparison operator and without .*.

    -

    Using the --detection-priority comprehensive option ensures that the tool establishes a minimum version, which is particularly useful in scenarios where identifying the exact version is challenging. -In such case Trivy parses specifiers >=,~= and a trailing .*.

    -

    keyring >= 4.1.1            # Minimum version 4.1.1
    -Mopidy-Dirble ~= 1.1        # Minimum version 1.1
    -python-gitlab==2.0.*        # Minimum version 2.0.0
    -
    -Also, there is a way to convert unsupported version specifiers - use the pip freeze command.

    -
    $ cat requirements.txt 
    -boto3~=1.24.60
    -click>=8.0
    -json-fix==0.5.*
    -$ pip install -r requirements.txt
    -...
    -$ pip freeze > requirements.txt 
    -$ cat requirements.txt 
    -boto3==1.24.96
    -botocore==1.27.96
    -click==8.1.7
    -jmespath==1.0.1
    -json-fix==0.5.2
    -python-dateutil==2.8.2
    -s3transfer==0.6.2
    -setuptools==69.0.2
    -six==1.16.0
    -urllib3==1.26.18
    -wheel==0.42.0
    -
    -

    requirements.txt files usually contain only the direct dependencies and not contain the transitive dependencies. -Therefore, Trivy scans only for the direct dependencies with requirements.txt.

    -

    To detect transitive dependencies as well, you need to generate requirements.txt with pip freeze.

    -
    $ cat requirements.txt # it will only find `requests@2.28.2`.
    -requests==2.28.2 
    -$ pip install -r requirements.txt
    -...
    -
    -$ pip freeze > requirements.txt   
    -$ cat requirements.txt # it will also find the transitive dependencies of `requests@2.28.2`.
    -certifi==2022.12.7
    -charset-normalizer==3.1.0
    -idna==3.4
    -PyJWT==2.1.0
    -requests==2.28.2
    -urllib3==1.26.15
    -
    -

    pip freeze also helps to resolve extras(optional) dependencies (like package[extras]=0.0.0).

    -

    requirements.txt files don't contain information about dependencies used for development. -Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

    -

    License detection

    -

    requirements.txt files don't contain information about licenses. -Therefore, Trivy checks METADATA files from lib/site-packages directory.

    -

    Trivy uses 3 ways to detect site-packages directory:

    -
      -
    • Checks VIRTUAL_ENV environment variable.
    • -
    • Detects path to python1 binary and checks ../lib/pythonX.Y/site-packages directory.
    • -
    • Detects path to python1 binary and checks ../../lib/site-packages directory.
    • -
    -

    Pipenv

    -

    Trivy parses Pipfile.lock. -Pipfile.lock files don't contain information about dependencies used for development. -Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

    -

    License detection is not supported for Pipenv.

    -

    Poetry

    -

    Trivy uses poetry.lock to identify dependencies and find vulnerabilities. -To build the correct dependency graph, pyproject.toml also needs to be present next to poetry.lock.

    -

    License detection is not supported for Poetry.

    -

    Packaging

    -

    Trivy parses the manifest files of installed packages in container image scanning and so on. -See here for the detail.

    -

    Egg

    -

    Trivy looks for *.egg-info, *.egg-info/PKG-INFO, *.egg and EGG-INFO/PKG-INFO to identify Python packages.

    -

    Wheel

    -

    Trivy looks for .dist-info/META-DATA to identify Python packages.

    -
    -
    -
      -
    1. -

      Trivy checks python, python3, python2 and python.exe file names. 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/ruby/index.html b/v0.58.0/docs/coverage/language/ruby/index.html deleted file mode 100644 index 8b3ef9f6891e..000000000000 --- a/v0.58.0/docs/coverage/language/ruby/index.html +++ /dev/null @@ -1,7927 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ruby - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Ruby

    -

    Trivy supports Bundler and RubyGems. -The following scanners are supported for Cargo.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Bundler-
    RubyGems
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    BundlerGemfile.lockIncluded
    RubyGems.gemspec-Included--
    -

    Bundler

    -

    Trivy searches for Gemfile.lock to detect dependencies.

    -

    RubyGems

    -

    .gemspec files doesn't contains transitive dependencies. You need to scan each .gemspec file separately.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/rust/index.html b/v0.58.0/docs/coverage/language/rust/index.html deleted file mode 100644 index d63f3bfc0889..000000000000 --- a/v0.58.0/docs/coverage/language/rust/index.html +++ /dev/null @@ -1,8000 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rust - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Rust

    -

    Trivy supports Cargo, which is the Rust package manager. -The following scanners are supported for Cargo.

    - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Cargo-
    -

    In addition, it supports binaries built with cargo-auditable.

    - - - - - - - - - - - - - - - - - -
    ArtifactSBOMVulnerabilityLicense
    Binaries-
    -

    Features

    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    CargoCargo.lockExcluded1
    - - - - - - - - - - - - - - - - - - - -
    ArtifactTransitive dependenciesDev dependenciesDependency graphPosition
    BinariesExcluded--
    -

    Cargo

    -

    Trivy searches for Cargo.lock to detect dependencies.

    -

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. -Since this information is not included in Cargo.lock, Trivy parses Cargo.toml, which should be located next to Cargo.lock. -If you want to see the dependency tree, please ensure that Cargo.toml is present.

    -

    Scan Cargo.lock and Cargo.toml together also removes developer dependencies.

    -

    Binaries

    -

    Trivy scans binaries built with cargo-auditable. -If such a binary exists, Trivy will identify it as being built with cargo-audit and scan it.

    -
    -
    -
      -
    1. -

      When you scan Cargo.lock and Cargo.toml together. 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/language/swift/index.html b/v0.58.0/docs/coverage/language/swift/index.html deleted file mode 100644 index 8e480040da07..000000000000 --- a/v0.58.0/docs/coverage/language/swift/index.html +++ /dev/null @@ -1,7938 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Swift - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Swift

    -

    Trivy supports CocoaPods and Swift package managers.

    -

    The following scanners are supported.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerSBOMVulnerabilityLicense
    Swift-
    CocoaPods-
    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPosition
    SwiftPackage.resolvedIncluded-
    CocoaPodsPodfile.lockIncluded-
    -

    These may be enabled or disabled depending on the target. -See here for the detail.

    -

    Swift

    -

    Trivy parses Package.resolved file to find dependencies. -Don't forget to update (swift package update command) this file before scanning.

    -

    CocoaPods

    -

    CocoaPods uses package names in PodFile.lock, but GitHub Advisory Database (GHSA) Trivy relies on uses Git URLs. -We parse the CocoaPods Specs to match package names and links.

    -
    -

    Limitation

    -

    Since GHSA holds only Git URLs, such as github.com/apple/swift-nio, -Trivy can't identify affected submodules, and detect all submodules maintained by the same URL. -For example, SwiftNIOHTTP1 and SwiftNIOWebSocket both are maintained under github.com/apple/swift-nio, -and Trivy detect CVE-2022-3215 for both of them, even though only SwiftNIOHTTP1 is actually affected.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/alma/index.html b/v0.58.0/docs/coverage/os/alma/index.html deleted file mode 100644 index 67f37213e050..000000000000 --- a/v0.58.0/docs/coverage/os/alma/index.html +++ /dev/null @@ -1,8112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AlmaLinux - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    AlmaLinux

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    -

    Vulnerability

    -

    AlmaLinux offers its own security advisories, and these are utilized when scanning AlmaLinux for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    When looking at fixed versions, it's crucial to consider the patches supplied by AlmaLinux. -For example, for CVE-2023-0464, the fixed version for AlmaLinux 9 is listed as 3.0.7-16.el9_2 in their advisory. -Note that this is different from the upstream fixed version, which is 3.0.9, 3.1.1, and son on. -Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    -

    Severity

    -

    Trivy calculates the severity of an issue based on the severity provided by AlmaLinux. -If the severity is not provided or defined yet by AlmaLinux, the severity from the NVD is taken into account.

    -

    Using CVE-2023-0464 as an example, while it is rated as "High" in NVD, AlmaLinux has marked as "moderate". -As a result, Trivy will display it as "Medium".

    -

    The table below is the mapping of AlmaLinux's severity to Trivy's severity levels.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    AlmaLinuxTrivy
    LowLow
    ModerateMedium
    ImportantHigh
    CriticalCritical
    -

    Status

    -

    Trivy supports the following vulnerability statuses for AlmaLinux.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/alpine/index.html b/v0.58.0/docs/coverage/os/alpine/index.html deleted file mode 100644 index fdae5a57b132..000000000000 --- a/v0.58.0/docs/coverage/os/alpine/index.html +++ /dev/null @@ -1,8082 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Alpine Linux - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Alpine Linux

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through apk.

    -

    Vulnerability

    -

    Alpine Linux offers its own security advisories, and these are utilized when scanning Alpine for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    When looking at fixed versions, it's crucial to consider the patches supplied by Alpine. -For example, for CVE-2023-0464, the fixed version for Alpine Linux is listed as 3.1.0-r1 in the secfixes. -Note that this is different from the upstream fixed version, which is 3.1.1. -Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    -

    Severity

    -

    For Alpine vulnerabilities, the severity is determined using the values set by NVD.

    -

    Status

    -

    Trivy supports the following vulnerability statuses for Alpine.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of APK packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/amazon/index.html b/v0.58.0/docs/coverage/os/amazon/index.html deleted file mode 100644 index a6a75307edaf..000000000000 --- a/v0.58.0/docs/coverage/os/amazon/index.html +++ /dev/null @@ -1,8112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Amazon Linux - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Amazon Linux

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    -

    Vulnerability

    -

    Amazon Linux offers its own security advisories, and these are utilized when scanning Amazon Linux for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    When looking at fixed versions, it's crucial to consider the patches supplied by Amazon. -For example, for CVE-2023-0464, the fixed version for Amazon Linux 2023 is listed as 3.0.8-1.amzn2023.0.2 in ALAS2023-2023-181. -Note that this is different from the upstream fixed version, which is 3.0.9, 3.1.1, and so on. -Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    -

    Severity

    -

    Trivy determines vulnerability severity based on the severity metric provided by Amazon. -For example, the security patch for CVE-2023-0464 in Amazon Linux 2023 is provided as ALAS2023-2023-181. -Its severity is rated as "Medium". -Thus, even though it's evaluated as "HIGH" in the NVD, Trivy displays it with a severity of "MEDIUM".

    -

    The table below is the mapping of Amazon's severity to Trivy's severity levels.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    AmazonTrivy
    LowLow
    MediumMedium
    ImportantHigh
    CriticalCritical
    -

    Status

    -

    Trivy supports the following vulnerability statuses for Amazon Linux.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/azure/index.html b/v0.58.0/docs/coverage/os/azure/index.html deleted file mode 100644 index 2cce5d3e8f66..000000000000 --- a/v0.58.0/docs/coverage/os/azure/index.html +++ /dev/null @@ -1,8140 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Azure Linux (CBL-Mariner) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Azure Linux (CBL-Mariner)

    -

    CBL-Mariner was rebranded to Azure Linux for version 3.0 onwards.

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    VersionSBOMVulnerabilityLicense
    1.0
    1.0 (Distroless)
    2.0
    2.0 (Distroless)
    3.0
    3.0 (Distroless)
    -

    The following table provides an outline of the targets Trivy supports.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    VersionContainer imageVirtual machineArch
    1.0amd64, arm64
    2.0amd64, arm64
    3.0amd64, arm64
    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Detect unfixed vulnerabilities
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as tdnf, dnf and yum.

    -

    Vulnerability

    -

    Azure Linux offers its own security advisories, and these are utilized when scanning Azure Linux for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    Trivy takes fixed versions from Azure Linux OVAL.

    -

    Severity

    -

    Trivy calculates the severity of an issue based on the severity provided in Azure Linux OVAL.

    -

    Status

    -

    Trivy supports the following vulnerability statuses for Azure Linux.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    -
    -

    Note

    -

    License detection is not supported for Azure Linux Distroless images.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/centos/index.html b/v0.58.0/docs/coverage/os/centos/index.html deleted file mode 100644 index 982747c0c754..000000000000 --- a/v0.58.0/docs/coverage/os/centos/index.html +++ /dev/null @@ -1,7945 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CentOS - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    CentOS

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities
    Dependency graph
    -

    SBOM

    -

    Same as RHEL.

    -

    Vulnerability

    -

    CentOS does not provide straightforward machine-readable security advisories. -As a result, Trivy utilizes the security advisories from Red Hat Enterprise Linux (RHEL) for detecting vulnerabilities in CentOS. -This approach might lead to situations where, even though Trivy displays a fixed version, CentOS might not have the patch available yet. -Since patches released for RHEL often become available in CentOS after some time, it's usually just a matter of waiting.

    -
    -

    Note

    -

    The case for CentOS Stream, which is not supported by Trivy, is entirely different from CentOS.

    -
    -

    As Trivy relies on Red Hat's advisories, please refer to Red Hat for details regarding vulnerability severity and status.

    -

    License

    -

    Same as RHEL.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/chainguard/index.html b/v0.58.0/docs/coverage/os/chainguard/index.html deleted file mode 100644 index 04635c4ebf0b..000000000000 --- a/v0.58.0/docs/coverage/os/chainguard/index.html +++ /dev/null @@ -1,7973 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Chainguard - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Chainguard

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Detect unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Same as Alpine Linux.

    -

    Vulnerability

    -

    Chainguard offers its own security advisories, and these are utilized when scanning Chainguard for vulnerabilities. -Everything else is the same as Alpine Linux.

    -

    Data Source

    -

    See here.

    -

    License

    -

    Same as Alpine Linux.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/debian/index.html b/v0.58.0/docs/coverage/os/debian/index.html deleted file mode 100644 index 2f1273d8580c..000000000000 --- a/v0.58.0/docs/coverage/os/debian/index.html +++ /dev/null @@ -1,8091 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Debian - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Debian

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as apt and dpkg. -While there are some exceptions, like Go binaries and JAR files, it's important to note that binaries that have been custom-built using make or tools installed via curl are generally not detected.

    -

    Vulnerability

    -

    Debian offers its own security advisories, and these are utilized when scanning Debian for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    When looking at fixed versions, it's crucial to consider the patches supplied by Debian. -For example, for CVE-2023-3269, the fixed version for Debian 12 (bookworm) is listed as 6.1.37-1 in the Security Tracker. -This patch is provided in DSA-5448-1. -Note that this is different from the upstream fixed version, which is 6.5. -Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    -

    Severity

    -

    Trivy calculates the severity of an issue based on the 'Urgency' metric found in the Security Tracker. -If 'Urgency' isn't provided by Debian, the severity from the NVD is taken into account.

    -

    Using CVE-2019-15052 as an example, while it is rated as "Critical" in NVD, Debian has marked its "Urgency" as "Low". -As a result, Trivy will display it as "Low".

    -

    Status

    -

    Trivy supports the following vulnerability statuses for Debian.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    To identify the license of a package, Trivy checks the copyright file located at /usr/share/doc/*/copyright.

    -

    However, this method has its limitations as the file isn't machine-readable, leading to situations where the license isn't detected. -In such scenarios, the --license-full flag can be passed. -It compares the contents of known licenses with the copyright file to discern the license in question. -Please be aware that using this flag can increase memory usage, so it's disabled by default for efficiency.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/google-distroless/index.html b/v0.58.0/docs/coverage/os/google-distroless/index.html deleted file mode 100644 index 60919d1cabb1..000000000000 --- a/v0.58.0/docs/coverage/os/google-distroless/index.html +++ /dev/null @@ -1,7937 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Google Distroless (Images) - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Google Distroless Images

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages pre-installed in distroless images.

    -

    Vulnerability

    -

    Google Distroless is based on Debian; see there for details.

    -

    License

    -

    Google Distroless is based on Debian; see there for details.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/index.html b/v0.58.0/docs/coverage/os/index.html deleted file mode 100644 index 844414c90637..000000000000 --- a/v0.58.0/docs/coverage/os/index.html +++ /dev/null @@ -1,8031 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    OS

    -

    Scanner

    -

    Trivy supports operating systems for

    - -

    Supported OS

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OSSupported VersionsPackage Managers
    Alpine Linux2.2 - 2.7, 3.0 - 3.20, edgeapk
    Wolfi Linux(n/a)apk
    Chainguard(n/a)apk
    Red Hat Enterprise Linux6, 7, 8dnf/yum/rpm
    CentOS16, 7, 8dnf/yum/rpm
    AlmaLinux8, 9dnf/yum/rpm
    Rocky Linux8, 9dnf/yum/rpm
    Oracle Linux5, 6, 7, 8dnf/yum/rpm
    Azure Linux (CBL-Mariner)1.0, 2.0, 3.0tdnf/dnf/yum/rpm
    Amazon Linux1, 2, 2023dnf/yum/rpm
    openSUSE Leap42, 15zypper/rpm
    openSUSE Tumbleweed(n/a)zypper/rpm
    SUSE Linux Enterprise11, 12, 15zypper/rpm
    SUSE Linux Enterprise Micro5, 6zypper/rpm
    Photon OS1.0, 2.0, 3.0, 4.0tndf/yum/rpm
    Debian GNU/Linux7, 8, 9, 10, 11, 12apt/dpkg
    UbuntuAll versions supported by Canonicalapt/dpkg
    OSs with installed Conda-conda
    -

    Supported container images

    - - - - - - - - - - - - - - - - - - - - -
    Container imageSupported VersionsPackage Managers
    Google Distroless2Anyapt/dpkg
    BitnamiAny-
    -

    Each page gives more details.

    -
    -
    -
      -
    1. -

      CentOS Stream is not supported 

      -
    2. -
    3. -

      https://github.com/GoogleContainerTools/distroless 

      -
    4. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/oracle/index.html b/v0.58.0/docs/coverage/os/oracle/index.html deleted file mode 100644 index 329cd9a52896..000000000000 --- a/v0.58.0/docs/coverage/os/oracle/index.html +++ /dev/null @@ -1,8173 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Oracle Linux - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Oracle Linux

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    -

    Vulnerability

    -

    Oracle Linux offers its own security advisories, and these are utilized when scanning Oracle Linux for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    Trivy takes fixed versions from Oracle security advisories.

    -

    Flavors

    -

    Trivy detects the flavor for version of the found package and finds vulnerabilities only for that flavor.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    FlavorFormatExample
    normalversion without fips and ksplice3.6.16-4.el8
    fips*_fips10:3.6.16-4.0.1.el8_fips
    ksplice*.ksplice*.*2:2.34-60.0.3.ksplice1.el9_2.7, 151.0.1.ksplice2.el8
    -

    For example Trivy finds CVE-2021-33560 only for the normal and fips flavors. -For the ksplice flavor, CVE-2021-33560 will be skipped.

    -

    Severity

    -

    Trivy determines vulnerability severity based on the severity metric provided in Oracle security advisories. -For example, the security patch for CVE-2023-0464 is provided as ELSA-2023-2645. -Its severity is rated as "MODERATE". -Thus, even though it's evaluated as "HIGH" in the NVD, Trivy displays it with a severity of "MEDIUM".

    -

    The table below is the mapping of Oracle's threat to Trivy's severity levels.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    OracleTrivy
    LowLow
    ModerateMedium
    ImportantHigh
    CriticalCritical
    -

    Status

    -

    Trivy supports the following vulnerability statuses for Oracle Linux.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/photon/index.html b/v0.58.0/docs/coverage/os/photon/index.html deleted file mode 100644 index f7473862ae72..000000000000 --- a/v0.58.0/docs/coverage/os/photon/index.html +++ /dev/null @@ -1,8080 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Photon OS - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Photon OS

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as tdnf and yum.

    -

    Vulnerability

    -

    Photon OS offers its own security advisories, and these are utilized when scanning Photon OS for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    Trivy takes fixed versions from Photon CVE metadata.

    -

    Severity

    -

    Trivy determines the severity of vulnerabilities based on the CVSSv3 score provided by Photon OS. -See here for the conversion table from CVSS score to severity.

    -

    Status

    -

    Trivy supports the following vulnerability statuses for Photon OS.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/rhel/index.html b/v0.58.0/docs/coverage/os/rhel/index.html deleted file mode 100644 index cf6dcaa2bb0d..000000000000 --- a/v0.58.0/docs/coverage/os/rhel/index.html +++ /dev/null @@ -1,8122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Red Hat - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Red Hat Enterprise Linux

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    -

    Vulnerability

    -

    Red Hat offers its own security advisories, and these are utilized when scanning Red Hat Enterprise Linux (RHEL) for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    When looking at fixed versions, it's crucial to consider the patches supplied by Red Hat. -For example, for CVE-2023-0464, the fixed version for RHEL 9 is listed as 3.0.7-16.el9_2 in their advisory. -This patch is provided in RHSA-2023:3722. -Note that this is different from the upstream fixed version, which is 3.0.9, 3.1.1, and so on. -Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    -

    Severity

    -

    Trivy calculates the severity of a vulnerability based on the 'Impact' metric provided by Red Hat. -If the impact is not provided or defined yet by Red Hat, the severity from the NVD is taken into account.

    -

    Using CVE-2023-0464 as an example, while it is rated as "HIGH" in NVD, Red Hat has marked its 'Impact' as "Low". -As a result, Trivy will display it as "Low".

    -

    The table below is the mapping of Red Hat's impact to Trivy's severity levels.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Red HatTrivy
    LowLow
    ModerateMedium
    ImportantHigh
    CriticalCritical
    -

    Status

    -

    Trivy supports the following vulnerability statuses for RHEL.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    When a vulnerability status is listed as "End of Life", it means a vulnerability with the impact level assigned to this CVE is no longer covered by its current support lifecycle phase. -The product has been identified to contain the impacted component, but analysis to determine whether it is affected or not by this vulnerability was not performed. -Red Hat advises that the product should be assumed to be affected. -Therefore, Trivy detects vulnerabilities with this status as "End of Life".

    -

    On the other hand, for those marked "Under Investigation," the impact is unclear as they are still being examined, so Trivy does not detect them. Once the investigation is completed, the status should be updated.

    -
    -

    Abstract

    -

    Vulnerabilities with a status of "End of Life", where the presence or absence of impact is unclear, are detected by Trivy. However, those with a status of "Under Investigation" are not detected.

    -
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/rocky/index.html b/v0.58.0/docs/coverage/os/rocky/index.html deleted file mode 100644 index f856d8653d40..000000000000 --- a/v0.58.0/docs/coverage/os/rocky/index.html +++ /dev/null @@ -1,8113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rocky Linux - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Rocky Linux

    -

    Trivy supports the following scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    -

    Vulnerability

    -

    Rocky Linux offers its own security advisories, and these are utilized when scanning Rocky Linux for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    Trivy takes fixed versions from Rocky Linux Errata, not NVD or somewhere else. -See here for more details.

    -
    -

    Architectures

    -

    There are cases when the vulnerability affects packages of not all architectures. -For example, vulnerable packages for CVE-2023-0361 are only aarch64 packages.

    -

    Trivy only detects vulnerabilities for packages of your architecture.

    -
    -

    Severity

    -

    Trivy calculates the severity of an issue based on the severity provided in Rocky Linux Errata.

    -

    The table below is the mapping of Rocky Linux's severity to Trivy's severity levels.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Rocky LinuxTrivy
    LowLow
    ModerateMedium
    ImportantHigh
    CriticalCritical
    -

    Status

    -

    Trivy supports the following vulnerability statuses for Rocky Linux.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/suse/index.html b/v0.58.0/docs/coverage/os/suse/index.html deleted file mode 100644 index 83378396ed4b..000000000000 --- a/v0.58.0/docs/coverage/os/suse/index.html +++ /dev/null @@ -1,7980 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SUSE - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    SUSE

    -

    Trivy supports the following distributions:

    -
      -
    • openSUSE Leap
    • -
    • openSUSE Tumbleweed
    • -
    • SUSE Linux Enterprise (SLE)
    • -
    • SUSE Linux Enterprise Micro
    • -
    -

    Please see here for supported versions.

    -

    Trivy supports these scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    -

    Vulnerability

    -

    SUSE offers its own security advisories, and these are utilized when scanning openSUSE/SLE for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    License

    -

    Trivy identifies licenses by examining the metadata of RPM packages.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/ubuntu/index.html b/v0.58.0/docs/coverage/os/ubuntu/index.html deleted file mode 100644 index c8bafee1d517..000000000000 --- a/v0.58.0/docs/coverage/os/ubuntu/index.html +++ /dev/null @@ -1,8085 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ubuntu - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Ubuntu

    -

    Trivy supports these scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    Please see here for supported versions.

    -

    The following table provides an outline of the features Trivy offers.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Detect unfixed vulnerabilities
    Dependency graph
    -

    SBOM

    -

    Same as Debian.

    -

    Vulnerability

    -

    Ubuntu offers its own security advisories, and these are utilized when scanning Ubuntu for vulnerabilities.

    -

    Data Source

    -

    See here.

    -

    Fixed Version

    -

    When looking at fixed versions, it's crucial to consider the patches supplied by Ubuntu. -As an illustration, for CVE-2023-3269, the fixed version for Ubuntu 23.04 (lunar) is listed as 6.2.0-26.26 in the Security Tracker. -It's essential to recognize that this differs from the upstream fixed version, which stands at 6.5. -Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    -

    Severity

    -

    Trivy calculates the severity of an issue based on the 'Priority' metric found in the Security Tracker. -If 'Priority' isn't provided by Ubuntu, the severity from the NVD is taken into account.

    -

    Using CVE-2019-15052 as an example, while it is rated as "Critical" in NVD, Ubuntu has marked its "Priority" as "Medium". -As a result, Trivy will display it as "Medium".

    -

    Status

    -

    Trivy supports the following vulnerability statuses for Ubuntu.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    Same as Debian.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/os/wolfi/index.html b/v0.58.0/docs/coverage/os/wolfi/index.html deleted file mode 100644 index eb2043fb038f..000000000000 --- a/v0.58.0/docs/coverage/os/wolfi/index.html +++ /dev/null @@ -1,7973 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Wolfi - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Wolfi Linux

    -

    Trivy supports these scanners for OS packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Detect unfixed vulnerabilities-
    Dependency graph
    -

    SBOM

    -

    Same as Alpine Linux.

    -

    Vulnerability

    -

    Wolfi Linux offers its own security advisories, and these are utilized when scanning Wolfi for vulnerabilities. -Everything else is the same as Alpine Linux.

    -

    Data Source

    -

    See here.

    -

    License

    -

    Same as Alpine Linux.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/others/bitnami/index.html b/v0.58.0/docs/coverage/others/bitnami/index.html deleted file mode 100644 index 4255292e12b8..000000000000 --- a/v0.58.0/docs/coverage/others/bitnami/index.html +++ /dev/null @@ -1,8068 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Bitnami Images - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Bitnami Images

    -
    -

    EXPERIMENTAL

    -

    Scanning results may be inaccurate.

    -
    -

    While it is not an OS, this page describes the details of the container images provided by Bitnami. -Bitnami images are based on Debian. -Please see the Debian page for OS packages.

    -

    Trivy supports the following scanners for Bitnami packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability
    License
    -

    The table below outlines the features offered by Trivy.

    - - - - - - - - - - - - - - - - - -
    FeatureSupported
    Unfixed vulnerabilities-
    Dependency graph-
    -

    SBOM

    -

    Trivy analyzes the SBOM information contained within the container images provided by Bitnami. -The SBOM files are located at /opt/bitnami/<component>/.spdx-<component>.spdx.

    -

    Vulnerability

    -

    Since Bitnami has its own vulnerability database, it uses these for vulnerability detection of applications and packages distributed by Bitnami.

    -
    -

    Note

    -

    Trivy does not support vulnerability detection of independently compiled binaries, so even if you scan container images like nginx:1.15.2, vulnerabilities in Nginx cannot be detected. -This is because main applications like Nginx are not installed by the package manager. -However, in the case of Bitnami images, since these SBOMs are stored within the image, scanning bitnami/nginx:1.15.2 allows for the detection of vulnerabilities in Nginx.

    -
    -

    Fixed Version

    -

    Trivy refers to the Bitnami database. Please note that these may differ from the upstream fixed versions.

    -

    Severity

    -

    Similar to Fixed versions, it follows Bitnami's vulnerability database.

    -

    Status

    -

    Trivy supports the following vulnerability statuses for Bitnami packages.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StatusSupported
    Fixed
    Affected
    Under Investigation
    Will Not Fix
    Fix Deferred
    End of Life
    -

    License

    -

    If licenses are included in the SBOM distributed by Bitnami, they will be used for scanning.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/others/conda/index.html b/v0.58.0/docs/coverage/others/conda/index.html deleted file mode 100644 index c66068fef4be..000000000000 --- a/v0.58.0/docs/coverage/others/conda/index.html +++ /dev/null @@ -1,8055 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Conda - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Conda

    -

    Trivy supports the following scanners for Conda packages.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability-
    License
    - - - - - - - - - - - - - - - - - - - - - - - -
    Package managerFileTransitive dependenciesDev dependenciesDependency graphPositionDetection Priority
    Condaenvironment.yml-Include--
    -

    <package>.json

    -

    SBOM

    -

    Trivy parses <conda-root>/envs/<env>/conda-meta/<package>.json files to find the dependencies installed in your env.

    -

    License

    -

    The <package>.json files contain package license information. -Trivy includes licenses for the packages it finds without having to parse additional files.

    -

    environment.yml1

    -

    SBOM

    -

    Trivy supports parsing environment.yml1 files to find dependency list.

    -

    environment.yml1 files supports version range. We can't be sure about versions for these dependencies. -Therefore, you need to use conda env export command to get dependency list in Conda default format before scanning environment.yml1 file.

    -
    -

    Note

    -

    For dependencies in a non-Conda format, Trivy doesn't include a version of them.

    -
    -

    License

    -

    Trivy parses conda-meta/<package>.json files at the prefix path.

    -

    To correctly define licenses, make sure your environment.yml1 contains prefix field and prefix directory contains package.json files.

    -
    -

    Note

    -

    To get correct environment.yml1 file and fill prefix directory - use conda env export command.

    -
    -
    -
    -
      -
    1. -

      Trivy supports both yaml and yml extensions. 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/others/index.html b/v0.58.0/docs/coverage/others/index.html deleted file mode 100644 index fb4f58713f17..000000000000 --- a/v0.58.0/docs/coverage/others/index.html +++ /dev/null @@ -1,7918 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Others

    -

    In this section we have placed images, package managers and files that we can't assign to existing sections.

    -

    Trivy supports them for

    - -

    Supported elements

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ElementFileImage1Rootfs2Filesystem3Repository4
    Bitnami packages/opt/bitnami/<component>/.spdx-<component>.spdx--
    Conda<conda-root>/envs/<env>/conda-meta/<package>.json--
    environment.yml--
    RPM Archives*.rpm5555
    -
    -
    -
      -
    1. -

      ✅ means "enabled" and - means "disabled" in the image scanning 

      -
    2. -
    3. -

      ✅ means "enabled" and - means "disabled" in the rootfs scanning 

      -
    4. -
    5. -

      ✅ means "enabled" and - means "disabled" in the filesystem scanning 

      -
    6. -
    7. -

      ✅ means "enabled" and - means "disabled" in the git repository scanning 

      -
    8. -
    9. -

      Only if the TRIVY_EXPERIMENTAL_RPM_ARCHIVE env is set. 

      -
    10. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/coverage/others/rpm/index.html b/v0.58.0/docs/coverage/others/rpm/index.html deleted file mode 100644 index 5efe9160d7f4..000000000000 --- a/v0.58.0/docs/coverage/others/rpm/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RPM Archives - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    RPM Archives

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy supports the following scanners for RPM archives.

    - - - - - - - - - - - - - - - - - - - - - -
    ScannerSupported
    SBOM
    Vulnerability1
    License
    -

    The table below outlines the features offered by Trivy.

    -

    SBOM

    -

    Trivy analyzes RPM archives matching *.rpm. -This feature is currently disabled by default but can be enabled with an environment variable, TRIVY_EXPERIMENTAL_RPM_ARCHIVE.

    -
    TRIVY_EXPERIMENTAL_RPM_ARCHIVE=true trivy fs ./rpms --format cyclonedx --output rpms.cdx.json
    -
    -
    -

    Note

    -

    Currently, it works with --format cyclonedx, --format spdx or --format spdx-json.

    -
    -

    Vulnerability

    -

    Since RPM files don't have OS information, you need to generate SBOM, fill in the OS information manually and then scan the SBOM for vulnerabilities.

    -

    For example:

    -
    $ TRIVY_EXPERIMENTAL_RPM_ARCHIVE=true trivy fs ./rpms -f cyclonedx -o rpms.cdx.json
    -$ jq '(.components[] | select(.type == "operating-system")) |= (.name = "redhat" | .version = "7.9")' rpms.cdx.json > rpms-res.cdx.json
    -$ trivy sbom ./rpms-res.cdx.json
    -
    -

    License

    -

    If licenses are included in the RPM archive, Trivy extracts it.

    -
    -
    -
      -
    1. -

      Need to generate SBOM first and add OS information to that SBOM 

      -
    2. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/index.html b/v0.58.0/docs/index.html deleted file mode 100644 index 1194482505d5..000000000000 --- a/v0.58.0/docs/index.html +++ /dev/null @@ -1,7777 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Docs

    -

    Welcome to the Trivy documentation!
    -Here you can find complete and thorough information about every aspect of Trivy, how to use it, features available, and configuration options.

    -

    👈 Please use the left side navigation browse the different topics.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/plugin/developer-guide/index.html b/v0.58.0/docs/plugin/developer-guide/index.html deleted file mode 100644 index c6b74577344d..000000000000 --- a/v0.58.0/docs/plugin/developer-guide/index.html +++ /dev/null @@ -1,8437 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Developer guide - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Developer Guide

    -

    Developing Trivy plugins

    -

    This section will guide you through the process of developing Trivy plugins. -To help you get started quickly, we have published a plugin template repository. -You can use this template as a starting point for your plugin development.

    -

    Introduction

    -

    If you are looking to start developing plugins for Trivy, read the user guide first.

    -

    The development process involves the following steps:

    -
      -
    • Create a repository for your plugin, named trivy-plugin-<name>.
    • -
    • Create an executable binary that can be invoked as trivy <name>.
    • -
    • Place the executable binary in a repository.
    • -
    • Create a plugin.yaml file that describes the plugin.
    • -
    • (Submit your plugin to the Trivy plugin index.)
    • -
    -

    After you develop a plugin with a good name following the best practices and publish it, you can submit your plugin to the Trivy plugin index.

    -

    Naming

    -

    This section describes guidelines for naming your plugins.

    -

    Use trivy-plugin- prefix

    -

    The name of the plugin repository should be prefixed with trivy-plugin-.

    -

    Use lowercase and hyphens

    -

    Plugin names must be all lowercase and separate words with hyphens. -Don’t use camelCase, PascalCase, or snake_case; use kebab-case.

    -
      -
    • NO: trivy OpenSvc
    • -
    • YES: trivy open-svc
    • -
    -

    Be specific

    -

    Plugin names should not be verbs or nouns that are generic, already overloaded, or likely to be used for broader purposes by another plugin.

    -
      -
    • NO: trivy sast (Too broad)
    • -
    • YES: trivy govulncheck
    • -
    -

    Be unique

    -

    Find a unique name for your plugin that differentiates it from other plugins that perform a similar function.

    -
      -
    • NO: trivy images (Unclear how it is different from the builtin “image" command)
    • -
    • YES: trivy registry-images (Unique name).
    • -
    -

    Prefix Vendor Identifiers

    -

    Use vendor-specific strings as prefix, separated with a dash. -This makes it easier to search/group plugins that are about a specific vendor.

    -
      -
    • NO: `trivy security-hub-aws (Makes it harder to search or locate in a plugin list)
    • -
    • YES: `trivy aws-security-hub (Will show up together with other aws-* plugins)
    • -
    -

    Choosing a language

    -

    Since Trivy plugins are standalone executables, you can write them in any programming language.

    -

    If you are planning to write a plugin with Go, check out the Report struct, -which is the output of Trivy scan.

    -

    Writing your plugin

    -

    Each plugin has a top-level directory, and then a plugin.yaml file.

    -
    your-plugin/
    -  |
    -  |- plugin.yaml
    -  |- your-plugin.sh
    -
    -

    In the example above, the plugin is contained inside a directory named your-plugin. -It has two files: plugin.yaml (required) and an executable script, your-plugin.sh (optional).

    -

    Writing a plugin manifest

    -

    The plugin manifest is a simple YAML file named plugin.yaml. -Here is an example YAML of trivy-plugin-kubectl plugin that adds support for Kubernetes scanning.

    -
    name: "kubectl"
    -version: "0.1.0"
    -repository: github.com/aquasecurity/trivy-plugin-kubectl
    -maintainer: aquasecurity
    -output: false
    -summary: Scan kubectl resources
    -description: |-
    -  A Trivy plugin that scans the images of a kubernetes resource.
    -  Usage: trivy kubectl TYPE[.VERSION][.GROUP] NAME
    -platforms:
    -  - selector: # optional
    -      os: darwin
    -      arch: amd64
    -    uri: ./trivy-kubectl # where the execution file is (local file, http, git, etc.)
    -    bin: ./trivy-kubectl # path to the execution file
    -  - selector: # optional
    -      os: linux
    -      arch: amd64
    -    uri: https://github.com/aquasecurity/trivy-plugin-kubectl/releases/download/v0.1.0/trivy-kubectl.tar.gz
    -    bin: ./trivy-kubectl
    -
    -

    We encourage you to copy and adapt plugin manifests of existing plugins.

    - -

    The plugin.yaml field should contain the following information:

    -
      -
    • name: The name of the plugin. This also determines how the plugin will be made available in the Trivy CLI. For example, if the plugin is named kubectl, you can call the plugin with trivy kubectl. (required)
    • -
    • version: The version of the plugin. Semantic Versioning should be used. (required)
    • -
    • repository: The repository name where the plugin is hosted. (required)
    • -
    • maintainer: The name of the maintainer of the plugin. (required)
    • -
    • output: Whether the plugin supports the output mode. (optional)
    • -
    • usage: Deprecated: use summary instead. (optional)
    • -
    • summary: A short usage description. (required)
    • -
    • description: A long description of the plugin. This is where you could provide a helpful documentation of your plugin. (required)
    • -
    • platforms: (required)
        -
      • selector: The OS/Architecture specific variations of a execution file. (optional)
          -
        • os: OS information based on GOOS (linux, darwin, etc.) (optional)
        • -
        • arch: The architecture information based on GOARCH (amd64, arm64, etc.) (optional)
        • -
        -
      • -
      • uri: Where the executable file is. Relative path from the root directory of the plugin or remote URL such as HTTP and S3. (required)
      • -
      • bin: Which file to call when the plugin is executed. Relative path from the root directory of the plugin. (required)
      • -
      -
    • -
    -

    The following rules will apply in deciding which platform to select:

    -
      -
    • If both os and arch under selector match the current platform, search will stop and the platform will be used.
    • -
    • If selector is not present, the platform will be used.
    • -
    • If os matches and there is no more specific arch match, the platform will be used.
    • -
    • If no platform match is found, Trivy will exit with an error.
    • -
    -

    After determining platform, Trivy will download the execution file from uri and store it in the plugin cache. -When the plugin is called via Trivy CLI, bin command will be executed.

    -

    Tagging plugin repositories

    -

    If you are hosting your plugin in a Git repository, it is strongly recommended to tag your releases with a version number. -By tagging your releases, Trivy can install specific versions of your plugin.

    -
    $ trivy plugin install referrer@v0.3.0
    -
    -

    When tagging versions, you must follow the Semantic Versioning and prefix the tag with v, like v1.2.3.

    -

    Plugin arguments/flags

    -

    The plugin is responsible for handling flags and arguments. -Any arguments are passed to the plugin from the trivy command.

    -

    Testing plugin installation locally

    -

    A plugin should be archived *.tar.gz. -After you have archived your plugin into a .tar.gz file, you can verify that your plugin installs correctly with Trivy.

    -
    $ tar -czvf myplugin.tar.gz plugin.yaml script.py
    -plugin.yaml
    -script.py
    -
    -$ trivy plugin install myplugin.tar.gz
    -2023-03-03T19:04:42.026+0600    INFO    Installing the plugin from myplugin.tar.gz...
    -2023-03-03T19:04:42.026+0600    INFO    Loading the plugin metadata...
    -
    -$ trivy myplugin
    -Hello from Trivy demo plugin!
    -
    -

    Publishing plugins

    -

    The plugin.yaml file is the core of your plugin, so as long as it is published somewhere, your plugin can be installed. -If you choose to publish your plugin on GitHub, you can make it installable by placing the plugin.yaml file in the root directory of your repository. -Users can then install your plugin with the command, trivy plugin install github.com/org/repo.

    -

    While the uri specified in the plugin.yaml file doesn't necessarily need to point to the same repository, it's a good practice to host the executable file within the same repository when using GitHub. -You can utilize GitHub Releases to distribute the executable file. -For an example of how to structure your plugin repository, refer to the plugin template repository.

    -

    Distributing plugins via the Trivy plugin index

    -

    Trivy can install plugins directly by specifying a repository, like trivy plugin install github.com/aquasecurity/trivy-plugin-referrer, -so you don't necessarily need to register your plugin in the Trivy plugin index. -However, we would recommend distributing your plugin via the Trivy plugin index -since it makes it easier for other users to find (trivy plugin search) and install your plugin (e.g. trivy plugin install kubectl).

    -

    Pre-submit checklist

    - -

    Submitting plugins

    -

    Submitting your plugin to the plugin index is a straightforward process. -All you need to do is create a YAML file for your plugin and place it in the plugins/ directory of the index repository.

    -

    Once you've done that, create a pull request (PR) and have it reviewed by the maintainers. -Once your PR is merged, the index will be updated, and your plugin will be available for installation. -The plugin index page will also be automatically updated to list your newly added plugin.

    -

    The content of the YAML file is very simple. -You only need to specify the name of your plugin and the repository where it is distributed.

    -
    name: referrer
    -repository: github.com/aquasecurity/trivy-plugin-referrer
    -
    -

    After your PR is merged, the CI system will automatically retrieve the plugin.yaml file from your repository and update the index.yaml file. -If any required fields are missing from your plugin.yaml, the CI will fail, so make sure your plugin.yaml has all the required fields before creating a PR. -Once the index.yaml has been updated, running trivy plugin update will download the updated index to your local machine.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/plugin/index.html b/v0.58.0/docs/plugin/index.html deleted file mode 100644 index b157987f1033..000000000000 --- a/v0.58.0/docs/plugin/index.html +++ /dev/null @@ -1,7921 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugins

    -

    Trivy provides a plugin feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. -This plugin system was inspired by the plugin system used in kubectl, Helm, and Conftest.

    -

    Overview

    -

    Trivy plugins are add-on tools that integrate seamlessly with Trivy. -They provide a way to extend the core feature set of Trivy, but without requiring every new feature to be written in Go and added to the core tool.

    -
      -
    • They can be added and removed from a Trivy installation without impacting the core Trivy tool.
    • -
    • They can be written in any programming language.
    • -
    • They integrate with Trivy, and will show up in Trivy help and subcommands.
    • -
    -
    -

    Warning

    -

    Trivy plugins available in public are not audited for security. -You should install and run third-party plugins at your own risk, since they are arbitrary programs running on your machine.

    -
    -

    Quickstart

    -

    Trivy helps you discover and install plugins on your machine.

    -

    You can install and use a wide variety of Trivy plugins to enhance your experience.

    -

    Let’s get started:

    -
      -
    1. -

      Download the plugin list:

      -
      $ trivy plugin update
      -
      -
    2. -
    3. -

      Discover Trivy plugins available on the plugin index:

      -
      $ trivy plugin search
      -NAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT
      -aqua                 A plugin for integration with Aqua Security SaaS platform    aquasecurity
      -kubectl              A plugin scanning the images of a kubernetes resource        aquasecurity
      -referrer             A plugin for OCI referrers                                   aquasecurity           ✓
      -[...]
      -
      -
    4. -
    5. -

      Choose a plugin from the list and install it:

      -
      $ trivy plugin install referrer
      -
      -
    6. -
    7. -

      Use the installed plugin:

      -
      $ trivy referrer --help
      -
      -
    8. -
    9. -

      Keep your plugins up-to-date:

      -
      $ trivy plugin upgrade
      -
      -
    10. -
    11. -

      Uninstall a plugin you no longer use:

      -
      trivy plugin uninstall referrer
      -
      -
    12. -
    -

    This is practically all you need to know to start using Trivy plugins.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/plugin/user-guide/index.html b/v0.58.0/docs/plugin/user-guide/index.html deleted file mode 100644 index c70c3946b9ea..000000000000 --- a/v0.58.0/docs/plugin/user-guide/index.html +++ /dev/null @@ -1,8170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - User guide - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    User Guide

    -

    Discovering Plugins

    -

    You can find a list of Trivy plugins distributed via trivy-plugin-index here. -However, you can find plugins using the command line as well.

    -

    First, refresh your local copy of the plugin index:

    -
    $ trivy plugin update
    -
    -

    To list all plugins available, run:

    -
    $ trivy plugin search
    -NAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT
    -aqua                 A plugin for integration with Aqua Security SaaS platform    aquasecurity
    -kubectl              A plugin scanning the images of a kubernetes resource        aquasecurity
    -referrer             A plugin for OCI referrers                                   aquasecurity           ✓
    -
    -

    You can specify search keywords as arguments:

    -
    $ trivy plugin search referrer
    -
    -NAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT
    -referrer             A plugin for OCI referrers                                   aquasecurity           ✓
    -
    -

    It lists plugins with the keyword in the name or description.

    -

    Installing Plugins

    -

    Plugins can be installed with the trivy plugin install command:

    -
    $ trivy plugin install referrer
    -
    -

    This command will download the plugin and install it in the plugin cache.

    -

    Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. -Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache. -The preference order is as follows:

    -
      -
    • XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir
    • -
    • ~/.trivy/plugins
    • -
    -

    Furthermore, it is possible to download plugins that are not registered in the index by specifying the URL directly or by specifying the file path.

    -

    $ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl
    -
    -
    $ trivy plugin install https://github.com/aquasecurity/trivy-plugin-kubectl/archive/refs/heads/main.zip
    -
    -
    $ trivy plugin install ./myplugin.tar.gz
    -

    -

    If the plugin's Git repository is properly tagged, you can specify the version to install like this:

    -
    $ trivy plugin install referrer@v0.3.0
    -
    -
    -

    Note

    -

    The leading v in the version is required. Also, the version must follow the Semantic Versioning.

    -
    -

    Under the hood Trivy leverages go-getter to download plugins. -This means the following protocols are supported for downloading plugins:

    -
      -
    • OCI Registries
    • -
    • Local Files
    • -
    • Git
    • -
    • HTTP/HTTPS
    • -
    • Mercurial
    • -
    • Amazon S3
    • -
    • Google Cloud Storage
    • -
    -

    Listing Installed Plugins

    -

    To list all plugins installed, run:

    -
    $ trivy plugin list
    -
    -

    Using Plugins

    -

    Once the plugin is installed, Trivy will load all available plugins in the cache on the start of the next Trivy execution. -A plugin will be made in the Trivy CLI based on the plugin name. -To display all plugins, you can list them by trivy --help

    -
    $ trivy --help
    -NAME:
    -   trivy - A simple and comprehensive vulnerability scanner for containers
    -
    -USAGE:
    -   trivy [global options] command [command options] target
    -
    -VERSION:
    -   dev
    -
    -Scanning Commands
    -  config      Scan config files for misconfigurations
    -  filesystem  Scan local filesystem
    -  image       Scan a container image
    -
    -...
    -
    -Plugin Commands
    -  kubectl     scan kubectl resources
    -  referrer    Put referrers to OCI registry
    -
    -

    As shown above, kubectl subcommand exists in the Plugin Commands section. -To call the kubectl plugin and scan existing Kubernetes deployments, you can execute the following command:

    -
    $ trivy kubectl deployment <deployment-id> -- --ignore-unfixed --severity CRITICAL
    -
    -

    Internally the kubectl plugin calls the kubectl binary to fetch information about that deployment and passes the using images to Trivy. -You can see the detail here.

    -

    If you want to omit even the subcommand, you can use TRIVY_RUN_AS_PLUGIN environment variable.

    -
    $ TRIVY_RUN_AS_PLUGIN=kubectl trivy job your-job -- --format json
    -
    -

    Installing and Running Plugins on the fly

    -

    trivy plugin run installs a plugin and runs it on the fly. -If the plugin is already present in the cache, the installation is skipped.

    -
    trivy plugin run kubectl pod your-pod -- --exit-code 1
    -
    -

    Upgrading Plugins

    -

    To upgrade all plugins that you have installed to their latest versions, run:

    -
    $ trivy plugin upgrade
    -
    -

    To upgrade only certain plugins, you can explicitly specify their names:

    -
    $ trivy plugin upgrade <PLUGIN1> <PLUGIN2>
    -
    -

    Uninstalling Plugins

    -

    Specify a plugin name with trivy plugin uninstall command.

    -
    $ trivy plugin uninstall kubectl
    -
    -

    Here's the revised English documentation based on your requested changes:

    -

    Output Mode Support

    -

    While plugins are typically intended to be used as subcommands of Trivy, plugins supporting the output mode can be invoked as part of Trivy's built-in commands.

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy supports plugins that are compatible with the output mode, which process Trivy's output, such as by transforming the output format or sending it elsewhere. -You can determine whether a plugin supports the output mode by checking the OUTPUT column in the output of trivy plugin search or trivy plugin list.

    -
    $ trivy plugin search
    -NAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT
    -aqua                 A plugin for integration with Aqua Security SaaS platform    aquasecurity
    -kubectl              A plugin scanning the images of a kubernetes resource        aquasecurity
    -referrer             A plugin for OCI referrers                                   aquasecurity           ✓
    -
    -

    In this case, the referrer plugin supports the output mode.

    -

    For instance, in the case of image scanning, a plugin supporting the output mode can be called as follows:

    -
    $ trivy image --format json --output plugin=<plugin_name> [--output-plugin-arg <plugin_flags>] <image_name>
    -
    -

    Since scan results are passed to the plugin via standard input, plugins must be capable of handling standard input.

    -
    -

    Warning

    -

    To avoid Trivy hanging, you need to read all data from Stdin before the plugin exits successfully or stops with an error.

    -
    -

    While the example passes JSON to the plugin, other formats like SBOM can also be passed (e.g., --format cyclonedx).

    -

    If a plugin requires flags or other arguments, they can be passed using --output-plugin-arg. -This is directly forwarded as arguments to the plugin. -For example, --output plugin=myplugin --output-plugin-arg "--foo --bar=baz" translates to myplugin --foo --bar=baz in execution.

    -

    An example of a plugin supporting the output mode is available here. -It can be used as below:

    -
    # Install the plugin first
    -$ trivy plugin install count
    -
    -# Call the plugin supporting the output mode in image scanning
    -$ trivy image --format json --output plugin=count --output-plugin-arg "--published-after 2023-10-01" debian:12
    -
    -

    Example

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy/index.html b/v0.58.0/docs/references/configuration/cli/trivy/index.html deleted file mode 100644 index 13988c7daf1a..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy/index.html +++ /dev/null @@ -1,7991 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Overview

    - -

    trivy

    -

    Unified security scanner

    -

    Synopsis

    -

    Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets

    -
    trivy [global flags] command [flags] target
    -
    -

    Examples

    -
      # Scan a container image
    -  $ trivy image python:3.4-alpine
    -
    -  # Scan a container image from a tar archive
    -  $ trivy image --input ruby-3.1.tar
    -
    -  # Scan local filesystem
    -  $ trivy fs .
    -
    -  # Run in server mode
    -  $ trivy server
    -
    -

    Options

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -  -f, --format string             version format (json)
    -      --generate-default-config   write the default config to trivy-default.yaml
    -  -h, --help                      help for trivy
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_clean/index.html b/v0.58.0/docs/references/configuration/cli/trivy_clean/index.html deleted file mode 100644 index 42c8dedd84c7..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_clean/index.html +++ /dev/null @@ -1,7978 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Clean - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Clean

    - -

    trivy clean

    -

    Remove cached files

    -
    trivy clean [flags]
    -
    -

    Examples

    -
      # Remove all caches
    -  $ trivy clean --all
    -
    -  # Remove scan cache
    -  $ trivy clean --scan-cache
    -
    -  # Remove vulnerability database
    -  $ trivy clean --vuln-db
    -
    -

    Options

    -
      -a, --all             remove all caches
    -      --checks-bundle   remove checks bundle
    -  -h, --help            help for clean
    -      --java-db         remove Java database
    -      --scan-cache      remove scan cache (container and VM image analysis results)
    -      --vex-repo        remove VEX repositories
    -      --vuln-db         remove vulnerability database
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_config/index.html b/v0.58.0/docs/references/configuration/cli/trivy_config/index.html deleted file mode 100644 index 063d5a947375..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_config/index.html +++ /dev/null @@ -1,7985 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Config - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Config

    - -

    trivy config

    -

    Scan config files for misconfigurations

    -
    trivy config [flags] DIR
    -
    -

    Options

    -
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --cf-params strings                 specify paths to override the CloudFormation parameters files
    -      --check-namespaces strings          Rego namespaces
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --compliance string                 compliance report to generate
    -      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files
    -      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --enable-modules strings            [EXPERIMENTAL] module names to enable
    -      --exit-code int                     specify exit code when any security issues are found
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for config
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --include-deprecated-checks         include deprecated checks
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --k8s-version string                specify k8s version to validate outdated api by it (example: 1.21.0)
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --module-dir string                 specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin                    password from stdin. Comma-separated passwords are not supported.
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string             registry token
    -      --report string                     specify a compliance report format for the output (all,summary) (default "all")
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --skip-check-update                 skip fetching rego check updates
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --tf-vars strings                   specify paths to override the Terraform tfvars files
    -      --trace                             enable more verbose trace output for custom queries
    -      --username strings                  username. Comma-separated usernames allowed.
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_convert/index.html b/v0.58.0/docs/references/configuration/cli/trivy_convert/index.html deleted file mode 100644 index 4baa1b745daa..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_convert/index.html +++ /dev/null @@ -1,7981 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Convert - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Convert

    - -

    trivy convert

    -

    Convert Trivy JSON report into a different format

    -
    trivy convert [flags] RESULT_JSON
    -
    -

    Examples

    -
      # report conversion
    -  $ trivy image --format json --output result.json --list-all-pkgs debian:11
    -  $ trivy convert --format cyclonedx --output result.cdx result.json
    -
    -

    Options

    -
          --compliance string          compliance report to generate
    -      --dependency-tree            [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --exit-code int              specify exit code when any security issues are found
    -      --exit-on-eol int            exit with the specified code when the OS reaches end of service/life
    -  -f, --format string              format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -  -h, --help                       help for convert
    -      --ignore-policy string       specify the Rego file path to evaluate each vulnerability
    -      --ignorefile string          specify .trivyignore file (default ".trivyignore")
    -      --list-all-pkgs              output all packages in the JSON report regardless of vulnerability
    -  -o, --output string              output file name
    -      --output-plugin-arg string   [EXPERIMENTAL] output plugin arguments
    -      --report string              specify a report format for the output (all,summary) (default "all")
    -  -s, --severity strings           severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed            [EXPERIMENTAL] show suppressed vulnerabilities
    -  -t, --template string            output template
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_filesystem/index.html b/v0.58.0/docs/references/configuration/cli/trivy_filesystem/index.html deleted file mode 100644 index 701a2b676fac..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_filesystem/index.html +++ /dev/null @@ -1,8047 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Filesystem

    - -

    trivy filesystem

    -

    Scan local filesystem

    -
    trivy filesystem [flags] PATH
    -
    -

    Examples

    -
      # Scan a local project including language-specific files
    -  $ trivy fs /path/to/your_project
    -
    -  # Scan a single file
    -  $ trivy fs ./trivy-ci-test/Pipfile.lock
    -
    -

    Options

    -
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --cf-params strings                 specify paths to override the CloudFormation parameters files
    -      --check-namespaces strings          Rego namespaces
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --compliance string                 compliance report to generate
    -      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files
    -      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --custom-headers strings            custom headers in client mode
    -      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --detection-priority string         specify the detection priority:
    -                                            - "precise": Prioritizes precise by minimizing false positives.
    -                                            - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                           (precise,comprehensive) (default "precise")
    -      --download-db-only                  download/update vulnerability database but don't run a scan
    -      --download-java-db-only             download/update Java index database but don't run a scan
    -      --enable-modules strings            [EXPERIMENTAL] module names to enable
    -      --exit-code int                     specify exit code when any security issues are found
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for filesystem
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed                    display only fixed vulnerabilities
    -      --ignored-licenses strings          specify a list of license to ignore
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --include-deprecated-checks         include deprecated checks
    -      --include-dev-deps                  include development dependencies in the report (supported: npm, yarn)
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --license-confidence-level float    specify license classifier's confidence level (default 0.9)
    -      --license-full                      eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --module-dir string                 specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                       suppress progress bar
    -      --offline-scan                      do not issue API requests to identify dependencies
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
    -      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin                    password from stdin. Comma-separated passwords are not supported.
    -      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings                 list of package types (os,library) (default [os,library])
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string             registry token
    -      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --report string                     specify a compliance report format for the output (all,summary) (default "all")
    -      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
    -      --secret-config string              specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                     server address in client mode
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-check-update                 skip fetching rego check updates
    -      --skip-db-update                    skip updating vulnerability database
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -      --skip-java-db-update               skip updating Java index database
    -      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --tf-vars strings                   specify paths to override the Terraform tfvars files
    -      --token string                      for authentication in client/server mode
    -      --token-header string               specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                             enable more verbose trace output for custom queries
    -      --username strings                  username. Comma-separated usernames allowed.
    -      --vex strings                       [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_image/index.html b/v0.58.0/docs/references/configuration/cli/trivy_image/index.html deleted file mode 100644 index bba33e69c535..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_image/index.html +++ /dev/null @@ -1,8067 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Image - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Image

    - -

    trivy image

    -

    Scan a container image

    -
    trivy image [flags] IMAGE_NAME
    -
    -

    Examples

    -
      # Scan a container image
    -  $ trivy image python:3.4-alpine
    -
    -  # Scan a container image from a tar archive
    -  $ trivy image --input ruby-3.1.tar
    -
    -  # Filter by severities
    -  $ trivy image --severity HIGH,CRITICAL alpine:3.15
    -
    -  # Ignore unfixed/unpatched vulnerabilities
    -  $ trivy image --ignore-unfixed alpine:3.15
    -
    -  # Scan a container image in client mode
    -  $ trivy image --server http://127.0.0.1:4954 alpine:latest
    -
    -  # Generate json result
    -  $ trivy image --format json --output result.json alpine:3.15
    -
    -  # Generate a report in the CycloneDX format
    -  $ trivy image --format cyclonedx --output result.cdx alpine:3.15
    -
    -

    Options

    -
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --check-namespaces strings          Rego namespaces
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --compliance string                 compliance report to generate (docker-cis-1.6.0)
    -      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files
    -      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --custom-headers strings            custom headers in client mode
    -      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --detection-priority string         specify the detection priority:
    -                                            - "precise": Prioritizes precise by minimizing false positives.
    -                                            - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                           (precise,comprehensive) (default "precise")
    -      --docker-host string                unix domain socket path to use for docker scanning
    -      --download-db-only                  download/update vulnerability database but don't run a scan
    -      --download-java-db-only             download/update Java index database but don't run a scan
    -      --enable-modules strings            [EXPERIMENTAL] module names to enable
    -      --exit-code int                     specify exit code when any security issues are found
    -      --exit-on-eol int                   exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for image
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed                    display only fixed vulnerabilities
    -      --ignored-licenses strings          specify a list of license to ignore
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --image-config-scanners strings     comma-separated list of what security issues to detect on container image configurations (misconfig,secret)
    -      --image-src strings                 image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
    -      --include-deprecated-checks         include deprecated checks
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --input string                      input file path instead of image name
    -      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --license-confidence-level float    specify license classifier's confidence level (default 0.9)
    -      --license-full                      eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --module-dir string                 specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                       suppress progress bar
    -      --offline-scan                      do not issue API requests to identify dependencies
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
    -      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin                    password from stdin. Comma-separated passwords are not supported.
    -      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings                 list of package types (os,library) (default [os,library])
    -      --platform string                   set platform in the form os/arch if image is multi-platform capable
    -      --podman-host string                unix podman socket path to use for podman scanning
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string             registry token
    -      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --removed-pkgs                      detect vulnerabilities of removed packages (only for Alpine)
    -      --report string                     specify a format for the compliance report. (all,summary) (default "summary")
    -      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
    -      --secret-config string              specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                     server address in client mode
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-check-update                 skip fetching rego check updates
    -      --skip-db-update                    skip updating vulnerability database
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -      --skip-java-db-update               skip updating Java index database
    -      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --token string                      for authentication in client/server mode
    -      --token-header string               specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                             enable more verbose trace output for custom queries
    -      --username strings                  username. Comma-separated usernames allowed.
    -      --vex strings                       [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_kubernetes/index.html b/v0.58.0/docs/references/configuration/cli/trivy_kubernetes/index.html deleted file mode 100644 index 59e31d59dc9e..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_kubernetes/index.html +++ /dev/null @@ -1,8078 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kubernetes - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Kubernetes

    - -

    trivy kubernetes

    -

    [EXPERIMENTAL] Scan kubernetes cluster

    -

    Synopsis

    -

    Default context in kube configuration will be used unless specified

    -
    trivy kubernetes [flags] [CONTEXT]
    -
    -

    Examples

    -
      # cluster scanning
    -  $ trivy k8s --report summary
    -
    -  # cluster scanning with specific namespace:
    -  $ trivy k8s --include-namespaces kube-system --report summary 
    -
    -  # cluster with specific context:
    -  $ trivy k8s kind-kind --report summary 
    -
    -

    Options

    -
          --burst int                         specify the maximum burst for throttle (default 10)
    -      --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --check-namespaces strings          Rego namespaces
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --compliance string                 compliance report to generate (k8s-nsa-1.0,k8s-cis-1.23,eks-cis-1.4,rke2-cis-1.24,k8s-pss-baseline-0.1,k8s-pss-restricted-0.1)
    -      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files
    -      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --detection-priority string         specify the detection priority:
    -                                            - "precise": Prioritizes precise by minimizing false positives.
    -                                            - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                           (precise,comprehensive) (default "precise")
    -      --disable-node-collector            When the flag is activated, the node-collector job will not be executed, thus skipping misconfiguration findings on the node.
    -      --download-db-only                  download/update vulnerability database but don't run a scan
    -      --download-java-db-only             download/update Java index database but don't run a scan
    -      --exclude-kinds strings             indicate the kinds exclude from scanning (example: node)
    -      --exclude-namespaces strings        indicate the namespaces excluded from scanning (example: kube-system)
    -      --exclude-nodes strings             indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)
    -      --exclude-owned                     exclude resources that have an owner reference
    -      --exit-code int                     specify exit code when any security issues are found
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,cyclonedx) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for kubernetes
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed                    display only fixed vulnerabilities
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --image-src strings                 image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
    -      --include-deprecated-checks         include deprecated checks
    -      --include-kinds strings             indicate the kinds included in scanning (example: node)
    -      --include-namespaces strings        indicate the namespaces included in scanning (example: kube-system)
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --k8s-version string                specify k8s version to validate outdated api by it (example: 1.21.0)
    -      --kubeconfig string                 specify the kubeconfig file path to use
    -      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --no-progress                       suppress progress bar
    -      --node-collector-imageref string    indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.3.1")
    -      --node-collector-namespace string   specify the namespace in which the node-collector job should be deployed (default "trivy-temp")
    -      --offline-scan                      do not issue API requests to identify dependencies
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
    -      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin                    password from stdin. Comma-separated passwords are not supported.
    -      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings                 list of package types (os,library) (default [os,library])
    -      --qps float                         specify the maximum QPS to the master from this client (default 5)
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string             registry token
    -      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --report string                     specify a report format for the output (all,summary) (default "all")
    -      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,rbac) (default [vuln,misconfig,secret,rbac])
    -      --secret-config string              specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-check-update                 skip fetching rego check updates
    -      --skip-db-update                    skip updating vulnerability database
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -      --skip-images                       skip the downloading and scanning of images (vulnerabilities and secrets) in the cluster resources
    -      --skip-java-db-update               skip updating Java index database
    -      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --tolerations strings               specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)
    -      --trace                             enable more verbose trace output for custom queries
    -      --username strings                  username. Comma-separated usernames allowed.
    -      --vex strings                       [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_module/index.html b/v0.58.0/docs/references/configuration/cli/trivy_module/index.html deleted file mode 100644 index 6485c6490af1..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_module/index.html +++ /dev/null @@ -1,7944 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Module - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Module

    - -

    trivy module

    -

    Manage modules

    -

    Options

    -
          --enable-modules strings   [EXPERIMENTAL] module names to enable
    -  -h, --help                     help for module
    -      --module-dir string        specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_module_install/index.html b/v0.58.0/docs/references/configuration/cli/trivy_module_install/index.html deleted file mode 100644 index 3247519b811f..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_module_install/index.html +++ /dev/null @@ -1,7944 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Module Install - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Module Install

    - -

    trivy module install

    -

    Install a module

    -
    trivy module install [flags] REPOSITORY
    -
    -

    Options

    -
      -h, --help   help for install
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --enable-modules strings    [EXPERIMENTAL] module names to enable
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -      --module-dir string         specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_module_uninstall/index.html b/v0.58.0/docs/references/configuration/cli/trivy_module_uninstall/index.html deleted file mode 100644 index 438a3af97f74..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_module_uninstall/index.html +++ /dev/null @@ -1,7944 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Module Uninstall - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Module Uninstall

    - -

    trivy module uninstall

    -

    Uninstall a module

    -
    trivy module uninstall [flags] REPOSITORY
    -
    -

    Options

    -
      -h, --help   help for uninstall
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --enable-modules strings    [EXPERIMENTAL] module names to enable
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -      --module-dir string         specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin/index.html deleted file mode 100644 index 1aa811ee03e9..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin/index.html +++ /dev/null @@ -1,7948 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin

    - -

    trivy plugin

    -

    Manage plugins

    -

    Options

    -
      -h, --help   help for plugin
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_info/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_info/index.html deleted file mode 100644 index 441213fb0e45..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_info/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Info - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Info

    - -

    trivy plugin info

    -

    Show information about the specified plugin

    -
    trivy plugin info PLUGIN_NAME
    -
    -

    Options

    -
      -h, --help   help for info
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_install/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_install/index.html deleted file mode 100644 index a35164b3c73d..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_install/index.html +++ /dev/null @@ -1,7974 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Install - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Install

    - -

    trivy plugin install

    -

    Install a plugin

    -
    trivy plugin install NAME | URL | FILE_PATH
    -
    -

    Examples

    -
      # Install a plugin from the plugin index
    -  $ trivy plugin install referrer
    -
    -  # Specify the version of the plugin to install
    -  $ trivy plugin install referrer@v0.3.0
    -
    -  # Install a plugin from a URL
    -  $ trivy plugin install github.com/aquasecurity/trivy-plugin-referrer
    -
    -

    Options

    -
      -h, --help   help for install
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_list/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_list/index.html deleted file mode 100644 index 6db87a57ee3e..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_list/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin List - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin List

    - -

    trivy plugin list

    -

    List installed plugin

    -
    trivy plugin list
    -
    -

    Options

    -
      -h, --help   help for list
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_run/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_run/index.html deleted file mode 100644 index 50ecf40e4384..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_run/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Run - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Run

    - -

    trivy plugin run

    -

    Run a plugin on the fly

    -
    trivy plugin run NAME | URL | FILE_PATH
    -
    -

    Options

    -
      -h, --help   help for run
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_search/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_search/index.html deleted file mode 100644 index b6b492aed754..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_search/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Search - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Search

    - - -

    List Trivy plugins available on the plugin index and search among them

    -
    trivy plugin search [KEYWORD]
    -
    -

    Options

    -
      -h, --help   help for search
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_uninstall/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_uninstall/index.html deleted file mode 100644 index 564284d7a1d8..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_uninstall/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Uninstall - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Uninstall

    - -

    trivy plugin uninstall

    -

    Uninstall a plugin

    -
    trivy plugin uninstall PLUGIN_NAME
    -
    -

    Options

    -
      -h, --help   help for uninstall
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_update/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_update/index.html deleted file mode 100644 index 4297e650e80e..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_update/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Update - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Update

    - -

    trivy plugin update

    -

    Update the local copy of the plugin index

    -
    trivy plugin update
    -
    -

    Options

    -
      -h, --help   help for update
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_plugin_upgrade/index.html b/v0.58.0/docs/references/configuration/cli/trivy_plugin_upgrade/index.html deleted file mode 100644 index 8dfb9e6c5680..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_plugin_upgrade/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin Upgrade - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Plugin Upgrade

    - -

    trivy plugin upgrade

    -

    Upgrade installed plugins to newer versions

    -
    trivy plugin upgrade [PLUGIN_NAMES]
    -
    -

    Options

    -
      -h, --help   help for upgrade
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_registry/index.html b/v0.58.0/docs/references/configuration/cli/trivy_registry/index.html deleted file mode 100644 index c0e20b098617..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_registry/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Registry - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Registry

    - -

    trivy registry

    -

    Manage registry authentication

    -

    Options

    -
      -h, --help   help for registry
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_registry_login/index.html b/v0.58.0/docs/references/configuration/cli/trivy_registry_login/index.html deleted file mode 100644 index 2d28b0a0f5f1..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_registry_login/index.html +++ /dev/null @@ -1,7971 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Registry Login - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Registry Login

    - -

    trivy registry login

    -

    Log in to a registry

    -
    trivy registry login SERVER [flags]
    -
    -

    Examples

    -
      # Log in to reg.example.com
    -  cat ~/my_password.txt | trivy registry login --username foo --password-stdin reg.example.com
    -
    -

    Options

    -
      -h, --help               help for login
    -      --password strings   password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin     password from stdin. Comma-separated passwords are not supported.
    -      --username strings   username. Comma-separated usernames allowed.
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_registry_logout/index.html b/v0.58.0/docs/references/configuration/cli/trivy_registry_logout/index.html deleted file mode 100644 index c0529043cd9b..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_registry_logout/index.html +++ /dev/null @@ -1,7968 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Registry Logout - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Registry Logout

    - -

    trivy registry logout

    -

    Log out of a registry

    -
    trivy registry logout SERVER [flags]
    -
    -

    Examples

    -
      # Log out of reg.example.com
    -  trivy registry logout reg.example.com
    -
    -

    Options

    -
      -h, --help   help for logout
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_repository/index.html b/v0.58.0/docs/references/configuration/cli/trivy_repository/index.html deleted file mode 100644 index 4493222a98a5..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_repository/index.html +++ /dev/null @@ -1,8047 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Repository - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Repository

    - -

    trivy repository

    -

    Scan a repository

    -
    trivy repository [flags] (REPO_PATH | REPO_URL)
    -
    -

    Examples

    -
      # Scan your remote git repository
    -  $ trivy repo https://github.com/knqyf263/trivy-ci-test
    -  # Scan your local git repository
    -  $ trivy repo /path/to/your/repository
    -
    -

    Options

    -
          --branch string                     pass the branch name to be scanned
    -      --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --cf-params strings                 specify paths to override the CloudFormation parameters files
    -      --check-namespaces strings          Rego namespaces
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --commit string                     pass the commit hash to be scanned
    -      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files
    -      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --custom-headers strings            custom headers in client mode
    -      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --detection-priority string         specify the detection priority:
    -                                            - "precise": Prioritizes precise by minimizing false positives.
    -                                            - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                           (precise,comprehensive) (default "precise")
    -      --download-db-only                  download/update vulnerability database but don't run a scan
    -      --download-java-db-only             download/update Java index database but don't run a scan
    -      --enable-modules strings            [EXPERIMENTAL] module names to enable
    -      --exit-code int                     specify exit code when any security issues are found
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for repository
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed                    display only fixed vulnerabilities
    -      --ignored-licenses strings          specify a list of license to ignore
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --include-deprecated-checks         include deprecated checks
    -      --include-dev-deps                  include development dependencies in the report (supported: npm, yarn)
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --license-confidence-level float    specify license classifier's confidence level (default 0.9)
    -      --license-full                      eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --module-dir string                 specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                       suppress progress bar
    -      --offline-scan                      do not issue API requests to identify dependencies
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
    -      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin                    password from stdin. Comma-separated passwords are not supported.
    -      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings                 list of package types (os,library) (default [os,library])
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string             registry token
    -      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
    -      --secret-config string              specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                     server address in client mode
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-check-update                 skip fetching rego check updates
    -      --skip-db-update                    skip updating vulnerability database
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -      --skip-java-db-update               skip updating Java index database
    -      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update
    -      --tag string                        pass the tag name to be scanned
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --tf-vars strings                   specify paths to override the Terraform tfvars files
    -      --token string                      for authentication in client/server mode
    -      --token-header string               specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                             enable more verbose trace output for custom queries
    -      --username strings                  username. Comma-separated usernames allowed.
    -      --vex strings                       [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_rootfs/index.html b/v0.58.0/docs/references/configuration/cli/trivy_rootfs/index.html deleted file mode 100644 index fc05481e7752..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_rootfs/index.html +++ /dev/null @@ -1,8048 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rootfs - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Rootfs

    - -

    trivy rootfs

    -

    Scan rootfs

    -
    trivy rootfs [flags] ROOTDIR
    -
    -

    Examples

    -
      # Scan unpacked filesystem
    -  $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
    -  $ trivy rootfs /tmp/rootfs
    -
    -  # Scan from inside a container
    -  $ docker run --rm -it alpine:3.11
    -  / # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
    -  / # trivy rootfs /
    -
    -

    Options

    -
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --cf-params strings                 specify paths to override the CloudFormation parameters files
    -      --check-namespaces strings          Rego namespaces
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files
    -      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --custom-headers strings            custom headers in client mode
    -      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --detection-priority string         specify the detection priority:
    -                                            - "precise": Prioritizes precise by minimizing false positives.
    -                                            - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                           (precise,comprehensive) (default "precise")
    -      --download-db-only                  download/update vulnerability database but don't run a scan
    -      --download-java-db-only             download/update Java index database but don't run a scan
    -      --enable-modules strings            [EXPERIMENTAL] module names to enable
    -      --exit-code int                     specify exit code when any security issues are found
    -      --exit-on-eol int                   exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for rootfs
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed                    display only fixed vulnerabilities
    -      --ignored-licenses strings          specify a list of license to ignore
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --include-deprecated-checks         include deprecated checks
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --license-confidence-level float    specify license classifier's confidence level (default 0.9)
    -      --license-full                      eagerly look for licenses in source code headers and license files
    -      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --module-dir string                 specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                       suppress progress bar
    -      --offline-scan                      do not issue API requests to identify dependencies
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
    -      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin                    password from stdin. Comma-separated passwords are not supported.
    -      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings                 list of package types (os,library) (default [os,library])
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string             registry token
    -      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
    -      --secret-config string              specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                     server address in client mode
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-check-update                 skip fetching rego check updates
    -      --skip-db-update                    skip updating vulnerability database
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -      --skip-java-db-update               skip updating Java index database
    -      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --tf-vars strings                   specify paths to override the Terraform tfvars files
    -      --token string                      for authentication in client/server mode
    -      --token-header string               specify a header name for token in client/server mode (default "Trivy-Token")
    -      --trace                             enable more verbose trace output for custom queries
    -      --username strings                  username. Comma-separated usernames allowed.
    -      --vex strings                       [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_sbom/index.html b/v0.58.0/docs/references/configuration/cli/trivy_sbom/index.html deleted file mode 100644 index 200ebe81498e..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_sbom/index.html +++ /dev/null @@ -1,8020 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    SBOM

    - -

    trivy sbom

    -

    Scan SBOM for vulnerabilities and licenses

    -
    trivy sbom [flags] SBOM_PATH
    -
    -

    Examples

    -
      # Scan CycloneDX and show the result in tables
    -  $ trivy sbom /path/to/report.cdx
    -
    -  # Scan CycloneDX-type attestation and show the result in tables
    -  $ trivy sbom /path/to/report.cdx.intoto.jsonl
    -
    -

    Options

    -
          --cache-backend string         [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory")
    -      --cache-ttl duration           cache TTL when using redis as cache backend
    -      --compliance string            compliance report to generate
    -      --custom-headers strings       custom headers in client mode
    -      --db-repository strings        OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --detection-priority string    specify the detection priority:
    -                                       - "precise": Prioritizes precise by minimizing false positives.
    -                                       - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                      (precise,comprehensive) (default "precise")
    -      --download-db-only             download/update vulnerability database but don't run a scan
    -      --download-java-db-only        download/update Java index database but don't run a scan
    -      --exit-code int                specify exit code when any security issues are found
    -      --exit-on-eol int              exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings        specify config file patterns
    -  -f, --format string                format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -  -h, --help                         help for sbom
    -      --ignore-policy string         specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings        comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed               display only fixed vulnerabilities
    -      --ignored-licenses strings     specify a list of license to ignore
    -      --ignorefile string            specify .trivyignore file (default ".trivyignore")
    -      --java-db-repository strings   OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --list-all-pkgs                output all packages in the JSON report regardless of vulnerability
    -      --no-progress                  suppress progress bar
    -      --offline-scan                 do not issue API requests to identify dependencies
    -  -o, --output string                output file name
    -      --output-plugin-arg string     [EXPERIMENTAL] output plugin arguments
    -      --password strings             password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin               password from stdin. Comma-separated passwords are not supported.
    -      --pkg-relationships strings    list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings            list of package types (os,library) (default [os,library])
    -      --redis-ca string              redis ca file location, if using redis as cache backend
    -      --redis-cert string            redis certificate file location, if using redis as cache backend
    -      --redis-key string             redis key file location, if using redis as cache backend
    -      --redis-tls                    enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string        registry token
    -      --rekor-url string             [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --sbom-sources strings         [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings             comma-separated list of what security issues to detect (vuln,license) (default [vuln])
    -      --server string                server address in client mode
    -  -s, --severity strings             severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed              [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-db-update               skip updating vulnerability database
    -      --skip-dirs strings            specify the directories or glob patterns to skip
    -      --skip-files strings           specify the files or glob patterns to skip
    -      --skip-java-db-update          skip updating Java index database
    -      --skip-vex-repo-update         [EXPERIMENTAL] Skip VEX Repository update
    -  -t, --template string              output template
    -      --token string                 for authentication in client/server mode
    -      --token-header string          specify a header name for token in client/server mode (default "Trivy-Token")
    -      --username strings             username. Comma-separated usernames allowed.
    -      --vex strings                  [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_server/index.html b/v0.58.0/docs/references/configuration/cli/trivy_server/index.html deleted file mode 100644 index bb6b0c2504b0..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_server/index.html +++ /dev/null @@ -1,7988 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Server - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Server

    - -

    trivy server

    -

    Server mode

    -
    trivy server [flags]
    -
    -

    Examples

    -
      # Run a server
    -  $ trivy server
    -
    -  # Listen on 0.0.0.0:10000
    -  $ trivy server --listen 0.0.0.0:10000
    -
    -

    Options

    -
          --cache-backend string     [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration       cache TTL when using redis as cache backend
    -      --db-repository strings    OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --download-db-only         download/update vulnerability database but don't run a scan
    -      --enable-modules strings   [EXPERIMENTAL] module names to enable
    -  -h, --help                     help for server
    -      --listen string            listen address in server mode (default "localhost:4954")
    -      --module-dir string        specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress              suppress progress bar
    -      --password strings         password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
    -      --password-stdin           password from stdin. Comma-separated passwords are not supported.
    -      --redis-ca string          redis ca file location, if using redis as cache backend
    -      --redis-cert string        redis certificate file location, if using redis as cache backend
    -      --redis-key string         redis key file location, if using redis as cache backend
    -      --redis-tls                enable redis TLS with public certificates, if using redis as cache backend
    -      --registry-token string    registry token
    -      --skip-db-update           skip updating vulnerability database
    -      --token string             for authentication in client/server mode
    -      --token-header string      specify a header name for token in client/server mode (default "Trivy-Token")
    -      --username strings         username. Comma-separated usernames allowed.
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_version/index.html b/v0.58.0/docs/references/configuration/cli/trivy_version/index.html deleted file mode 100644 index 8ff3fb92660d..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_version/index.html +++ /dev/null @@ -1,7941 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Version - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Version

    - -

    trivy version

    -

    Print the version

    -
    trivy version [flags]
    -
    -

    Options

    -
      -f, --format string   version format (json)
    -  -h, --help            help for version
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_vex/index.html b/v0.58.0/docs/references/configuration/cli/trivy_vex/index.html deleted file mode 100644 index 4a98b9869a96..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_vex/index.html +++ /dev/null @@ -1,7941 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    VEX

    - -

    trivy vex

    -

    [EXPERIMENTAL] VEX utilities

    -

    Options

    -
      -h, --help   help for vex
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo/index.html b/v0.58.0/docs/references/configuration/cli/trivy_vex_repo/index.html deleted file mode 100644 index 28af2b0ca7f3..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo/index.html +++ /dev/null @@ -1,7975 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX Repo - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    VEX Repo

    - -

    trivy vex repo

    -

    Manage VEX repositories

    -

    Examples

    -
      # Initialize the configuration file
    -  $ trivy vex repo init
    -
    -  # List VEX repositories
    -  $ trivy vex repo list
    -
    -  # Download the VEX repositories
    -  $ trivy vex repo download
    -
    -

    Options

    -
      -h, --help   help for repo
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_download/index.html b/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_download/index.html deleted file mode 100644 index 6a2137964a3d..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_download/index.html +++ /dev/null @@ -1,7966 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX Download - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    VEX Download

    - -

    trivy vex repo download

    -

    Download the VEX repositories

    -

    Synopsis

    -

    Downloads enabled VEX repositories. If specific repository names are provided as arguments, only those repositories will be downloaded. Otherwise, all enabled repositories are downloaded.

    -
    trivy vex repo download [REPO_NAMES] [flags]
    -
    -

    Options

    -
      -h, --help   help for download
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_init/index.html b/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_init/index.html deleted file mode 100644 index 52f041d7e9e2..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_init/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX Init - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    VEX Init

    - -

    trivy vex repo init

    -

    Initialize a configuration file

    -
    trivy vex repo init [flags]
    -
    -

    Options

    -
      -h, --help   help for init
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_list/index.html b/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_list/index.html deleted file mode 100644 index 719764141b32..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_list/index.html +++ /dev/null @@ -1,7942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX List - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    VEX List

    - -

    trivy vex repo list

    -

    List VEX repositories

    -
    trivy vex repo list [flags]
    -
    -

    Options

    -
      -h, --help   help for list
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/cli/trivy_vm/index.html b/v0.58.0/docs/references/configuration/cli/trivy_vm/index.html deleted file mode 100644 index 76c89cdd121e..000000000000 --- a/v0.58.0/docs/references/configuration/cli/trivy_vm/index.html +++ /dev/null @@ -1,8032 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    VM

    - -

    trivy vm

    -

    [EXPERIMENTAL] Scan a virtual machine image

    -
    trivy vm [flags] VM_IMAGE
    -
    -

    Examples

    -
      # Scan your AWS AMI
    -  $ trivy vm --scanners vuln ami:${your_ami_id}
    -
    -  # Scan your AWS EBS snapshot
    -  $ trivy vm ebs:${your_ebs_snapshot_id}
    -
    -

    Options

    -
          --aws-region string                 AWS region to scan
    -      --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "fs")
    -      --cache-ttl duration                cache TTL when using redis as cache backend
    -      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default "mirror.gcr.io/aquasec/trivy-checks:1")
    -      --compliance string                 compliance report to generate
    -      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking
    -      --custom-headers strings            custom headers in client mode
    -      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])
    -      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages
    -      --detection-priority string         specify the detection priority:
    -                                            - "precise": Prioritizes precise by minimizing false positives.
    -                                            - "comprehensive": Aims to detect more security findings at the cost of potential false positives.
    -                                           (precise,comprehensive) (default "precise")
    -      --download-db-only                  download/update vulnerability database but don't run a scan
    -      --download-java-db-only             download/update Java index database but don't run a scan
    -      --enable-modules strings            [EXPERIMENTAL] module names to enable
    -      --exit-code int                     specify exit code when any security issues are found
    -      --exit-on-eol int                   exit with the specified code when the OS reaches end of service/life
    -      --file-patterns strings             specify config file patterns
    -  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table")
    -      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)
    -      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.
    -      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
    -      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
    -      --helm-values strings               specify paths to override the Helm values.yaml files
    -  -h, --help                              help for vm
    -      --ignore-policy string              specify the Rego file path to evaluate each vulnerability
    -      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)
    -      --ignore-unfixed                    display only fixed vulnerabilities
    -      --ignorefile string                 specify .trivyignore file (default ".trivyignore")
    -      --include-non-failures              include successes, available with '--scanners misconfig'
    -      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
    -      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability
    -      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
    -      --module-dir string                 specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
    -      --no-progress                       suppress progress bar
    -      --offline-scan                      do not issue API requests to identify dependencies
    -  -o, --output string                     output file name
    -      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments
    -      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
    -      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
    -      --pkg-types strings                 list of package types (os,library) (default [os,library])
    -      --redis-ca string                   redis ca file location, if using redis as cache backend
    -      --redis-cert string                 redis certificate file location, if using redis as cache backend
    -      --redis-key string                  redis key file location, if using redis as cache backend
    -      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend
    -      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
    -      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
    -      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
    -      --secret-config string              specify a path to config file for secret scanning (default "trivy-secret.yaml")
    -      --server string                     server address in client mode
    -  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
    -      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities
    -      --skip-db-update                    skip updating vulnerability database
    -      --skip-dirs strings                 specify the directories or glob patterns to skip
    -      --skip-files strings                specify the files or glob patterns to skip
    -      --skip-java-db-update               skip updating Java index database
    -      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update
    -  -t, --template string                   output template
    -      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules
    -      --token string                      for authentication in client/server mode
    -      --token-header string               specify a header name for token in client/server mode (default "Trivy-Token")
    -      --vex strings                       [EXPERIMENTAL] VEX sources ("repo", "oci" or file path)
    -
    -

    Options inherited from parent commands

    -
          --cache-dir string          cache directory (default "/path/to/cache")
    -  -c, --config string             config path (default "trivy.yaml")
    -  -d, --debug                     debug mode
    -      --generate-default-config   write the default config to trivy-default.yaml
    -      --insecure                  allow insecure server connections
    -  -q, --quiet                     suppress progress bar and log output
    -      --timeout duration          timeout (default 5m0s)
    -  -v, --version                   show version
    -
    -

    SEE ALSO

    -
      -
    • trivy - Unified security scanner
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/configuration/config-file/index.html b/v0.58.0/docs/references/configuration/config-file/index.html deleted file mode 100644 index ac47fcbf54e6..000000000000 --- a/v0.58.0/docs/references/configuration/config-file/index.html +++ /dev/null @@ -1,8784 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Config file - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Config file

    -

    Trivy can be customized by tweaking a trivy.yaml file. -The config path can be overridden by the --config flag.

    -

    An example is here.

    -

    These samples contain default values for flags.

    -

    Global options

    -
    cache:
    -  # Same as '--cache-dir'
    -  dir: "/path/to/cache"
    -
    -# Same as '--debug'
    -debug: false
    -
    -# Same as '--insecure'
    -insecure: false
    -
    -# Same as '--quiet'
    -quiet: false
    -
    -# Same as '--timeout'
    -timeout: 5m0s
    -
    -

    Cache options

    -
    cache:
    -  # Same as '--cache-backend'
    -  backend: "fs"
    -
    -  redis:
    -    # Same as '--redis-ca'
    -    ca: ""
    -
    -    # Same as '--redis-cert'
    -    cert: ""
    -
    -    # Same as '--redis-key'
    -    key: ""
    -
    -    # Same as '--redis-tls'
    -    tls: false
    -
    -  # Same as '--cache-ttl'
    -  ttl: 0s
    -
    -

    Clean options

    -
    clean:
    -  # Same as '--all'
    -  all: false
    -
    -  # Same as '--checks-bundle'
    -  checks-bundle: false
    -
    -  # Same as '--java-db'
    -  java-db: false
    -
    -  # Same as '--scan-cache'
    -  scan-cache: false
    -
    -  # Same as '--vex-repo'
    -  vex-repo: false
    -
    -  # Same as '--vuln-db'
    -  vuln-db: false
    -
    -

    Client/Server options

    -
    server:
    -  # Same as '--server'
    -  addr: ""
    -
    -  # Same as '--custom-headers'
    -  custom-headers: []
    -
    -  # Same as '--listen'
    -  listen: "localhost:4954"
    -
    -  # Same as '--token'
    -  token: ""
    -
    -  # Same as '--token-header'
    -  token-header: "Trivy-Token"
    -
    -

    DB options

    -
    db:
    -  # Same as '--download-java-db-only'
    -  download-java-only: false
    -
    -  # Same as '--download-db-only'
    -  download-only: false
    -
    -  # Same as '--java-db-repository'
    -  java-repository:
    -   - mirror.gcr.io/aquasec/trivy-java-db:1
    -   - ghcr.io/aquasecurity/trivy-java-db:1
    -
    -  # Same as '--skip-java-db-update'
    -  java-skip-update: false
    -
    -  # Same as '--no-progress'
    -  no-progress: false
    -
    -  # Same as '--db-repository'
    -  repository:
    -   - mirror.gcr.io/aquasec/trivy-db:2
    -   - ghcr.io/aquasecurity/trivy-db:2
    -
    -  # Same as '--skip-db-update'
    -  skip-update: false
    -
    -

    Image options

    -
    image:
    -  docker:
    -    # Same as '--docker-host'
    -    host: ""
    -
    -  # Same as '--image-config-scanners'
    -  image-config-scanners: []
    -
    -  # Same as '--input'
    -  input: ""
    -
    -  # Same as '--platform'
    -  platform: ""
    -
    -  podman:
    -    # Same as '--podman-host'
    -    host: ""
    -
    -  # Same as '--removed-pkgs'
    -  removed-pkgs: false
    -
    -  # Same as '--image-src'
    -  source:
    -   - docker
    -   - containerd
    -   - podman
    -   - remote
    -
    -

    Kubernetes options

    -
    kubernetes:
    -  # Same as '--burst'
    -  burst: 10
    -
    -  # Same as '--disable-node-collector'
    -  disableNodeCollector: false
    -
    -  exclude:
    -    # Same as '--exclude-nodes'
    -    nodes: []
    -
    -    # Same as '--exclude-owned'
    -    owned: false
    -
    -  # Same as '--exclude-kinds'
    -  excludeKinds: []
    -
    -  # Same as '--exclude-namespaces'
    -  excludeNamespaces: []
    -
    -  # Same as '--include-kinds'
    -  includeKinds: []
    -
    -  # Same as '--include-namespaces'
    -  includeNamespaces: []
    -
    -  # Same as '--k8s-version'
    -  k8s-version: ""
    -
    -  # Same as '--kubeconfig'
    -  kubeconfig: ""
    -
    -  node-collector:
    -    # Same as '--node-collector-imageref'
    -    imageref: "ghcr.io/aquasecurity/node-collector:0.3.1"
    -
    -    # Same as '--node-collector-namespace'
    -    namespace: "trivy-temp"
    -
    -  # Same as '--qps'
    -  qps: 5
    -
    -  # Same as '--skip-images'
    -  skipImages: false
    -
    -  # Same as '--tolerations'
    -  tolerations: []
    -
    -

    License options

    -
    license:
    -  # Same as '--license-confidence-level'
    -  confidenceLevel: 0.9
    -
    -  forbidden:
    -   - AGPL-1.0
    -   - AGPL-3.0
    -   - CC-BY-NC-1.0
    -   - CC-BY-NC-2.0
    -   - CC-BY-NC-2.5
    -   - CC-BY-NC-3.0
    -   - CC-BY-NC-4.0
    -   - CC-BY-NC-ND-1.0
    -   - CC-BY-NC-ND-2.0
    -   - CC-BY-NC-ND-2.5
    -   - CC-BY-NC-ND-3.0
    -   - CC-BY-NC-ND-4.0
    -   - CC-BY-NC-SA-1.0
    -   - CC-BY-NC-SA-2.0
    -   - CC-BY-NC-SA-2.5
    -   - CC-BY-NC-SA-3.0
    -   - CC-BY-NC-SA-4.0
    -   - Commons-Clause
    -   - Facebook-2-Clause
    -   - Facebook-3-Clause
    -   - Facebook-Examples
    -   - WTFPL
    -
    -  # Same as '--license-full'
    -  full: false
    -
    -  # Same as '--ignored-licenses'
    -  ignored: []
    -
    -  notice:
    -   - AFL-1.1
    -   - AFL-1.2
    -   - AFL-2.0
    -   - AFL-2.1
    -   - AFL-3.0
    -   - Apache-1.0
    -   - Apache-1.1
    -   - Apache-2.0
    -   - Artistic-1.0-cl8
    -   - Artistic-1.0-Perl
    -   - Artistic-1.0
    -   - Artistic-2.0
    -   - BSL-1.0
    -   - BSD-2-Clause-FreeBSD
    -   - BSD-2-Clause-NetBSD
    -   - BSD-2-Clause
    -   - BSD-3-Clause-Attribution
    -   - BSD-3-Clause-Clear
    -   - BSD-3-Clause-LBNL
    -   - BSD-3-Clause
    -   - BSD-4-Clause
    -   - BSD-4-Clause-UC
    -   - BSD-Protection
    -   - CC-BY-1.0
    -   - CC-BY-2.0
    -   - CC-BY-2.5
    -   - CC-BY-3.0
    -   - CC-BY-4.0
    -   - FTL
    -   - ISC
    -   - ImageMagick
    -   - Libpng
    -   - Lil-1.0
    -   - Linux-OpenIB
    -   - LPL-1.02
    -   - LPL-1.0
    -   - MS-PL
    -   - MIT
    -   - NCSA
    -   - OpenSSL
    -   - PHP-3.01
    -   - PHP-3.0
    -   - PIL
    -   - Python-2.0
    -   - Python-2.0-complete
    -   - PostgreSQL
    -   - SGI-B-1.0
    -   - SGI-B-1.1
    -   - SGI-B-2.0
    -   - Unicode-DFS-2015
    -   - Unicode-DFS-2016
    -   - Unicode-TOU
    -   - UPL-1.0
    -   - W3C-19980720
    -   - W3C-20150513
    -   - W3C
    -   - X11
    -   - Xnet
    -   - Zend-2.0
    -   - zlib-acknowledgement
    -   - Zlib
    -   - ZPL-1.1
    -   - ZPL-2.0
    -   - ZPL-2.1
    -
    -  permissive: []
    -
    -  reciprocal:
    -   - APSL-1.0
    -   - APSL-1.1
    -   - APSL-1.2
    -   - APSL-2.0
    -   - CDDL-1.0
    -   - CDDL-1.1
    -   - CPL-1.0
    -   - EPL-1.0
    -   - EPL-2.0
    -   - FreeImage
    -   - IPL-1.0
    -   - MPL-1.0
    -   - MPL-1.1
    -   - MPL-2.0
    -   - Ruby
    -
    -  restricted:
    -   - BCL
    -   - CC-BY-ND-1.0
    -   - CC-BY-ND-2.0
    -   - CC-BY-ND-2.5
    -   - CC-BY-ND-3.0
    -   - CC-BY-ND-4.0
    -   - CC-BY-SA-1.0
    -   - CC-BY-SA-2.0
    -   - CC-BY-SA-2.5
    -   - CC-BY-SA-3.0
    -   - CC-BY-SA-4.0
    -   - GPL-1.0
    -   - GPL-2.0
    -   - GPL-2.0-with-autoconf-exception
    -   - GPL-2.0-with-bison-exception
    -   - GPL-2.0-with-classpath-exception
    -   - GPL-2.0-with-font-exception
    -   - GPL-2.0-with-GCC-exception
    -   - GPL-3.0
    -   - GPL-3.0-with-autoconf-exception
    -   - GPL-3.0-with-GCC-exception
    -   - LGPL-2.0
    -   - LGPL-2.1
    -   - LGPL-3.0
    -   - NPL-1.0
    -   - NPL-1.1
    -   - OSL-1.0
    -   - OSL-1.1
    -   - OSL-2.0
    -   - OSL-2.1
    -   - OSL-3.0
    -   - QPL-1.0
    -   - Sleepycat
    -
    -  unencumbered:
    -   - CC0-1.0
    -   - Unlicense
    -   - 0BSD
    -
    -

    Misconfiguration options

    -
    misconfiguration:
    -  # Same as '--checks-bundle-repository'
    -  checks-bundle-repository: "mirror.gcr.io/aquasec/trivy-checks:1"
    -
    -  cloudformation:
    -    # Same as '--cf-params'
    -    params: []
    -
    -  # Same as '--config-file-schemas'
    -  config-file-schemas: []
    -
    -  helm:
    -    # Same as '--helm-api-versions'
    -    api-versions: []
    -
    -    # Same as '--helm-kube-version'
    -    kube-version: ""
    -
    -    # Same as '--helm-set'
    -    set: []
    -
    -    # Same as '--helm-set-file'
    -    set-file: []
    -
    -    # Same as '--helm-set-string'
    -    set-string: []
    -
    -    # Same as '--helm-values'
    -    values: []
    -
    -  # Same as '--include-non-failures'
    -  include-non-failures: false
    -
    -  # Same as '--misconfig-scanners'
    -  scanners:
    -   - azure-arm
    -   - cloudformation
    -   - dockerfile
    -   - helm
    -   - kubernetes
    -   - terraform
    -   - terraformplan-json
    -   - terraformplan-snapshot
    -
    -  terraform:
    -    # Same as '--tf-exclude-downloaded-modules'
    -    exclude-downloaded-modules: false
    -
    -    # Same as '--tf-vars'
    -    vars: []
    -
    -

    Module options

    -
    module:
    -  # Same as '--module-dir'
    -  dir: "$HOME/.trivy/modules"
    -
    -  # Same as '--enable-modules'
    -  enable-modules: []
    -
    -

    Package options

    -
    pkg:
    -  # Same as '--include-dev-deps'
    -  include-dev-deps: false
    -
    -  # Same as '--pkg-relationships'
    -  relationships:
    -   - unknown
    -   - root
    -   - workspace
    -   - direct
    -   - indirect
    -
    -  # Same as '--pkg-types'
    -  types:
    -   - os
    -   - library
    -
    -

    Registry options

    -
    registry:
    -  # Same as '--password'
    -  password: []
    -
    -  # Same as '--password-stdin'
    -  password-stdin: false
    -
    -  # Same as '--registry-token'
    -  token: ""
    -
    -  # Same as '--username'
    -  username: []
    -
    -

    Rego options

    -
    rego:
    -  # Same as '--config-check'
    -  check: []
    -
    -  # Same as '--config-data'
    -  data: []
    -
    -  # Same as '--include-deprecated-checks'
    -  include-deprecated-checks: false
    -
    -  # Same as '--check-namespaces'
    -  namespaces: []
    -
    -  # Same as '--skip-check-update'
    -  skip-check-update: false
    -
    -  # Same as '--trace'
    -  trace: false
    -
    -

    Report options

    -
    # Same as '--dependency-tree'
    -dependency-tree: false
    -
    -# Same as '--exit-code'
    -exit-code: 0
    -
    -# Same as '--exit-on-eol'
    -exit-on-eol: 0
    -
    -# Same as '--format'
    -format: "table"
    -
    -# Same as '--ignore-policy'
    -ignore-policy: ""
    -
    -# Same as '--ignorefile'
    -ignorefile: ".trivyignore"
    -
    -# Same as '--list-all-pkgs'
    -list-all-pkgs: false
    -
    -# Same as '--output'
    -output: ""
    -
    -# Same as '--output-plugin-arg'
    -output-plugin-arg: ""
    -
    -# Same as '--report'
    -report: "all"
    -
    -scan:
    -  # Same as '--compliance'
    -  compliance: ""
    -
    -  # Same as '--show-suppressed'
    -  show-suppressed: false
    -
    -# Same as '--severity'
    -severity:
    - - UNKNOWN
    - - LOW
    - - MEDIUM
    - - HIGH
    - - CRITICAL
    -
    -# Same as '--template'
    -template: ""
    -
    -

    Repository options

    -
    repository:
    -  # Same as '--branch'
    -  branch: ""
    -
    -  # Same as '--commit'
    -  commit: ""
    -
    -  # Same as '--tag'
    -  tag: ""
    -
    -

    Scan options

    -
    scan:
    -  # Same as '--detection-priority'
    -  detection-priority: "precise"
    -
    -  # Same as '--file-patterns'
    -  file-patterns: []
    -
    -  # Same as '--offline-scan'
    -  offline: false
    -
    -  # Same as '--parallel'
    -  parallel: 5
    -
    -  # Same as '--rekor-url'
    -  rekor-url: "https://rekor.sigstore.dev"
    -
    -  # Same as '--sbom-sources'
    -  sbom-sources: []
    -
    -  # Same as '--scanners'
    -  scanners:
    -   - vuln
    -   - secret
    -
    -  # Same as '--skip-dirs'
    -  skip-dirs: []
    -
    -  # Same as '--skip-files'
    -  skip-files: []
    -
    -

    Secret options

    -
    secret:
    -  # Same as '--secret-config'
    -  config: "trivy-secret.yaml"
    -
    -

    Vulnerability options

    -
    vulnerability:
    -  # Same as '--ignore-status'
    -  ignore-status: []
    -
    -  # Same as '--ignore-unfixed'
    -  ignore-unfixed: false
    -
    -  # Same as '--skip-vex-repo-update'
    -  skip-vex-repo-update: false
    -
    -  # Same as '--vex'
    -  vex: []
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/modes/client-server/index.html b/v0.58.0/docs/references/modes/client-server/index.html deleted file mode 100644 index 8c63290ade49..000000000000 --- a/v0.58.0/docs/references/modes/client-server/index.html +++ /dev/null @@ -1,8424 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Client/Server - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Client/Server

    -

    Trivy has client/server mode. Trivy server has vulnerability database and Trivy client doesn't have to download vulnerability database. It is useful if you want to scan images or files at multiple locations and do not want to download the database at every location.

    - - - - - - - - - - - - - - - - - - - - - - - -
    Client/Server ModeImageRootfsFilesystemRepositoryConfigK8s
    Supported--
    -

    Some scanners run on the client side, even in client/server mode.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    ScannerRun on Client or Server
    VulnerabilityServer
    MisconfigurationClient1
    SecretClient2
    LicenseServer
    -
    -

    Note

    -

    Scanning of misconfigurations and licenses is performed on the client side (as in standalone mode). -Otherwise, the client would need to send files to the server that may contain sensitive information.

    -
    -

    Server

    -

    At first, you need to launch Trivy server. It downloads vulnerability database automatically and continue to fetch the latest DB in the background. -

    $ trivy server --listen localhost:8080
    -2019-12-12T15:17:06.551+0200    INFO    Need to update DB
    -2019-12-12T15:17:56.706+0200    INFO    Reopening DB...
    -2019-12-12T15:17:56.707+0200    INFO    Listening localhost:8080...
    -

    -

    If you want to accept a connection from outside, you have to specify 0.0.0.0 or your ip address, not localhost.

    -
    $ trivy server --listen 0.0.0.0:8080
    -
    -

    Remote image scan

    -

    Then, specify the server address for image command. -

    $ trivy image --server http://localhost:8080 alpine:3.10
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    alpine:3.10 (alpine 3.10.2)
    -===========================
    -Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 2, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |
    -+---------+------------------+----------+-------------------+---------------+
    -| openssl | CVE-2019-1549    | MEDIUM   | 1.1.1c-r0         | 1.1.1d-r0     |
    -+         +------------------+          +                   +               +
    -|         | CVE-2019-1563    |          |                   |               |
    -+         +------------------+----------+                   +               +
    -|         | CVE-2019-1547    | LOW      |                   |               |
    -+---------+------------------+----------+-------------------+---------------+
    -
    -
    - -

    Remote scan of local filesystem

    -

    Also, there is a way to scan local file system: -

    $ trivy fs --server http://localhost:8080 --severity CRITICAL ./integration/testdata/fixtures/fs/pom/
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    pom.xml (pom)
    -=============
    -Total: 24 (CRITICAL: 24)
    -
    -+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+
    -|                   LIBRARY                   | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |         FIXED VERSION          |                 TITLE                 |
    -+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+
    -| com.fasterxml.jackson.core:jackson-databind | CVE-2017-17485   | CRITICAL | 2.9.1             | 2.8.11, 2.9.4                  | jackson-databind: Unsafe              |
    -|                                             |                  |          |                   |                                | deserialization due to                |
    -|                                             |                  |          |                   |                                | incomplete black list (incomplete     |
    -|                                             |                  |          |                   |                                | fix for CVE-2017-15095)...            |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2017-17485 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-11307   |          |                   | 2.7.9.4, 2.8.11.2, 2.9.6       | jackson-databind: Potential           |
    -|                                             |                  |          |                   |                                | information exfiltration with         |
    -|                                             |                  |          |                   |                                | default typing, serialization         |
    -|                                             |                  |          |                   |                                | gadget from MyBatis                   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-11307 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-14718   |          |                   | 2.6.7.2, 2.9.7                 | jackson-databind: arbitrary code      |
    -|                                             |                  |          |                   |                                | execution in slf4j-ext class          |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14718 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-14719   |          |                   |                                | jackson-databind: arbitrary           |
    -|                                             |                  |          |                   |                                | code execution in blaze-ds-opt        |
    -|                                             |                  |          |                   |                                | and blaze-ds-core classes             |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14719 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-14720   |          |                   |                                | jackson-databind: exfiltration/XXE    |
    -|                                             |                  |          |                   |                                | in some JDK classes                   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14720 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-14721   |          |                   |                                | jackson-databind: server-side request |
    -|                                             |                  |          |                   |                                | forgery (SSRF) in axis2-jaxws class   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14721 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-19360   |          |                   | 2.6.7.3, 2.7.9.5, 2.8.11.3,    | jackson-databind: improper            |
    -|                                             |                  |          |                   | 2.9.8                          | polymorphic deserialization           |
    -|                                             |                  |          |                   |                                | in axis2-transport-jms class          |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19360 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-19361   |          |                   |                                | jackson-databind: improper            |
    -|                                             |                  |          |                   |                                | polymorphic deserialization           |
    -|                                             |                  |          |                   |                                | in openjpa class                      |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19361 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2018-19362   |          |                   |                                | jackson-databind: improper            |
    -|                                             |                  |          |                   |                                | polymorphic deserialization           |
    -|                                             |                  |          |                   |                                | in jboss-common-core class            |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19362 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2018-7489    |          |                   | 2.7.9.3, 2.8.11.1, 2.9.5       | jackson-databind: incomplete fix      |
    -|                                             |                  |          |                   |                                | for CVE-2017-7525 permits unsafe      |
    -|                                             |                  |          |                   |                                | serialization via c3p0 libraries      |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-7489  |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14379   |          |                   | 2.7.9.6, 2.8.11.4, 2.9.9.2     | jackson-databind: default             |
    -|                                             |                  |          |                   |                                | typing mishandling leading            |
    -|                                             |                  |          |                   |                                | to remote code execution              |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14379 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14540   |          |                   | 2.9.10                         | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | com.zaxxer.hikari.HikariConfig        |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14540 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14892   |          |                   | 2.6.7.3, 2.8.11.5, 2.9.10      | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in classes of the             |
    -|                                             |                  |          |                   |                                | commons-configuration package         |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14892 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-14893   |          |                   | 2.8.11.5, 2.9.10               | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | classes of the xalan package          |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14893 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-16335   |          |                   | 2.9.10                         | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | com.zaxxer.hikari.HikariDataSource    |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16335 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-16942   |          |                   | 2.9.10.1                       | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | org.apache.commons.dbcp.datasources.* |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16942 |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2019-16943   |          |                   |                                | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | com.p6spy.engine.spy.P6DataSource     |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16943 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-17267   |          |                   | 2.9.10                         | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in classes of                 |
    -|                                             |                  |          |                   |                                | the ehcache package                   |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-17267 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-17531   |          |                   | 2.9.10.1                       | jackson-databind:                     |
    -|                                             |                  |          |                   |                                | Serialization gadgets in              |
    -|                                             |                  |          |                   |                                | org.apache.log4j.receivers.db.*       |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-17531 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2019-20330   |          |                   | 2.8.11.5, 2.9.10.2             | jackson-databind: lacks               |
    -|                                             |                  |          |                   |                                | certain net.sf.ehcache blocking       |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-20330 |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2020-8840    |          |                   | 2.7.9.7, 2.8.11.5, 2.9.10.3    | jackson-databind: Lacks certain       |
    -|                                             |                  |          |                   |                                | xbean-reflect/JNDI blocking           |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-8840  |
    -+                                             +------------------+          +                   +--------------------------------+---------------------------------------+
    -|                                             | CVE-2020-9546    |          |                   | 2.7.9.7, 2.8.11.6, 2.9.10.4    | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in shaded-hikari-config       |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9546  |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2020-9547    |          |                   |                                | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in ibatis-sqlmap              |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9547  |
    -+                                             +------------------+          +                   +                                +---------------------------------------+
    -|                                             | CVE-2020-9548    |          |                   |                                | jackson-databind: Serialization       |
    -|                                             |                  |          |                   |                                | gadgets in anteros-core               |
    -|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9548  |
    -+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+
    -
    -
    - -

    Remote scan of root filesystem

    -

    Also, there is a way to scan root file system: -

    $ trivy rootfs --server http://localhost:8080 --severity CRITICAL /tmp/rootfs
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    /tmp/rootfs (alpine 3.10.2)
    -
    -Total: 1 (CRITICAL: 1)
    -
    -┌───────────┬────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│  Library  │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├───────────┼────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ apk-tools │ CVE-2021-36159 │ CRITICAL │ 2.10.4-r2         │ 2.10.7-r0     │ libfetch before 2021-07-26, as used in apk-tools, xbps, and │
    -│           │                │          │                   │               │ other products, mishandles...                               │
    -│           │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-36159                  │
    -└───────────┴────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -
    -
    - -

    Remote scan of git repository

    -

    Also, there is a way to scan remote git repository: -

    $ trivy repo https://github.com/knqyf263/trivy-ci-test --server http://localhost:8080 
    -
    -Note: It's important to specify the protocol (http or https).

    -
    -Result - -
    Cargo.lock (cargo)
    -==================
    -Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 0)
    -
    -┌───────────┬─────────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│  Library  │    Vulnerability    │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├───────────┼─────────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ ammonia   │ CVE-2019-15542      │ HIGH     │ 1.9.0             │ 2.1.0         │ Uncontrolled recursion in ammonia                           │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-15542                  │
    -│           ├─────────────────────┼──────────┤                   ├───────────────┼─────────────────────────────────────────────────────────────┤
    -│           │ CVE-2021-38193      │ MEDIUM   │                   │ 2.1.3, 3.1.0  │ An issue was discovered in the ammonia crate before 3.1.0   │
    -│           │                     │          │                   │               │ for Rust....                                                │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2021-38193                  │
    -├───────────┼─────────────────────┤          ├───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ smallvec  │ CVE-2019-15551      │          │ 0.6.9             │ 0.6.10        │ An issue was discovered in the smallvec crate before 0.6.10 │
    -│           │                     │          │                   │               │ for Rust....                                                │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2019-15551                  │
    -│           ├─────────────────────┼──────────┤                   ├───────────────┼─────────────────────────────────────────────────────────────┤
    -│           │ CVE-2018-25023      │ HIGH     │                   │ 0.6.13        │ An issue was discovered in the smallvec crate before 0.6.13 │
    -│           │                     │          │                   │               │ for Rust....                                                │
    -│           │                     │          │                   │               │ https://avd.aquasec.com/nvd/cve-2018-25023                  │
    -│           ├─────────────────────┼──────────┤                   │               ├─────────────────────────────────────────────────────────────┤
    -│           │ GHSA-66p5-j55p-32r9 │ MEDIUM   │                   │               │ smallvec creates uninitialized value of any type            │
    -│           │                     │          │                   │               │ https://github.com/advisories/GHSA-66p5-j55p-32r9           │
    -└───────────┴─────────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -
    -Pipfile.lock (pipenv)
    -=====================
    -Total: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
    -
    -┌─────────────────────┬────────────────┬──────────┬───────────────────┬────────────────────────┬──────────────────────────────────────────────────────────────┐
    -│       Library       │ Vulnerability  │ Severity │ Installed Version │     Fixed Version      │                            Title                             │
    -├─────────────────────┼────────────────┼──────────┼───────────────────┼────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ celery              │ CVE-2021-23727 │ HIGH     │ 4.3.0             │ 5.2.2                  │ celery: stored command injection vulnerability may allow     │
    -│                     │                │          │                   │                        │ privileges escalation                                        │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2021-23727                   │
    -├─────────────────────┼────────────────┤          ├───────────────────┼────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ django              │ CVE-2019-6975  │          │ 2.0.9             │ 1.11.19, 2.0.12, 2.1.7 │ python-django: memory exhaustion in                          │
    -│                     │                │          │                   │                        │ django.utils.numberformat.format()                           │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-6975                    │
    -│                     ├────────────────┼──────────┤                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2019-3498  │ MEDIUM   │                   │ 1.11.18, 2.0.10, 2.1.5 │ python-django: Content spoofing via URL path in default 404  │
    -│                     │                │          │                   │                        │ page                                                         │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-3498                    │
    -│                     ├────────────────┤          │                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2021-33203 │          │                   │ 2.2.24, 3.1.12, 3.2.4  │ django: Potential directory traversal via ``admindocs``      │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2021-33203                   │
    -├─────────────────────┼────────────────┤          ├───────────────────┼────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ urllib3             │ CVE-2019-11324 │          │ 1.24.1            │ 1.24.2                 │ python-urllib3: Certification mishandle when error should be │
    -│                     │                │          │                   │                        │ thrown                                                       │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-11324                   │
    -│                     ├────────────────┤          │                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2021-33503 │          │                   │ 1.26.5                 │ python-urllib3: ReDoS in the parsing of authority part of    │
    -│                     │                │          │                   │                        │ URL                                                          │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2021-33503                   │
    -│                     ├────────────────┼──────────┤                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2019-11236 │ MEDIUM   │                   │ 1.24.3                 │ python-urllib3: CRLF injection due to not encoding the       │
    -│                     │                │          │                   │                        │ '\r\n' sequence leading to...                                │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2019-11236                   │
    -│                     ├────────────────┤          │                   ├────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                     │ CVE-2020-26137 │          │                   │ 1.25.9                 │ python-urllib3: CRLF injection via HTTP request method       │
    -│                     │                │          │                   │                        │ https://avd.aquasec.com/nvd/cve-2020-26137                   │
    -└─────────────────────┴────────────────┴──────────┴───────────────────┴────────────────────────┴──────────────────────────────────────────────────────────────┘
    -
    -
    - -

    Authentication

    -
    $ trivy server --listen localhost:8080 --token dummy
    -
    -
    $ trivy image --server http://localhost:8080 --token dummy alpine:3.10
    -
    -

    Endpoints

    -

    Health

    -

    Checks whether the Trivy server is running. Authentication is not required.

    -

    Example request: -

    curl -s 0.0.0.0:8080/healthz
    -ok
    -

    -

    Returns the 200 OK status if the request was successful.

    -

    Version

    -

    Returns the version of the Trivy and all components (db, policy). Authentication is not required.

    -

    Example request: -

    curl -s 0.0.0.0:8080/version | jq
    -{
    -  "Version": "dev",
    -  "VulnerabilityDB": {
    -    "Version": 2,
    -    "NextUpdate": "2023-07-25T14:15:29.876639806Z",
    -    "UpdatedAt": "2023-07-25T08:15:29.876640206Z",
    -    "DownloadedAt": "2023-07-25T09:36:25.599004Z"
    -  },
    -  "JavaDB": {
    -    "Version": 1,
    -    "NextUpdate": "2023-07-28T01:03:52.169192565Z",
    -    "UpdatedAt": "2023-07-25T01:03:52.169192765Z",
    -    "DownloadedAt": "2023-07-25T09:37:48.906152Z"
    -  },
    -  "PolicyBundle": {
    -    "Digest": "sha256:829832357626da2677955e3b427191212978ba20012b6eaa03229ca28569ae43",
    -    "DownloadedAt": "2023-07-23T11:40:33.122462Z"
    -  }
    -}
    -

    -

    Returns the 200 OK status if the request was successful.

    -

    Architecture

    -

    architecture

    -
    -
    -
      -
    1. -

      The checks bundle is also downloaded on the client side. 

      -
    2. -
    3. -

      The scan result with masked secrets is sent to the server 

      -
    4. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/modes/standalone/index.html b/v0.58.0/docs/references/modes/standalone/index.html deleted file mode 100644 index 415e0f42341e..000000000000 --- a/v0.58.0/docs/references/modes/standalone/index.html +++ /dev/null @@ -1,7895 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Standalone - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Standalone

    -

    trivy image, trivy filesystem, and trivy repo works as standalone mode.

    -

    Image

    -

    standalone

    -

    Filesystem

    -

    fs

    -

    Git Repository

    -

    repo

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/terminology/index.html b/v0.58.0/docs/references/terminology/index.html deleted file mode 100644 index a6ad1541fd76..000000000000 --- a/v0.58.0/docs/references/terminology/index.html +++ /dev/null @@ -1,8663 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Terminology - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Terminology

    -

    This page explains the terminology system used in Trivy, helping users understand the specific terms and concepts unique to the Trivy ecosystem.

    -

    Inclusion Criteria

    -
      -
    1. -

      Core Components of Trivy

      -
        -
      • Primary features such as Scanner, Target
      • -
      • Essential components such as Scan Assets (trivy-db, trivy-java-db)
      • -
      • Components that users directly interact with
      • -
      -
    2. -
    3. -

      Trivy-specific Terms

      -
        -
      • Terms unique to Trivy (e.g., VEX Hub)
      • -
      • Terms that have special meaning in Trivy's context (e.g., Plugin, Module)
      • -
      -
    4. -
    -

    Exclusion Criteria

    -
      -
    1. -

      General Terms

      -
        -
      • Common security/technical terms (e.g., CVE, CVSS, Container, Registry)
      • -
      • Standard industry terminology
      • -
      -
    2. -
    3. -

      Implementation Details

      -
        -
      • Internal workings of components
      • -
      • Usage instructions (these belong in feature documentation)
      • -
      -
    4. -
    -

    Core Concepts

    -

    Target

    -

    Types of artifacts that Trivy can scan, like container images and filesystem.

    -

    Scanner

    -

    Trivy's built-in security scanning engines. Trivy has four main scanners:

    - -
    -

    Note

    -
    -

    SBOM is not a scanner but an output format option.

    -

    Scan Assets

    -

    External data that Trivy downloads (if needed for scanner) and uses during scanning:

    - -

    Vulnerability Scanning

    -

    Vulnerability Database (Trivy DB, trivy-db)

    -

    The core vulnerability database required for vulnerability detection. -Contains comprehensive vulnerability information for multiple ecosystems. -Distributed via OCI registry.

    -

    Managed at https://github.com/aquasecurity/trivy-db.

    -

    The vulnerability database is built from a GitHub repository that collects and stores vulnerability information from various data sources. -This repository serves as the foundation for building the Trivy DB.

    -

    Managed at:

    - -

    Java Index Database (Trivy Java DB, trivy-java-db)

    -

    Specialized database used for identifying Java libraries and their components during JAR/WAR/PAR/EAR scanning. -Distributed via OCI registry.

    -

    Managed at https://github.com/aquasecurity/trivy-java-db.

    -

    Misconfiguration Scanning

    -

    When the context does not clearly indicate these terms are related to misconfiguration scanning, they may be prefixed with "Misconfiguration" for clarity. -For example, "Check" may be referred to as "Misconfiguration Check", and "Checks Bundle" as "Misconfiguration Checks Bundle".

    -

    Check

    -

    A Rego file that defines rules for detecting misconfigurations in various types of IaC files.

    -

    Built-in Checks

    -

    Default set of checks distributed through the trivy-checks repository, providing standard security and configuration best practices.

    -

    Checks Bundle

    -

    A tar.gz archive containing the built-in checks, distributed via OCI registry.

    -

    Secret Scanning

    -

    Rule

    -

    Pattern matching rules used to detect hardcoded secrets and sensitive information. -Each rule consists of:

    -
      -
    • Metadata (ID, Category, Title, etc.)
    • -
    • Regular expressions for matching sensitive patterns
    • -
    • Additional context for detection accuracy
    • -
    -

    Kubernetes Integration

    -

    KBOM (Kubernetes Bill of Materials)

    -

    A specialized SBOM format for Kubernetes clusters that includes detailed information about the cluster's components.

    -

    VEX (Vulnerability Exploitability eXchange)

    -

    VEX Repository

    -

    A repository system that stores VEX documents following the VEX Repository Specification. -VEX repositories help users manage and share information about vulnerability applicability and exploitability.

    -

    For detailed information about VEX repositories, see the document.

    -

    VEX Hub

    -

    The default VEX repository managed by Aqua Security at https://github.com/aquasecurity/vexhub. -It primarily aggregates VEX documents published by package maintainers in their source repositories. -VEX Hub serves as a central point for collecting and distributing vulnerability applicability information for OSS projects.

    -

    Cache System

    -

    Cache Types

    -

    The cache directory contains several distinct types of data:

    - -

    Asset Cache

    -

    Downloaded assets like vulnerability databases and Java index databases.

    -

    Scan Cache

    -

    A caching mechanism that stores analysis results from previous scans to speed up subsequent scans. -For container image scanning, the scan cache stores analysis results including package names and versions per layer.

    -

    For detailed information about caching, see the document.

    -

    Plugin System

    -

    Plugin

    -

    An add-on tool that integrates with Trivy to extend its core functionality. -Plugins can be written in any programming language and integrate seamlessly with Trivy CLI, appearing in Trivy help and subcommands. -They can be installed and removed independently without affecting the core Trivy installation.

    -

    For detailed information about plugins, see the document.

    -

    Plugin Index (trivy-plugin-index)

    -

    A centralized registry that lists available Trivy plugins, managed at https://github.com/aquasecurity/trivy-plugin-index. -The index maintains a curated list of official and community plugins, providing metadata such as plugin names, descriptions, and maintainers. -It enables plugin discovery through the trivy plugin search command and facilitates automatic plugin installation and updates.

    -

    For detailed information about the plugin index, see the document.

    -

    Module System

    -

    Module

    -

    A WebAssembly-based extension mechanism that allows custom scanning logic without modifying the Trivy binary. -Modules can modify scan results by analyzing files or post-processing results.

    -

    For detailed information about modules, see the document.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/references/troubleshooting/index.html b/v0.58.0/docs/references/troubleshooting/index.html deleted file mode 100644 index 7976ce6d1f23..000000000000 --- a/v0.58.0/docs/references/troubleshooting/index.html +++ /dev/null @@ -1,8652 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Troubleshooting - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Troubleshooting

    -

    Scan

    -

    Timeout

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -analyze error: timeout: context deadline exceeded
    -
    -
    -

    Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as --timeout 15m.

    -

    Unable to initialize an image scanner

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -2024-01-19T08:15:33.288Z    FATAL   image scan error: scan error: unable to initialize a scanner: unable to initialize an image scanner: 4 errors occurred:
    -* docker error: unable to inspect the image (ContainerImageName): Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    -* containerd error: containerd socket not found: /run/containerd/containerd.sock
    -* podman error: unable to initialize Podman client: no podman socket found: stat podman/podman.sock: no such file or directory
    -* remote error: GET https://index.docker.io/v2/ContainerImageName: MANIFEST_UNKNOWN: manifest unknown; unknown tag=0.1
    -
    -
    -

    It means Trivy is unable to find the container image in the following places:

    -
      -
    • Docker Engine
    • -
    • containerd
    • -
    • Podman
    • -
    • A remote registry
    • -
    -

    Please see error messages for details of each error.

    -

    Common mistakes include the following, depending on where you are pulling images from:

    -

    Common

    -
      -
    • Typos in the image name
        -
      • Common mistake :)
      • -
      -
    • -
    • Forgetting to specify the registry
        -
      • By default, it is considered to be Docker Hub ( index.docker.io ).
      • -
      -
    • -
    -

    Docker Engine

    -
      -
    • Incorrect Docker host
        -
      • If the Docker daemon's socket path is not /var/run/docker.sock, you need to specify the --docker-host flag or the DOCKER_HOST environment variable. - The same applies when using TCP; you must specify the correct host address.
      • -
      -
    • -
    -

    containerd

    -
      -
    • Incorrect containerd address
        -
      • If you are using a non-default path, you need to specify the CONTAINERD_ADDRESS environment variable. - Please refer to this documentation.
      • -
      -
    • -
    • Incorrect namespace
        -
      • If you are using a non-default namespace, you need to specify the CONTAINERD_NAMESPACE environment variable. - Please refer to this documentation.
      • -
      • -
      -
    • -
    -

    Podman

    -
      -
    • Podman socket configuration -
    • -
    -

    Container Registry

    -
      -
    • Unauthenticated
        -
      • If you are using a private container registry, you need to authenticate. Please refer to this documentation.
      • -
      -
    • -
    • Using a proxy
        -
      • If you are using a proxy within your network, you need to correctly set the HTTP_PROXY, HTTPS_PROXY, etc., environment variables.
      • -
      -
    • -
    • Use of a self-signed certificate in the registry
        -
      • Because certificate verification will fail, you need to either trust that certificate or use the --insecure flag (not recommended in production).
      • -
      -
    • -
    -

    Certification

    -
    -

    Error

    -

    Error: x509: certificate signed by unknown authority

    -
    -

    TRIVY_INSECURE can be used to allow insecure connections to a container registry when using SSL.

    -
    $ TRIVY_INSECURE=true trivy image [YOUR_IMAGE]
    -
    -

    GitHub Rate limiting

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -API rate limit exceeded for xxx.xxx.xxx.xxx.
    -
    -
    -

    Specify GITHUB_TOKEN for authentication -https://developer.github.com/v3/#rate-limiting

    -
    $ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10
    -
    -

    Unable to open JAR files

    -
    -

    Error

    -
    $ trivy image ...
    -...
    -failed to analyze file: failed to analyze usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: unable to open usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: failed to open: unable to read the file: stream error: stream ID 9; PROTOCOL_ERROR; received from peer
    -
    -
    -

    Currently, we're investigating this issue. As a temporary mitigation, you may be able to avoid this issue by downloading the Java DB in advance.

    -
    $ trivy image --download-java-db-only
    -2023-02-01T16:57:04.322+0900    INFO    Downloading the Java DB...
    -$ trivy image [YOUR_JAVA_IMAGE]
    -
    -

    Running in parallel takes same time as series run

    -

    When running trivy on multiple images simultaneously, it will take same time as running trivy in series. -This is because of a limitation of boltdb.

    -
    -

    Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.

    -
    -

    Reference : boltdb: Opening a database.

    -

    Multiple Trivy servers

    -
    -

    Error

    -
    $ trivy image --server http://xxx.com:xxxx test-image
    -...
    -- twirp error internal: failed scan, test-image: failed to apply layers: layer cache missing: sha256:*****
    -
    -
    -

    To run multiple Trivy servers, you need to use Redis as the cache backend so that those servers can share the cache. -Follow this instruction to do so.

    -

    Problems with /tmp on remote Git repository scans

    -
    -

    Error

    -

    FATAL repository scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: git clone error: write /tmp/fanal-remote...

    -
    -

    Trivy clones remote Git repositories under the /tmp directory before scanning them. If /tmp doesn't work for you, you can change it by setting the TMPDIR environment variable.

    -

    Try:

    -
    $ TMPDIR=/my/custom/path trivy repo ...
    -
    -

    Running out of space during image scans

    -
    -

    Error

    -
    image scan failed:
    -failed to copy the image:
    -write /tmp/fanal-3323732142: no space left on device
    -
    -
    -

    Trivy uses a temporary directory during image scans. -The directory path would be determined as follows:

    -
      -
    • On Unix systems: Use $TMPDIR if non-empty, else /tmp.
    • -
    • On Windows: Uses GetTempPath, returning the first non-empty value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.
    • -
    -

    See this documentation for more details.

    -

    If the image is large or the temporary directory has insufficient space, the scan will fail. -You can configure the directory path to redirect Trivy to a directory with adequate storage. -On Unix systems, you can set the $TMPDIR environment variable.

    -
    $ TMPDIR=/my/custom/path trivy image ...
    -
    -

    When scanning images from a container registry, Trivy processes each layer by streaming, loading only the necessary files for the scan into memory and discarding unnecessary files. -If a layer contains large files that are necessary for the scan (such as JAR files or binary files), Trivy saves them to a temporary directory (e.g. $TMPDIR) on local storage to avoid increased memory consumption. -Although these files are deleted after the scan is complete, they can temporarily increase disk consumption and potentially exhaust storage. -In such cases, there are currently three workarounds:

    -
      -
    1. -

      Use a temporary directory with sufficient capacity

      -

      This is the same as explained above.

      -
    2. -
    3. -

      Specify a small value for --parallel

      -

      By default, multiple layers are processed in parallel. -If each layer contains large files, disk space may be consumed rapidly. -By specifying a small value such as --parallel 1, parallelism is reduced, which can mitigate the issue.

      -
    4. -
    5. -

      Specify --skip-files or --skip-dirs

      -

      If the container image contains large files that do not need to be scanned, you can skip their processing by specifying --skip-files or --skip-dirs. -For more details, please refer to this documentation.

      -
    6. -
    -

    DB

    -

    Old DB schema

    -
    -

    Error

    -

    --skip-update cannot be specified with the old DB schema.

    -
    -

    Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow the instruction of air-gapped environment.

    -

    Error downloading vulnerability DB

    -
    -

    Error

    -

    FATAL failed to download vulnerability DB

    -
    -

    If Trivy is running behind corporate firewall, refer to the necessary connectivity requirements as described here.

    -

    Denied

    - -

    Your local GHCR (GitHub Container Registry) token might be expired. -Please remove the token and try downloading the DB again.

    -
    docker logout ghcr.io
    -
    -

    Homebrew

    -

    Scope error

    -
    -

    Error

    -

    Error: Your macOS keychain GitHub credentials do not have sufficient scope!

    -
    -
    $ brew tap aquasecurity/trivy
    -Error: Your macOS keychain GitHub credentials do not have sufficient scope!
    -Scopes they need: none
    -Scopes they have:
    -Create a personal access token:
    -https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew
    -echo 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.zshrc
    -
    -

    Try:

    -
    $ printf "protocol=https\nhost=github.com\n" | git credential-osxkeychain erase
    -
    -

    Already installed

    -
    -

    Error

    -

    Error: aquasecurity/trivy/trivy 64 already installed

    -
    -
    $ brew upgrade
    -...
    -Error: aquasecurity/trivy/trivy 64 already installed
    -
    -

    Try:

    -
    $ brew unlink trivy && brew uninstall trivy
    -($ rm -rf /usr/local/Cellar/trivy/64)
    -$ brew install aquasecurity/trivy/trivy
    -
    -

    Others

    -

    Unknown error

    -

    Try again after running trivy clean --all:

    -
    $ trivy clean --all
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/license/index.html b/v0.58.0/docs/scanner/license/index.html deleted file mode 100644 index 9c13162b064c..000000000000 --- a/v0.58.0/docs/scanner/license/index.html +++ /dev/null @@ -1,8378 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - License - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    - -
    - - - -
    - -
    - - - - - - - - - - - - - -

    License Scanning

    -

    Trivy scans any container image for license files and offers an opinionated view on the risk associated with the license.

    -

    License are classified using the Google License Classification -

    -
      -
    • Forbidden
    • -
    • Restricted
    • -
    • Reciprocal
    • -
    • Notice
    • -
    • Permissive
    • -
    • Unencumbered
    • -
    • Unknown
    • -
    -
    -

    Tip

    -

    Licenses that Trivy fails to recognize are classified as UNKNOWN. -As those licenses may be in violation, it is recommended to check those unknown licenses as well.

    -
    -

    By default, Trivy scans licenses for packages installed by apk, apt-get, dnf, npm, pip, gem, etc. -Check out the coverage document for details.

    -

    To enable extended license scanning, you can use --license-full. -In addition to package licenses, Trivy scans source code files, Markdown documents, text files and LICENSE documents to identify license usage within the image or filesystem.

    -

    By default, Trivy only classifies licenses that are matched with a confidence level of 0.9 or more by the classifier. -To configure the confidence level, you can use --license-confidence-level. This enables us to classify licenses that might be matched with a lower confidence level by the classifer.

    -
    -

    Note

    -

    The full license scanning is expensive. It takes a while.

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    License scanningImageRootfsFilesystemRepositorySBOM
    Standard1212
    Full (--license-full)-
    -

    License checking classifies the identified licenses and map the classification to severity.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ClassificationSeverity
    ForbiddenCRITICAL
    RestrictedHIGH
    ReciprocalMEDIUM
    NoticeLOW
    PermissiveLOW
    UnencumberedLOW
    UnknownUNKNOWN
    -

    Quick start

    -

    This section shows how to scan license in container image and filesystem.

    -

    Standard scanning

    -

    Specify an image name with --scanners license.

    -
    $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15
    -2022-07-13T17:28:39.526+0300    INFO    License scanning is enabled
    -
    -OS Packages (license)
    -=====================
    -Total: 6 (UNKNOWN: 0, HIGH: 6, CRITICAL: 0)
    -
    -┌───────────────────┬─────────┬────────────────┬──────────┐
    -│      Package       License  Classification  Severity │
    -├───────────────────┼─────────┼────────────────┼──────────┤
    -│ alpine-baselayout  GPL-2.0  Restricted      HIGH     │
    -├───────────────────┤                                   │
    -│ apk-tools                                            │
    -├───────────────────┤                                   │
    -│ busybox                                              │
    -├───────────────────┤                                   │
    -│ musl-utils                                           │
    -├───────────────────┤                                   │
    -│ scanelf                                              │
    -├───────────────────┤                                   │
    -│ ssl_client                                           │
    -└───────────────────┴─────────┴────────────────┴──────────┘
    -
    -

    Full scanning

    -

    Specify --license-full

    -
    $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana
    -2022-07-13T17:48:40.905+0300    INFO    Full license scanning is enabled
    -
    -OS Packages (license)
    -=====================
    -Total: 20 (UNKNOWN: 9, HIGH: 11, CRITICAL: 0)
    -
    -┌───────────────────┬───────────────────┬────────────────┬──────────┐
    -│      Package            License       Classification  Severity │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ alpine-baselayout  GPL-2.0            Restricted      HIGH     │
    -├───────────────────┤                                             │
    -│ apk-tools                                                      │
    -├───────────────────┼───────────────────┤                          │
    -│ bash               GPL-3.0                                     │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ keyutils-libs      GPL-2.0            Restricted      HIGH     │
    -│                   ├───────────────────┼────────────────┼──────────┤
    -│                    LGPL-2.0-or-later  Non Standard    UNKNOWN  │
    -├───────────────────┼───────────────────┤                          │
    -│ libaio             LGPL-2.1-or-later                           │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ libcom_err         GPL-2.0            Restricted      HIGH     │
    -│                   ├───────────────────┼────────────────┼──────────┤
    -│                    LGPL-2.0-or-later  Non Standard    UNKNOWN  │
    -├───────────────────┼───────────────────┼────────────────┼──────────┤
    -│ tzdata             Public-Domain      Non Standard    UNKNOWN  │
    -└───────────────────┴───────────────────┴────────────────┴──────────┘
    -
    -Loose File License(s) (license)
    -===============================
    -Total: 6 (UNKNOWN: 4, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────────┬──────────┬──────────────┬──────────────────────────────────────────────────────────────┐
    -│ Classification  Severity    License                            File Location                         │
    -├────────────────┼──────────┼──────────────┼──────────────────────────────────────────────────────────────┤
    -│ Forbidden       CRITICAL  AGPL-3.0      /usr/share/grafana/LICENSE                                   │
    -│                                                                                                      │
    -│                                                                                                      │
    -├────────────────┼──────────┼──────────────┼──────────────────────────────────────────────────────────────┤
    -│ Non Standard    UNKNOWN   BSD-0-Clause  /usr/share/grafana/public/build/5069.d6aae9dd11d49c741a80.j- │
    -│                                         s.LICENSE.txt                                                │
    -│                                        ├──────────────────────────────────────────────────────────────┤
    -│                                         /usr/share/grafana/public/build/6444.d6aae9dd11d49c741a80.j- │
    -│                                         s.LICENSE.txt                                                │
    -│                                        ├──────────────────────────────────────────────────────────────┤
    -│                                         /usr/share/grafana/public/build/7889.d6aae9dd11d49c741a80.j- │
    -│                                         s.LICENSE.txt                                                │
    -│                                        ├──────────────────────────────────────────────────────────────┤
    -│                                         /usr/share/grafana/public/build/canvasPanel.d6aae9dd11d49c7- │
    -│                                         41a80.js.LICENSE.txt                                         │
    -└────────────────┴──────────┴──────────────┴──────────────────────────────────────────────────────────────┘
    -
    -

    Configuration

    -

    Trivy has number of configuration flags for use with license scanning;

    -

    Ignored Licenses

    -

    Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the --ignored-licenses flag;

    -
    $ trivy image --scanners license --ignored-licenses MPL-2.0,MIT --severity HIGH grafana/grafana:latest
    -2022-07-13T18:15:28.605Z        INFO    License scanning is enabled
    -
    -OS Packages (license)
    -=====================
    -Total: 2 (HIGH: 2, CRITICAL: 0)
    -
    -┌───────────────────┬─────────┬────────────────┬──────────┐
    -│      Package       License  Classification  Severity │
    -├───────────────────┼─────────┼────────────────┼──────────┤
    -│ alpine-baselayout  GPL-2.0  Restricted      HIGH     │
    -├───────────────────┤                                   │
    -│ ssl_client                                           │
    -└───────────────────┴─────────┴────────────────┴──────────┘
    -
    -

    Configuring Classifier Confidence Level

    -

    You can use the --license-confidence-level flag to adjust the confidence level between 0.0 to 1.0 (default 0.9). -For example, when you run the scanner with the default confidence level on SPDX license list data, it is able to detect only 258 licenses.

    -
    $ trivy fs --scanners license --license-full <path/to/spdx/list/data>
    -2023-04-18T10:05:13.601-0700    INFO    Full license scanning is enabled
    -
    -Loose File License(s) (license)
    -===============================
    -Total: 258 (UNKNOWN: 70, LOW: 90, MEDIUM: 18, HIGH: 58, CRITICAL: 22)
    -
    -

    However, by configuring the confidence level to 0.8, the scanner is now able to detect 282 licenses.

    -
    $ trivy fs --scanners license --license-full --license-confidence-level 0.8 <path/to/spdx/list/data>
    -2023-04-18T10:21:39.637-0700    INFO    Full license scanning is enabled
    -
    -Loose File License(s) (license)
    -===============================
    -Total: 282 (UNKNOWN: 81, LOW: 97, MEDIUM: 24, HIGH: 58, CRITICAL: 22)
    -
    -

    Custom Classification

    -

    You can generate the default config by the --generate-default-config flag and customize the license classification. -For example, if you want to forbid only AGPL-3.0, you can leave it under forbidden and move other licenses to another classification.

    -
    $ trivy image --generate-default-config
    -$ vim trivy.yaml
    -license:
    -  forbidden:
    -  - AGPL-3.0
    -
    -  restricted:
    -  - AGPL-1.0
    -  - CC-BY-NC-1.0
    -  - CC-BY-NC-2.0
    -  - CC-BY-NC-2.5
    -  - CC-BY-NC-3.0
    -  - CC-BY-NC-4.0
    -  - CC-BY-NC-ND-1.0
    -  - CC-BY-NC-ND-2.0
    -  - CC-BY-NC-ND-2.5
    -  - CC-BY-NC-ND-3.0
    -  - CC-BY-NC-ND-4.0
    -  - CC-BY-NC-SA-1.0
    -  - CC-BY-NC-SA-2.0
    -  - CC-BY-NC-SA-2.5
    -  - CC-BY-NC-SA-3.0
    -  - CC-BY-NC-SA-4.0
    -  - Commons-Clause
    -  - Facebook-2-Clause
    -  - Facebook-3-Clause
    -  - Facebook-Examples
    -  - WTFPL
    -  - BCL
    -  - CC-BY-ND-1.0
    -  - CC-BY-ND-2.0
    -  - CC-BY-ND-2.5
    -  - CC-BY-ND-3.0
    -  - CC-BY-ND-4.0
    -  - CC-BY-SA-1.0
    -  - CC-BY-SA-2.0
    -  - CC-BY-SA-2.5
    -  - CC-BY-SA-3.0
    -  - CC-BY-SA-4.0
    -  - GPL-1.0
    -  - GPL-2.0
    -  - GPL-2.0-with-autoconf-exception
    -  - GPL-2.0-with-bison-exception
    -  - GPL-2.0-with-classpath-exception
    -  - GPL-2.0-with-font-exception
    -  - GPL-2.0-with-GCC-exception
    -  - GPL-3.0
    -  - GPL-3.0-with-autoconf-exception
    -  - GPL-3.0-with-GCC-exception
    -  - LGPL-2.0
    -  - LGPL-2.1
    -  - LGPL-3.0
    -  - NPL-1.0
    -  - NPL-1.1
    -  - OSL-1.0
    -  - OSL-1.1
    -  - OSL-2.0
    -  - OSL-2.1
    -  - OSL-3.0
    -  - QPL-1.0
    -  - Sleepycat
    -
    -  reciprocal:
    -  - APSL-1.0
    -  - APSL-1.1
    -  - APSL-1.2
    -  - APSL-2.0
    -  - CDDL-1.0
    -  - CDDL-1.1
    -  - CPL-1.0
    -  - EPL-1.0
    -  - EPL-2.0
    -  - FreeImage
    -  - IPL-1.0
    -  - MPL-1.0
    -  - MPL-1.1
    -  - MPL-2.0
    -  - Ruby
    -
    -  notice:
    -  - AFL-1.1
    -  - AFL-1.2
    -  - AFL-2.0
    -  - AFL-2.1
    -  - AFL-3.0
    -  - Apache-1.0
    -  - Apache-1.1
    -  - Apache-2.0
    -  - Artistic-1.0-cl8
    -  - Artistic-1.0-Perl
    -  - Artistic-1.0
    -  - Artistic-2.0
    -  - BSL-1.0
    -  - BSD-2-Clause-FreeBSD
    -  - BSD-2-Clause-NetBSD
    -  - BSD-2-Clause
    -  - BSD-3-Clause-Attribution
    -  - BSD-3-Clause-Clear
    -  - BSD-3-Clause-LBNL
    -  - BSD-3-Clause
    -  - BSD-4-Clause
    -  - BSD-4-Clause-UC
    -  - BSD-Protection
    -  - CC-BY-1.0
    -  - CC-BY-2.0
    -  - CC-BY-2.5
    -  - CC-BY-3.0
    -  - CC-BY-4.0
    -  - FTL
    -  - ISC
    -  - ImageMagick
    -  - Libpng
    -  - Lil-1.0
    -  - Linux-OpenIB
    -  - LPL-1.02
    -  - LPL-1.0
    -  - MS-PL
    -  - MIT
    -  - NCSA
    -  - OpenSSL
    -  - PHP-3.01
    -  - PHP-3.0
    -  - PIL
    -  - Python-2.0
    -  - Python-2.0-complete
    -  - PostgreSQL
    -  - SGI-B-1.0
    -  - SGI-B-1.1
    -  - SGI-B-2.0
    -  - Unicode-DFS-2015
    -  - Unicode-DFS-2016
    -  - Unicode-TOU
    -  - UPL-1.0
    -  - W3C-19980720
    -  - W3C-20150513
    -  - W3C
    -  - X11
    -  - Xnet
    -  - Zend-2.0
    -  - zlib-acknowledgement
    -  - Zlib
    -  - ZPL-1.1
    -  - ZPL-2.0
    -  - ZPL-2.1
    -
    -  unencumbered:
    -  - CC0-1.0
    -  - Unlicense
    -  - 0BSD
    -
    -  permissive: []
    -
    -
    -
    -
      -
    1. -

      See the list of supported language files here

      -
    2. -
    3. -

      Some lock files require additional files (e.g. files from the cache directory) to detect licenses. Check coverage for more information. 

      -
    4. -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/check/builtin/index.html b/v0.58.0/docs/scanner/misconfiguration/check/builtin/index.html deleted file mode 100644 index 72d6b30d44de..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/check/builtin/index.html +++ /dev/null @@ -1,7936 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Built-in Checks - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Built-in Checks

    -

    Checks Sources

    -

    Trivy has an extensive library of misconfiguration checks that is maintained at https://github.com/aquasecurity/trivy-checks.
    -Trivy checks are mainly written in Rego, while some checks are written in Go.
    -See here for the list of supported config types.

    -

    Checks Bundle

    -

    When performing a misconfiguration scan, Trivy will automatically download the relevant Checks bundle. The bundle is cached locally and Trivy will reuse it for subsequent scans on the same machine. Trivy takes care of updating the cache automatically, so normally users can be oblivious to it.

    -

    Checks Distribution

    -

    Trivy checks are distributed as an OPA bundle hosted in the following GitHub Container Registry: https://ghcr.io/aquasecurity/trivy-checks.
    -Trivy checks for updates to OPA bundle on GHCR every 24 hours and pulls it if there are any updates.

    -

    External connectivity

    -

    Trivy needs to connect to the internet to download the bundle. If you are running Trivy in an air-gapped environment, or an tightly controlled network, please refer to the Advanced Network Scenarios document.
    -The Checks bundle is also embedded in the Trivy binary (at build time), and will be used as a fallback if Trivy is unable to download the bundle. This means that you can still scan for misconfigurations in an air-gapped environment using the Checks from the time of the Trivy release you are using.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/combine/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/combine/index.html deleted file mode 100644 index 745154788220..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/combine/index.html +++ /dev/null @@ -1,7906 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Combine - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Combined input

    -

    Overview

    -

    Trivy usually scans each configuration file individually. -Sometimes it might be useful to compare values from different configuration files simultaneously.

    -

    When combine is set to true, all config files under the specified directory are combined into one input data structure.

    -
    -

    Example

    -
    __rego_input__ := {
    -    "combine": false,
    -}
    -
    -
    -

    In "combine" mode, the input document becomes an array, where each element is an object with two fields:

    -
      -
    • "path": "path/to/file": the relative file path of the respective file
    • -
    • "contents": ...: the parsed content of the respective file
    • -
    -

    Now you can ensure that duplicate values match across the entirety of your configuration files.

    -

    Return value

    -

    In "combine" mode, the deny entrypoint must return an object with two keys

    -
    -
    filepath (required)
    -
    the relative file path of the file being evaluated
    -
    msg (required)
    -
    the message describing an issue
    -
    -
    -

    Example

    -
    deny[res] {
    -    resource := input[i].contents
    -    ... some logic ...
    -
    -    res := {
    -        "filepath": input[i].path,
    -        "msg": "something bad",
    -    }
    -}
    -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/contribute-checks/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/contribute-checks/index.html deleted file mode 100644 index bb3b2ba93218..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/contribute-checks/index.html +++ /dev/null @@ -1,7844 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Contribute Checks - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Contribute Checks

    - -

    Contribute Rego Checks

    -

    The contributing section provides detailed information on how to contribute custom checks to the trivy-checks repository

    -

    This way, they become accessible as default checks.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/data/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/data/index.html deleted file mode 100644 index be132549e962..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/data/index.html +++ /dev/null @@ -1,7801 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Data - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Custom Data

    -

    Custom checks may require additional data in order to make a resolution. You can pass arbitrary data files to Trivy to be used when evaluating rego checks using the --data flag. -Trivy recursively searches the specified data paths for JSON (*.json) and YAML (*.yaml) files.

    -

    For example, consider an allowed list of resources that can be created. -Instead of hardcoding this information inside your policy, you can maintain the list in a separate file.

    -

    Example data file:

    -
    services:
    -  ports:
    -    - "20"
    -    - "20/tcp"
    -    - "20/udp"
    -    - "23"
    -    - "23/tcp"
    -
    -

    Example usage in a Rego check:

    -
    import data.services
    -
    -ports := services.ports
    -
    -

    Example loading the data file:

    -
    trivy config --config-check ./checks --data ./data --namespaces user ./configs
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/debug/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/debug/index.html deleted file mode 100644 index 5b57b5ac15f1..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/debug/index.html +++ /dev/null @@ -1,8082 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Debugging Policies - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Debugging checks

    -

    When working on more complex queries (or when learning Rego), it's useful to see exactly how the policy is applied. -For this purpose you can use the --trace flag. -This will output a large trace from Open Policy Agent like the following:

    -
    -

    Tip

    -

    Only failed checks show traces. If you want to debug a passed check, you need to make it fail on purpose.

    -
    -
    $ trivy config --trace configs/
    -2022-05-16T13:47:58.853+0100    INFO    Detected config files: 1
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 23 (SUCCESSES: 21, FAILURES: 2)
    -Failures: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 1, CRITICAL: 0)
    -
    -MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.
    -
    -See https://avd.aquasec.com/misconfig/ds001
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - Dockerfile:1
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   1 [ FROM alpine:latest
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -HIGH: Last USER command in Dockerfile should not be 'root'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - Dockerfile:3
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   3 [ USER root
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -ID: DS001
    -File: Dockerfile
    -Namespace: builtin.dockerfile.DS001
    -Query: data.builtin.dockerfile.DS001.deny
    -Message: Specify a tag in the 'FROM' statement for image 'alpine'
    -TRACE  Enter data.builtin.dockerfile.DS001.deny = _
    -TRACE  | Eval data.builtin.dockerfile.DS001.deny = _
    -TRACE  | Index data.builtin.dockerfile.DS001.deny (matched 1 rule)
    -TRACE  | Enter data.builtin.dockerfile.DS001.deny
    -TRACE  | | Eval output = data.builtin.dockerfile.DS001.fail_latest[_]
    -TRACE  | | Index data.builtin.dockerfile.DS001.fail_latest (matched 1 rule)
    -TRACE  | | Enter data.builtin.dockerfile.DS001.fail_latest
    -TRACE  | | | Eval output = data.builtin.dockerfile.DS001.image_tags[_]
    -TRACE  | | | Index data.builtin.dockerfile.DS001.image_tags (matched 2 rules)
    -TRACE  | | | Enter data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | | Eval from = data.lib.docker.from[_]
    -TRACE  | | | | Index data.lib.docker.from (matched 1 rule)
    -TRACE  | | | | Enter data.lib.docker.from
    -TRACE  | | | | | Eval instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "from"
    -TRACE  | | | | | Exit data.lib.docker.from
    -TRACE  | | | | Redo data.lib.docker.from
    -TRACE  | | | | | Redo instruction.Cmd = "from"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "from"
    -TRACE  | | | | | Fail instruction.Cmd = "from"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "from"
    -TRACE  | | | | | Fail instruction.Cmd = "from"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | Eval name = from.Value[0]
    -TRACE  | | | | Eval not startswith(name, "$")
    -TRACE  | | | | Enter startswith(name, "$")
    -TRACE  | | | | | Eval startswith(name, "$")
    -TRACE  | | | | | Fail startswith(name, "$")
    -TRACE  | | | | Eval data.builtin.dockerfile.DS001.parse_tag(name, __local505__)
    -TRACE  | | | | Index data.builtin.dockerfile.DS001.parse_tag (matched 2 rules)
    -TRACE  | | | | Enter data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | | Eval split(name, ":", __local504__)
    -TRACE  | | | | | Eval [img, tag] = __local504__
    -TRACE  | | | | | Exit data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | Eval [img, tag] = __local505__
    -TRACE  | | | | Eval output = {"cmd": from, "img": img, "tag": tag}
    -TRACE  | | | | Exit data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | Redo data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | | Redo output = {"cmd": from, "img": img, "tag": tag}
    -TRACE  | | | | Redo [img, tag] = __local505__
    -TRACE  | | | | Redo data.builtin.dockerfile.DS001.parse_tag(name, __local505__)
    -TRACE  | | | | Redo data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | | Redo [img, tag] = __local504__
    -TRACE  | | | | | Redo split(name, ":", __local504__)
    -TRACE  | | | | Enter data.builtin.dockerfile.DS001.parse_tag
    -TRACE  | | | | | Eval tag = "latest"
    -TRACE  | | | | | Eval not contains(img, ":")
    -TRACE  | | | | | Enter contains(img, ":")
    -TRACE  | | | | | | Eval contains(img, ":")
    -TRACE  | | | | | | Exit contains(img, ":")
    -TRACE  | | | | | Redo contains(img, ":")
    -TRACE  | | | | | | Redo contains(img, ":")
    -TRACE  | | | | | Fail not contains(img, ":")
    -TRACE  | | | | | Redo tag = "latest"
    -TRACE  | | | | Redo name = from.Value[0]
    -TRACE  | | | | Redo from = data.lib.docker.from[_]
    -TRACE  | | | Enter data.builtin.dockerfile.DS001.image_tags
    -TRACE  | | | | Eval from = data.lib.docker.from[i]
    -TRACE  | | | | Index data.lib.docker.from (matched 1 rule)
    -TRACE  | | | | Eval name = from.Value[0]
    -TRACE  | | | | Eval cmd_obj = input.stages[j][k]
    -TRACE  | | | | Eval possibilities = {"arg", "env"}
    -TRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Redo possibilities = {"arg", "env"}
    -TRACE  | | | | Redo cmd_obj = input.stages[j][k]
    -TRACE  | | | | Eval possibilities = {"arg", "env"}
    -TRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Redo possibilities = {"arg", "env"}
    -TRACE  | | | | Redo cmd_obj = input.stages[j][k]
    -TRACE  | | | | Eval possibilities = {"arg", "env"}
    -TRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]
    -TRACE  | | | | Redo possibilities = {"arg", "env"}
    -TRACE  | | | | Redo cmd_obj = input.stages[j][k]
    -TRACE  | | | | Redo name = from.Value[0]
    -TRACE  | | | | Redo from = data.lib.docker.from[i]
    -TRACE  | | | Eval __local752__ = output.img
    -TRACE  | | | Eval neq(__local752__, "scratch")
    -TRACE  | | | Eval __local753__ = output.img
    -TRACE  | | | Eval not data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | Enter data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | | Eval data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | | Index data.builtin.dockerfile.DS001.is_alias (matched 1 rule, early exit)
    -TRACE  | | | | Enter data.builtin.dockerfile.DS001.is_alias
    -TRACE  | | | | | Eval img = data.builtin.dockerfile.DS001.get_aliases[_]
    -TRACE  | | | | | Index data.builtin.dockerfile.DS001.get_aliases (matched 1 rule)
    -TRACE  | | | | | Enter data.builtin.dockerfile.DS001.get_aliases
    -TRACE  | | | | | | Eval from_cmd = data.lib.docker.from[_]
    -TRACE  | | | | | | Index data.lib.docker.from (matched 1 rule)
    -TRACE  | | | | | | Eval __local749__ = from_cmd.Value
    -TRACE  | | | | | | Eval data.builtin.dockerfile.DS001.get_alias(__local749__, __local503__)
    -TRACE  | | | | | | Index data.builtin.dockerfile.DS001.get_alias (matched 1 rule)
    -TRACE  | | | | | | Enter data.builtin.dockerfile.DS001.get_alias
    -TRACE  | | | | | | | Eval __local748__ = values[i]
    -TRACE  | | | | | | | Eval lower(__local748__, __local501__)
    -TRACE  | | | | | | | Eval "as" = __local501__
    -TRACE  | | | | | | | Fail "as" = __local501__
    -TRACE  | | | | | | | Redo lower(__local748__, __local501__)
    -TRACE  | | | | | | | Redo __local748__ = values[i]
    -TRACE  | | | | | | Fail data.builtin.dockerfile.DS001.get_alias(__local749__, __local503__)
    -TRACE  | | | | | | Redo __local749__ = from_cmd.Value
    -TRACE  | | | | | | Redo from_cmd = data.lib.docker.from[_]
    -TRACE  | | | | | Fail img = data.builtin.dockerfile.DS001.get_aliases[_]
    -TRACE  | | | | Fail data.builtin.dockerfile.DS001.is_alias(__local753__)
    -TRACE  | | | Eval output.tag = "latest"
    -TRACE  | | | Exit data.builtin.dockerfile.DS001.fail_latest
    -TRACE  | | Redo data.builtin.dockerfile.DS001.fail_latest
    -TRACE  | | | Redo output.tag = "latest"
    -TRACE  | | | Redo __local753__ = output.img
    -TRACE  | | | Redo neq(__local752__, "scratch")
    -TRACE  | | | Redo __local752__ = output.img
    -TRACE  | | | Redo output = data.builtin.dockerfile.DS001.image_tags[_]
    -TRACE  | | Eval __local754__ = output.img
    -TRACE  | | Eval sprintf("Specify a tag in the 'FROM' statement for image '%s'", [__local754__], __local509__)
    -TRACE  | | Eval msg = __local509__
    -TRACE  | | Eval __local755__ = output.cmd
    -TRACE  | | Eval data.lib.docker.result(msg, __local755__, __local510__)
    -TRACE  | | Index data.lib.docker.result (matched 1 rule)
    -TRACE  | | Enter data.lib.docker.result
    -TRACE  | | | Eval object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | | Eval object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Eval object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Eval result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Exit data.lib.docker.result
    -TRACE  | | Eval res = __local510__
    -TRACE  | | Exit data.builtin.dockerfile.DS001.deny
    -TRACE  | Redo data.builtin.dockerfile.DS001.deny
    -TRACE  | | Redo res = __local510__
    -TRACE  | | Redo data.lib.docker.result(msg, __local755__, __local510__)
    -TRACE  | | Redo data.lib.docker.result
    -TRACE  | | | Redo result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Redo object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Redo object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Redo object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | Redo __local755__ = output.cmd
    -TRACE  | | Redo msg = __local509__
    -TRACE  | | Redo sprintf("Specify a tag in the 'FROM' statement for image '%s'", [__local754__], __local509__)
    -TRACE  | | Redo __local754__ = output.img
    -TRACE  | | Redo output = data.builtin.dockerfile.DS001.fail_latest[_]
    -TRACE  | Exit data.builtin.dockerfile.DS001.deny = _
    -TRACE  Redo data.builtin.dockerfile.DS001.deny = _
    -TRACE  | Redo data.builtin.dockerfile.DS001.deny = _
    -TRACE
    -
    -
    -ID: DS002
    -File: Dockerfile
    -Namespace: builtin.dockerfile.DS002
    -Query: data.builtin.dockerfile.DS002.deny
    -Message: Last USER command in Dockerfile should not be 'root'
    -TRACE  Enter data.builtin.dockerfile.DS002.deny = _
    -TRACE  | Eval data.builtin.dockerfile.DS002.deny = _
    -TRACE  | Index data.builtin.dockerfile.DS002.deny (matched 2 rules)
    -TRACE  | Enter data.builtin.dockerfile.DS002.deny
    -TRACE  | | Eval data.builtin.dockerfile.DS002.fail_user_count
    -TRACE  | | Index data.builtin.dockerfile.DS002.fail_user_count (matched 1 rule, early exit)
    -TRACE  | | Enter data.builtin.dockerfile.DS002.fail_user_count
    -TRACE  | | | Eval __local771__ = data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | Index data.builtin.dockerfile.DS002.get_user (matched 1 rule)
    -TRACE  | | | Enter data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | | Eval user = data.lib.docker.user[_]
    -TRACE  | | | | Index data.lib.docker.user (matched 1 rule)
    -TRACE  | | | | Enter data.lib.docker.user
    -TRACE  | | | | | Eval instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "user"
    -TRACE  | | | | | Fail instruction.Cmd = "user"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "user"
    -TRACE  | | | | | Exit data.lib.docker.user
    -TRACE  | | | | Redo data.lib.docker.user
    -TRACE  | | | | | Redo instruction.Cmd = "user"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | | Eval instruction.Cmd = "user"
    -TRACE  | | | | | Fail instruction.Cmd = "user"
    -TRACE  | | | | | Redo instruction = input.stages[_][_]
    -TRACE  | | | | Eval username = user.Value[_]
    -TRACE  | | | | Exit data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | Redo data.builtin.dockerfile.DS002.get_user
    -TRACE  | | | | Redo username = user.Value[_]
    -TRACE  | | | | Redo user = data.lib.docker.user[_]
    -TRACE  | | | Eval count(__local771__, __local536__)
    -TRACE  | | | Eval lt(__local536__, 1)
    -TRACE  | | | Fail lt(__local536__, 1)
    -TRACE  | | | Redo count(__local771__, __local536__)
    -TRACE  | | | Redo __local771__ = data.builtin.dockerfile.DS002.get_user
    -TRACE  | | Fail data.builtin.dockerfile.DS002.fail_user_count
    -TRACE  | Enter data.builtin.dockerfile.DS002.deny
    -TRACE  | | Eval cmd = data.builtin.dockerfile.DS002.fail_last_user_root[_]
    -TRACE  | | Index data.builtin.dockerfile.DS002.fail_last_user_root (matched 1 rule)
    -TRACE  | | Enter data.builtin.dockerfile.DS002.fail_last_user_root
    -TRACE  | | | Eval stage_users = data.lib.docker.stage_user[_]
    -TRACE  | | | Index data.lib.docker.stage_user (matched 1 rule)
    -TRACE  | | | Enter data.lib.docker.stage_user
    -TRACE  | | | | Eval stage = input.stages[stage_name]
    -TRACE  | | | | Eval users = [cmd | cmd = stage[_]; cmd.Cmd = "user"]
    -TRACE  | | | | Enter cmd = stage[_]; cmd.Cmd = "user"
    -TRACE  | | | | | Eval cmd = stage[_]
    -TRACE  | | | | | Eval cmd.Cmd = "user"
    -TRACE  | | | | | Fail cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd = stage[_]
    -TRACE  | | | | | Eval cmd.Cmd = "user"
    -TRACE  | | | | | Exit cmd = stage[_]; cmd.Cmd = "user"
    -TRACE  | | | | Redo cmd = stage[_]; cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd = stage[_]
    -TRACE  | | | | | Eval cmd.Cmd = "user"
    -TRACE  | | | | | Fail cmd.Cmd = "user"
    -TRACE  | | | | | Redo cmd = stage[_]
    -TRACE  | | | | Exit data.lib.docker.stage_user
    -TRACE  | | | Redo data.lib.docker.stage_user
    -TRACE  | | | | Redo users = [cmd | cmd = stage[_]; cmd.Cmd = "user"]
    -TRACE  | | | | Redo stage = input.stages[stage_name]
    -TRACE  | | | Eval count(stage_users, __local537__)
    -TRACE  | | | Eval len = __local537__
    -TRACE  | | | Eval minus(len, 1, __local538__)
    -TRACE  | | | Eval last = stage_users[__local538__]
    -TRACE  | | | Eval user = last.Value[0]
    -TRACE  | | | Eval user = "root"
    -TRACE  | | | Exit data.builtin.dockerfile.DS002.fail_last_user_root
    -TRACE  | | Redo data.builtin.dockerfile.DS002.fail_last_user_root
    -TRACE  | | | Redo user = "root"
    -TRACE  | | | Redo user = last.Value[0]
    -TRACE  | | | Redo last = stage_users[__local538__]
    -TRACE  | | | Redo minus(len, 1, __local538__)
    -TRACE  | | | Redo len = __local537__
    -TRACE  | | | Redo count(stage_users, __local537__)
    -TRACE  | | | Redo stage_users = data.lib.docker.stage_user[_]
    -TRACE  | | Eval msg = "Last USER command in Dockerfile should not be 'root'"
    -TRACE  | | Eval data.lib.docker.result(msg, cmd, __local540__)
    -TRACE  | | Index data.lib.docker.result (matched 1 rule)
    -TRACE  | | Enter data.lib.docker.result
    -TRACE  | | | Eval object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | | Eval object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Eval object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Eval result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Exit data.lib.docker.result
    -TRACE  | | Eval res = __local540__
    -TRACE  | | Exit data.builtin.dockerfile.DS002.deny
    -TRACE  | Redo data.builtin.dockerfile.DS002.deny
    -TRACE  | | Redo res = __local540__
    -TRACE  | | Redo data.lib.docker.result(msg, cmd, __local540__)
    -TRACE  | | Redo data.lib.docker.result
    -TRACE  | | | Redo result = {"endline": __local470__, "filepath": __local471__, "msg": msg, "startline": __local472__}
    -TRACE  | | | Redo object.get(cmd, "StartLine", 0, __local472__)
    -TRACE  | | | Redo object.get(cmd, "Path", "", __local471__)
    -TRACE  | | | Redo object.get(cmd, "EndLine", 0, __local470__)
    -TRACE  | | Redo msg = "Last USER command in Dockerfile should not be 'root'"
    -TRACE  | | Redo cmd = data.builtin.dockerfile.DS002.fail_last_user_root[_]
    -TRACE  | Exit data.builtin.dockerfile.DS002.deny = _
    -TRACE  Redo data.builtin.dockerfile.DS002.deny = _
    -TRACE  | Redo data.builtin.dockerfile.DS002.deny = _
    -TRACE
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/index.html deleted file mode 100644 index 41a01b1dfd16..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/index.html +++ /dev/null @@ -1,8481 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Custom Checks

    -

    Overview

    -

    You can write custom checks in Rego. -Once you finish writing custom checks, you can pass the check files or the directory where those checks are stored with --config-check` option.

    -
    trivy config --config-check /path/to/policy.rego --config-check /path/to/custom_checks --namespaces user /path/to/config_dir
    -
    -

    As for --namespaces option, the detail is described as below.

    -

    File formats

    -

    If a file name matches the following file patterns, Trivy will parse the file and pass it as input to your Rego policy.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    File formatFile pattern
    JSON*.json
    YAML*.yaml and *.yml
    DockerfileDockerfile, Dockerfile.*, and *.Dockerfile
    ContainerfileContainerfile, Containerfile.*, and *.Containerfile
    Terraform*.tf and *.tf.json
    -

    Configuration languages

    -

    In the above general file formats, Trivy automatically identifies the following types of configuration files:

    -
      -
    • CloudFormation (JSON/YAML)
    • -
    • Kubernetes (JSON/YAML)
    • -
    • Helm (YAML)
    • -
    • Terraform Plan (JSON/Snapshot)
    • -
    -

    This is useful for filtering inputs, as described below.

    -

    Rego format

    -

    A single package must contain only one policy.

    -
    -

    Example

    -
    # METADATA
    -# title: Deployment not allowed
    -# description: Deployments are not allowed because of some reasons.
    -# schemas:
    -#   - input: schema["kubernetes"]
    -# custom:
    -#   id: ID001
    -#   severity: LOW
    -#   input:
    -#     selector: 
    -#     - type: kubernetes
    -package user.kubernetes.ID001
    -
    -deny[res] {
    -    input.kind == "Deployment"
    -    msg := sprintf("Found deployment '%s' but deployments are not allowed", [input.metadata.name])
    -    res := result.new(msg, input.kind)
    -}
    -
    -
    -

    In this example, ID001 "Deployment not allowed" is defined under user.kubernetes.ID001. -If you add a new custom policy, it must be defined under a new package like user.kubernetes.ID002.

    -

    Policy structure

    -
    -
    # METADATA (optional unless the check will be contributed into Trivy)
    -
    -
      -
    • SHOULD be defined for clarity since these values will be displayed in the scan results
    • -
    • custom.input SHOULD be set to indicate the input type the policy should be applied to. See list of available types
    • -
    -
    -
    package (required)
    -
    -
      -
    • MUST follow the Rego's specification
    • -
    • MUST be unique per policy
    • -
    • SHOULD include policy id for uniqueness
    • -
    • MAY include the group name such as kubernetes for clarity
        -
      • Group name has no effect on policy evaluation
      • -
      -
    • -
    -
    -
    deny (required)
    -
    -
      -
    • SHOULD be deny or start with deny_
        -
      • Although warn, warn_*, violation, violation_ also work for compatibility, deny is recommended as severity can be defined in __rego_metadata__.
      • -
      -
    • -
    • SHOULD return ONE OF:
        -
      • The result of a call to result.new(msg, cause). The msg is a string describing the issue occurrence, and the cause is the property/object where the issue occurred. Providing this allows Trivy to ascertain line numbers and highlight code in the output.
      • -
      • A string denoting the detected issue
          -
        • Although object with msg field is accepted, other fields are dropped and string is recommended if result.new() is not utilised.
        • -
        • e.g. {"msg": "deny message", "details": "something"}
        • -
        -
      • -
      -
    • -
    -
    -
    -

    Package

    -

    A package name must be unique per policy.

    -
    -

    Example

    -
    package user.kubernetes.ID001
    -
    -
    -

    By default, only builtin.* packages will be evaluated. -If you define custom packages, you have to specify the package prefix via --namespaces option. By default, Trivy only runs in its own namespace, unless specified by the user. Note that the custom namespace does not have to be user as in this example. It could be anything user-defined.

    -
    trivy config --config-check /path/to/custom_checks --namespaces user /path/to/config_dir
    -
    -

    In this case, user.* will be evaluated. -Any package prefixes such as main and user are allowed.

    -

    Metadata

    -

    The check must contain a Rego Metadata section. Trivy uses standard rego metadata to define the new policy and general information about it.

    -

    Trivy supports extra fields in the custom section as described below.

    -
    -

    Example

    -
    # METADATA
    -# title: Deployment not allowed
    -# description: Deployments are not allowed because of some reasons.
    -# custom:
    -#   id: ID001
    -#   severity: LOW
    -#   input:
    -#     selector:
    -#     - type: kubernetes
    -
    -
    -

    If you are creating checks for your Trivy misconfiguration scans, some fields are optional as referenced in the table below. The schemas field should be used to enable policy validation using a built-in schema. It is recommended to use this to ensure your checks are -correct and do not reference incorrect properties/values.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Field nameAllowed valuesDefault valueIn tableIn JSON
    titleAny charactersN/A:material-check::material-check:
    descriptionAny characters:material-close::material-check:
    schemas.inputschema["kubernetes"], schema["dockerfile"], schema["cloud"](applied to all input types):material-close::material-close:
    custom.idAny charactersN/A:material-check::material-check:
    custom.severityLOW, MEDIUM, HIGH, CRITICALUNKNOWN:material-check::material-check:
    custom.recommended_actionsAny characters:material-close::material-check:
    custom.deprecatedtrue, falsefalse:material-close::material-check:
    custom.input.selector.typeAny item(s) in this list:material-close::material-check:
    urlAny characters:material-close::material-check:
    -

    custom.avd_id and custom.id

    -

    The AVD_ID can be used to link the check to the Aqua Vulnerability Database (AVD) entry. For example, the avd_id AVD-AWS-0176 is the ID of the check in the AWS Vulnerability Database. If you are contributing your check to trivy-checks, you need to generate an ID using make id in the trivy-checks repository. The output of the command will provide you the next free IDs for the different providers in Trivy.

    -

    The ID is based on the AVD_ID. For instance if the avd_id is AVD-AWS-0176, the ID is ID0176.

    -

    custom.provider

    -

    The provider field references the provider available in Trivy. This should be the same as the provider name in the pkg/iac/providers directory, e.g. aws.

    -

    custom.service

    -

    Services are defined within a provider. For instance, RDS is a service and AWS is a provider. This should be the same as the service name in one of the provider directories. (Link), e.g. aws/rds.

    -

    custom.input

    -

    The input tells Trivy what inputs this check should be applied to. Cloud provider checks should always use the selector input, and should always use the type selector with cloud. Check targeting Kubernetes yaml can use kubenetes, RBAC can use rbac, and so on.

    -

    Subtypes in the custom data

    -

    Subtypes currently only need to be defined for cloud providers as detailed in the documentation.

    -

    Scan Result

    -

    Some fields are displayed in scan results.

    -
    k.yaml (kubernetes)
    -───────────────────
    -
    -Tests: 32 (SUCCESSES: 31, FAILURES: 1)
    -Failures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -LOW: Found deployment 'my-deployment' but deployments are not allowed
    -════════════════════════════════════════════════════════════════════════
    -Deployments are not allowed because of some reasons.
    -────────────────────────────────────────────────────────────────────────
    - k.yaml:1-2
    -────────────────────────────────────────────────────────────────────────
    -   1  apiVersion: v1
    -   2  kind: Deployment
    -────────────────────────────────────────────────────────────────────────
    -
    -

    Input

    -

    You can specify input format via the custom.input annotation.

    -
    -

    Example

    -
    # METADATA
    -# custom:
    -#   input:
    -#     combine: false
    -#     selector:
    -#     - type: kubernetes
    -
    -
    -
    -
    combine (boolean)
    -
    The details are here.
    -
    selector (array)
    -
    -

    This option filters the input by file format or configuration language. -In the above example, Trivy passes only Kubernetes files to this policy. -Even if a Dockerfile exists in the specified directory, it will not be passed to the policy as input.

    -

    Possible values for input types are:

    -
      -
    • dockerfile (Dockerfile)
    • -
    • kubernetes (Kubernetes YAML/JSON)
    • -
    • rbac (Kubernetes RBAC YAML/JSON)
    • -
    • cloud (Cloud format, as defined by Trivy - this is used for Terraform, CloudFormation, and Cloud/AWS scanning)
    • -
    • yaml (Generic YAML)
    • -
    • json (Generic JSON)
    • -
    • toml (Generic TOML)
    • -
    -

    When configuration languages such as Kubernetes are not identified, file formats such as JSON will be used as type. -When a configuration language is identified, it will overwrite type.

    -
    -

    Example

    -

    pod.yaml including Kubernetes Pod will be handled as kubernetes, not yaml. -type is overwritten by kubernetes from yaml.

    -
    -

    type accepts kubernetes, dockerfile, cloudformation, terraform, terraformplan, json, or yaml.

    -
    -
    -

    Schemas

    -

    See here for the detail.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/schema/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/schema/index.html deleted file mode 100644 index 2b27398ac3b9..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/schema/index.html +++ /dev/null @@ -1,7943 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Schemas - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Input Schema

    -

    Overview

    -

    Checks can be defined with custom schemas that allow inputs to be verified against them. Adding a policy schema -enables Trivy to show more detailed error messages when an invalid input is encountered.

    -

    In Trivy we have been able to define a schema for a Dockerfile -Without input schemas, a policy would be as follows:

    -
    -

    Example

    -
    # METADATA
    -package mypackage
    -
    -deny {
    -    input.evil == "foo bar"
    -}
    -
    -
    -

    If this policy is run against offending Dockerfile(s), there will not be any issues as the policy will fail to evaluate. -Although the policy's failure to evaluate is legitimate, this should not result in a positive result for the scan.

    -

    For instance if we have a policy that checks for misconfigurations in a Dockerfile, we could define the -schema as such

    -
    -

    Example

    -
    # METADATA
    -# schemas:
    -# - input: schema["dockerfile"]
    -package mypackage
    -
    -deny {
    -    input.evil == "foo bar"
    -}
    -
    -
    -

    Here input: schema["dockerfile"] points to a schema that expects a valid Dockerfile as input. An example of this -can be found here.

    -

    Now if this policy is evaluated against, a more descriptive error will be available to help fix the problem.

    -
    1 error occurred: testpolicy.rego:8: rego_type_error: undefined ref: input.evil
    -        input.evil
    -              ^
    -              have: "evil"
    -              want (one of): ["Stages"]
    -
    -

    Currently, out of the box the following schemas are supported natively:

    -
      -
    1. Docker
    2. -
    3. Kubernetes
    4. -
    5. Cloud
    6. -
    -

    Custom Checks with Custom Schemas

    -

    You can also bring a custom policy that defines one or more custom schema.

    -
    -

    Example

    -
    # METADATA
    -# schemas:
    -# - input: schema["fooschema"]
    -# - input: schema["barschema"]
    -package mypackage
    -
    -deny {
    -    input.evil == "foo bar"
    -}
    -
    -
    -

    The checks can be placed in a structure as follows

    -
    -

    Example

    -
    /Users/user/my-custom-checks
    -├── my_policy.rego
    -└── schemas
    -    └── fooschema.json
    -    └── barschema.json
    -
    -
    -

    To use such a policy with Trivy, use the --config-policy flag that points to the policy file or to the directory where the schemas and checks are contained.

    -
    $ trivy --config-policy=/Users/user/my-custom-checks <path/to/iac>
    -
    -

    For more details on how to define schemas within Rego checks, please see the OPA guide that describes it in more detail.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/selectors/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/selectors/index.html deleted file mode 100644 index bdb5bdf54cb9..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/selectors/index.html +++ /dev/null @@ -1,7974 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Selectors - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Input Selectors

    -

    Overview

    -

    Sometimes you might want to limit a certain policy to only be run on certain resources. This can be -achieved with input selectors.

    -

    Use case

    -

    For instance, if you have a custom policy that you only want to be evaluated if a certain resource type is being scanned. -In such a case you could utilize input selectors to limit its evaluation on only those resources.

    -
    -

    Example

    -
        # METADATA
    -    # title: "RDS Publicly Accessible"
    -    # description: "Ensures RDS instances are not launched into the public cloud."
    -    # custom:
    -    #   input:
    -    #     selector:
    -    #     - type: cloud
    -    #       subtypes:
    -    #         - provider: aws
    -    #           service: rds
    -    package builtin.aws.rds.aws0999
    -
    -    deny[res] {
    -    instance := input.aws.rds.instances[_]
    -    instance.publicaccess.value
    -    res := result.new("Instance has Public Access enabled", instance.publicaccess)
    -
    -
    -

    Observe the following subtypes defined: -

            #       subtypes:
    -        #         - provider: aws
    -        #           service: rds
    -

    -

    They will ensure that the policy is only run when the input to such a policy contains an RDS instance.

    -

    Enabling selectors and subtypes

    -

    Currently, the following are supported:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    SelectorSubtype fields requiredExample
    Cloud (AWS, Azure, etc.)provider, serviceprovider: aws, service: rds
    Kubernetestype: kubernetes
    Dockerfiletype: dockerfile
    -

    Default behaviour

    -

    If no subtypes or selectors are specified, the policy will be evaluated regardless of input.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/custom/testing/index.html b/v0.58.0/docs/scanner/misconfiguration/custom/testing/index.html deleted file mode 100644 index a2ab43dc3f7c..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/custom/testing/index.html +++ /dev/null @@ -1,7944 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Testing - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Testing

    -

    It is highly recommended to write tests for your custom checks.

    -

    Rego testing

    -

    To help you verify the correctness of your custom checks, OPA gives you a framework that you can use to write tests for your checks. -By writing tests for your custom checks you can speed up the development process of new rules and reduce the amount of time it takes to modify rules as requirements evolve.

    -

    For more details, see Policy Testing.

    -
    -

    Example

    -
    package user.dockerfile.ID002
    -
    -test_add_denied {
    -    r := deny with input as {"stages": {"alpine:3.13": [
    -        {"Cmd": "add", "Value": ["/target/resources.tar.gz", "resources.jar"]},
    -        {"Cmd": "add", "Value": ["/target/app.jar", "app.jar"]},
    -    ]}}
    -
    -    count(r) == 1
    -    r[_] == "Consider using 'COPY /target/app.jar app.jar' command instead of 'ADD /target/app.jar app.jar'"
    -}
    -
    -
    -

    To write tests for custom checks, you can refer to existing tests under [trivy-checks][trivy-checks].

    -

    Go testing

    -

    Fanal which is a core library of Trivy can be imported as a Go library. -You can scan config files in Go and test your custom checks using Go's testing methods, such as table-driven tests. -This allows you to use the actual configuration file as input, making it easy to prepare test data and ensure that your custom checks work in practice.

    -

    In particular, Dockerfile and HCL need to be converted to structural data as input, which may be different from the expected input format.

    -
    -

    Tip

    -

    We recommend writing OPA and Go tests both since they have different roles, like unit tests and integration tests.

    -
    -

    The following example stores allowed and denied configuration files in a directory. -Successes contains the result of successes, and Failures contains the result of failures.

    -
    {
    -    name:  "disallowed ports",
    -    input: "configs/",
    -    fields: fields{
    -        policyPaths: []string{"policy"},
    -        dataPaths:   []string{"data"},
    -        namespaces:  []string{"user"},
    -    },
    -    want: []types.Misconfiguration{
    -        {
    -            FileType: types.Dockerfile,
    -            FilePath: "Dockerfile.allowed",
    -            Successes: types.MisconfResults{
    -                {
    -                    Namespace: "user.dockerfile.ID002",
    -                    PolicyMetadata: types.PolicyMetadata{
    -                        ID:          "ID002",
    -                        Type:        "Docker Custom Check",
    -                        Title:       "Disallowed ports exposed",
    -                        Severity:    "HIGH",
    -                    },
    -                },
    -            },
    -        },
    -        {
    -            FileType: types.Dockerfile,
    -            FilePath: "Dockerfile.denied",
    -            Failures: types.MisconfResults{
    -                {
    -                    Namespace: "user.dockerfile.ID002",
    -                    Message:   "Port 23 should not be exposed",
    -                    PolicyMetadata: types.PolicyMetadata{
    -                        ID:          "ID002",
    -                        Type:        "Docker Custom Check",
    -                        Title:       "Disallowed ports exposed",
    -                        Severity:    "HIGH",
    -                    },
    -                },
    -            },
    -        },
    -    },
    -},
    -
    -

    Dockerfile.allowed has one successful result in Successes, while Dockerfile.denied has one failure result in Failures.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/misconfiguration/index.html b/v0.58.0/docs/scanner/misconfiguration/index.html deleted file mode 100644 index 92470cdba77a..000000000000 --- a/v0.58.0/docs/scanner/misconfiguration/index.html +++ /dev/null @@ -1,8710 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Misconfiguration Scanning

    -

    Trivy provides built-in checks to detect configuration issues in popular Infrastructure as Code files, such as: Docker, Kubernetes, Terraform, CloudFormation, and more. -In addition to built-in checks, you can write your own custom checks, as you can see here.

    -

    Quick start

    -

    Simply specify a directory containing IaC files such as Terraform, CloudFormation, Azure ARM templates, Helm Charts and Dockerfile.

    -
    $ trivy config [YOUR_IaC_DIRECTORY]
    -
    -
    -

    Example

    -
    $ ls build/
    -Dockerfile
    -$ trivy config ./build
    -2022-05-16T13:29:29.952+0100    INFO    Detected config files: 1
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 23 (SUCCESSES: 22, FAILURES: 1)
    -Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -MEDIUM: Specify a tag in the 'FROM' statement for image 'alpine'
    -══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.
    -
    -See https://avd.aquasec.com/misconfig/ds001
    -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -Dockerfile:1
    -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -1 [ FROM alpine:latest
    -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -

    You can also enable misconfiguration detection in container image, filesystem and git repository scanning via --scanners misconfig.

    -
    $ trivy image --scanners misconfig IMAGE_NAME
    -
    -
    $ trivy fs --scanners misconfig /path/to/dir
    -
    -
    -

    Note

    -

    Misconfiguration detection is not enabled by default in image, fs and repo subcommands.

    -
    -

    Unlike the config subcommand, image, fs and repo subcommands can also scan for vulnerabilities and secrets at the same time. -You can specify --scanners vuln,misconfig,secret to enable vulnerability and secret detection as well as misconfiguration detection.

    -
    -

    Example

    -
    $ ls myapp/
    -Dockerfile Pipfile.lock
    -$ trivy fs --scanners vuln,misconfig,secret --severity HIGH,CRITICAL myapp/
    -2022-05-16T13:42:21.440+0100    INFO    Number of language-specific files: 1
    -2022-05-16T13:42:21.440+0100    INFO    Detecting pipenv vulnerabilities...
    -2022-05-16T13:42:21.440+0100    INFO    Detected config files: 1
    -
    -Pipfile.lock (pipenv)
    -=====================
    -Total: 1 (HIGH: 1, CRITICAL: 0)
    -
    -┌──────────┬────────────────┬──────────┬───────────────────┬───────────────┬───────────────────────────────────────────────────────────┐
    -│ Library   Vulnerability   Severity  Installed Version  Fixed Version                            Title                           │
    -├──────────┼────────────────┼──────────┼───────────────────┼───────────────┼───────────────────────────────────────────────────────────┤
    -│ httplib2  CVE-2021-21240  HIGH      0.12.1             0.19.0         python-httplib2: Regular expression denial of service via │
    -│                                                                       malicious header                                          │
    -│                                                                       https://avd.aquasec.com/nvd/cve-2021-21240                │
    -└──────────┴────────────────┴──────────┴───────────────────┴───────────────┴───────────────────────────────────────────────────────────┘
    -
    -Dockerfile (dockerfile)
    -=======================
    -Tests: 17 (SUCCESSES: 16, FAILURES: 1)
    -Failures: 1 (HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Last USER command in Dockerfile should not be 'root'
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -Dockerfile:3
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -3 [ USER root
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -

    In the above example, Trivy detected vulnerabilities of Python dependencies and misconfigurations in Dockerfile.

    -

    Type detection

    -

    The specified directory can contain mixed types of IaC files. -Trivy automatically detects config types and applies relevant checks.

    -

    For example, the following example holds IaC files for Terraform, CloudFormation, Kubernetes, Helm Charts, and Dockerfile in the same directory.

    -
    $ ls iac/
    -Dockerfile  deployment.yaml  main.tf mysql-8.8.26.tar
    -$ trivy config --severity HIGH,CRITICAL ./iac
    -
    -
    -Result - -
    2022-06-06T11:01:21.142+0100    INFO    Detected config files: 8
    -
    -Dockerfile (dockerfile)
    -
    -Tests: 21 (SUCCESSES: 20, FAILURES: 1)
    -Failures: 1 (MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -deployment.yaml (kubernetes)
    -
    -Tests: 20 (SUCCESSES: 15, FAILURES: 5)
    -Failures: 5 (MEDIUM: 4, HIGH: 1, CRITICAL: 0)
    -
    -MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.allowPrivilegeEscalation' to false
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.
    -
    -See https://avd.aquasec.com/misconfig/ksv001
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:16-19
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  16        - name: hello-kubernetes
    -  17          image: hello-kubernetes:1.5
    -  18          ports:
    -  19          - containerPort: 8080
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -HIGH: Deployment 'hello-kubernetes' should not specify '/var/run/docker.socker' in 'spec.template.volumes.hostPath.path'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Mounting docker.sock from the host can give the container full root access to the host.
    -
    -See https://avd.aquasec.com/misconfig/ksv006
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:6-29
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   6    replicas: 3
    -   7    selector:
    -   8      matchLabels:
    -   9        app: hello-kubernetes
    -  10    template:
    -  11      metadata:
    -  12        labels:
    -  13          app: hello-kubernetes
    -  14      spec:
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.runAsNonRoot' to true
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.
    -
    -See https://avd.aquasec.com/misconfig/ksv012
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:16-19
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  16        - name: hello-kubernetes
    -  17          image: hello-kubernetes:1.5
    -  18          ports:
    -  19          - containerPort: 8080
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Deployment 'hello-kubernetes' should not set 'spec.template.volumes.hostPath'
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -HostPath volumes must be forbidden.
    -
    -See https://avd.aquasec.com/misconfig/ksv023
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:6-29
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   6    replicas: 3
    -   7    selector:
    -   8      matchLabels:
    -   9        app: hello-kubernetes
    -  10    template:
    -  11      metadata:
    -  12        labels:
    -  13          app: hello-kubernetes
    -  14      spec:
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Deployment 'hello-kubernetes' should set 'securityContext.sysctl' to the allowed values
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed 'safe' subset. A sysctl is considered safe if it is namespaced in the container or the Pod, and it is isolated from other Pods or processes on the same Node.
    -
    -See https://avd.aquasec.com/misconfig/ksv026
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - deployment.yaml:6-29
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   6    replicas: 3
    -   7    selector:
    -   8      matchLabels:
    -   9        app: hello-kubernetes
    -  10    template:
    -  11      metadata:
    -  12        labels:
    -  13          app: hello-kubernetes
    -  14      spec:
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -
    -mysql-8.8.26.tar:templates/primary/statefulset.yaml (helm)
    -
    -Tests: 20 (SUCCESSES: 18, FAILURES: 2)
    -Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0)
    -
    -MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.allowPrivilegeEscalation' to false
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.
    -
    -See https://avd.aquasec.com/misconfig/ksv001
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  56          - name: mysql
    -  57            image: docker.io/bitnami/mysql:8.0.28-debian-10-r23
    -  58            imagePullPolicy: "IfNotPresent"
    -  59            securityContext:
    -  60              runAsUser: 1001
    -  61            env:
    -  62              - name: BITNAMI_DEBUG
    -  63                value: "false"
    -  64              - name: MYSQL_ROOT_PASSWORD
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -MEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.runAsNonRoot' to true
    -═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.
    -
    -See https://avd.aquasec.com/misconfig/ksv012
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  56          - name: mysql
    -  57            image: docker.io/bitnami/mysql:8.0.28-debian-10-r23
    -  58            imagePullPolicy: "IfNotPresent"
    -  59            securityContext:
    -  60              runAsUser: 1001
    -  61            env:
    -  62              - name: BITNAMI_DEBUG
    -  63                value: "false"
    -  64              - name: MYSQL_ROOT_PASSWORD
    -  ..   
    -───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    - -
    - -

    You can see the config type next to each file name.

    -
    -

    Example

    -
    -
    Dockerfile (dockerfile)
    -=======================
    -Tests: 23 (SUCCESSES: 22, FAILURES: 1)
    -Failures: 1 (HIGH: 1, CRITICAL: 0)
    -
    -...
    -
    -deployment.yaml (kubernetes)
    -============================
    -Tests: 28 (SUCCESSES: 15, FAILURES: 13)
    -Failures: 13 (MEDIUM: 4, HIGH: 1, CRITICAL: 0)
    -
    -...
    -
    -main.tf (terraform)
    -===================
    -Tests: 23 (SUCCESSES: 14, FAILURES: 9)
    -Failures: 9 (HIGH: 6, CRITICAL: 1)
    -
    -...
    -
    -bucket.yaml (cloudformation)
    -============================
    -Tests: 9 (SUCCESSES: 3, FAILURES: 6)
    -Failures: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 4, CRITICAL: 0)
    -
    -...
    -
    -mysql-8.8.26.tar:templates/primary/statefulset.yaml (helm)
    -==========================================================
    -Tests: 20 (SUCCESSES: 18, FAILURES: 2)
    -Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0)
    -
    -

    Configuration

    -

    This section describes misconfiguration-specific configuration. -Other common options are documented here.

    -

    External connectivity

    -

    Trivy needs to connect to the internet to download the checks bundle. If you are running Trivy in an air-gapped environment, or an tightly controlled network, please refer to the Advanced Network Scenarios document.

    -

    Enabling a subset of misconfiguration scanners

    -

    It's possible to only enable certain misconfiguration scanners if you prefer. -You can do so by passing the --misconfig-scanners option. -This flag takes a comma-separated list of configuration scanner types.

    -
    trivy config --misconfig-scanners=terraform,dockerfile .
    -
    -

    Will only scan for misconfigurations that pertain to Terraform and Dockerfiles.

    -

    Loading custom checks

    -

    You can load check files or directories including your custom checks using the --config-check flag. -This can be repeated for specifying multiple files or directories.

    -
    trivy config --config-check custom-policy/policy --config-check combine/policy --config-check policy.rego --namespaces user myapp
    -
    -

    You can load checks bundle as OCI Image from a Container Registry using the --checks-bundle-repository flag.

    -
    trivy config --checks-bundle-repository myregistry.local/mychecks --namespaces user myapp
    -
    -

    Scan arbitrary JSON and YAML configurations

    -

    By default, scanning JSON and YAML configurations is disabled, since Trivy does not contain built-in checks for these configurations. To enable it, pass the json or yaml to --misconfig-scanners. See Enabling a subset of misconfiguration scanners for more information. Trivy will pass each file as is to the checks input.

    -
    -

    Example

    -
    -
    $ cat iac/serverless.yaml
    -service: serverless-rest-api-with-pynamodb
    -
    -frameworkVersion: ">=2.24.0"
    -
    -plugins:
    -  - serverless-python-requirements
    -...
    -
    -$ cat serverless.rego
    -# METADATA
    -# title: Serverless Framework service name not starting with "aws-"
    -# description: Ensure that Serverless Framework service names start with "aws-"
    -# schemas:
    -#   - input: schema["serverless-schema"]
    -# custom:
    -#   id: SF001
    -#   severity: LOW
    -package user.serverless001
    -
    -deny[res] {
    -    not startswith(input.service, "aws-")
    -    res := result.new(
    -        sprintf("Service name %q is not allowed", [input.service]),
    -        input.service
    -    )
    -}
    -
    -$ trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user ./iac
    -serverless.yaml (yaml)
    -
    -Tests: 4 (SUCCESSES: 3, FAILURES: 1)
    -Failures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -LOW: Service name "serverless-rest-api-with-pynamodb" is not allowed
    -═════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Ensure that Serverless Framework service names start with "aws-"
    -
    -
    -

    Note

    -

    In the case above, the custom check specified has a metadata annotation for the input schema input: schema["serverless-schema"]. This allows Trivy to type check the input IaC files provided.

    -
    -

    Optionally, you can also pass schemas using the config-file-schemas flag. Trivy will use these schemas for file filtering and type checking in Rego checks.

    -
    -

    Example

    -
    -
    $ trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user --config-file-schemas ./serverless-schema.json ./iac
    -
    -

    If the --config-file-schemas flag is specified Trivy ensures that each input IaC config file being scanned is type-checked against the schema. If the input file does not match any of the passed schemas, it will be ignored.

    -

    If the schema is specified in the check metadata and is in the directory specified in the --config-check argument, it will be automatically loaded as specified here, and will only be used for type checking in Rego.

    -
    -

    Note

    -

    If a user specifies the --config-file-schemas flag, all input IaC config files are ensured that they pass type-checking. It is not required to pass an input schema in case type checking is not required. This is helpful for scenarios where you simply want to write a Rego check and pass in IaC input for it. Such a use case could include scanning for a new service which Trivy might not support just yet.

    -
    -
    -

    Tip

    -

    It is also possible to specify multiple input schemas with --config-file-schema flag as it can accept a comma seperated list of file paths or a directory as input. In the case of multiple schemas being specified, all of them will be evaluated against all the input files.

    -
    -

    Passing custom data

    -

    You can pass directories including your custom data through --data option. -This can be repeated for specifying multiple directories.

    -
    cd examples/misconf/custom-data
    -trivy config --config-check ./my-check --data ./data --namespaces user ./configs
    -
    -

    For more details, see Custom Data.

    -

    Passing namespaces

    -

    By default, Trivy evaluates checks defined in builtin.*. -If you want to evaluate custom checks in other packages, you have to specify package prefixes through --namespaces option. -This can be repeated for specifying multiple packages.

    -
    trivy config --config-check ./my-check --namespaces main --namespaces user ./configs
    -
    -

    Private Terraform registries

    -

    Trivy can download Terraform code from private registries. -To pass credentials you must use the TF_TOKEN_ environment variables. -You cannot use a .terraformrc or terraform.rc file, these are not supported by trivy yet.

    -

    From the Terraform docs:

    -
    -

    Environment variable names should have the prefix TF_TOKEN_ added to the domain name, with periods encoded as underscores. -For example, the value of a variable named TF_TOKEN_app_terraform_io will be used as a bearer authorization token when the CLI makes service requests to the hostname app.terraform.io.

    -

    You must convert domain names containing non-ASCII characters to their punycode equivalent with an ACE prefix. -For example, token credentials for 例えば.com must be set in a variable called TF_TOKEN_xn--r8j3dr99h_com.

    -

    Hyphens are also valid within host names but usually invalid as variable names and may be encoded as double underscores. -For example, you can set a token for the domain name café.fr as TF_TOKEN_xn--caf-dma_fr or TF_TOKEN_xn_cafdmafr.

    -
    -

    If multiple variables evaluate to the same hostname, Trivy will choose the environment variable name where the dashes have not been encoded as double underscores.

    -

    Skipping resources by inline comments

    -

    Trivy supports ignoring misconfigured resources by inline comments for Terraform and CloudFormation configuration files only.

    -

    In cases where Trivy can detect comments of a specific format immediately adjacent to resource definitions, it is possible to ignore findings from a single source of resource definition (in contrast to .trivyignore, which has a directory-wide scope on all of the files scanned). The format for these comments is trivy:ignore:<rule> immediately following the format-specific line-comment token.

    -

    The ignore rule must contain one of the possible check IDs that can be found in its metadata: ID, short code or alias. The id from the metadata is not case-sensitive, so you can specify, for example, AVD-AWS-0089 or avd-aws-0089.

    -

    For example, to ignore a misconfiguration ID AVD-GCP-0051 in a Terraform HCL file:

    -
    #trivy:ignore:AVD-GCP-0051
    -resource "google_container_cluster" "example" {
    -  name     = var.cluster_name
    -  location = var.region
    -}
    -
    -

    You can add multiple ignores on the same comment line: -

    #trivy:ignore:AVD-GCP-0051 trivy:ignore:AVD-GCP-0053
    -resource "google_container_cluster" "example" {
    -  name     = var.cluster_name
    -  location = var.region
    -}
    -

    -

    You can also specify a long ID, which is formed as follows: <provider>-<service>-<short-code>.

    -

    As an example, consider the following check metadata:

    -
    # custom:
    -  # id: AVD-AWS-0089
    -  # avd_id: AVD-AWS-0089
    -  # provider: aws
    -  # service: s3
    -  # severity: LOW
    -  # short_code: enable-logging
    -
    -

    Long ID would look like the following: aws-s3-enable-logging.

    -

    Example for CloudFromation: -

    AWSTemplateFormatVersion: "2010-09-09"
    -Resources:
    -#trivy:ignore:*
    -  S3Bucket:
    -    Type: 'AWS::S3::Bucket'
    -    Properties:
    -      BucketName: test-bucket
    -

    -

    Expiration Date

    -

    You can specify the expiration date of the ignore rule in yyyy-mm-dd format. This is a useful feature when you want to make sure that an ignored issue is not forgotten and worth revisiting in the future. For example: -

    #trivy:ignore:aws-s3-enable-logging:exp:2024-03-10
    -resource "aws_s3_bucket" "example" {
    -  bucket = "test"
    -}
    -

    -

    The aws-s3-enable-logging check will be ignored until 2024-03-10 until the ignore rule expires.

    -

    Ignoring by attributes

    -

    You can ignore a resource by its attribute value. This is useful when using the for-each meta-argument. For example:

    -
    locals {
    -  ports = ["3306", "5432"]
    -}
    -
    -#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=3306]
    -resource "aws_security_group_rule" "example" {
    -  for_each                 = toset(local.ports)
    -  type                     = "ingress"
    -  from_port                = each.key
    -  to_port                  = each.key
    -  protocol                 = "TCP"
    -  cidr_blocks              = ["0.0.0.0/0"]
    -  security_group_id        = aws_security_group.example.id
    -  source_security_group_id = aws_security_group.example.id
    -}
    -
    -

    The aws-ec2-no-public-ingress-sgr check will be ignored only for the aws_security_group_rule resource with port number 5432. It is important to note that the ignore rule should not enclose the attribute value in quotes, despite the fact that the port is represented as a string.

    -

    If you want to ignore multiple resources on different attributes, you can specify multiple ignore rules:

    -
    #trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=3306]
    -#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=5432]
    -
    -

    You can also ignore a resource on multiple attributes in the same rule: -

    locals {
    -  rules = {
    -    first = {
    -      port = 1000
    -      type = "ingress"
    -    },
    -    second = {
    -      port = 1000
    -      type = "egress"
    -    }
    -  }
    -}
    -
    -#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=1000,type=egress]
    -resource "aws_security_group_rule" "example" {
    -  for_each = { for k, v in local.rules : k => v }
    -
    -  type                     = each.value.type
    -  from_port                = each.value.port
    -  to_port                  = each.value.port
    -  protocol                 = "TCP"
    -  cidr_blocks              = ["0.0.0.0/0"]
    -  security_group_id        = aws_security_group.example.id
    -  source_security_group_id = aws_security_group.example.id
    -}
    -

    -

    Checks can also be ignored by nested attributes:

    -
    #trivy:ignore:*[logging_config.prefix=myprefix]
    -resource "aws_cloudfront_distribution" "example" {
    -  logging_config {
    -    include_cookies = false
    -    bucket          = "mylogs.s3.amazonaws.com"
    -    prefix          = "myprefix"
    -  }
    -}
    -
    -

    Ignoring module issues

    -

    Issues in third-party modules cannot be ignored using the method described above, because you may not have access to modify the module source code. In such a situation you can add ignore rules above the module block, for example:

    -
    #trivy:ignore:aws-s3-enable-logging
    -module "s3_bucket" {
    -  source = "terraform-aws-modules/s3-bucket/aws"
    -
    -  bucket = "my-s3-bucket"
    -}
    -
    -

    An example of ignoring checks for a specific bucket in a module: -

    locals {
    -  bucket = ["test1", "test2"]
    -}
    -
    -#trivy:ignore:*[bucket=test1]
    -module "s3_bucket" {
    -  for_each = toset(local.bucket)
    -  source   = "terraform-aws-modules/s3-bucket/aws"
    -  bucket   = each.value
    -}
    -

    -

    Support for Wildcards

    -

    You can use wildcards in the ws (workspace) and ignore sections of the ignore rules.

    -
    # trivy:ignore:aws-s3-*:ws:dev-*
    -
    -

    This example ignores all checks starting with aws-s3- for workspaces matching the pattern dev-*.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/secret/index.html b/v0.58.0/docs/scanner/secret/index.html deleted file mode 100644 index bc057873e41d..000000000000 --- a/v0.58.0/docs/scanner/secret/index.html +++ /dev/null @@ -1,8394 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Secret - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    - -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Secret Scanning

    -

    Trivy scans any container image, filesystem and git repository to detect exposed secrets like passwords, api keys, and tokens. -Secret scanning is enabled by default.

    -

    Trivy will scan every plaintext file, according to builtin rules or configuration. Also, Trivy can detect secrets in compiled Python files (.pyc).

    -

    There are plenty of builtin rules:

    -
      -
    • AWS access key
    • -
    • GCP service account
    • -
    • GitHub personal access token
    • -
    • GitLab personal access token
    • -
    • Slack access token
    • -
    • etc.
    • -
    -

    You can see a full list of built-in rules and built-in allow rules.

    -
    -

    Tip

    -

    If your secret is not detected properly, please make sure that your file including the secret is not in the allowed paths. -You can disable allow rules via disable-allow-rules.

    -
    -

    Quick start

    -

    This section shows how to scan secrets in container image and filesystem. Other subcommands should be the same.

    -

    Container image

    -

    Specify an image name.

    -
    $ trivy image myimage:1.0.0
    -2022-04-21T18:56:44.099+0300    INFO    Detected OS: alpine
    -2022-04-21T18:56:44.099+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-04-21T18:56:44.101+0300    INFO    Number of language-specific files: 0
    -
    -myimage:1.0.0 (alpine 3.15.0)
    -=============================
    -Total: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| busybox      | CVE-2022-28391   | CRITICAL | 1.34.1-r3         | 1.34.1-r5     | CVE-2022-28391 affecting              |
    -|              |                  |          |                   |               | package busybox 1.35.0                |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-28391 |
    -+--------------+------------------|          |-------------------+---------------+---------------------------------------+
    -| ssl_client   | CVE-2022-28391   |          | 1.34.1-r3         | 1.34.1-r5     | CVE-2022-28391 affecting              |
    -|              |                  |          |                   |               | package busybox 1.35.0                |
    -|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-28391 |
    -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
    -
    -app/secret.sh (secrets)
    -=======================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
    -
    -+----------+-------------------+----------+---------+--------------------------------+
    -| CATEGORY |    DESCRIPTION    | SEVERITY | LINE NO |             MATCH              |
    -+----------+-------------------+----------+---------+--------------------------------+
    -|   AWS    | AWS Access Key ID | CRITICAL |   10    | export AWS_ACCESS_KEY_ID=***** |
    -+----------+-------------------+----------+---------+--------------------------------+
    -
    -
    -

    Tip

    -

    Trivy tries to detect a base image and skip those layers for secret scanning. -A base image usually contains a lot of files and makes secret scanning much slower. -If a secret is not detected properly, you can see base layers with the --debug flag.

    -
    -

    Filesystem

    -
    $ trivy fs /path/to/your_project
    -...(snip)...
    -
    -certs/key.pem (secrets)
    -========================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -+----------------------+------------------------+----------+---------+---------------------------------+
    -|       CATEGORY       |      DESCRIPTION       | SEVERITY | LINE NO |              MATCH              |
    -+----------------------+------------------------+----------+---------+---------------------------------+
    -| AsymmetricPrivateKey | Asymmetric Private Key |   HIGH   |    1    | -----BEGIN RSA PRIVATE KEY----- |
    -+----------------------+------------------------+----------+---------+---------------------------------+
    -
    -
    -

    Tip

    -

    Your project may have some secrets for testing. You can skip them with --skip-dirs or --skip-files. -We would recommend specifying these options so that the secret scanning can be faster if those files don't need to be scanned. -Also, you can specify paths to be allowed in a configuration file. See the detail here.

    -
    -

    Configuration

    -

    This section describes secret-specific configuration. -Other common options are documented here.

    -

    Trivy has a set of builtin rules for secret scanning, which can be extended or modified by a configuration file. -Trivy tries to load trivy-secret.yaml in the current directory by default. -If the file doesn't exist, only built-in rules are used. -You can customize the config file path via the --secret-config flag.

    -
    -

    Warning

    -

    Trivy uses Golang regexp package. To use ^ and $ as symbols of begin and end of line use multi-line mode -(?m).

    -
    -

    Custom Rules

    -

    Trivy allows defining custom rules.

    -
    rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    path: .*\.sh
    -    keywords:
    -      - secret
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -    secret-group-name: secret
    -    allow-rules:
    -      - id: skip-text
    -        description: skip text files
    -        path: .*\.txt
    -
    -
    -
    id (required)
    -
    -
      -
    • Unique identifier for this rule.
    • -
    -
    -
    category (required)
    -
    -
      -
    • String used for metadata and reporting purposes.
    • -
    -
    -
    title (required)
    -
    -
      -
    • Short human-readable title of the rule.
    • -
    -
    -
    severity (required)
    -
    -
      -
    • How critical this rule is.
    • -
    • Allowed values:
    • -
    • CRITICAL
    • -
    • HIGH
    • -
    • MEDIUM
    • -
    • LOW
    • -
    -
    -
    regex (required)
    -
    -
      -
    • Golang regular expression used to detect secrets.
    • -
    -
    -
    path (optional)
    -
    -
      -
    • Golang regular expression used to match paths.
    • -
    -
    -
    keywords (optional, recommended)
    -
    -
      -
    • Keywords are used for pre-regex check filtering.
    • -
    • Rules that contain keywords will perform a quick string compare check to make sure the keyword(s) are in the content being scanned.
    • -
    • Ideally these values should either be part of the identifier or unique strings specific to the rule's regex.
    • -
    • It is recommended to define for better performance.
    • -
    -
    -
    allow-rules (optional)
    -
    -
      -
    • Allow rules for a single rule to reduce false positives with known secrets.
    • -
    • The details are below.
    • -
    -
    -
    -

    Allow Rules

    -

    If the detected secret is matched with the specified regex, then that secret will be skipped and not detected. -The same logic applies for path.

    -

    allow-rules can be defined globally and per each rule. The fields are the same.

    -
    rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -    allow-rules:
    -      - id: skip-text
    -        description: skip text files
    -        path: .*\.txt
    -allow-rules:
    -  - id: social-security-number
    -    description: skip social security number
    -    regex: 219-09-9999
    -
    -
    -
    id (required)
    -
    -
      -
    • Unique identifier for this allow rule.
    • -
    -
    -
    description (optional)
    -
    -
      -
    • Short human-readable description of this allow rule.
    • -
    -
    -
    regex (optional)
    -
    -
      -
    • Golang regular expression used to allow detected secrets.
    • -
    • regex or path must be specified.
    • -
    -
    -
    path (optional)
    -
    -
      -
    • Golang regular expression used to allow matched paths.
    • -
    • regex or path must be specified.
    • -
    -
    -
    -

    Enable Rules

    -

    Trivy provides plenty of out-of-box rules and allow rules, but you may not need all of them. -In that case, enable-builtin-rules will be helpful. -If you just need AWS secret detection, you can enable only relevant rules as shown below. -It specifies AWS-related rule IDs in enable-builtin-rules. -All other rules are disabled, so the scanning will be much faster. -We would strongly recommend using this option if you don't need all rules.

    -

    You can see a full list of built-in rule IDs and built-in allow rule IDs.

    -
    enable-builtin-rules:
    -  - aws-access-key-id
    -  - aws-account-id
    -  - aws-secret-access-key
    -
    -

    Disable Rules

    -

    Trivy offers built-in rules and allow rules, but you may want to disable some of them. -For example, you don't use Slack, so Slack doesn't have to be scanned. -You can specify the Slack rule IDs, slack-access-token and slack-web-hook in disable-rules so that those rules will be disabled for less false positives.

    -

    You should specify either enable-builtin-rules or disable-rules. -If they both are specified, disable-rules takes precedence. -In case github-pat is specified in enable-builtin-rules and disable-rules, it will be disabled.

    -

    In addition, there are some allow rules. -Markdown files are ignored by default, but you may want to scan markdown files as well. -You can disable the allow rule by adding markdown to disable-allow-rules.

    -

    You can see a full list of built-in rule IDs and built-in allow rule IDs.

    -
    disable-rules:
    -  - slack-access-token
    -  - slack-web-hook
    -disable-allow-rules:
    -  - markdown
    -
    -

    Recommendation

    -

    We would recommend specifying --skip-dirs for faster secret scanning. -In container image scanning, Trivy walks the file tree rooted / and scans all the files other than built-in allowed paths. -It will take a while if your image contains a lot of files even though Trivy tries to avoid scanning layers from a base image. -If you want to make scanning faster, --skip-dirs and --skip-files helps so that Trivy will skip scanning those files and directories. -You can see more options here.

    -

    allow-rules is also helpful. See the allow-rules section.

    -

    In addition, all the built-in rules are enabled by default, so it takes some time to scan all of them. -If you don't need all those rules, you can use enable-builtin-rules or disable-rules in the configuration file. -You should use enable-builtin-rules if you need only AWS secret detection, for example. -All rules are disabled except for the ones you specify, so it runs very fast. -On the other hand, you should use disable-rules if you just want to disable some built-in rules. -See the enable-rules and disable-rules sections for the detail.

    -

    If you don't need secret scanning, you can disable it via the --scanners flag.

    -
    $ trivy image --scanners vuln alpine:3.15
    -
    -

    Example

    -

    trivy-secret.yaml in the working directory is loaded by default.

    -
    $ cat trivy-secret.yaml
    -rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -allow-rules:
    -  - id: social-security-number
    -    description: skip social security number
    -    regex: 219-09-9999
    -  - id: log-dir
    -    description: skip log directory
    -    path: ^\/var\/log\/
    -disable-rules:
    -  - slack-access-token
    -  - slack-web-hook
    -disable-allow-rules:
    -  - markdown
    -
    -# The following command automatically loads the above configuration.
    -$ trivy image YOUR_IMAGE
    -
    -

    Also, you can customize the config file path via --secret-config.

    -
    $ cat ./secret-config/trivy.yaml
    -rules:
    -  - id: rule1
    -    category: general
    -    title: Generic Rule
    -    severity: HIGH
    -    regex: (?i)(?P<key>(secret))(=|:).{0,5}['"](?P<secret>[0-9a-zA-Z\-_=]{8,64})['"]
    -    allow-rules:
    -      - id: skip-text
    -        description: skip text files
    -        path: .*\.txt
    -enable-builtin-rules:
    -  - aws-access-key-id
    -  - aws-account-id
    -  - aws-secret-access-key
    -disable-allow-rules:
    -  - usr-dirs
    -
    -# Pass the above config with `--secret-config`.
    -$ trivy fs --secret-config ./secret-config/trivy.yaml /path/to/your_project
    -
    -

    Credit

    -

    This feature is inspired by gitleaks.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/scanner/vulnerability/index.html b/v0.58.0/docs/scanner/vulnerability/index.html deleted file mode 100644 index 1539b5777b56..000000000000 --- a/v0.58.0/docs/scanner/vulnerability/index.html +++ /dev/null @@ -1,8815 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Vulnerability - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Vulnerability Scanning

    -

    Trivy detects known vulnerabilities in software components that it finds in the scan target.

    -

    The following are supported:

    - -

    OS Packages

    -

    Trivy is capable of automatically detecting installed OS packages when scanning container images, VM images and running hosts.

    -
    -

    Note

    -

    Trivy doesn't support third-party/self-compiled packages/binaries, but official packages provided by vendors such as Red Hat and Debian.

    -
    -

    Supported OS

    -

    See here for the supported OSes.

    -

    Data Sources

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OSSource
    Arch LinuxVulnerable Issues
    Alpine Linuxsecdb
    Wolfi Linuxsecdb
    Chainguardsecdb
    Amazon LinuxAmazon Linux Security Center
    DebianSecurity Bug Tracker / OVAL
    UbuntuUbuntu CVE Tracker
    RHEL/CentOSOVAL / Security Data
    AlmaLinuxAlmaLinux Product Errata
    Rocky LinuxRocky Linux UpdateInfo
    Oracle LinuxOVAL
    Azure Linux (CBL-Mariner)OVAL
    OpenSUSE/SLESCVRF
    Photon OSPhoton Security Advisory
    -

    Data Source Selection

    -

    Trivy only consumes security advisories from the sources listed in the above table.

    -

    As for packages installed from OS package managers (dpkg, yum, apk, etc.), Trivy uses the advisory database from the appropriate OS vendor.

    -

    For example: for a python package installed from yum (Amazon linux), Trivy will only get advisories from ALAS. -But for a python package installed from another source (e.g. pip), Trivy will get advisories from the GitLab and GitHub databases.

    -

    This advisory selection is essential to avoid getting false positives because OS vendors usually backport upstream fixes, and the fixed version can be different from the upstream fixed version.

    -

    Severity Selection

    -

    The severity is taken from the selected data source since the severity from vendors is more accurate. -Using CVE-2023-0464 as an example, while it is rated as "HIGH" in NVD, Red Hat has marked its 'Impact' as "Low". -As a result, Trivy will display it as "Low".

    -

    The severity depends on the compile option, the default configuration, etc. -NVD doesn't know how the vendor distributes the software. -Red Hat evaluates the severity more accurately. -That's why Trivy prefers vendor scores over NVD.

    -

    If the data source does not provide a severity, the severity is determined based on the CVSS score as follows:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Base Score RangeSeverity
    0.1-3.9Low
    4.0-6.9Medium
    7.0-8.9High
    9.0-10.0Critical
    -

    If the CVSS score is also not provided, it falls back to NVD.

    -

    NVD and some vendors may delay severity analysis, while other vendors, such as Red Hat, are able to quickly evaluate and announce the severity of vulnerabilities. -To avoid marking too many vulnerabilities as "UNKNOWN" severity, Trivy uses severity ratings from other vendors when the NVD information is not yet available. -The order of preference for vendor severity data can be found here.

    -

    You can reference SeveritySource in the JSON reporting format to see from where the severity is taken for a given vulnerability.

    -
    "SeveritySource": "debian",
    -
    -

    In addition, you can see all the vendor severity ratings.

    -
    "VendorSeverity": {
    -  "amazon": 2,
    -  "cbl-mariner": 4,
    -  "ghsa": 4,
    -  "nvd": 4,
    -  "photon": 4,
    -  "redhat": 2,
    -  "ubuntu": 2
    -}
    -
    -

    Here is the severity mapping in Trivy:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NumberSeverity
    0Unknown
    1Low
    2Medium
    3High
    4Critical
    -

    If no vendor has a severity, the UNKNOWN severity will be used.

    -

    Unfixed Vulnerabilities

    -

    The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution. -To hide unfixed/unfixable vulnerabilities, you can use the --ignore-unfixed flag.

    -

    Language-specific Packages

    -

    Supported Languages

    -

    See here for the supported languages.

    -

    Data Sources

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LanguageSourceCommercial UseDelay1
    PHPPHP Security Advisories Database-
    GitHub Advisory Database (Composer)-
    PythonGitHub Advisory Database (pip)-
    Open Source Vulnerabilities (PyPI)-
    RubyRuby Advisory Database-
    GitHub Advisory Database (RubyGems)-
    Node.jsEcosystem Security Working Group-
    GitHub Advisory Database (npm)-
    JavaGitHub Advisory Database (Maven)-
    GoGitHub Advisory Database (Go)-
    Go Vulnerability Database-
    RustOpen Source Vulnerabilities (crates.io)-
    .NETGitHub Advisory Database (NuGet)-
    C/C++GitLab Advisories Community1 month
    DartGitHub Advisory Database (Pub)-
    ElixirGitHub Advisory Database (Erlang)-
    SwiftGitHub Advisory Database (Swift)-
    -

    Non-packaged software

    -

    If you have software that is not managed by a package manager, Trivy can still detect vulnerabilities in it in some cases:

    - -

    Kubernetes

    -

    Trivy can detect vulnerabilities in Kubernetes clusters and components by scanning a Kubernetes Cluster, or a KBOM (Kubernetes bill of Material). To learn more, see the documentation for Kubernetes scanning.

    -

    Data Sources

    - - - - - - - - - - - - - -
    VendorSource
    KubernetesKubernetes Official CVE feed1
    -

    Databases

    -

    The information from the above sources is collected and stored in databases that Trivy uses for vulnerability scanning. Trivy automatically fetches, maintains, and caches the relevant databases when performing a vulnerability scan -For more information about Trivy's Databases mechanism and configurations, refer to the Databases document.

    -

    Detection Behavior

    -

    Trivy prioritizes precision in vulnerability detection, aiming to minimize false positives while potentially accepting some false negatives. -This approach is particularly relevant in two key areas:

    -
      -
    • Handling Software Installed via OS Packages
    • -
    • Handling Packages with Unspecified Versions
    • -
    -

    Handling Software Installed via OS Packages

    -

    For files installed by OS package managers, such as apt, Trivy exclusively uses advisories from the OS vendor. -This means that even if a JAR file is present in a container image, if it was installed via an OS package manager (e.g., apt), Trivy will not analyze the JAR file itself and use upstream security advisories.

    -

    For example, consider the Python requests package in Red Hat Universal Base Image 8:

    -
    [root@987ee49dc93d /]# head -n 3 /usr/lib/python3.6/site-packages/requests-2.20.0-py3.6.egg-info/PKG-INFO
    -Metadata-Version: 2.1
    -Name: requests
    -Version: 2.20.0
    -
    -

    Version 2.20.0 is installed, and this package is installed by dnf.

    -
    [root@987ee49dc93d /]# rpm -ql python3-requests | grep PKG-INFO
    -/usr/lib/python3.6/site-packages/requests-2.20.0-py3.6.egg-info/PKG-INFO
    -
    -

    At first glance, this might seem vulnerable to CVE-2023-32681, which affects versions of requests prior to v2.31.0. -However, Red Hat backported the fix to v2.20.0-3 in RHSA-2023:4520, and the package is not vulnerable.

    -
      -
    • Upstream (PyPI requests): Fixed in v2.31.0
    • -
    • Red Hat (python-requests): Backported fix applied in v2.20.0-3 (RHSA-2023:4520)
    • -
    -

    If Trivy were to detect CVE-2023-32681 in this case, it would be a false positive. -This illustrates why using the correct security advisory is crucial to avoid false detections. -To minimize false positives, Trivy trusts the OS vendor's advisory for software installed via OS package managers and does not use upstream advisories for these packages.

    -

    However, this approach may lead to false negatives if the OS vendor's advisories are delayed or missing. -In such cases, using --detection-priority comprehensive allows Trivy to consider upstream advisories (e.g., GitHub Advisory Database), potentially increasing false positives but reducing false negatives.

    -

    Handling Packages with Unspecified Versions

    -

    When a package version cannot be uniquely determined (e.g., package-a: ">=3.0"), Trivy typically skips vulnerability detection for that package to avoid false positives. -If a lock file is present with fixed versions, Trivy will use those for detection.

    -

    To detect potential vulnerabilities even with unspecified versions, use --detection-priority comprehensive. -This option makes Trivy use the minimum version in the specified range for vulnerability detection. -While this may increase false positives if the actual version used is not the minimum, it helps reduce false negatives.

    -

    Configuration

    -

    This section describes vulnerability-specific configuration. -Other common options are documented here.

    -

    Enabling a Subset of Package Types

    -

    It's possible to only enable certain package types if you prefer. -You can do so by passing the --pkg-types option. -This flag takes a comma-separated list of package types.

    -

    Available values:

    -
      -
    • os
        -
      • Scan OS packages managed by the OS package manager (e.g. dpkg, yum, apk).
      • -
      -
    • -
    • library
        -
      • Scan language-specific packages (e.g. packages installed by pip, npm, or gem).
      • -
      -
    • -
    -
    $ trivy image --pkg-types os ruby:2.4.0
    -
    -
    -Result - -
    2019-05-22T19:36:50.530+0200    INFO    Updating vulnerability database...
    -2019-05-22T19:36:51.681+0200    INFO    Detecting Alpine vulnerabilities...
    -2019-05-22T19:36:51.685+0200    INFO    Updating npm Security DB...
    -2019-05-22T19:36:52.389+0200    INFO    Detecting npm vulnerabilities...
    -2019-05-22T19:36:52.390+0200    INFO    Updating pipenv Security DB...
    -2019-05-22T19:36:53.406+0200    INFO    Detecting pipenv vulnerabilities...
    -
    -ruby:2.4.0 (debian 8.7)
    -=======================
    -Total: 7 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 3, CRITICAL: 2)
    -
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |              TITLE               |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| curl    | CVE-2018-14618   | CRITICAL | 7.61.0-r0         | 7.61.1-r0     | curl: NTLM password overflow     |
    -|         |                  |          |                   |               | via integer overflow             |
    -+         +------------------+----------+                   +---------------+----------------------------------+
    -|         | CVE-2018-16839   | HIGH     |                   | 7.61.1-r1     | curl: Integer overflow leading   |
    -|         |                  |          |                   |               | to heap-based buffer overflow in |
    -|         |                  |          |                   |               | Curl_sasl_create_plain_message() |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| git     | CVE-2018-17456   | HIGH     | 2.15.2-r0         | 2.15.3-r0     | git: arbitrary code execution    |
    -|         |                  |          |                   |               | via .gitmodules                  |
    -+         +------------------+          +                   +               +----------------------------------+
    -|         | CVE-2018-19486   |          |                   |               | git: Improper handling of        |
    -|         |                  |          |                   |               | PATH allows for commands to be   |
    -|         |                  |          |                   |               | executed from...                 |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| libssh2 | CVE-2019-3855    | CRITICAL | 1.8.0-r2          | 1.8.1-r0      | libssh2: Integer overflow in     |
    -|         |                  |          |                   |               | transport read resulting in      |
    -|         |                  |          |                   |               | out of bounds write...           |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| sqlite  | CVE-2018-20346   | MEDIUM   | 3.21.0-r1         | 3.25.3-r0     | CVE-2018-20505 CVE-2018-20506    |
    -|         |                  |          |                   |               | sqlite: Multiple flaws in        |
    -|         |                  |          |                   |               | sqlite which can be triggered    |
    -|         |                  |          |                   |               | via...                           |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -| tar     | CVE-2018-20482   | LOW      | 1.29-r1           | 1.31-r0       | tar: Infinite read loop in       |
    -|         |                  |          |                   |               | sparse_dump_region function in   |
    -|         |                  |          |                   |               | sparse.c                         |
    -+---------+------------------+----------+-------------------+---------------+----------------------------------+
    -
    - -
    - -
    -

    Info

    -

    This flag filters the packages themselves, so it also affects the --list-all-pkgs option and SBOM generation.

    -
    -

    Filtering by Package Relationships

    -

    Trivy supports filtering vulnerabilities based on the relationship of packages within a project. -This is achieved through the --pkg-relationships flag. -This feature allows you to focus on vulnerabilities in specific types of dependencies, such as only those in direct dependencies.

    -

    In Trivy, there are four types of package relationships:

    -
      -
    1. root: The root package being scanned
    2. -
    3. direct: Direct dependencies of the root package
    4. -
    5. indirect: Transitive dependencies
    6. -
    7. unknown: Packages whose relationship cannot be determined
    8. -
    -

    The available relationships may vary depending on the ecosystem. -To see which relationships are supported for a particular project, you can use the JSON output format and check the Relationship field:

    -
    $ trivy repo -f json --list-all-pkgs /path/to/project
    -
    -

    To scan only the root package and its direct dependencies, you can use the flag as follows:

    -
    $ trivy repo --pkg-relationships root,direct /path/to/project
    -
    -

    By default, all relationships are included in the scan.

    -
    -

    Info

    -

    This flag filters the packages themselves, so it also affects the --list-all-pkgs option and SBOM generation.

    -
    -
    -

    Warning

    -

    As it may not provide a complete package list, --pkg-relationships cannot be used with --dependency-tree, --vex or SBOM generation.

    -
    -

    Detection Priority

    -

    Trivy provides a --detection-priority flag to control the balance between false positives and false negatives in vulnerability detection. -This concept is similar to the relationship between precision and recall in machine learning evaluation.

    -
    $ trivy image --detection-priority {precise|comprehensive} alpine:3.15
    -
    -
      -
    • precise: This mode prioritizes reducing false positives. It results in less noisy vulnerability reports but may miss some potential vulnerabilities.
    • -
    • comprehensive: This mode aims to detect more vulnerabilities, potentially including some that might be false positives. - It provides broader coverage but may increase the noise in the results.
    • -
    -

    The default value is precise. Also refer to the detection behavior section for more information.

    -

    Regardless of the chosen mode, user review of detected vulnerabilities is crucial:

    -
      -
    • precise: Review thoroughly, considering potential missed vulnerabilities.
    • -
    • comprehensive: Carefully investigate each reported vulnerability due to increased false positive possibility.
    • -
    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/attestation/rekor/index.html b/v0.58.0/docs/supply-chain/attestation/rekor/index.html deleted file mode 100644 index d444fc1b48c1..000000000000 --- a/v0.58.0/docs/supply-chain/attestation/rekor/index.html +++ /dev/null @@ -1,8104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SBOM Attestation in Rekor - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Scan SBOM attestation in Rekor

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Container images

    -

    Trivy can retrieve SBOM attestation of the specified container image in the Rekor instance and scan it for vulnerabilities.

    -

    Prerequisites

    -
      -
    1. SBOM attestation stored in Rekor -
    2. -
    -

    Scanning

    -

    You need to pass --sbom-sources rekor so that Trivy will look for SBOM attestation in Rekor.

    -
    -

    Note

    -

    --sbom-sources can be used only with trivy image at the moment.

    -
    -
    $ trivy image --sbom-sources rekor otms61/alpine:3.7.3                                                                            [~/src/github.com/aquasecurity/trivy]
    -2022-09-16T17:37:13.258+0900    INFO    Vulnerability scanning is enabled
    -2022-09-16T17:37:13.258+0900    INFO    Secret scanning is enabled
    -2022-09-16T17:37:13.258+0900    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
    -2022-09-16T17:37:13.258+0900    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection
    -2022-09-16T17:37:14.827+0900    INFO    Detected SBOM format: cyclonedx-json
    -2022-09-16T17:37:14.901+0900    INFO    Found SBOM (cyclonedx) attestation in Rekor
    -2022-09-16T17:37:14.903+0900    INFO    Detected OS: alpine
    -2022-09-16T17:37:14.903+0900    INFO    Detecting Alpine vulnerabilities...
    -2022-09-16T17:37:14.907+0900    INFO    Number of language-specific files: 0
    -2022-09-16T17:37:14.908+0900    WARN    This OS version is no longer supported by the distribution: alpine 3.7.3
    -2022-09-16T17:37:14.908+0900    WARN    The vulnerability detection may be insufficient because security updates are not provided
    -
    -otms61/alpine:3.7.3 (alpine 3.7.3)
    -==================================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────┐
    -│  Library    Vulnerability   Severity  Installed Version  Fixed Version                           Title                           │
    -├────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────┤
    -│ musl        CVE-2019-14697  CRITICAL  1.1.18-r3          1.1.18-r4      musl libc through 1.1.23 has an x87 floating-point stack │
    -│                                                                         adjustment im ......                                     │
    -│                                                                         https://avd.aquasec.com/nvd/cve-2019-14697               │
    -├────────────┤                                                                                                                      │
    -│ musl-utils                                                                                                                       │
    -│                                                                                                                                  │
    -│                                                                                                                                  │
    -└────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────┘
    -
    -

    If you have your own Rekor instance, you can specify the URL via --rekor-url.

    -
    $ trivy image --sbom-sources rekor --rekor-url https://my-rekor.dev otms61/alpine:3.7.3
    -
    -

    Non-packaged binaries

    -

    Trivy can retrieve SBOM attestation of non-packaged binaries in the Rekor instance and scan it for vulnerabilities.

    -

    Prerequisites

    -
      -
    1. SBOM attestation stored in Rekor -
    2. -
    -

    Cosign currently does not support keyless signing for blob attestation, so use our plugin at the moment. -This example uses a cat clone bat written in Rust. -You need to generate SBOM from lock files like Cargo.lock at first.

    -
    $ git clone -b v0.20.0 https://github.com/sharkdp/bat
    -$ trivy fs --format cyclonedx --output bat.cdx ./bat/Cargo.lock
    -
    -

    Then our attestation plugin allows you to store the SBOM attestation linking to a bat binary in the Rekor instance.

    -
    $ wget https://github.com/sharkdp/bat/releases/download/v0.20.0/bat-v0.20.0-x86_64-apple-darwin.tar.gz
    -$ tar xvf bat-v0.20.0-x86_64-apple-darwin.tar.gz
    -$ trivy plugin install github.com/aquasecurity/trivy-plugin-attest
    -$ trivy attest --predicate ./bat.cdx --type cyclonedx ./bat-v0.20.0-x86_64-apple-darwin/bat
    -
    -
    -

    Note

    -

    The public instance of the Rekor maintained by the Sigstore team limits the attestation size. -If you are using the public instance, please make sure that your SBOM is small enough. -To get more detail, please refer to the Rekor project's documentation.

    -
    -

    Scan a non-packaged binary

    -

    Trivy calculates the digest of the bat binary and searches for the SBOM attestation by the digest in Rekor. -If it is found, Trivy uses that for vulnerability scanning.

    -
    $ trivy fs --sbom-sources rekor ./bat-v0.20.0-x86_64-apple-darwin/bat
    -2022-10-25T13:27:25.950+0300    INFO    Found SBOM attestation in Rekor: bat
    -2022-10-25T13:27:25.993+0300    INFO    Number of language-specific files: 1
    -2022-10-25T13:27:25.993+0300    INFO    Detecting cargo vulnerabilities...
    -
    -bat (cargo)
    -===========
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -┌───────────┬───────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│  Library     Vulnerability    Severity  Installed Version  Fixed Version                            Title                            │
    -├───────────┼───────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ regex      CVE-2022-24713     HIGH      1.5.4              1.5.5          Mozilla: Denial of Service via complex regular expressions │
    -│                                                                           https://avd.aquasec.com/nvd/cve-2022-24713                 │
    -└───────────┴───────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -

    Also, it is applied to non-packaged binaries even in container images.

    -
    $ trivy image --sbom-sources rekor --scanners vuln alpine-with-bat
    -2022-10-25T13:40:14.920+0300    INFO    Vulnerability scanning is enabled
    -2022-10-25T13:40:18.047+0300    INFO    Found SBOM attestation in Rekor: bat
    -2022-10-25T13:40:18.186+0300    INFO    Detected OS: alpine
    -2022-10-25T13:40:18.186+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-10-25T13:40:18.199+0300    INFO    Number of language-specific files: 1
    -2022-10-25T13:40:18.199+0300    INFO    Detecting cargo vulnerabilities...
    -
    -alpine-with-bat (alpine 3.15.6)
    -===============================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -
    -bat (cargo)
    -===========
    -Total: 4 (UNKNOWN: 3, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -┌───────────┬───────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│  Library     Vulnerability    Severity  Installed Version  Fixed Version                            Title                            │
    -├───────────┼───────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ regex      CVE-2022-24713     HIGH      1.5.4              1.5.5          Mozilla: Denial of Service via complex regular expressions │
    -│                                                                           https://avd.aquasec.com/nvd/cve-2022-24713                 │
    -└───────────┴───────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -
    -

    Note

    -

    The --sbom-sources rekor flag slows down the scanning as it queries Rekor on the Internet for all non-packaged binaries.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/attestation/sbom/index.html b/v0.58.0/docs/supply-chain/attestation/sbom/index.html deleted file mode 100644 index de3dbff3d8fb..000000000000 --- a/v0.58.0/docs/supply-chain/attestation/sbom/index.html +++ /dev/null @@ -1,7950 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    SBOM attestation

    -

    Cosign supports generating and verifying in-toto attestations. This tool enables you to sign and verify SBOM attestation. -And, Trivy can take an SBOM attestation as input and scan for vulnerabilities

    -
    -

    Note

    -

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. -If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    -
    -

    Sign with a local key pair

    -

    Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs.

    -
    $ cosign generate-key-pair
    -
    -

    In the following example, Trivy generates an SBOM in the CycloneDX format, and then Cosign attaches an attestation of the SBOM to a container image with a local key pair.

    -
    # The cyclonedx type is supported in Cosign v1.10.0 or later.
    -$ trivy image --format cyclonedx -o sbom.cdx.json <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type cyclonedx --predicate sbom.cdx.json <IMAGE>
    -
    -

    Then, you can verify attestations on the image.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE>
    -
    -

    You can also create attestations of other formatted SBOM.

    -
    # spdx
    -$ trivy image --format spdx -o sbom.spdx <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx <IMAGE>
    -
    -# spdx-json
    -$ trivy image --format spdx-json -o sbom.spdx.json <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx.json <IMAGE>
    -
    -

    Keyless signing

    -

    You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).

    -
    # The cyclonedx type is supported in Cosign v1.10.0 or later.
    -$ trivy image --format cyclonedx -o sbom.cdx.json <IMAGE>
    -# The following command uploads SBOM attestation to the public Rekor instance.
    -$ COSIGN_EXPERIMENTAL=1 cosign attest --type cyclonedx --predicate sbom.cdx.json <IMAGE>
    -
    -

    You can verify attestations. -

    $ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type cyclonedx <IMAGE>
    -

    -

    Scanning

    -

    Trivy can take an SBOM attestation as input and scan for vulnerabilities. Currently, Trivy supports CycloneDX-type attestation.

    -

    In the following example, Cosign can get an CycloneDX-type attestation and trivy scan it. -You must create CycloneDX-type attestation before trying the example. -To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the Sign with a local key pair section.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE> > sbom.cdx.intoto.jsonl
    -$ trivy sbom ./sbom.cdx.intoto.jsonl
    -
    -sbom.cdx.intoto.jsonl (alpine 3.7.3)
    -=========================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────┐
    -│  Library    Vulnerability   Severity  Installed Version  Fixed Version                           Title                           │
    -├────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────┤
    -│ musl        CVE-2019-14697  CRITICAL  1.1.18-r3          1.1.18-r4      musl libc through 1.1.23 has an x87 floating-point stack │
    -│                                                                         adjustment im ......                                     │
    -│                                                                         https://avd.aquasec.com/nvd/cve-2019-14697               │
    -├────────────┤                                                                                                                      │
    -│ musl-utils                                                                                                                       │
    -│                                                                                                                                  │
    -│                                                                                                                                  │
    -└────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────┘
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/attestation/vuln/index.html b/v0.58.0/docs/supply-chain/attestation/vuln/index.html deleted file mode 100644 index a2b0544c102b..000000000000 --- a/v0.58.0/docs/supply-chain/attestation/vuln/index.html +++ /dev/null @@ -1,8086 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cosign Vulnerability Scan Record - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Cosign Vulnerability Attestation

    -

    Generate Cosign Vulnerability Scan Record

    -

    Trivy generates reports in the Cosign vulnerability scan record format.

    -

    You can use the regular subcommands (like image, fs and rootfs) and specify cosign-vuln with the --format option.

    -
    $ trivy image --format cosign-vuln --output vuln.json alpine:3.10
    -
    -
    -Result - -
    {
    -  "invocation": {
    -    "parameters": null,
    -    "uri": "",
    -    "event_id": "",
    -    "builder.id": ""
    -  },
    -  "scanner": {
    -    "uri": "pkg:github/aquasecurity/trivy@v0.30.1-8-gf9cb8a28",
    -    "version": "v0.30.1-8-gf9cb8a28",
    -    "db": {
    -      "uri": "",
    -      "version": ""
    -    },
    -    "result": {
    -      "SchemaVersion": 2,
    -      "CreatedAt": 1629894030,
    -      "ArtifactName": "alpine:3.10",
    -      "ArtifactType": "container_image",
    -      "Metadata": {
    -        "OS": {
    -          "Family": "alpine",
    -          "Name": "3.10.9",
    -          "EOSL": true
    -        },
    -        "ImageID": "sha256:e7b300aee9f9bf3433d32bc9305bfdd22183beb59d933b48d77ab56ba53a197a",
    -        "DiffIDs": [
    -          "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
    -        ],
    -        "RepoTags": [
    -          "alpine:3.10"
    -        ],
    -        "RepoDigests": [
    -          "alpine@sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98"
    -        ],
    -        "ImageConfig": {
    -          "architecture": "amd64",
    -          "container": "fdb7e80e3339e8d0599282e606c907aa5881ee4c668a68136119e6dfac6ce3a4",
    -          "created": "2021-04-14T19:20:05.338397761Z",
    -          "docker_version": "19.03.12",
    -          "history": [
    -            {
    -              "created": "2021-04-14T19:20:04.987219124Z",
    -              "created_by": "/bin/sh -c #(nop) ADD file:c5377eaa926bf412dd8d4a08b0a1f2399cfd708743533b0aa03b53d14cb4bb4e in / "
    -            },
    -            {
    -              "created": "2021-04-14T19:20:05.338397761Z",
    -              "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
    -              "empty_layer": true
    -            }
    -          ],
    -          "os": "linux",
    -          "rootfs": {
    -            "type": "layers",
    -            "diff_ids": [
    -              "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
    -            ]
    -          },
    -          "config": {
    -            "Cmd": [
    -              "/bin/sh"
    -            ],
    -            "Env": [
    -              "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    -            ],
    -            "Image": "sha256:eb2080c455e94c22ae35b3aef9e078c492a00795412e026e4d6b41ef64bc7dd8"
    -          }
    -        }
    -      },
    -      "Results": [
    -        {
    -          "Target": "alpine:3.10 (alpine 3.10.9)",
    -          "Class": "os-pkgs",
    -          "Type": "alpine",
    -          "Vulnerabilities": [
    -            {
    -              "VulnerabilityID": "CVE-2021-36159",
    -              "PkgName": "apk-tools",
    -              "InstalledVersion": "2.10.6-r0",
    -              "FixedVersion": "2.10.7-r0",
    -              "Layer": {
    -                "Digest": "sha256:396c31837116ac290458afcb928f68b6cc1c7bdd6963fc72f52f365a2a89c1b5",
    -                "DiffID": "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
    -              },
    -              "SeveritySource": "nvd",
    -              "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-36159",
    -              "DataSource": {
    -                "ID": "alpine",
    -                "Name": "Alpine Secdb",
    -                "URL": "https://secdb.alpinelinux.org/"
    -              },
    -              "Description": "libfetch before 2021-07-26, as used in apk-tools, xbps, and other products, mishandles numeric strings for the FTP and HTTP protocols. The FTP passive mode implementation allows an out-of-bounds read because strtol is used to parse the relevant numbers into address bytes. It does not check if the line ends prematurely. If it does, the for-loop condition checks for the '\\0' terminator one byte too late.",
    -              "Severity": "CRITICAL",
    -              "CweIDs": [
    -                "CWE-125"
    -              ],
    -              "CVSS": {
    -                "nvd": {
    -                  "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:P",
    -                  "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H",
    -                  "V2Score": 6.4,
    -                  "V3Score": 9.1
    -                }
    -              },
    -              "References": [
    -                "https://github.com/freebsd/freebsd-src/commits/main/lib/libfetch",
    -                "https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10749",
    -                "https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cdev.kafka.apache.org%3E",
    -                "https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cusers.kafka.apache.org%3E",
    -                "https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cdev.kafka.apache.org%3E",
    -                "https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cusers.kafka.apache.org%3E"
    -              ],
    -              "PublishedDate": "2021-08-03T14:15:00Z",
    -              "LastModifiedDate": "2021-10-18T12:19:00Z"
    -            }
    -          ]
    -        }
    -      ]
    -    }
    -  },
    -  "metadata": {
    -    "scanStartedOn": "2022-07-24T17:14:04.864682+09:00",
    -    "scanFinishedOn": "2022-07-24T17:14:04.864682+09:00"
    -  }
    -}
    -
    - -
    - -

    Create Cosign Vulnerability Attestation

    -

    Cosign supports generating and verifying in-toto attestations. This tool enables you to sign and verify Cosign vulnerability attestation.

    -
    -

    Note

    -

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. -If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    -
    -

    Sign with a local key pair

    -

    Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs.

    -
    $ cosign generate-key-pair
    -
    -

    In the following example, Trivy generates a cosign vulnerability scan record, and then Cosign attaches an attestation of it to a container image with a local key pair.

    -
    $ trivy image --format cosign-vuln --output vuln.json <IMAGE>
    -$ cosign attest --key /path/to/cosign.key --type vuln --predicate vuln.json <IMAGE>
    -
    -

    Then, you can verify attestations on the image.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type vuln <IMAGE>
    -
    -

    Keyless signing

    -

    You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).

    -

    $ trivy image --format cosign-vuln -o vuln.json <IMAGE>
    -$ cosign attest --type vuln --predicate vuln.json <IMAGE>
    -
    -This will provide a certificate in the output section.

    -

    You can verify attestations:

    -
    $ cosign verify-attestation --certificate=path-to-the-certificate --type vuln --certificate-identity Email-used-to-sign  --certificate-oidc-issuer='the-issuer-used' <IMAGE>
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/sbom/index.html b/v0.58.0/docs/supply-chain/sbom/index.html deleted file mode 100644 index edd6d16ed251..000000000000 --- a/v0.58.0/docs/supply-chain/sbom/index.html +++ /dev/null @@ -1,8835 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    - -
    - - - -
    - -
    - - - - - - - - - - - - - -

    SBOM

    -

    Generating

    -

    Trivy can generate the following SBOM formats.

    - -

    CLI commands

    -

    To generate SBOM, you can use the --format option for each subcommand such as image, fs and vm.

    -
    $ trivy image --format spdx-json --output result.json alpine:3.15
    -
    -
    $ trivy fs --format cyclonedx --output result.json /app/myproject
    -
    -
    -Result - -
    {
    -  "bomFormat": "CycloneDX",
    -  "specVersion": "1.3",
    -  "serialNumber": "urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace",
    -  "version": 1,
    -  "metadata": {
    -    "timestamp": "2022-02-22T15:11:40.270597Z",
    -    "tools": [
    -      {
    -        "vendor": "aquasecurity",
    -        "name": "trivy",
    -        "version": "dev"
    -      }
    -    ],
    -    "component": {
    -      "bom-ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "type": "container",
    -      "name": "alpine:3.15",
    -      "version": "",
    -      "purl": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SchemaVersion",
    -          "value": "2"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:ImageID",
    -          "value": "sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoDigest",
    -          "value": "alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:DiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoTag",
    -          "value": "alpine:3.15"
    -        }
    -      ]
    -    }
    -  },
    -  "components": [
    -    {
    -      "bom-ref": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "type": "library",
    -      "name": "alpine-baselayout",
    -      "version": "3.2.0-r18",
    -      "licenses": [
    -        {
    -          "expression": "GPL-2.0-only"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "alpine-baselayout"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "3.2.0-r18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    ...(snip)...
    -    {
    -      "bom-ref": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "type": "library",
    -      "name": "zlib",
    -      "version": "1.2.11-r3",
    -      "licenses": [
    -        {
    -          "expression": "Zlib"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "zlib"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "1.2.11-r3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    {
    -      "bom-ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "type": "operating-system",
    -      "name": "alpine",
    -      "version": "3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:Type",
    -          "value": "alpine"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:Class",
    -          "value": "os-pkgs"
    -        }
    -      ]
    -    }
    -  ],
    -  "dependencies": [
    -    {
    -      "ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "dependsOn": [
    -        "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -        "pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0",
    -        "pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0",
    -        "pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0",
    -        "pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0",
    -        "pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0",
    -        "pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0"
    -      ]
    -    },
    -    {
    -      "ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "dependsOn": [
    -        "3da6a469-964d-4b4e-b67d-e94ec7c88d37"
    -      ]
    -    }
    -  ]
    -}
    -
    - -
    - -

    Supported packages

    -

    Trivy supports the following packages.

    - -

    Formats

    -

    CycloneDX

    -

    Trivy can generate SBOM in the CycloneDX format. -Note that XML format is not supported at the moment.

    -

    You can use the regular subcommands (like image, fs and rootfs) and specify cyclonedx with the --format option.

    -

    CycloneDX can represent either or both SBOM or BOV.

    - -

    By default, --format cyclonedx represents SBOM and doesn't include vulnerabilities in the CycloneDX output.

    -
    $ trivy image --format cyclonedx --output result.json alpine:3.15
    -2022-07-19T07:47:27.624Z        INFO    "--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.
    -
    -
    -Result - -
    $ cat result.json | jq .
    -{
    -  "bomFormat": "CycloneDX",
    -  "specVersion": "1.5",
    -  "serialNumber": "urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace",
    -  "version": 1,
    -  "metadata": {
    -    "timestamp": "2022-02-22T15:11:40.270597Z",
    -    "tools": {
    -      "components": [
    -        {
    -          "type": "application",
    -          "group": "aquasecurity",
    -          "name": "trivy",
    -          "version": "dev"
    -        }
    -      ]
    -    },
    -    "component": {
    -      "bom-ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "type": "container",
    -      "name": "alpine:3.15",
    -      "version": "",
    -      "purl": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SchemaVersion",
    -          "value": "2"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:ImageID",
    -          "value": "sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoDigest",
    -          "value": "alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:DiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:RepoTag",
    -          "value": "alpine:3.15"
    -        }
    -      ]
    -    }
    -  },
    -  "components": [
    -    {
    -      "bom-ref": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "type": "library",
    -      "name": "alpine-baselayout",
    -      "version": "3.2.0-r18",
    -      "licenses": [
    -        {
    -          "expression": "GPL-2.0-only"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "alpine-baselayout"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "3.2.0-r18"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    ...(snip)...
    -    {
    -      "bom-ref": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "type": "library",
    -      "name": "zlib",
    -      "version": "1.2.11-r3",
    -      "licenses": [
    -        {
    -          "expression": "Zlib"
    -        }
    -      ],
    -      "purl": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:SrcName",
    -          "value": "zlib"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:SrcVersion",
    -          "value": "1.2.11-r3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDigest",
    -          "value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:LayerDiffID",
    -          "value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
    -        }
    -      ]
    -    },
    -    {
    -      "bom-ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "type": "operating-system",
    -      "name": "alpine",
    -      "version": "3.15.0",
    -      "properties": [
    -        {
    -          "name": "aquasecurity:trivy:Type",
    -          "value": "alpine"
    -        },
    -        {
    -          "name": "aquasecurity:trivy:Class",
    -          "value": "os-pkgs"
    -        }
    -      ]
    -    }
    -  ],
    -  "dependencies": [
    -    {
    -      "ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
    -      "dependsOn": [
    -        "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
    -        "pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0",
    -        "pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0",
    -        "pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0",
    -        "pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0",
    -        "pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0",
    -        "pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0",
    -        "pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0",
    -        "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0"
    -      ]
    -    },
    -    {
    -      "ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
    -      "dependsOn": [
    -        "3da6a469-964d-4b4e-b67d-e94ec7c88d37"
    -      ]
    -    }
    -  ],
    -  "vulnerabilities": [
    -    {
    -      "id": "CVE-2021-42386",
    -      "source": {
    -        "name": "alpine",
    -        "url": "https://secdb.alpinelinux.org/"
    -      },
    -      "ratings": [
    -        {
    -          "source": {
    -            "name": "nvd"
    -          },
    -          "score": 7.2,
    -          "severity": "high",
    -          "method": "CVSSv31",
    -          "vector": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H"
    -        },
    -        {
    -          "source": {
    -            "name": "nvd"
    -          },
    -          "score": 6.5,
    -          "severity": "medium",
    -          "method": "CVSSv2",
    -          "vector": "AV:N/AC:L/Au:S/C:P/I:P/A:P"
    -        },
    -        {
    -          "source": {
    -            "name": "redhat"
    -          },
    -          "score": 6.6,
    -          "severity": "medium",
    -          "method": "CVSSv31",
    -          "vector": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H"
    -        }
    -      ],
    -      "cwes": [
    -        416
    -      ],
    -      "description": "A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the nvalloc function",
    -      "advisories": [
    -        {
    -          "url": "https://access.redhat.com/security/cve/CVE-2021-42386"
    -        },
    -        {
    -          "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42386"
    -        }
    -      ],
    -      "published": "2021-11-15 21:15:00 +0000 UTC",
    -      "updated": "2022-01-04 17:14:00 +0000 UTC",
    -      "affects": [
    -        {
    -          "ref": "pkg:apk/alpine/busybox@1.33.1-r3?distro=3.14.2"
    -        },
    -        {
    -          "ref": "pkg:apk/alpine/ssl_client@1.33.1-r3?distro=3.14.2"
    -        }
    -      ]
    -    }
    -  ]
    -}
    -
    - -
    - -

    If you want to include vulnerabilities, you can enable vulnerability scanning via --scanners vuln.

    -
    $ trivy image --scanners vuln --format cyclonedx --output result.json alpine:3.15
    -
    -

    SPDX

    -

    Trivy can generate SBOM in the SPDX format.

    -

    You can use the regular subcommands (like image, fs and rootfs) and specify spdx with the --format option.

    -
    $ trivy image --format spdx --output result.spdx alpine:3.15
    -
    -
    -Result - -
    $ cat result.spdx
    -SPDXVersion: SPDX-2.2
    -DataLicense: CC0-1.0
    -SPDXID: SPDXRef-DOCUMENT
    -DocumentName: alpine:3.15
    -DocumentNamespace: https://aquasecurity.github.io/trivy/container_image/alpine:3.15-bebf6b19-a94c-4e2c-af44-065f63923f48
    -Creator: Organization: aquasecurity
    -Creator: Tool: trivy-0.38.1
    -Created: 2022-04-28T07:32:57.142806Z
    -
    -##### Package: zlib
    -
    -PackageName: zlib
    -SPDXID: SPDXRef-12bc938ac028a5e1
    -PackageVersion: 1.2.12-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: Zlib
    -PackageLicenseDeclared: Zlib
    -
    -##### Package: apk-tools
    -
    -PackageName: apk-tools
    -SPDXID: SPDXRef-26c274652190d87f
    -PackageVersion: 2.12.7-r3
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: libretls
    -
    -PackageName: libretls
    -SPDXID: SPDXRef-2b021966d19a8211
    -PackageVersion: 3.3.4-r3
    -FilesAnalyzed: false
    -PackageLicenseConcluded: ISC AND (BSD-3-Clause OR MIT)
    -PackageLicenseDeclared: ISC AND (BSD-3-Clause OR MIT)
    -
    -##### Package: busybox
    -
    -PackageName: busybox
    -SPDXID: SPDXRef-317ce3476703f20d
    -PackageVersion: 1.34.1-r5
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: libcrypto1.1
    -
    -PackageName: libcrypto1.1
    -SPDXID: SPDXRef-34f407fb4dbd67f4
    -PackageVersion: 1.1.1n-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: OpenSSL
    -PackageLicenseDeclared: OpenSSL
    -
    -##### Package: libc-utils
    -
    -PackageName: libc-utils
    -SPDXID: SPDXRef-4bbc1cb449d54083
    -PackageVersion: 0.7.2-r3
    -FilesAnalyzed: false
    -PackageLicenseConcluded: BSD-2-Clause AND BSD-3-Clause
    -PackageLicenseDeclared: BSD-2-Clause AND BSD-3-Clause
    -
    -##### Package: alpine-keys
    -
    -PackageName: alpine-keys
    -SPDXID: SPDXRef-a3bdd174be1456b6
    -PackageVersion: 2.4-r1
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MIT
    -PackageLicenseDeclared: MIT
    -
    -##### Package: ca-certificates-bundle
    -
    -PackageName: ca-certificates-bundle
    -SPDXID: SPDXRef-ac6472ba26fb991c
    -PackageVersion: 20211220-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MPL-2.0 AND MIT
    -PackageLicenseDeclared: MPL-2.0 AND MIT
    -
    -##### Package: libssl1.1
    -
    -PackageName: libssl1.1
    -SPDXID: SPDXRef-b2d1b1d70fe90f7d
    -PackageVersion: 1.1.1n-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: OpenSSL
    -PackageLicenseDeclared: OpenSSL
    -
    -##### Package: scanelf
    -
    -PackageName: scanelf
    -SPDXID: SPDXRef-c617077ba6649520
    -PackageVersion: 1.3.3-r0
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: musl
    -
    -PackageName: musl
    -SPDXID: SPDXRef-ca80b810029cde0e
    -PackageVersion: 1.2.2-r7
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MIT
    -PackageLicenseDeclared: MIT
    -
    -##### Package: alpine-baselayout
    -
    -PackageName: alpine-baselayout
    -SPDXID: SPDXRef-d782e64751ba9faa
    -PackageVersion: 3.2.0-r18
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    -##### Package: musl-utils
    -
    -PackageName: musl-utils
    -SPDXID: SPDXRef-e5e8a237f6162e22
    -PackageVersion: 1.2.2-r7
    -FilesAnalyzed: false
    -PackageLicenseConcluded: MIT BSD GPL2+
    -PackageLicenseDeclared: MIT BSD GPL2+
    -
    -##### Package: ssl_client
    -
    -PackageName: ssl_client
    -SPDXID: SPDXRef-fdf0ce84f6337be4
    -PackageVersion: 1.34.1-r5
    -FilesAnalyzed: false
    -PackageLicenseConcluded: GPL-2.0-only
    -PackageLicenseDeclared: GPL-2.0-only
    -
    - -
    - -

    SPDX-JSON format is also supported by using spdx-json with the --format option.

    -
    $ trivy image --format spdx-json --output result.spdx.json alpine:3.15
    -
    -
    -Result - -
    $ cat result.spdx.json | jq .
    -{
    -    "SPDXID": "SPDXRef-DOCUMENT",
    -    "creationInfo": {
    -        "created": "2022-04-28T08:16:55.328255Z",
    -        "creators": [
    -            "Tool: trivy-0.38.1",
    -            "Organization: aquasecurity"
    -        ]
    -    },
    -    "dataLicense": "CC0-1.0",
    -    "documentNamespace": "http://aquasecurity.github.io/trivy/container_image/alpine:3.15-d9549e3a-a4c5-4ee3-8bde-8c78d451fbe7",
    -    "name": "alpine:3.15",
    -    "packages": [
    -        {
    -            "SPDXID": "SPDXRef-12bc938ac028a5e1",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "Zlib",
    -            "licenseDeclared": "Zlib",
    -            "name": "zlib",
    -            "versionInfo": "1.2.12-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-26c274652190d87f",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "apk-tools",
    -            "versionInfo": "2.12.7-r3"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-2b021966d19a8211",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "ISC AND (BSD-3-Clause OR MIT)",
    -            "licenseDeclared": "ISC AND (BSD-3-Clause OR MIT)",
    -            "name": "libretls",
    -            "versionInfo": "3.3.4-r3"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-317ce3476703f20d",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "busybox",
    -            "versionInfo": "1.34.1-r5"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-34f407fb4dbd67f4",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "OpenSSL",
    -            "licenseDeclared": "OpenSSL",
    -            "name": "libcrypto1.1",
    -            "versionInfo": "1.1.1n-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-4bbc1cb449d54083",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "BSD-2-Clause AND BSD-3-Clause",
    -            "licenseDeclared": "BSD-2-Clause AND BSD-3-Clause",
    -            "name": "libc-utils",
    -            "versionInfo": "0.7.2-r3"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-a3bdd174be1456b6",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MIT",
    -            "licenseDeclared": "MIT",
    -            "name": "alpine-keys",
    -            "versionInfo": "2.4-r1"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-ac6472ba26fb991c",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MPL-2.0 AND MIT",
    -            "licenseDeclared": "MPL-2.0 AND MIT",
    -            "name": "ca-certificates-bundle",
    -            "versionInfo": "20211220-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-b2d1b1d70fe90f7d",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "OpenSSL",
    -            "licenseDeclared": "OpenSSL",
    -            "name": "libssl1.1",
    -            "versionInfo": "1.1.1n-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-c617077ba6649520",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "scanelf",
    -            "versionInfo": "1.3.3-r0"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-ca80b810029cde0e",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MIT",
    -            "licenseDeclared": "MIT",
    -            "name": "musl",
    -            "versionInfo": "1.2.2-r7"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-d782e64751ba9faa",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "alpine-baselayout",
    -            "versionInfo": "3.2.0-r18"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-e5e8a237f6162e22",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "MIT BSD GPL2+",
    -            "licenseDeclared": "MIT BSD GPL2+",
    -            "name": "musl-utils",
    -            "versionInfo": "1.2.2-r7"
    -        },
    -        {
    -            "SPDXID": "SPDXRef-fdf0ce84f6337be4",
    -            "filesAnalyzed": false,
    -            "licenseConcluded": "GPL-2.0-only",
    -            "licenseDeclared": "GPL-2.0-only",
    -            "name": "ssl_client",
    -            "versionInfo": "1.34.1-r5"
    -        }
    -    ],
    -    "spdxVersion": "SPDX-2.2"
    -}
    -
    - -
    - -

    Scanning

    -

    SBOM as Target

    -

    Trivy can take SBOM documents as input for scanning, e.g trivy sbom ./sbom.spdx. -See here for more details.

    -

    SBOM Detection inside Targets

    -

    Trivy searches for SBOM files in container images with the following extensions:

    -
      -
    • .spdx
    • -
    • .spdx.json
    • -
    • .cdx
    • -
    • .cdx.json
    • -
    -

    In addition, Trivy automatically detects SBOM files in Bitnami images, see here for more details.

    -

    It is enabled in the following targets.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TargetEnabled
    Container Image
    Filesystem
    Rootfs
    Git Repository
    VM Image
    Kubernetes
    AWS
    SBOM
    -

    SBOM Discovery for Container Images

    -

    When scanning container images, Trivy can discover SBOM for those images. See here for more details.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/vex/file/index.html b/v0.58.0/docs/supply-chain/vex/file/index.html deleted file mode 100644 index 7c3f304caf26..000000000000 --- a/v0.58.0/docs/supply-chain/vex/file/index.html +++ /dev/null @@ -1,8813 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Local VEX Files - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Local VEX Files

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    In addition to VEX repositories, Trivy also supports the use of local VEX files for vulnerability filtering. -This method is useful when you have specific VEX documents that you want to apply to your scans. -Currently, Trivy supports the following formats:

    - -

    CycloneDX

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TargetSupported
    Container Image
    Filesystem
    Code Repository
    VM Image
    Kubernetes
    SBOM
    -

    There are two VEX formats for CycloneDX:

    -
      -
    • Independent BOM and VEX BOM
    • -
    • BOM With Embedded VEX
    • -
    -

    Trivy only supports the Independent BOM and VEX BOM format, so you need to provide a separate VEX file alongside the SBOM. -The input SBOM format must be in CycloneDX format.

    -

    The following steps are required:

    -
      -
    1. Generate a CycloneDX SBOM
    2. -
    3. Create a VEX based on the SBOM generated in step 1
    4. -
    5. Provide the VEX when scanning the CycloneDX SBOM
    6. -
    -

    Generate the SBOM

    -

    You can generate a CycloneDX SBOM with Trivy as follows:

    -
    $ trivy image --format cyclonedx --output debian11.sbom.cdx debian:11
    -
    -

    Create the VEX

    -

    Next, create a VEX based on the generated SBOM. -Multiple vulnerability statuses can be defined under vulnerabilities. -Take a look at the example below.

    -
    $ cat <<EOF > trivy.vex.cdx
    -{
    -  "bomFormat": "CycloneDX",
    -  "specVersion": "1.5",
    -  "version": 1,
    -  "vulnerabilities": [
    -    {
    -      "id": "CVE-2020-8911",
    -      "analysis": {
    -        "state": "not_affected",
    -        "justification": "code_not_reachable",
    -        "response": ["will_not_fix", "update"],
    -        "detail": "The vulnerable function is not called"
    -      },
    -      "affects": [
    -        {
    -          "ref": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#pkg:golang/github.com/aws/aws-sdk-go@v1.44.234"
    -        }
    -      ]
    -    }
    -  ]
    -}
    -EOF
    -
    -

    This is a VEX document in the CycloneDX format. -The vulnerability ID, such as a CVE-ID or GHSA-ID, should be placed in vulnerabilities.id. -When the analysis.state is set to not_affected, Trivy will not detect the vulnerability.

    -

    BOM-Links must be placed in affects.ref. -The BOM-Link has the following syntax and consists of three elements:

    -
    urn:cdx:serialNumber/version#bom-ref
    -
    -
      -
    • serialNumber
    • -
    • version
    • -
    • bom-ref
    • -
    -

    These values must be obtained from the CycloneDX SBOM. -Please note that while the serialNumber starts with urn:uuid:, the BOM-Link starts with urn:cdx:.

    -

    The bom-ref must contain the BOM-Ref of the package affected by the vulnerability. -In the example above, since the Go package github.com/aws/aws-sdk-go is affected by CVE-2020-8911, it was necessary to specify the SBOM's BOM-Ref, pkg:golang/github.com/aws/aws-sdk-go@1.44.234.

    -

    For more details on CycloneDX VEX and BOM-Link, please refer to the following links:

    - -

    Scan SBOM with VEX

    -

    Provide the VEX when scanning the CycloneDX SBOM.

    -
    $ trivy sbom trivy.sbom.cdx --vex trivy.vex.cdx
    -...
    -2023-04-13T12:55:44.838+0300    INFO    Filtered out the detected vulnerability {"VEX format": "CycloneDX", "vulnerability-id": "CVE-2020-8911", "status": "not_affected", "justification": "code_not_reachable"}
    -
    -go.mod (gomod)
    -==============
    -Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -┌───────────────────────────┬───────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│          Library           Vulnerability  Severity  Installed Version  Fixed Version                            Title                            │
    -├───────────────────────────┼───────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ github.com/aws/aws-sdk-go  CVE-2020-8912  LOW       v1.44.234                         aws-sdk-go: In-band key negotiation issue in AWS S3 Crypto │
    -│                                                                                       SDK for golang...                                          │
    -│                                                                                       https://avd.aquasec.com/nvd/cve-2020-8912                  │
    -└───────────────────────────┴───────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    -

    CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document.

    -

    OpenVEX

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TargetSupported
    Container Image
    Filesystem
    Code Repository
    VM Image
    Kubernetes
    SBOM
    -

    Trivy also supports OpenVEX that is designed to be minimal, compliant, interoperable, and embeddable. -OpenVEX can be used in all Trivy targets, unlike CycloneDX VEX.

    -

    The following steps are required:

    -
      -
    1. Create a VEX document
    2. -
    3. Provide the VEX when scanning your target
    4. -
    -

    Create the VEX document

    -

    Please see also the example. -Trivy requires the Package URL (PURL) as the product identifier.

    -
    $ cat <<EOF > debian11.openvex.json
    -{
    -  "@context": "https://openvex.dev/ns/v0.2.0",
    -  "@id": "https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f",
    -  "author": "Aqua Security",
    -  "timestamp": "2023-08-29T19:07:16.853479631-06:00",
    -  "version": 1,
    -  "statements": [
    -    {
    -      "vulnerability": {"name": "CVE-2019-8457"},
    -      "products": [
    -        {"@id": "pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8"}
    -      ],
    -      "status": "not_affected",
    -      "justification": "vulnerable_code_not_in_execute_path"
    -    }
    -  ]
    -}
    -EOF
    -
    -

    In the above example, PURLs, pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8 are used for the product identifier. -You can find PURLs in the JSON report generated by Trivy. -This VEX statement is applied if the PURL specified in the VEX matches the PURL found during the scan. -See here for more details of PURL matching.

    -

    Trivy also supports OpenVEX subcomponents, which allow for more precise specification of the scope of a VEX statement, reducing the risk of incorrect filtering. -Let's say you want to suppress vulnerabilities within a container image. -If you only specify the PURL of the container image as the product, the resulting VEX would look like this:

    -
    -OpenVEX products only - -
    "statements": [
    -  {
    -    "vulnerability": {"name": "CVE-2024-32002"},
    -    "products": [
    -      {"@id": "pkg:oci/trivy?repository_url=ghcr.io%2Faquasecurity%2Ftrivy"}
    -    ],
    -    "status": "not_affected",
    -    "justification": "vulnerable_code_not_in_execute_path"
    -  }
    -]
    -
    - -
    - -

    However, this approach would suppress all instances of CVE-2024-32002 within the container image. -If the intention is to declare that the git package distributed by Alpine Linux within this image is not affected, subcomponents can be utilized as follows:

    -
    -OpenVEX subcomponents - -
    "statements": [
    -  {
    -    "vulnerability": {"name": "CVE-2024-32002"},
    -    "products": [
    -      {
    -        "@id": "pkg:oci/trivy?repository_url=ghcr.io%2Faquasecurity%2Ftrivy",
    -        "subcomponents": [
    -          {"@id": "pkg:apk/alpine/git"}
    -        ]
    -      }
    -    ],
    -    "status": "not_affected",
    -    "justification": "vulnerable_code_not_in_execute_path"
    -  }
    -]
    -
    - -
    - -

    By declaring the subcomponent in this manner, Trivy will filter the results, considering only the git package within the ghcr.io/aquasecurity/trivy container image as not affected. -Omitting the version in the PURL applies the statement to all versions of the package. -More details about PURL matching can be found here.

    -

    Furthermore, the product specified in a VEX statement does not necessarily need to be the target of the scan. -It is possible to specify a component that is included in the scan target as the product. -For example, you can designate a specific Go project as the product and its dependent modules as subcomponents.

    -

    In the following example, the VEX statement declares that the github.com/docker/docker module, which is a dependency of the github.com/aquasecurity/trivy Go project, is not affected by CVE-2024-29018.

    -
    -OpenVEX intermediate components - -
    "statements": [
    -  {
    -    "vulnerability": {"name": "CVE-2024-29018"},
    -    "products": [
    -      {
    -        "@id": "pkg:golang/github.com/aquasecurity/trivy",
    -        "subcomponents": [
    -          { "@id": "pkg:golang/github.com/docker/docker" }
    -        ]
    -      }
    -    ],
    -    "status": "not_affected",
    -    "justification": "vulnerable_code_not_in_execute_path"
    -  }
    -]
    -
    - -
    - -

    This VEX document can be used when scanning a container image as well as other targets. -The VEX statement will be applied when Trivy finds the Go binary within the container image.

    -
    $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex trivy.openvex.json
    -
    -

    VEX documents can indeed be reused across different container images, eliminating the need to issue separate VEX documents for each image. -This is particularly useful when there is a common component or library that is used across multiple projects or container images.

    -

    You can see the appendix for more details on how VEX is applied in Trivy.

    -

    Scan with VEX

    -

    Provide the VEX when scanning your target.

    -
    $ trivy image debian:11 --vex debian11.openvex.json
    -...
    -2023-04-26T17:56:05.358+0300    INFO    Filtered out the detected vulnerability {"VEX format": "OpenVEX", "vulnerability-id": "CVE-2019-8457", "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path"}
    -
    -debian11.spdx.json (debian 11.6)
    -================================
    -Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)
    -
    -

    CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document.

    -

    CSAF

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TargetSupported
    Container Image
    Filesystem
    Code Repository
    VM Image
    Kubernetes
    SBOM
    -

    Trivy also supports CSAF format for VEX. -Since CSAF aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy.

    -

    The following steps are required:

    -
      -
    1. Create a CSAF document
    2. -
    3. Provide the CSAF when scanning your target
    4. -
    -

    Create the CSAF document

    -

    Create a CSAF document in JSON format as follows:

    -
    -CSAF VEX - -
    $ cat <<EOF > debian11.vex.csaf
    -{
    -  "document": {
    -    "category": "csaf_vex",
    -    "csaf_version": "2.0",
    -    "notes": [
    -      {
    -        "category": "summary",
    -        "text": "Example Company VEX document. Unofficial content for demonstration purposes only.",
    -        "title": "Author comment"
    -      }
    -    ],
    -    "publisher": {
    -      "category": "vendor",
    -      "name": "Example Company ProductCERT",
    -      "namespace": "https://psirt.example.com"
    -    },
    -    "title": "AquaSecurity example VEX document",
    -    "tracking": {
    -      "current_release_date": "2024-01-01T11:00:00.000Z",
    -      "generator": {
    -        "date": "2024-01-01T11:00:00.000Z",
    -        "engine": {
    -          "name": "Secvisogram",
    -          "version": "1.11.0"
    -        }
    -      },
    -      "id": "2024-EVD-UC-01-A-001",
    -      "initial_release_date": "2024-01-01T11:00:00.000Z",
    -      "revision_history": [
    -        {
    -          "date": "2024-01-01T11:00:00.000Z",
    -          "number": "1",
    -          "summary": "Initial version."
    -        }
    -      ],
    -      "status": "final",
    -      "version": "1"
    -    }
    -  },
    -  "product_tree": {
    -    "branches": [
    -      {
    -        "branches": [
    -          {
    -            "branches": [
    -              {
    -                "category": "product_version",
    -                "name": "5.3",
    -                "product": {
    -                  "name": "Database Libraries 5.3",
    -                  "product_id": "LIBDB-5328",
    -                  "product_identification_helper": {
    -                    "purl": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.8?arch=amd64\u0026distro=debian-11.8"
    -                  }
    -                }
    -              }
    -            ],
    -            "category": "product_name",
    -            "name": "Database Libraries"
    -          }
    -        ],
    -        "category": "vendor",
    -        "name": "Debian"
    -      }
    -    ]
    -  },
    -  "vulnerabilities": [
    -    {
    -      "cve": "CVE-2019-8457",
    -      "notes": [
    -        {
    -          "category": "description",
    -          "text": "SQLite3 from 3.6.0 to and including 3.27.2 is vulnerable to heap out-of-bound read in the rtreenode() function when handling invalid rtree tables.",
    -          "title": "CVE description"
    -        }
    -      ],
    -      "product_status": {
    -        "known_not_affected": [
    -          "LIBDB-5328"
    -        ]
    -      },
    -      "threats": [
    -        {
    -          "category": "impact",
    -          "details": "Vulnerable code not in execute path.",
    -          "product_ids": [
    -            "LIBDB-5328"
    -          ]
    -        }
    -      ]
    -    }
    -  ]
    -}
    -EOF
    -
    - -
    - -

    Trivy also supports CSAF relationships, reducing the risk of incorrect filtering. -It works in the same way as OpenVEX subcomponents. -At present, the specified relationship category is not taken into account and all the following categories are treated internally as "depends_on".

    -
      -
    • default_component_of
    • -
    • installed_on
    • -
    • installed_with
    • -
    -

    You can see the appendix for more details on how VEX is applied in Trivy.

    -

    Scan with CSAF VEX

    -

    Provide the CSAF document when scanning your target.

    -
    $ trivy image debian:11 --vex debian11.vex.csaf
    -...
    -2024-01-02T10:28:26.704+0100    INFO    Filtered out the detected vulnerability {"VEX format": "CSAF", "vulnerability-id": "CVE-2019-8457", "status": "not_affected"}
    -
    -debian11.spdx.json (debian 11.6)
    -================================
    -Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)
    -
    -

    CVE-2019-8457 is no longer shown as it is filtered out according to the given CSAF document.

    -

    Appendix

    -

    PURL matching

    -

    In the context of VEX, Package URLs (PURLs) are utilized to identify specific software packages and their versions. -The PURL matching specification outlines how PURLs are interpreted for vulnerability exception processing, ensuring precise identification and broad coverage of software packages.

    -
    -

    Note

    -

    The following PURL matching rules are not formally defined within the current official PURL specification. -Instead, they represent a community consensus on how to interpret PURLs.

    -
    -

    Below are the key aspects of the PURL matching rules:

    -

    Matching Without Version

    -

    A PURL without a specified version (e.g., pkg:maven/com.google.guava/guava) matches all versions of that package. -This rule simplifies the application of vulnerability exceptions to all versions of a package.

    -

    Example: pkg:maven/com.google.guava/guava matches:

    -
      -
    • All versions of guava, such as com.google.guava:guava:24.1.1, com.google.guava:guava:30.0.
    • -
    -

    Matching Without Qualifiers

    -

    A PURL without any qualifiers (e.g., pkg:maven/com.google.guava/guava@24.1.1) matches any variation of that package, irrespective of qualifiers. -This approach ensures broad matching capabilities, covering all architectural or platform-specific variations of a package version.

    -

    Example: pkg:maven/com.google.guava/guava@24.1.1 matches:

    -
      -
    • pkg:maven/com.google.guava/guava@24.1.1?classifier=x86
    • -
    • pkg:maven/com.google.guava/guava@24.1.1?type=pom
    • -
    -

    Matching With Specific Qualifiers

    -

    A PURL that includes specific qualifiers (e.g., pkg:maven/com.google.guava/guava@24.1.1?classifier=x86) matches only those package versions that include the same qualifiers.

    -

    Example: pkg:maven/com.google.guava/guava@24.1.1?classifier=x86 matches:

    -
      -
    • pkg:maven/com.google.guava/guava@24.1.1?classifier=x86&type=dll
        -
      • Extra qualifiers (e.g., type=dll) are ignored.
      • -
      -
    • -
    -

    does not match:

    -
      -
    • pkg:maven/com.google.guava/guava@24.1.1
        -
      • classifier=x86 is missing.
      • -
      -
    • -
    • pkg:maven/com.google.guava/guava@24.1.1?classifier=sources
        -
      • classifier must have the same value.
      • -
      -
    • -
    -

    Applying VEX to Dependency Trees

    -

    Trivy internally generates a dependency tree and applies VEX statements to this graph. -Let's consider a project with the following dependency tree, where Module C v2.0.0 is assumed to have a vulnerability CVE-XXXX-YYYY:

    -
    graph TD;
    -  modRootA(Module Root A v1.0.0)
    -  modB(Module B v1.0.0) 
    -  modC(Module C v2.0.0)
    -
    -  modRootA-->modB
    -  modB-->modC
    -

    Now, suppose a VEX statement is issued for Module B as follows:

    -
    "statements": [
    -  {
    -    "vulnerability": {"name": "CVE-XXXX-YYYY"},
    -    "products": [
    -      {
    -        "@id": "pkg:golang/module-b@v1.0.0",
    -        "subcomponents": [
    -          { "@id": "pkg:golang/module-c@v2.0.0" }
    -        ]
    -      }
    -    ],
    -    "status": "not_affected",
    -    "justification": "vulnerable_code_not_in_execute_path"  
    -  }
    -]
    -
    -

    It declares that Module B is not affected by CVE-XXXX-YYYY on Module C.

    -
    -

    Note

    -

    The VEX in this example defines the relationship between Module B and Module C. -However, as Trivy traverses all parents from vulnerable packages, it is also possible to define a VEX for the relationship between a vulnerable package and any parent, such as Module A and Module C, etc.

    -
    -

    Mapping this VEX onto the dependency tree would look like this:

    -
    graph TD;
    -  modRootA(Module Root A v1.0.0)
    -
    -  subgraph "VEX (Not Affected)"
    -  modB(Module B v1.0.0)
    -  modC(Module C v2.0.0)
    -  end
    -
    -  modRootA-->modB
    -  modB-->modC
    -

    In this case, it's clear that Module Root A is also not affected by CVE-XXXX-YYYY, so this vulnerability is suppressed.

    -

    Now, let's consider another project:

    -
    graph TD;
    -  modRootZ(Module Root Z v1.0.0)
    -  modB'(Module B v1.0.0)
    -  modC'(Module C v2.0.0)
    -  modD'(Module D v3.0.0)
    -
    -  modRootZ-->modB'
    -  modRootZ-->modD'
    -  modB'-->modC'
    -  modD'-->modC'
    -

    Assuming the same VEX as before, applying it to this dependency tree would look like:

    -
    graph TD;
    -  modRootZ(Module Root Z v1.0.0)
    -
    -  subgraph "VEX (Not Affected)"
    -  modB'(Module B v1.0.0)
    -  modC'(Module C v2.0.0)
    -  end
    -
    -  modD'(Module D v3.0.0)
    -
    -  modRootZ-->modB'
    -  modRootZ-->modD'
    -  modB'-->modC'
    -  modD'-->modC'
    -

    Module Root Z depends on Module C via multiple paths. -While the VEX tells us that Module B is not affected by the vulnerability, Module D might be. -In the absence of a VEX, the default assumption is that it is affected. -Taking all of this into account, Trivy determines that Module Root Z is affected by this vulnerability.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/vex/index.html b/v0.58.0/docs/supply-chain/vex/index.html deleted file mode 100644 index 25a7785b25a1..000000000000 --- a/v0.58.0/docs/supply-chain/vex/index.html +++ /dev/null @@ -1,7908 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Vulnerability Exploitability Exchange (VEX)

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy supports filtering detected vulnerabilities using the Vulnerability Exploitability eXchange (VEX), a standardized format for sharing and exchanging information about vulnerabilities. -By providing VEX during scanning, it is possible to filter vulnerabilities based on their status.

    -

    VEX Usage Methods

    -

    Trivy currently supports two methods for utilizing VEX:

    -
      -
    1. VEX Repository
    2. -
    3. Local VEX Files
    4. -
    5. VEX Attestation
    6. -
    -

    Enabling VEX

    -

    To enable VEX, use the --vex option. -You can specify the method to use:

    -
      -
    • To enable the VEX Repository: --vex repo
    • -
    • To use a local VEX file: --vex /path/to/vex-document.json
    • -
    • To enable VEX attestation discovery in OCI registry: --vex oci
    • -
    -
    $ trivy image ghcr.io/aquasecurity/trivy:0.52.0 --vex repo
    -
    -

    You can enable these methods simultaneously. -The order of specification determines the priority:

    -
      -
    • --vex repo --vex /path/to/vex-document.json: VEX Repository has priority
    • -
    • --vex /path/to/vex-document.json --vex repo: Local file has priority
    • -
    -

    For detailed information on each method, please refer to each page.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/vex/oci/index.html b/v0.58.0/docs/supply-chain/vex/oci/index.html deleted file mode 100644 index 371c835d59a5..000000000000 --- a/v0.58.0/docs/supply-chain/vex/oci/index.html +++ /dev/null @@ -1,8009 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX Attestation - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Discover VEX Attestation in OCI Registry

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy can discover VEX attestations for container images. -This feature allows you to automatically use VEX during container image scanning.

    -

    How It Works

    -

    Trivy can automatically discover and utilize VEX attestations for container images during scanning by using the --vex oci flag. -This process enhances vulnerability detection results by incorporating the information from the VEX attestation.

    -

    To use this feature, follow these three steps:

    -
      -
    1. Create a VEX document
    2. -
    3. Generate and upload a VEX attestation to an OCI registry
    4. -
    5. Use the VEX attestation with Trivy
    6. -
    -

    Steps 1 and 2 are not necessary if you are trying to scan a third-party container image and already have VEX attestation attached.

    -

    Let's go through each step in detail.

    -
    -

    Note

    -

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. -If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    -
    -

    Step 1: Create a VEX Document

    -

    Currently, Trivy does not have a built-in feature to create VEX documents, so you need to create them manually. -You can refer to the OpenVEX section for guidance on creating VEX files.

    -

    For container image vulnerabilities, the product ID should be the OCI type in the PURL format. -For example:

    -
    pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy
    -
    -

    This product ID applies the VEX statement to all tags of the ghcr.io/aquasecurity/trivy container image. -If you want to declare a statement for a specific digest only, you can use:

    -
    pkg:oci/trivy@sha256:5bd5ab35814f86783561603ebb35d5d5d99006dcdcd5c3f828ea1afb4c12d159?repository_url=ghcr.io/aquasecurity/trivy
    -
    -
    -

    Note

    -

    Using an image tag, like pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy&tag=0.50.0, is not supported in the product ID at the moment.

    -
    -

    Next, specify vulnerable packages as subcomponents, such as pkg:apk/alpine/busybox. -You can also include the package version and other qualifiers (e.g., arch) to limit statements, like pkg:apk/alpine/busybox@1.36.1-r29?arch=x86.

    -

    Lastly, include the vulnerability IDs.

    -

    Here's an example VEX document:

    -
    {
    -  "@context": "https://openvex.dev/ns/v0.2.0",
    -  "@id": "https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f",
    -  "author": "Aqua Security",
    -  "timestamp": "2024-07-30T19:07:16.853479631-06:00",
    -  "version": 1,
    -  "statements": [
    -    {
    -      "vulnerability": {
    -        "name": "CVE-2023-42363"
    -      },
    -      "products": [
    -        {
    -          "@id": "pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy",
    -          "subcomponents": [
    -            {"@id": "pkg:apk/alpine/busybox"},
    -            {"@id": "pkg:apk/alpine/busybox-binsh"}
    -          ]
    -        }
    -      ],
    -      "status": "not_affected",
    -      "justification": "vulnerable_code_cannot_be_controlled_by_adversary",
    -      "impact_statement": "awk is not used"
    -    }
    -  ]
    -}
    -
    -

    You can also refer to Trivy's example for more inspiration.

    -

    Step 2: Generate and Upload a VEX Attestation to an OCI Registry

    -

    You can use the Cosign command to generate and upload the VEX attestation. -Cosign offers methods both with and without keys. -For detailed instructions, please refer to the Cosign documentation.

    -

    To generate and attach a VEX attestation to your image, use the following command:

    -
    $ cosign attest --predicate oci.openvex.json --type openvex <IMAGE>
    -
    -

    Note that this command attaches the attestation only to the specified image tag. -If needed, repeat the process for other tags and digests.

    -

    Step 3: Use VEX Attestation with Trivy

    -

    Once you've attached the VEX attestation to the container image, Trivy can automatically discover and use it during scanning. -Simply add the --vex oci flag when scanning a container image:

    -
    $ trivy image --vex oci <IMAGE>
    -
    -

    To see which vulnerabilities were filtered by the VEX attestation, use the --show-suppressed flag:

    -
    $ trivy image --vex oci --show-suppressed <IMAGE>
    -
    -

    The <IMAGE> specified in these commands must be the same as the one to which you attached the VEX attestation.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/supply-chain/vex/repo/index.html b/v0.58.0/docs/supply-chain/vex/repo/index.html deleted file mode 100644 index 8012065f43a4..000000000000 --- a/v0.58.0/docs/supply-chain/vex/repo/index.html +++ /dev/null @@ -1,8298 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VEX Repository - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    VEX Repository

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Using VEX Repository

    -

    Trivy can download and utilize VEX documents from repositories that comply with the VEX Repository Specification. -While it's planned to be enabled by default in the future, currently it can be activated by explicitly specifying --vex repo.

    -
    $ trivy image ghcr.io/aquasecurity/trivy:0.52.0 --vex repo
    -2024-07-20T11:22:58+04:00       INFO    [vex] The default repository config has been created    
    -file_path="/Users/teppei/.trivy/vex/repository.yaml"
    -2024-07-20T11:23:23+04:00       INFO    [vex] Updating repository...    repo="default" url="https://github.com/aquasecurity/vexhub"
    -
    -

    During scanning, Trivy generates PURLs for discovered packages and searches for matching PURLs in the VEX Repository. -If a match is found, the corresponding VEX is utilized.

    -

    Configuration File

    -

    Default Configuration

    -

    When --vex repo is specified for the first time, a default configuration file is created at $HOME/.trivy/vex/repository.yaml. -The home directory can be configured through environment variable $XDG_DATA_HOME.

    -

    You can also create the configuration file in advance using the trivy vex repo init command and edit it.

    -

    The default configuration file looks like this:

    -
    repositories:
    -  - name: default
    -    url: https://github.com/aquasecurity/vexhub
    -    enabled: true
    -    username: ""
    -    password: ""
    -    token: ""
    -
    -

    By default, VEX Hub managed by Aqua Security is used. -VEX Hub primarily trusts VEX documents published by the package maintainers.

    -

    Show Configuration

    -

    You can see the config file path and the configured repositories with trivy vex repo list:

    -
    $ trivy vex repo list
    -VEX Repositories (config: /home/username/.trivy/vex/repository.yaml)
    -
    -- Name: default
    -  URL: https://github.com/aquasecurity/vexhub
    -  Status: Enabled
    -
    -

    Custom Repositories

    -

    If you want to trust VEX documents published by other organizations or use your own VEX repository, you can specify a custom repository that complies with the VEX Repository Specification. -You can add a custom repository as below:

    -
    - name: custom
    -  url: https://example.com/custom-repo
    -  enabled: true
    -
    -

    Authentication

    -

    For private repositories:

    -
      -
    • username/password can be used for Basic authentication
    • -
    • token can be used for Bearer authentication
    • -
    -
    - name: custom
    -  url: https://example.com/custom-repo
    -  enabled: true
    -  token: "my-token"
    -
    -

    Repository Priority

    -

    The priority of VEX repositories is determined by their order in the configuration file. -You can add repositories with higher priority than the default or even remove the default VEX Hub.

    -
    - name: repo1
    -  url: https://example.com/repo1
    -- name: repo2
    -  url: https://example.com/repo2
    -
    -

    In this configuration, when Trivy detects a vulnerability in a package, it generates a PURL for that package and searches for matching VEX documents in the configured repositories. -The search process follows this order:

    -
      -
    1. Trivy first looks for a VEX document matching the package's PURL in repo1.
    2. -
    3. If no matching VEX document is found in repo1, Trivy then searches in repo2.
    4. -
    5. This process continues through all configured repositories until a match is found.
    6. -
    -

    If a matching VEX document is found in any repository (e.g., repo1), the search stops, and Trivy uses that VEX document. -Subsequent repositories (e.g., repo2) are not checked for that specific vulnerability and package combination.

    -

    It's important to note that the first matching VEX document found determines the final status of the vulnerability. -For example, if repo1 states that a package is "Affected" by a vulnerability, this status will be used even if repo2 states that the same package is "Not Affected" for the same vulnerability. -The "Affected" status from the higher-priority repository (repo1) takes precedence, and Trivy will consider the package as affected by the vulnerability.

    -

    Repository Updates

    -

    VEX repositories are automatically updated during scanning. -Updates are performed based on the update frequency specified by the repository.

    -

    To disable auto-update, pass --skip-vex-repo-update.

    -
    $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex repo --skip-vex-repo-update
    -
    -

    To download VEX repositories in advance without scanning, use trivy vex repo download.

    -

    The cache can be cleared with trivy clean --vex-repo.

    -

    Displaying Filtered Vulnerabilities

    -

    To see which vulnerabilities were filtered and why, use the --show-suppressed option:

    -
    $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex repo --show-suppressed
    -...
    -
    -Suppressed Vulnerabilities (Total: 4)
    -=====================================
    -┌───────────────┬────────────────┬──────────┬──────────────┬───────────────────────────────────────────────────┬──────────────────────────────────────────┐
    -│    Library     Vulnerability   Severity     Status                         Statement                                       Source                  │
    -├───────────────┼────────────────┼──────────┼──────────────┼───────────────────────────────────────────────────┼──────────────────────────────────────────┤
    -│ busybox        CVE-2023-42364  MEDIUM    not_affected  vulnerable_code_cannot_be_controlled_by_adversary  VEX Repository: default                  │
    -│                                                                                                           (https://github.com/aquasecurity/vexhub) │
    -│               ├────────────────┤                                                                                                                     │
    -│                CVE-2023-42365                                                                                                                      │
    -│                                                                                                                                                    │
    -├───────────────┼────────────────┤                                                                                                                     │
    -│ busybox-binsh  CVE-2023-42364                                                                                                                      │
    -│                                                                                                                                                    │
    -│               ├────────────────┤                                                                                                                     │
    -│                CVE-2023-42365                                                                                                                      │
    -│                                                                                                                                                    │
    -└───────────────┴────────────────┴──────────┴──────────────┴───────────────────────────────────────────────────┴──────────────────────────────────────────┘
    -
    -

    Publishing VEX Documents

    -

    For OSS Projects

    -

    As an OSS developer or maintainer, you may encounter vulnerabilities in the packages your project depends on. -These vulnerabilities might be discovered through your own scans or reported by third parties using your OSS project.

    -

    While Trivy strives to minimize false positives, it doesn't perform code graph analysis, which means it can't evaluate exploitability at the code level. -Consequently, Trivy may report vulnerabilities even in cases where:

    -
      -
    1. The vulnerable function in a dependency is never called in your project.
    2. -
    3. The vulnerable code cannot be controlled by an attacker in the context of your project.
    4. -
    -

    If you're confident that a reported vulnerability in a dependency doesn't affect your OSS project or container image, you can publish a VEX document to reduce noise in Trivy scans. -To assess exploitability, you have several options:

    -
      -
    1. Manual assessment: As a maintainer, you can read the source code and determine if the vulnerability is exploitable in your project's context.
    2. -
    3. Automated assessment: You can use SAST (Static Application Security Testing) tools or similar tools to analyze the code and determine exploitability.
    4. -
    -

    By publishing VEX documents in the source repository, Trivy can automatically utilize them through VEX Hub. -The main steps are:

    -
      -
    1. Generate a VEX document
    2. -
    3. Commit the VEX document to the .vex/ directory in the source repository (e.g., Trivy's VEX)
    4. -
    5. Register your project's PURL in VEX Hub
    6. -
    -

    Step 3 is only necessary once. -After that, updating the VEX file in your repository will automatically be fetched by VEX Hub and utilized by Trivy. -See the VEX Hub repository for more information.

    -

    If you want to issue a VEX for an OSS project that you don't maintain, consider first proposing the VEX publication to the original repository. -Many OSS maintainers are open to contributions that improve the security posture of their projects. -However, if your proposal is not accepted, or if you want to issue a VEX with statements that differ from the maintainer's judgment, you may want to consider creating a custom repository.

    -

    For Private Projects

    -

    If you're working on private software or personal projects, you have several options:

    -
      -
    1. Local VEX files: You can create local VEX files and have Trivy read them during scans. This is suitable for individual use or small teams.
    2. -
    3. .trivyignore: For simpler cases, using a .trivyignore file might be sufficient to suppress specific vulnerabilities.
    4. -
    5. Custom repositories: For large organizations wanting to share VEX information for internally used software across different departments, setting up a custom VEX repository might be the best approach.
    6. -
    -

    Hosting Custom Repositories

    -

    While the principle is to store VEX documents for OSS packages in the source repository, it's possible to create a custom repository if that's difficult.

    -

    There are various use cases for providing custom repositories:

    -
      -
    • A Pull Request to add a VEX document upstream was not merged
    • -
    • Consolidating VEX documents output by SAST tools
    • -
    • Publishing vendor-specific VEX documents that differ from OSS maintainer statements
    • -
    • Creating a private VEX repository to publish common VEX for your company
    • -
    -

    In these cases, you can create a repository that complies with the VEX Repository Specification to make it available for use with Trivy.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/container_image/index.html b/v0.58.0/docs/target/container_image/index.html deleted file mode 100644 index 2819da1dd7a7..000000000000 --- a/v0.58.0/docs/target/container_image/index.html +++ /dev/null @@ -1,8900 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Container Image - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Container Image

    -

    Trivy supports two targets for container images.

    -
      -
    • Files inside container images
    • -
    • Container image metadata
    • -
    -

    Files inside container images

    -

    Container images consist of files. -For instance, new files will be installed if you install a package.

    -

    Trivy scans the files inside container images for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    -

    Vulnerabilities

    -

    It is enabled by default. -You can simply specify your image name (and a tag). -It detects known vulnerabilities in your container image. -See here for the detail.

    -
    $ trivy image [YOUR_IMAGE_NAME]
    -
    -

    For example:

    -
    $ trivy image python:3.4-alpine
    -
    -
    -Result - -
    2019-05-16T01:20:43.180+0900    INFO    Updating vulnerability database...
    -2019-05-16T01:20:53.029+0900    INFO    Detecting Alpine vulnerabilities...
    -
    -python:3.4-alpine3.9 (alpine 3.9.2)
    -===================================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
    -
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |
    -|         |                  |          |                   |               | with long nonces               |
    -+---------+------------------+----------+-------------------+---------------+--------------------------------+
    -
    - -
    - -

    To enable only vulnerability scanning, you can specify --scanners vuln.

    -
    $ trivy image --scanners vuln [YOUR_IMAGE_NAME]
    -
    -

    Misconfigurations

    -

    It is supported, but it is not useful in most cases. -As mentioned here, Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. -If your container image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners misconfig.

    -
    $ trivy image --scanners misconfig [YOUR_IMAGE_NAME]
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy image [YOUR_IMAGE_NAME]
    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy image --scanners license [YOUR_IMAGE_NAME]
    -
    -

    Container image metadata

    -

    Container images have configuration. -docker inspect and docker history show the information according to the configuration.

    -

    Trivy scans the configuration of container images for

    -
      -
    • Misconfigurations
    • -
    • Secrets
    • -
    -

    They are disabled by default. -You can enable them with --image-config-scanners.

    -
    -

    Tips

    -

    The configuration can be exported as the JSON file by docker save.

    -
    -

    Misconfigurations

    -

    Trivy detects misconfigurations on the configuration of container images. -The image config is converted into Dockerfile and Trivy handles it as Dockerfile. -See here for the detail of Dockerfile scanning.

    -

    It is disabled by default. -You can enable it with --image-config-scanners misconfig.

    -
    $ trivy image --image-config-scanners misconfig [YOUR_IMAGE_NAME]
    -
    -
    -Result - -
    alpine:3.17 (dockerfile)
    -========================
    -Tests: 24 (SUCCESSES: 21, FAILURES: 3)
    -Failures: 3 (UNKNOWN: 0, LOW: 2, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -HIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.
    -
    -See https://avd.aquasec.com/misconfig/ds002
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -LOW: Consider using 'COPY file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' command instead of 'ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /'
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.
    -
    -See https://avd.aquasec.com/misconfig/ds005
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - alpine:3.17:1
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -   1 [ ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -LOW: Add HEALTHCHECK instruction in your Dockerfile
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.
    -
    -See https://avd.aquasec.com/misconfig/ds026
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    - -
    -

    Tip

    -

    You can see how each layer is created with docker history.

    -
    -

    The AVD-DS-0016 check is disabled for this scan type, see issue for details.

    -

    Secrets

    -

    Trivy detects secrets on the configuration of container images. -The image config is converted into JSON and Trivy scans the file for secrets. -It is especially useful for environment variables that are likely to have credentials by accident. -See here for the detail.

    -
    $ trivy image --image-config-scanners secret [YOUR_IMAGE_NAME]
    -
    -
    -Result - -
    vuln-image (alpine 3.17.1)
    -==========================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -
    -vuln-image (secrets)
    -====================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -CRITICAL: GitHub (github-pat)
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -GitHub Personal Access Token
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - test:16
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  14     {
    -  15     "created": "2023-01-09T17:05:20Z",
    -  16 [   "created_by": "ENV secret=****************************************",
    -  17     "comment": "buildkit.dockerfile.v0",
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    -
    -CRITICAL: GitHub (github-pat)
    -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
    -GitHub Personal Access Token
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    - test:34
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -  32     "Env": [
    -  33     "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    -  34 [   "secret=****************************************"
    -  35     ]
    -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    -
    - -
    - -
    -

    Tip

    -

    You can see environment variables with docker inspect.

    -
    -

    Supported

    -

    Trivy will look for the specified image in a series of locations. By default, it -will first look in the local Docker Engine, then Containerd, Podman, and -finally container registry.

    -

    This behavior can be modified with the --image-src flag. For example, the -command

    -
    trivy image --image-src podman,containerd alpine:3.7.3
    -
    -

    Will first search in Podman. If the image is found there, it will be scanned -and the results returned. If the image is not found in Podman, then Trivy will -search in Containerd. If the image is not found there either, the scan will -fail and no more image sources will be searched.

    -

    Docker Engine

    -

    Trivy tries to looks for the specified image in your local Docker Engine. -It will be skipped if Docker Engine is not running locally.

    -

    If your docker socket is not the default path, you can override it via DOCKER_HOST.

    -

    containerd

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy tries to looks for the specified image in your local containerd. -It will be skipped if containerd is not running locally.

    -

    Specify your image name in containerd running locally.

    -
    $ nerdctl images
    -REPOSITORY        TAG       IMAGE ID        CREATED         PLATFORM       SIZE         BLOB SIZE
    -aquasec/nginx    latest    2bcabc23b454    3 hours ago     linux/amd64    149.1 MiB    54.1 MiB
    -$ trivy image aquasec/nginx
    -
    -

    If your containerd socket is not the default path (//run/containerd/containerd.sock), you can override it via CONTAINERD_ADDRESS.

    -
    $ export CONTAINERD_ADDRESS=/run/k3s/containerd/containerd.sock
    -$ trivy image aquasec/nginx
    -
    -

    If your scan targets are images in a namespace other than containerd's default namespace (default), you can override it via CONTAINERD_NAMESPACE.

    -
    $ export CONTAINERD_NAMESPACE=k8s.io
    -$ trivy image aquasec/nginx
    -
    -

    Podman

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Scan your image in Podman (>=2.0) running locally. The remote Podman is not supported. -If you prefer to keep the socket open at all times, then before performing Trivy commands, you can enable the podman.sock systemd service on your machine. -For more details, see here.

    -
    $ systemctl --user enable --now podman.socket
    -
    -

    Then, you can scan your image in Podman.

    -
    $ cat Dockerfile
    -FROM alpine:3.12
    -RUN apk add --no-cache bash
    -$ podman build -t test .
    -$ podman images
    -REPOSITORY                TAG     IMAGE ID      CREATED      SIZE
    -localhost/test            latest  efc372d4e0de  About a minute ago  7.94 MB
    -$ trivy image test
    -
    -

    If you prefer not to keep the socket open at all times, but to limit the socket opening for your trivy scanning duration only then you can scan your image with the following command:

    -
    podman system service --time=0 "${TMP_PODMAN_SOCKET}" &                                                                                                                                                             
    -PODMAN_SYSTEM_SERVICE_PID="$!"                                                                                                                                                                                      
    -trivy image --podman-host="${TMP_PODMAN_SOCKET}" --docker-host="${TMP_PODMAN_SOCKET}" test
    -kill "${PODMAN_SYSTEM_SERVICE_PID}"
    -
    -

    Container Registry

    -

    Trivy supports registries that comply with the following specifications.

    - -

    You can configure credentials with trivy registry login. -See here for the detail.

    -

    Tar Files

    -

    Trivy supports image tar files generated by the following tools.

    - -
    $ docker pull ruby:3.1-alpine3.15
    -$ docker save ruby:3.1-alpine3.15 -o ruby-3.1.tar
    -$ trivy image --input ruby-3.1.tar
    -
    -
    -Result - -
    2022-02-03T10:08:19.127Z        INFO    Detected OS: alpine
    -2022-02-03T10:08:19.127Z        WARN    This OS version is not on the EOL list: alpine 3.15
    -2022-02-03T10:08:19.127Z        INFO    Detecting Alpine vulnerabilities...
    -2022-02-03T10:08:19.127Z        INFO    Number of language-specific files: 2
    -2022-02-03T10:08:19.127Z        INFO    Detecting gemspec vulnerabilities...
    -2022-02-03T10:08:19.128Z        INFO    Detecting node-pkg vulnerabilities...
    -2022-02-03T10:08:19.128Z        WARN    This OS version is no longer supported by the distribution: alpine 3.15.0
    -2022-02-03T10:08:19.128Z        WARN    The vulnerability detection may be insufficient because security updates are not provided
    -
    -ruby-3.1.tar (alpine 3.15.0)
    -============================
    -Total: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0)
    -
    -+----------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
    -+----------+------------------+----------+-------------------+---------------+---------------------------------------+
    -| gmp      | CVE-2021-43618   | HIGH     | 6.2.1-r0          | 6.2.1-r1      | gmp: Integer overflow and resultant   |
    -|          |                  |          |                   |               | buffer overflow via crafted input     |
    -|          |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-43618 |
    -+----------+                  +          +                   +               +                                       +
    -| gmp-dev  |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -+----------+                  +          +                   +               +                                       +
    -| libgmpxx |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -|          |                  |          |                   |               |                                       |
    -+----------+------------------+----------+-------------------+---------------+---------------------------------------+
    -
    -Node.js (node-pkg)
    -==================
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    -
    -Ruby (gemspec)
    -==============
    -Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
    -
    - -
    - -

    OCI Layout

    -

    Trivy supports image directories compliant with Open Container Image Layout Specification.

    -

    Buildah:

    -
    $ buildah push docker.io/library/alpine:3.11 oci:/path/to/alpine
    -$ trivy image --input /path/to/alpine
    -
    -

    Skopeo:

    -
    $ skopeo copy docker-daemon:alpine:3.11 oci:/path/to/alpine
    -$ trivy image --input /path/to/alpine
    -
    -

    Referencing specific images can be done by their tag or by their manifest digest: -

    # Referenced by tag
    -$ trivy image --input /path/to/alpine:3.15
    -
    -# Referenced by digest
    -$ trivy image --input /path/to/alpine@sha256:82389ea44e50c696aba18393b168a833929506f5b29b9d75eb817acceb6d54ba
    -

    -

    SBOM

    -

    Trivy supports the generation of Software Bill of Materials (SBOM) for container images and the search for SBOMs during vulnerability scanning.

    -

    Generation

    -

    Trivy can generate SBOM for container images. -See here for the detail.

    -

    Discovery

    -

    Trivy can search for Software Bill of Materials (SBOMs) that reference container images. -If an SBOM is found, the vulnerability scan is performed using the SBOM instead of the container image. -By using the SBOM, you can perform a vulnerability scan more quickly, as it allows you to skip pulling the container image and analyzing its layers.

    -

    To enable this functionality, you need to specify the --sbom-sources flag. -The following two sources are supported:

    -
      -
    • OCI Registry (oci)
    • -
    • Rekor (rekor)
    • -
    -

    Example:

    -
    $ trivy image --sbom-sources oci ghcr.io/knqyf263/oci-referrers
    -2023-03-05T17:36:55.278+0200    INFO    Vulnerability scanning is enabled
    -2023-03-05T17:36:58.103+0200    INFO    Detected SBOM format: cyclonedx-json
    -2023-03-05T17:36:58.129+0200    INFO    Found SBOM (cyclonedx) in the OCI referrers
    -...
    -
    -ghcr.io/knqyf263/oci-referrers (alpine 3.16.2)
    -==============================================
    -Total: 17 (UNKNOWN: 0, LOW: 0, MEDIUM: 5, HIGH: 9, CRITICAL: 3)
    -
    -

    The OCI Registry utilizes the Referrers API. -For more information about Rekor, please refer to its documentation.

    -

    Compliance

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    This section describes container image specific compliance reports. -For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    -

    Built in reports

    -

    The following reports are available out of the box:

    - - - - - - - - - - - - - - - - - -
    ComplianceVersionName for commandMore info
    CIS Docker Community Edition Benchmark1.1.0docker-cis-1.6.0Link
    -

    Examples

    -

    Scan a container image configuration and generate a compliance summary report:

    -
    trivy image --compliance docker-cis-1.6.0 [YOUR_IMAGE_NAME]
    -
    -
    -

    Note

    -

    The Issues column represent the total number of failed checks for this control.

    -
    -

    Authentication

    -

    Please reference this page.

    -

    Options

    -

    Scan Image on a specific Architecture and OS

    -

    By default, Trivy loads an image on a "linux/amd64" machine. -To customise this, pass a --platform argument in the format OS/Architecture for the image:

    -
    $ trivy image --platform=os/architecture [YOUR_IMAGE_NAME]
    -
    -

    For example:

    -
    $ trivy image --platform=linux/arm alpine:3.16.1
    -
    -
    -Result - -
    2022-10-25T21:00:50.972+0300    INFO    Vulnerability scanning is enabled
    -2022-10-25T21:00:50.972+0300    INFO    Secret scanning is enabled
    -2022-10-25T21:00:50.972+0300    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
    -2022-10-25T21:00:50.972+0300    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection
    -2022-10-25T21:00:56.190+0300    INFO    Detected OS: alpine
    -2022-10-25T21:00:56.190+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-10-25T21:00:56.191+0300    INFO    Number of language-specific files: 0
    -
    -alpine:3.16.1 (alpine 3.16.1)
    -=============================
    -Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
    -
    -┌─────────┬────────────────┬──────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
    -│ Library │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                            Title                            │
    -├─────────┼────────────────┼──────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
    -│ zlib    │ CVE-2022-37434 │ CRITICAL │ 1.2.12-r1         │ 1.2.12-r2     │ zlib: heap-based buffer over-read and overflow in inflate() │
    -│         │                │          │                   │               │ in inflate.c via a...                                       │
    -│         │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-37434                  │
    -└─────────┴────────────────┴──────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
    -
    - -
    - -

    Configure Docker daemon socket to connect to.

    -

    You can configure Docker daemon socket with DOCKER_HOST or --docker-host.

    -
    $ trivy image --docker-host tcp://127.0.0.1:2375 YOUR_IMAGE
    -
    -

    Configure Podman daemon socket to connect to.

    -

    You can configure Podman daemon socket with --podman-host.

    -
    $ trivy image --podman-host /run/user/1000/podman/podman.sock YOUR_IMAGE
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/filesystem/index.html b/v0.58.0/docs/target/filesystem/index.html deleted file mode 100644 index e98dcdf88b95..000000000000 --- a/v0.58.0/docs/target/filesystem/index.html +++ /dev/null @@ -1,8036 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filesystem - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Filesystem

    -

    Scan your local projects for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    -
    $ trivy fs /path/to/project
    -
    -

    It's also possible to scan a single file.

    -
    $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test/Pipfile.lock
    -
    -

    Scanners

    -

    Vulnerabilities

    -

    It is enabled by default. -Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. -See here for the detail.

    -
    $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test
    -
    -
    -Result - -
    2020-06-01T17:06:58.652+0300    WARN    OS is not detected and vulnerabilities in OS packages are not detected.
    -2020-06-01T17:06:58.652+0300    INFO    Detecting pipenv vulnerabilities...
    -2020-06-01T17:06:58.691+0300    INFO    Detecting cargo vulnerabilities...
    -
    -Pipfile.lock
    -============
    -Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
    -
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -|       LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |     FIXED VERSION      |               TITLE                |
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -| django              | CVE-2020-7471    | HIGH     | 2.0.9             | 3.0.3, 2.2.10, 1.11.28 | django: potential                  |
    -|                     |                  |          |                   |                        | SQL injection via                  |
    -|                     |                  |          |                   |                        | StringAgg(delimiter)               |
    -+                     +------------------+----------+                   +------------------------+------------------------------------+
    -|                     | CVE-2019-19844   | MEDIUM   |                   | 3.0.1, 2.2.9, 1.11.27  | Django: crafted email address      |
    -|                     |                  |          |                   |                        | allows account takeover            |
    -+                     +------------------+          +                   +------------------------+------------------------------------+
    -|                     | CVE-2019-3498    |          |                   | 2.1.5, 2.0.10, 1.11.18 | python-django: Content             |
    -|                     |                  |          |                   |                        | spoofing via URL path in           |
    -|                     |                  |          |                   |                        | default 404 page                   |
    -+                     +------------------+          +                   +------------------------+------------------------------------+
    -|                     | CVE-2019-6975    |          |                   | 2.1.6, 2.0.11, 1.11.19 | python-django:                     |
    -|                     |                  |          |                   |                        | memory exhaustion in               |
    -|                     |                  |          |                   |                        | django.utils.numberformat.format() |
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -...
    -
    - -
    - -

    Misconfigurations

    -

    It is disabled by default and can be enabled with --scanners misconfig. -See here for the detail.

    -
    $ trivy fs --scanners misconfig /path/to/project
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy fs /path/to/project
    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy fs --scanners license /path/to/project
    -
    -

    SBOM generation

    -

    Trivy can generate SBOM for local projects. -See here for the detail.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/kubernetes/index.html b/v0.58.0/docs/target/kubernetes/index.html deleted file mode 100644 index ced69acada80..000000000000 --- a/v0.58.0/docs/target/kubernetes/index.html +++ /dev/null @@ -1,8487 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kubernetes - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Kubernetes

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    Trivy can connect to your Kubernetes cluster and scan it for security issues using the trivy k8s command. This page covers the technical capabilities of Trivy Kubernetes scanning. -Trivy can also be installed inside your cluster as a Kubernetes Operator, and continuously scan it. For more about this, please see the Trivy Operator project.

    -

    When scanning a Kubernetes cluster, Trivy differentiates between the following:

    -
      -
    1. Cluster infrastructure (e.g api-server, kubelet, addons)
    2. -
    3. Cluster configuration (e.g Roles, ClusterRoles).
    4. -
    5. Application workloads (e.g nginx, postgresql).
    6. -
    -

    When scanning any of the above, the container image is scanned separately to the Kubernetes resource definition (the YAML manifest) that defines the resource.

    -

    Container image is scanned for:

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Exposed secrets
    • -
    -

    Kubernetes resource definition is scanned for:

    -
      -
    • Vulnerabilities (Open Source Libraries, Control Plane and Node Components)
    • -
    • Misconfigurations
    • -
    • Exposed secrets
    • -
    -

    Kubernetes target configurations

    -
    trivy k8s [flags] [CONTEXT] -  if the target name [CONTEXT] is not specified, the default will be used.
    -
    -

    for example:

    -
    trivy k8s --report summary
    -
    -

    By default Trivy will look for a kubeconfig configuration file in the default location, and use the default cluster that is specified.
    -You can also specify a kubeconfig using the --kubeconfig flag:

    -
    trivy k8s --kubeconfig ~/.kube/config2
    -
    -

    By default, all cluster resource images will be downloaded and scanned.

    -

    Skip-images

    -

    You can control whether Trivy will scan and download the cluster resource images. To disable this feature, add the --skip-images flag.

    -
      -
    • --skip-images flag will prevent the downloading and scanning of images (including vulnerabilities and secrets) in the cluster resources.
    • -
    -

    Example:

    -
    trivy k8s --report summary --skip-images
    -
    -

    Include/Exclude Kinds

    -

    You can control which kinds of resources will be discovered using the --include-kinds or --exclude-kinds comma-separated flags:

    -

    Note: Both flags (--include-kinds or --exclude-kinds) cannot be set in conjunction.

    -
      -
    • --include-kinds will include the listed kinds in cluster scanning.
    • -
    • --exclude-kinds will exclude the listed kinds from cluster scanning.
    • -
    -

    By default, all kinds will be included in cluster scanning.

    -

    Example:

    -
    trivy k8s --report summary --exclude-kinds node,pod
    -
    -

    Include/Exclude Namespaces

    -

    You can control which namespaces will be discovered using the --include-namespaces or --exclude-namespaces comma-separated flags:

    -

    Note: Both flags (--include-namespaces or --exclude-namespaces) cannot be set in conjunction.

    -
      -
    • --include-namespaces will include the listed namespaces in cluster scanning.
    • -
    • --exclude-namespaces will exclude the listed namespaces from cluster scanning.
    • -
    -

    By default, all namespaces will be included in cluster scanning.

    -

    Example:

    -
    trivy k8s --report summary --exclude-namespace dev-system,staging-system
    -
    -

    Control Plane and Node Components Vulnerability Scanning

    -

    Trivy is capable of discovering Kubernetes control plane (apiserver, controller-manager and etc) and node components(kubelet, kube-proxy and etc), matching them against the official Kubernetes vulnerability database feed, and reporting any vulnerabilities it finds.

    -

    To read more about KBOM, see the documentation for Kubernetes scanning.

    -
    trivy k8s --scanners vuln  --report all
    -
    -NodeComponents/kind-control-plane (kubernetes)
    -
    -Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 2, CRITICAL: 0)
    -
    -┌────────────────┬────────────────┬──────────┬────────┬───────────────────┬──────────────────────────────────┬───────────────────────────────────────────────────┐
    -│    Library      Vulnerability   Severity  Status  Installed Version           Fixed Version                                  Title                       │
    -├────────────────┼────────────────┼──────────┼────────┼───────────────────┼──────────────────────────────────┼───────────────────────────────────────────────────┤
    -│ k8s.io/kubelet  CVE-2023-2431   LOW       fixed   1.21.1             1.24.14, 1.25.10, 1.26.5, 1.27.2  Bypass of seccomp profile enforcement             │
    -│                                                                                                        https://avd.aquasec.com/nvd/cve-2023-2431         │
    -│                ├────────────────┼──────────┤                           ├──────────────────────────────────┼───────────────────────────────────────────────────┤
    -│                 CVE-2021-25741  HIGH                                 1.19.16, 1.20.11, 1.21.5, 1.22.1  Symlink exchange can allow host filesystem access │
    -│                                                                                                        https://avd.aquasec.com/nvd/cve-2021-25741        │
    -│                ├────────────────┤                                     ├──────────────────────────────────┼───────────────────────────────────────────────────┤
    -│                 CVE-2021-25749                                       1.22.14, 1.23.11, 1.24.5          runAsNonRoot logic bypass for Windows containers  │
    -│                                                                                                        https://avd.aquasec.com/nvd/cve-2021-25749        │
    -└────────────────┴────────────────┴──────────┴────────┴───────────────────┴──────────────────────────────────┴───────────────────────────────────────────────────┘
    -
    -

    Node-Collector

    -

    Node-collector is a scan job that collects node configuration parameters and permission information. This information will be evaluated against Kubernetes hardening (e.g. CIS benchmark) and best practices values. The scan results will be output in infrastructure assessment and CIS benchmark compliance reports.

    -

    Disable Node Collector

    -

    You can control whether the node scan-job (node-collector) will run in the cluster. To disable it, add the --disable-node-collector flag

    -
      -
    • --disable-node-collector This flag will exclude findings related to Node (infra assessment) misconfigurations
    • -
    -

    By default, the node scan-job (node-collector) will run in the cluster.

    -

    Example:

    -
    trivy k8s --report summary --disable-node-collector
    -
    -

    Taints and Tolerations

    -

    The node-collector scan-job will run on every node. In case the node has been tainted, it is possible to add toleration to the scan job for it to be scheduled on the tainted node. for more details see k8s docs

    -
      -
    • --tolerations key1=value1:NoExecute,key2=value2:NoSchedule this flag wil enable node-collector to be schedule on tainted Node
    • -
    -

    Example:

    -
    trivy k8s --report summary --tolerations  key1=value1:NoExecute,key2=value2:NoSchedule
    -
    -

    Exclude Nodes by Label

    -

    You can exclude specific nodes from the scan using the --exclude-nodes flag, which takes a label in the format label-name:label-value and excludes all matching nodes:

    -
    trivy k8s --report summary --exclude-nodes kubernetes.io/arch:arm6
    -
    -

    Reporting and filtering

    -

    Since scanning an entire cluster for any security issue can be overwhelming, By default Trivy summarizes the results in a simple "summary" view. -By scoping the scan on a specific resource, you can see the detailed report. -You can always choose the report granularity using the --report summary/--report all flag.

    -

    Scan a full cluster and generate a simple summary report:

    -
    trivy k8s --report=summary
    -
    -

    k8s Summary Report

    -

    Filter by severity:

    -
    trivy k8s --severity=CRITICAL --report=all
    -
    -

    Filter by scanners (Vulnerabilities, Secrets or Misconfigurations):

    -
    trivy k8s --scanners=secret --report=summary
    -# or
    -trivy k8s --scanners=misconfig --report=summary
    -
    -

    The supported output formats are table, which is the default, and json.

    -
    trivy k8s --format json -o results.json cluster
    -
    -
    -Result - -
    {
    -  "ClusterName": "minikube",
    -  "Vulnerabilities": [
    -    {
    -      "Namespace": "default",
    -      "Kind": "Deployment",
    -      "Name": "app",
    -      "Results": [
    -        {
    -          "Target": "ubuntu:latest (ubuntu 22.04)",
    -          "Class": "os-pkgs",
    -          "Type": "ubuntu",
    -          "Vulnerabilities": [
    -            {
    -              "VulnerabilityID": "CVE-2016-2781",
    -              "PkgName": "coreutils",
    -              "InstalledVersion": "8.32-4.1ubuntu1",
    -              "Layer": {
    -                "Digest": "sha256:125a6e411906fe6b0aaa50fc9d600bf6ff9bb11a8651727ce1ed482dc271c24c",
    -                "DiffID": "sha256:e59fc94956120a6c7629f085027578e6357b48061d45714107e79f04a81a6f0c"
    -              },
    -              "SeveritySource": "ubuntu",
    -              "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2016-2781",
    -              "DataSource": {
    -                "ID": "ubuntu",
    -                "Name": "Ubuntu CVE Tracker",
    -                "URL": "https://git.launchpad.net/ubuntu-cve-tracker"
    -              },
    -              "Title": "coreutils: Non-privileged session can escape to the parent session in chroot",
    -              "Description": "chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.",
    -              "Severity": "LOW",
    -              "CweIDs": [
    -                "CWE-20"
    -              ],
    -              "VendorSeverity": {
    -                "cbl-mariner": 2,
    -                "nvd": 2,
    -                "redhat": 2,
    -                "ubuntu": 1
    -              },
    -              "CVSS": {
    -                "nvd": {
    -                  "V2Vector": "AV:L/AC:L/Au:N/C:N/I:P/A:N",
    -                  "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N",
    -                  "V2Score": 2.1,
    -                  "V3Score": 6.5
    -                },
    -                "redhat": {
    -                  "V2Vector": "AV:L/AC:H/Au:N/C:C/I:C/A:C",
    -                  "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
    -                  "V2Score": 6.2,
    -                  "V3Score": 8.6
    -                }
    -              },
    -              "References": [
    -                "http://seclists.org/oss-sec/2016/q1/452",
    -                "http://www.openwall.com/lists/oss-security/2016/02/28/2",
    -                "http://www.openwall.com/lists/oss-security/2016/02/28/3",
    -                "https://access.redhat.com/security/cve/CVE-2016-2781",
    -                "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2781",
    -                "https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E",
    -                "https://lore.kernel.org/patchwork/patch/793178/",
    -                "https://nvd.nist.gov/vuln/detail/CVE-2016-2781"
    -              ],
    -              "PublishedDate": "2017-02-07T15:59:00Z",
    -              "LastModifiedDate": "2021-02-25T17:15:00Z"
    -            }
    -          ]
    -        }
    -      ]
    -    }
    -  ],
    -  "Misconfigurations": [
    -    {
    -      "Namespace": "default",
    -      "Kind": "Deployment",
    -      "Name": "app",
    -      "Results": [
    -        {
    -          "Target": "Deployment/app",
    -          "Class": "config",
    -          "Type": "kubernetes",
    -          "MisconfSummary": {
    -            "Successes": 20,
    -            "Failures": 19
    -          },
    -          "Misconfigurations": [
    -            {
    -              "Type": "Kubernetes Security Check",
    -              "ID": "KSV001",
    -              "Title": "Process can elevate its own privileges",
    -              "Description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.",
    -              "Message": "Container 'app' of Deployment 'app' should set 'securityContext.allowPrivilegeEscalation' to false",
    -              "Namespace": "builtin.kubernetes.KSV001",
    -              "Query": "data.builtin.kubernetes.KSV001.deny",
    -              "Resolution": "Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.",
    -              "Severity": "MEDIUM",
    -              "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv001",
    -              "References": [
    -                "https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted",
    -                "https://avd.aquasec.com/misconfig/ksv001"
    -              ],
    -              "Status": "FAIL",
    -              "Layer": {},
    -              "IacMetadata": {
    -                "Provider": "Kubernetes",
    -                "Service": "general",
    -                "StartLine": 121,
    -                "EndLine": 133
    -              }
    -            },
    -            {
    -              "Type": "Kubernetes Security Check",
    -              "ID": "KSV003",
    -              "Title": "Default capabilities not dropped",
    -              "Description": "The container should drop all default capabilities and add only those that are needed for its execution.",
    -              "Message": "Container 'app' of Deployment 'app' should add 'ALL' to 'securityContext.capabilities.drop'",
    -              "Namespace": "builtin.kubernetes.KSV003",
    -              "Query": "data.builtin.kubernetes.KSV003.deny",
    -              "Resolution": "Add 'ALL' to containers[].securityContext.capabilities.drop.",
    -              "Severity": "LOW",
    -              "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv003",
    -              "References": [
    -                "https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/",
    -                "https://avd.aquasec.com/misconfig/ksv003"
    -              ],
    -              "Status": "FAIL",
    -              "Layer": {},
    -              "IacMetadata": {
    -                "Provider": "Kubernetes",
    -                "Service": "general",
    -                "StartLine": 121,
    -                "EndLine": 133
    -              }
    -            }
    -          ]
    -        }
    -      ]
    -    },
    -    {
    -      "Namespace": "default",
    -      "Kind": "ConfigMap",
    -      "Name": "kube-root-ca.crt"
    -    }
    -  ]
    -}
    -
    - -
    - -

    Compliance

    -

    This section describes Kubernetes specific compliance reports. -For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    -

    The following reports are available out of the box:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ComplianceName for commandMore info
    NSA, CISA Kubernetes Hardening Guidance v1.0k8s-nsa-1.0Link
    CIS Benchmark for Kubernetes v1.23k8s-cis-1.23Link
    CIS Benchmark for RKE2 v1.24rke2-cis-1.24Link
    CIS Benchmark for EKS v1.4eks-cis-1.4Link
    Pod Security Standards, Baselinek8s-pss-baseline-0.1Link
    Pod Security Standards, Restrictedk8s-pss-restricted-0.1Link
    -

    Examples:

    -

    Scan the cluster for Kubernetes Pod Security Standards Baseline compliance:

    -
    trivy k8s --compliance=k8s-pss-baseline --report summary
    -
    -

    Get the detailed report for checks:

    -
    trivy k8s --compliance=k8s-cis-1.23 --report all
    -
    -

    Get summary report in JSON format:

    -
    trivy k8s --compliance=k8s-cis-1.23 --report summary --format json
    -
    -

    Get detailed report in JSON format:

    -
    trivy k8s --compliance=k8s-cis-1.23 --report all --format json
    -
    -

    KBOM

    -

    KBOM, Kubernetes Bill of Materials, is a manifest of all the important components that make up your Kubernetes cluster – Control plane components, Node Components, and Addons, including their versions and images. Which “api-server” version are you currently running? Which flavor of "kubelet" is running on each node? What kind of etcd or storage are you currently using? And most importantly – are there any vulnerabilities known to affect these components? These are all questions that KBOM can help you answer.
    -For more background on KBOM, see here.

    -

    Trivy can generate KBOM in CycloneDX format:

    -
    trivy k8s --format cyclonedx --output mykbom.cdx.json
    -
    -

    Trivy can also scan that generated KBOM (or any SBOM) for vulnerabilities:

    -
    trivy sbom mykbom.cdx.json
    -
    -
    -Result - -
    2023-09-28T22:52:25.707+0300    INFO    Vulnerability scanning is enabled
    - 2023-09-28T22:52:25.707+0300    INFO    Detected SBOM format: cyclonedx-json
    - 2023-09-28T22:52:25.717+0300    WARN    No OS package is detected. Make sure you haven't deleted any files that contain information about the installed packages.
    - 2023-09-28T22:52:25.717+0300    WARN    e.g. files under "/lib/apk/db/", "/var/lib/dpkg/" and "/var/lib/rpm"
    - 2023-09-28T22:52:25.717+0300    INFO    Detected OS: debian gnu/linux
    - 2023-09-28T22:52:25.717+0300    WARN    unsupported os : debian gnu/linux
    - 2023-09-28T22:52:25.717+0300    INFO    Number of language-specific files: 3
    - 2023-09-28T22:52:25.717+0300    INFO    Detecting kubernetes vulnerabilities...
    - 2023-09-28T22:52:25.718+0300    INFO    Detecting gobinary vulnerabilities...
    - Kubernetes (kubernetes)
    - Total: 2 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    - ┌────────────────┬────────────────┬──────────┬────────┬───────────────────┬─────────────────────────────────┬──────────────────────────────────────────────────┐
    -     Library      Vulnerability   Severity  Status  Installed Version           Fixed Version                                Title                       │
    - ├────────────────┼────────────────┼──────────┼────────┼───────────────────┼─────────────────────────────────┼──────────────────────────────────────────────────┤
    -  k8s.io/kubelet  CVE-2021-25749  HIGH      fixed   1.24.0             1.22.14, 1.23.11, 1.24.5         runAsNonRoot logic bypass for Windows containers │
    -                                                                                                        https://avd.aquasec.com/nvd/cve-2021-25749       │
    -                 ├────────────────┼──────────┤                           ├─────────────────────────────────┼──────────────────────────────────────────────────┤
    -                  CVE-2023-2431   LOW                                  1.24.14, 1.25.9, 1.26.4, 1.27.1  Bypass of seccomp profile enforcement            │
    -                                                                                                        https://avd.aquasec.com/nvd/cve-2023-2431        │
    - └────────────────┴────────────────┴──────────┴────────┴───────────────────┴─────────────────────────────────┴──────────────────────────────────────────────────┘
    -
    - -
    - -

    Find more in the documentation for SBOM scanning.

    -

    Currently KBOM vulnerability matching works for plain Kubernetes distributions and does not work well for vendor variants, including some cloud managed distributions.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/repository/index.html b/v0.58.0/docs/target/repository/index.html deleted file mode 100644 index 19ffbef820e2..000000000000 --- a/v0.58.0/docs/target/repository/index.html +++ /dev/null @@ -1,8216 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code Repository - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Code Repository

    -

    Scan your local or remote code repositories for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    -
    $ trivy repo (REPO_PATH | REPO_URL)
    -
    -

    For example, you can scan a local repository as below.

    -
    $ trivy repo ./
    -
    -

    It's also possible to scan a single file.

    -
    $ trivy repo ./trivy-ci-test/Pipfile.lock
    -
    -

    To scan remote code repositories, you need to specify the URL.

    -
    $ trivy repo https://github.com/aquasecurity/trivy-ci-test
    -
    -

    Rationale

    -

    trivy repo is designed to scan code repositories, and it is intended to be used for scanning local/remote repositories in your machine or in your CI environment. -Therefore, unlike container/VM image scanning, it targets lock files such as package-lock.json and does not target artifacts like JAR files, binary files, etc. -See here for the detail.

    -

    Scanners

    -

    Vulnerabilities

    -

    It is enabled by default. -Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. -See here for the detail.

    -
    $ trivy repo ~/src/github.com/aquasecurity/trivy-ci-test
    -
    -
    -Result - -
    2020-06-01T17:06:58.652+0300    WARN    OS is not detected and vulnerabilities in OS packages are not detected.
    -2020-06-01T17:06:58.652+0300    INFO    Detecting pipenv vulnerabilities...
    -2020-06-01T17:06:58.691+0300    INFO    Detecting cargo vulnerabilities...
    -
    -Pipfile.lock
    -============
    -Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
    -
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -|       LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |     FIXED VERSION      |               TITLE                |
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -| django              | CVE-2020-7471    | HIGH     | 2.0.9             | 3.0.3, 2.2.10, 1.11.28 | django: potential                  |
    -|                     |                  |          |                   |                        | SQL injection via                  |
    -|                     |                  |          |                   |                        | StringAgg(delimiter)               |
    -+                     +------------------+----------+                   +------------------------+------------------------------------+
    -|                     | CVE-2019-19844   | MEDIUM   |                   | 3.0.1, 2.2.9, 1.11.27  | Django: crafted email address      |
    -|                     |                  |          |                   |                        | allows account takeover            |
    -+                     +------------------+          +                   +------------------------+------------------------------------+
    -|                     | CVE-2019-3498    |          |                   | 2.1.5, 2.0.10, 1.11.18 | python-django: Content             |
    -|                     |                  |          |                   |                        | spoofing via URL path in           |
    -|                     |                  |          |                   |                        | default 404 page                   |
    -+                     +------------------+          +                   +------------------------+------------------------------------+
    -|                     | CVE-2019-6975    |          |                   | 2.1.6, 2.0.11, 1.11.19 | python-django:                     |
    -|                     |                  |          |                   |                        | memory exhaustion in               |
    -|                     |                  |          |                   |                        | django.utils.numberformat.format() |
    -+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+
    -...
    -
    - -
    - -

    Misconfigurations

    -

    It is disabled by default and can be enabled with --scanners misconfig. -See here for the detail.

    -
    $ trivy repo --scanners misconfig (REPO_PATH | REPO_URL)
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy repo (REPO_PATH | REPO_URL)
    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy repo --scanners license (REPO_PATH | REPO_URL)
    -
    -

    SBOM generation

    -

    Trivy can generate SBOM for code repositories. -See here for the detail.

    -

    References

    -

    The following flags and environmental variables are available for remote git repositories.

    -

    Scanning a Branch

    -

    Pass a --branch argument with a valid branch name on the remote repository provided:

    -
    $ trivy repo --branch <branch-name> <repo-name>
    -
    -

    Scanning upto a Commit

    -

    Pass a --commit argument with a valid commit hash on the remote repository provided:

    -
    $ trivy repo --commit <commit-hash> <repo-name>
    -
    -

    Scanning a Tag

    -

    Pass a --tag argument with a valid tag on the remote repository provided:

    -
    $ trivy repo --tag <tag-name> <repo-name>
    -
    -

    Scanning Private Repositories

    -

    In order to scan private GitHub or GitLab repositories, the environment variable GITHUB_TOKEN or GITLAB_TOKEN must be set, respectively, with a valid token that has access to the private repository being scanned.

    -

    The GITHUB_TOKEN environment variable will take precedence over GITLAB_TOKEN, so if a private GitLab repository will be scanned, then GITHUB_TOKEN must be unset.

    -

    You can find how to generate your GitHub Token in the following GitHub documentation.

    -

    For example:

    -
    $ export GITHUB_TOKEN="your_private_github_token"
    -$ trivy repo <your private GitHub repo URL>
    -
    -# or
    -$ export GITLAB_TOKEN="your_private_gitlab_token"
    -$ trivy repo <your private GitLab repo URL>
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/rootfs/index.html b/v0.58.0/docs/target/rootfs/index.html deleted file mode 100644 index f692fc9b9327..000000000000 --- a/v0.58.0/docs/target/rootfs/index.html +++ /dev/null @@ -1,7790 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rootfs - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Rootfs

    -

    Rootfs scanning is for special use cases such as

    - -
    $ trivy rootfs /path/to/rootfs
    -
    -
    -

    Note

    -

    Rootfs scanning works differently from the Filesystem scanning. -You should use trivy fs to scan your local projects in CI/CD. -See here for the differences.

    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/sbom/index.html b/v0.58.0/docs/target/sbom/index.html deleted file mode 100644 index 3592585584d8..000000000000 --- a/v0.58.0/docs/target/sbom/index.html +++ /dev/null @@ -1,8036 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SBOM - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    SBOM scanning

    -

    Trivy can take the following SBOM formats as an input and scan for vulnerabilities and licenses.

    -
      -
    • CycloneDX
    • -
    • SPDX
    • -
    • SPDX JSON
    • -
    • CycloneDX-type attestation
    • -
    • KBOM in CycloneDX format
    • -
    -

    To scan SBOM, you can use the sbom subcommand and pass the path to the SBOM. -The input format is automatically detected.

    -
    $ trivy sbom /path/to/sbom_file
    -
    -

    By default, vulnerability scan in SBOM is executed. You can use --scanners vuln,license -command property to select also license scan, or --scanners license alone.

    -
    -

    Note

    -

    Passing SBOMs generated by tool other than Trivy may result in inaccurate detection -because Trivy relies on custom properties in SBOM for accurate scanning.

    -
    -

    CycloneDX

    -

    Trivy supports CycloneDX as an input.

    -
    -

    Note

    -

    CycloneDX XML is not supported at the moment.

    -
    -
    $ trivy sbom /path/to/cyclonedx.json
    -
    -

    SPDX

    -

    Trivy supports the SPDX SBOM as an input.

    -

    The following SPDX formats are supported:

    -
      -
    • Tag-value (--format spdx)
    • -
    • JSON (--format spdx-json)
    • -
    -
    $ trivy image --format spdx-json --output spdx.json alpine:3.16.0
    -$ trivy sbom spdx.json
    -
    -
    -Result - -
    2022-09-15T21:32:27.168+0300    INFO    Vulnerability scanning is enabled
    -2022-09-15T21:32:27.169+0300    INFO    Detected SBOM format: spdx-json
    -2022-09-15T21:32:27.210+0300    INFO    Detected OS: alpine
    -2022-09-15T21:32:27.210+0300    INFO    Detecting Alpine vulnerabilities...
    -2022-09-15T21:32:27.211+0300    INFO    Number of language-specific files: 0
    -
    -spdx.json (alpine 3.16.0)
    -=========================
    -Total: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 1)
    -
    -┌──────────────┬────────────────┬──────────┬───────────────────┬───────────────┬────────────────────────────────────────────────────────────┐
    -│   Library    │ Vulnerability  │ Severity │ Installed Version │ Fixed Version │                           Title                            │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ busybox      │ CVE-2022-30065 │ HIGH     │ 1.35.0-r13        │ 1.35.0-r15    │ busybox: A use-after-free in Busybox's awk applet leads to │
    -│              │                │          │                   │               │ denial of service...                                       │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-30065                 │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ libcrypto1.1 │ CVE-2022-2097  │ MEDIUM   │ 1.1.1o-r0         │ 1.1.1q-r0     │ openssl: AES OCB fails to encrypt some bytes               │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-2097                  │
    -├──────────────┤                │          │                   │               │                                                            │
    -│ libssl1.1    │                │          │                   │               │                                                            │
    -│              │                │          │                   │               │                                                            │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ ssl_client   │ CVE-2022-30065 │ HIGH     │ 1.35.0-r13        │ 1.35.0-r15    │ busybox: A use-after-free in Busybox's awk applet leads to │
    -│              │                │          │                   │               │ denial of service...                                       │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-30065                 │
    -├──────────────┼────────────────┼──────────┼───────────────────┼───────────────┼────────────────────────────────────────────────────────────┤
    -│ zlib         │ CVE-2022-37434 │ CRITICAL │ 1.2.12-r1         │ 1.2.12-r2     │ zlib: a heap-based buffer over-read or buffer overflow in  │
    -│              │                │          │                   │               │ inflate in inflate.c...                                    │
    -│              │                │          │                   │               │ https://avd.aquasec.com/nvd/cve-2022-37434                 │
    -└──────────────┴────────────────┴──────────┴───────────────────┴───────────────┴────────────────────────────────────────────────────────────┘
    -
    - -
    - -

    SBOM attestation

    -

    You can also scan an SBOM attestation. -In the following example, Cosign gets an attestation and Trivy scans it. -You must create CycloneDX-type attestation before trying the example. -To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the SBOM attestation page.

    -
    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE> > sbom.cdx.intoto.jsonl
    -$ trivy sbom ./sbom.cdx.intoto.jsonl
    -
    -sbom.cdx.intoto.jsonl (alpine 3.7.3)
    -=========================
    -Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)
    -
    -┌────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────┐
    -│  Library    Vulnerability   Severity  Installed Version  Fixed Version                           Title                           │
    -├────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────┤
    -│ musl        CVE-2019-14697  CRITICAL  1.1.18-r3          1.1.18-r4      musl libc through 1.1.23 has an x87 floating-point stack │
    -│                                                                         adjustment im ......                                     │
    -│                                                                         https://avd.aquasec.com/nvd/cve-2019-14697               │
    -├────────────┤                                                                                                                      │
    -│ musl-utils                                                                                                                       │
    -│                                                                                                                                  │
    -│                                                                                                                                  │
    -└────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────┘
    -
    -

    KBOM

    -

    To read more about KBOM, see the documentation for Kubernetes scanning.

    -

    The supported Kubernetes distributions for core components vulnerability scanning are:

    - -
    $ trivy k8s --format cyclonedx cluster -o kbom.json
    -$ trivy sbom kbom.json
    -2023-09-28T22:52:25.707+0300    INFO    Vulnerability scanning is enabled
    -2023-09-28T22:52:25.717+0300    INFO    Number of language-specific files: 3
    -2023-09-28T22:52:25.717+0300    INFO    Detecting kubernetes vulnerabilities...
    -2023-09-28T22:52:25.718+0300    INFO    Detecting gobinary vulnerabilities...
    -
    -Kubernetes (kubernetes)
    -
    -Total: 2 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    -
    -
    -┌────────────────┬────────────────┬──────────┬────────┬───────────────────┬────────────────────────────────┬──────────────────────────────────────────────────┐
    -│    Library      Vulnerability   Severity  Status  Installed Version           Fixed Version                          Title                            │
    -├────────────────┼────────────────┼──────────┼────────┼───────────────────┼────────────────────────────────┼──────────────────────────────────────────────────┤
    -│ k8s.io/kubelet  CVE-2021-25749  HIGH      fixed   1.24.0             1.22.14, 1.23.11, 1.24.5        runAsNonRoot logic bypass for Windows containers │
    -│                                                                                                      https://avd.aquasec.com/nvd/cve-2021-25749       │
    -│                ├────────────────┼──────────┤                           ├────────────────────────────────┼──────────────────────────────────────────────────┤
    -│                 CVE-2023-2431   LOW                                 │1.24.14, 1.25.9, 1.26.4, 1.27.1  Bypass of seccomp profile enforcement            │
    -│                                                                                                      https://avd.aquasec.com/nvd/cve-2023-2431        │
    -└────────────────┴────────────────┴──────────┴────────┴───────────────────┴────────────────────────────────┴──────────────────────────────────────────────────┘
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/docs/target/vm/index.html b/v0.58.0/docs/target/vm/index.html deleted file mode 100644 index f725ff7cb674..000000000000 --- a/v0.58.0/docs/target/vm/index.html +++ /dev/null @@ -1,8603 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Virtual Machine Image - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Virtual Machine Image

    -
    -

    EXPERIMENTAL

    -

    This feature might change without preserving backwards compatibility.

    -
    -

    To scan virtual machine (VM) images, you can use the vm subcommand.

    -

    Targets

    -

    The following targets are currently supported:

    -
      -
    • Local file
    • -
    • AWS EC2
        -
      • Amazon Machine Image (AMI)
      • -
      • Amazon Elastic Block Store (EBS) Snapshot
      • -
      -
    • -
    -

    Local file

    -

    Pass the path to your local VM image file.

    -
    $ trivy vm --scanners vuln disk.vmdk
    -
    -
    -Result - -
    disk.vmdk (amazon 2 (Karoo))
    -===========================================================================================
    -Total: 802 (UNKNOWN: 0, LOW: 17, MEDIUM: 554, HIGH: 221, CRITICAL: 10)
    -
    -┌────────────────────────────┬────────────────┬──────────┬───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────────────────────────────┐
    -│          Library           │ Vulnerability  │ Severity │       Installed Version       │         Fixed Version         │                            Title                             │
    -├────────────────────────────┼────────────────┼──────────┼───────────────────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ amazon-ssm-agent           │ CVE-2022-24675 │ HIGH     │ 3.0.529.0-1.amzn2             │ 3.1.1575.0-1.amzn2            │ golang: encoding/pem: fix stack overflow in Decode           │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2022-24675                   │
    -├────────────────────────────┼────────────────┤          ├───────────────────────────────┼───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ bind-export-libs           │ CVE-2021-25215 │          │ 32:9.11.4-26.P2.amzn2.4       │ 32:9.11.4-26.P2.amzn2.5       │ bind: An assertion check can fail while answering queries    │
    -│                            │                │          │                               │                               │ for DNAME records...                                         │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25215                   │
    -│                            ├────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                            │ CVE-2021-25214 │ MEDIUM   │                               │ 32:9.11.4-26.P2.amzn2.5.2     │ bind: Broken inbound incremental zone update (IXFR) can      │
    -│                            │                │          │                               │                               │ cause named to terminate...                                  │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25214                   │
    -├────────────────────────────┼────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ bind-libs                  │ CVE-2021-25215 │ HIGH     │                               │ 32:9.11.4-26.P2.amzn2.5       │ bind: An assertion check can fail while answering queries    │
    -│                            │                │          │                               │                               │ for DNAME records...                                         │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25215                   │
    -│                            ├────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                            │ CVE-2021-25214 │ MEDIUM   │                               │ 32:9.11.4-26.P2.amzn2.5.2     │ bind: Broken inbound incremental zone update (IXFR) can      │
    -│                            │                │          │                               │                               │ cause named to terminate...                                  │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25214                   │
    -├────────────────────────────┼────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│ bind-libs-lite             │ CVE-2021-25215 │ HIGH     │                               │ 32:9.11.4-26.P2.amzn2.5       │ bind: An assertion check can fail while answering queries    │
    -│                            │                │          │                               │                               │ for DNAME records...                                         │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25215                   │
    -│                            ├────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -│                            │ CVE-2021-25214 │ MEDIUM   │                               │ 32:9.11.4-26.P2.amzn2.5.2     │ bind: Broken inbound incremental zone update (IXFR) can      │
    -│                            │                │          │                               │                               │ cause named to terminate...                                  │
    -│                            │                │          │                               │                               │ https://avd.aquasec.com/nvd/cve-2021-25214                   │
    -├────────────────────────────┼────────────────┼──────────┤                               ├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
    -...
    -
    - -
    - -

    Amazon Machine Image (AMI)

    -

    You can specify your AMI ID with the ami: prefix.

    -
    $ trivy vm ami:${your_ami_id}
    -
    -
    -

    Note

    -

    AMIs in the marketplace are not supported because the EBS direct APIs don't support that. -See the AWS documentation for the detail.

    -
    -

    Example

    -
    $ trivy vm --scanners vuln ami:ami-0123456789abcdefg
    -
    -

    If you want to scan a AMI of non-default setting region, you can set any region via --aws-region option.

    -
    $ trivy vm --aws-region ap-northeast-1 ami:ami-0123456789abcdefg
    -
    -

    Required Actions

    -

    Some actions on EBS are also necessary since Trivy scans an EBS snapshot tied to the specified AMI under the hood.

    -
      -
    • ec2:DescribeImages
    • -
    • ebs:ListSnapshotBlocks
    • -
    • ebs:GetSnapshotBlock
    • -
    -

    Amazon Elastic Block Store (EBS) Snapshot

    -

    You can specify your EBS snapshot ID with the ebs: prefix.

    -
    $ trivy vm ebs:${your_ebs_snapshot_id}
    -
    -
    -

    Note

    -

    Public snapshots are not supported because the EBS direct APIs don't support that. -See the AWS documentation for the detail.

    -
    -

    Example

    -
    $ trivy vm --scanners vuln ebs:snap-0123456789abcdefg
    -
    -

    If you want to scan an EBS Snapshot of non-default setting region, you can set any region via --aws-region option.

    -
    $ trivy vm --aws-region ap-northeast-1 ebs:ebs-0123456789abcdefg
    -
    -

    The above command takes a while as it calls EBS API and fetches the EBS blocks. -If you want to scan the same snapshot several times, you can download the snapshot locally by using coldsnap maintained by AWS. -Then, Trivy can scan the local VM image file.

    -
    $ coldsnap download snap-0123456789abcdefg disk.img
    -$ trivy vm ./disk.img
    -
    -

    Required Actions

    -
      -
    • ebs:ListSnapshotBlocks
    • -
    • ebs:GetSnapshotBlock
    • -
    -

    Scanners

    -

    Trivy supports VM image scanning for

    -
      -
    • Vulnerabilities
    • -
    • Misconfigurations
    • -
    • Secrets
    • -
    • Licenses
    • -
    -

    Vulnerabilities

    -

    It is enabled by default. -You can simply specify your VM image location. -It detects known vulnerabilities in your VM image. -See here for the detail.

    -
    $ trivy vm [YOUR_VM_IMAGE]
    -
    -

    Misconfigurations

    -

    It is supported, but it is not useful in most cases. -As mentioned here, Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. -If your VM image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners misconfig.

    -
    $ trivy vm --scanners misconfig [YOUR_VM_IMAGE]
    -
    -

    Secrets

    -

    It is enabled by default. -See here for the detail.

    -
    $ trivy vm [YOUR_VM_IMAGE]
    -
    -
    -

    Tip

    -

    The scanning could be faster if you enable only vulnerability scanning (--scanners vuln) because Trivy tries to download only necessary blocks for vulnerability detection.

    -
    -

    Licenses

    -

    It is disabled by default. -See here for the detail.

    -
    $ trivy vm --scanners license [YOUR_VM_IMAGE]
    -
    -

    SBOM generation

    -

    Trivy can generate SBOM for VM images. -See here for the detail.

    -

    Supported Architectures

    -

    Virtual machine images

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Image formatSupport
    VMDK
    OVA
    VHD
    VHDX
    QCOW2
    -

    VMDK disk types

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    VMDK disk typeSupport
    streamOptimized
    monolithicSparse
    vmfs
    vmfsSparse
    twoGbMaxExtentSparse
    monolithicFlat
    twoGbMaxExtentFlat
    vmfsRaw
    fullDevice
    partitionedDevice
    vmfsRawDeviceMap
    vmfsPassthroughRawDeviceMap
    -

    Reference: VMware Virtual Disk Format 1.1.pdf

    -

    Disk partitions

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Disk formatSupport
    Master boot record (MBR)
    Extended master boot record
    GUID partition table (GPT)
    Logical volume manager (LVM)
    -

    Filesystems

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Filesystem formatSupport
    XFS
    EXT4
    EXT2/3
    ZFS
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/ecosystem/cicd/index.html b/v0.58.0/ecosystem/cicd/index.html deleted file mode 100644 index 05473ad86d61..000000000000 --- a/v0.58.0/ecosystem/cicd/index.html +++ /dev/null @@ -1,8117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CI/CD - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    CI/CD Integrations

    -

    Azure DevOps (Official)

    -

    Azure Devops is Microsoft Azure cloud native CI/CD service.

    -

    Trivy has a "Azure Devops Pipelines Task" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-azure-pipelines-task

    -

    GitHub Actions

    -

    GitHub Actions is GitHub's native CI/CD and job orchestration service.

    -

    trivy-action (Official)

    -

    GitHub Action for integrating Trivy into your GitHub pipeline

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-action

    -

    trivy-action (Community)

    -

    GitHub Action to scan vulnerability using Trivy. If vulnerabilities are found by Trivy, it creates a GitHub Issue.

    -

    👉 Get it at: https://github.com/marketplace/actions/trivy-action

    -

    trivy-github-issues (Community)

    -

    In this action, Trivy scans the dependency files such as package-lock.json and go.sum in your repository, then create GitHub issues according to the result.

    -

    👉 Get it at: https://github.com/marketplace/actions/trivy-github-issues

    -

    Buildkite Plugin (Community)

    -

    The trivy buildkite plugin provides a convenient mechanism for running the open-source trivy static analysis tool on your project.

    -

    👉 Get it at: https://github.com/equinixmetal-buildkite/trivy-buildkite-plugin

    -

    Dagger (Community)

    -

    Dagger is CI/CD as code that runs anywhere.

    -

    The Dagger module for Trivy provides functions for scanning container images from registries as well as Dagger Container objects from any Dagger SDK (e.g. Go, Python, Node.js, etc).

    -

    👉 Get it at: https://daggerverse.dev/mod/github.com/jpadams/daggerverse/trivy

    -

    Semaphore (Community)

    -

    Semaphore is a CI/CD service.

    -

    You can use Trivy in Semaphore for scanning code, containers, infrastructure, and Kubernetes in Semaphore workflow.

    -

    👉 Get it at: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy

    -

    CircleCI (Community)

    -

    CircleCI is a CI/CD service.

    -

    You can use the Trivy Orb for Circle CI to introduce security scanning into your workflow.

    -

    👉 Get it at: https://circleci.com/developer/orbs/orb/fifteen5/trivy-orb -Source: https://github.com/15five/trivy-orb

    -

    Woodpecker CI (Community)

    -

    Example Trivy step in pipeline

    -
    pipeline:
    -  securitycheck:
    -    image: aquasec/trivy:latest
    -    commands:
    -      # use any trivy command, if exit code is 0 woodpecker marks it as passed, else it assumes it failed
    -      - trivy fs --exit-code 1 --skip-dirs web/ --skip-dirs docs/ --severity MEDIUM,HIGH,CRITICAL .
    -
    -

    Woodpecker does use Trivy itself so you can see it in use there.

    -

    Concourse CI (Community)

    -

    Concourse CI is a CI/CD service.

    -

    You can use Trivy Resource in Concourse for scanning containers and introducing security scanning into your workflow. -It has capabilities to fail the pipeline, create issues, alert communication channels (using respective resources) based on Trivy scan output.

    -

    👉 Get it at: https://github.com/Comcast/trivy-resource/

    -

    SecObserve GitHub actions and GitLab templates (Community)

    -

    SecObserve GitHub actions and GitLab templates run various vulnerability scanners, providing uniform methods and parameters for launching the tools.

    -

    The Trivy integration supports scanning Docker images and local filesystems for vulnerabilities as well as scanning IaC files for misconfigurations.

    -

    👉 Get it at: https://github.com/MaibornWolff/secobserve_actions_templates

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/ecosystem/ide/index.html b/v0.58.0/ecosystem/ide/index.html deleted file mode 100644 index 9d15399b6ae8..000000000000 --- a/v0.58.0/ecosystem/ide/index.html +++ /dev/null @@ -1,8106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IDE and Dev tools - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    IDE and developer tools Integrations

    -

    VSCode (Official)

    -

    Visual Studio Code is an open source versatile code editor and development environment.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-vscode-extension

    -

    JetBrains (Official)

    -

    JetBrains makes IDEs such as Goland, Pycharm, IntelliJ, Webstorm, and more.

    -

    The Trivy plugin for JetBrains IDEs lets you use Trivy right from your development environment.

    -

    👉 Get it at: https://plugins.jetbrains.com/plugin/18690-trivy-findings-explorer

    -

    Kubernetes Lens (Official)

    -

    Kubernetes Lens is a management application for Kubernetes clusters.

    -

    Trivy has an extension for Kubernetes Lens that lets you scan Kubernetes workloads and view the results in the Lens UI.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-operator-lens-extension

    -

    Vim (Community)

    -

    Vim is a terminal based text editor.

    -

    Vim plugin for Trivy to install and run Trivy.

    -

    👉 Get it at: https://github.com/aquasecurity/vim-trivy

    -

    Docker Desktop (Community)

    -

    Docker Desktop is an easy way to install Docker container engine on your development machine, and manage it in a GUI .

    -

    Trivy Docker Desktop extension for scanning container images for vulnerabilities and generating SBOMs

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-docker-extension

    -

    Rancher Desktop (Community)

    -

    Rancher Desktop is an easy way to use containers and Kubernetes on your development machine, and manage it in a GUI.

    -

    Trivy is natively integrated with Rancher, no installation is needed. More info in Rancher documentation: https://docs.rancherdesktop.io/ui/images/#scanning-images

    -

    LazyTrivy (Community)

    -

    A terminal native UI for Trivy

    -

    👉 Get it at: https://github.com/owenrumney/lazytrivy

    -

    Trivy Vulnerability explorer (Community)

    -

    Web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table

    -

    👉 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer

    -

    Trivy pre-commit (Community)

    -

    A trivy pre-commit hook that runs a trivy fs in your git repo before commiting, preventing you from commiting secrets in the first place.

    -

    👉 Get it at: https://github.com/mxab/pre-commit-trivy

    -

    AWS CDK

    -

    The AWS Cloud Development Kit (AWS CDK) is an open-source software development framework to define cloud infrastructure in code and provision it through AWS CloudFormation.

    -

    image-scanner-with-trivy (Community)

    -

    A CDK Construct Library to scan an image with trivy in CDK codes.

    -

    👉 Get it at: https://constructs.dev/packages/image-scanner-with-trivy

    -

    Headlamp plugin (Community)

    -

    Headlamp is a user-friendly Kubernetes UI focused on extensibility. The Kubescape plugin extends Headlamp with views on Trivy reports.

    -

    👉 Get it at: https://github.com/kubebeam/trivy-headlamp-plugin

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/ecosystem/index.html b/v0.58.0/ecosystem/index.html deleted file mode 100644 index 544a87d3d4e9..000000000000 --- a/v0.58.0/ecosystem/index.html +++ /dev/null @@ -1,7818 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Ecosystem

    -

    Trivy is integrated into many popular tools and applications, so that you can easily add security to your workflow.

    -

    In this section you will find an aggregation of the different integrations. Integrations are listed as either "official" or "community". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers.

    -

    👈 Please use the side-navigation on the left in order to browse the different topics.

    -

    Add missing integration

    -

    We are happy to showcase community integrations in this section. To suggest an addition simply make a Pull Request to add the missing integration.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/ecosystem/prod/index.html b/v0.58.0/ecosystem/prod/index.html deleted file mode 100644 index c01aabd2df84..000000000000 --- a/v0.58.0/ecosystem/prod/index.html +++ /dev/null @@ -1,7955 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Production and Clouds - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    - -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Production and cloud Integrations

    -

    Kubernetes

    -

    Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.

    -

    Trivy Operator (Official)

    -

    Using the Trivy Operator you can install Trivy into a Kubernetes cluster so that it automatically and continuously scan your workloads and cluster for security issues.

    -

    👉 Get it at: https://github.com/aquasecurity/trivy-operator

    -

    Harbor (Official)

    -

    Harbor is an open source cloud native container and artifact registry.

    -

    Trivy is natively integrated into Harbor, no installation is needed. More info in Harbor documentation: https://goharbor.io/docs/2.6.0/administration/vulnerability-scanning

    -

    Kyverno (Community)

    -

    Kyverno is a policy management tool for Kubernetes.

    -

    You can use Kyverno to ensure and enforce that deployed workloads' images are scanned for vulnerabilities.

    -

    👉 Get it at: https://neonmirrors.net/post/2022-07/attesting-image-scans-kyverno

    -

    Zora (Community)

    -

    Zora is an open-source solution that scans Kubernetes clusters with multiple plugins at scheduled times.

    -

    Trivy is integrated into Zora as a vulnerability scanner plugin.

    -

    👉 Get it at: https://zora-docs.undistro.io/latest/plugins/trivy/

    -

    Helmper (Community)

    -

    Helmper is a go program that reads Helm Charts from remote OCI registries and pushes the Helm Charts and the Helm Charts container images to your OCI registries with optional OS level vulnerability patching

    -

    Trivy is integrated into Helmper as a vulnerability scanner in combination with Copacetic to fix detected vulnerabilities.

    -

    👉 Get it at: https://github.com/ChristofferNissen/helmper

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/ecosystem/reporting/index.html b/v0.58.0/ecosystem/reporting/index.html deleted file mode 100644 index 34a5126c3931..000000000000 --- a/v0.58.0/ecosystem/reporting/index.html +++ /dev/null @@ -1,7966 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reporting - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Reporting

    -

    DefectDojo (Community)

    -

    DefectDojo can parse Trivy JSON reports. The parser supports deduplication and auto-close features.

    -

    👉 Get it at: https://github.com/DefectDojo/django-DefectDojo

    -

    SecObserve (Community)

    -

    SecObserve can parse Trivy results as CycloneDX reports and provides an unified overview of vulnerabilities from different sources. Vulnerabilities can be evaluated with manual and rule based assessments.

    -

    👉 Get it at: https://github.com/MaibornWolff/SecObserve

    -

    Scan2html (Community)

    -

    A Trivy plugin that scans and outputs the results to an interactive html file.

    -

    👉 Get it at: https://github.com/fatihtokus/scan2html

    -

    SonarQube (Community)

    -

    A Trivy plugin that converts JSON report to SonarQube generic issues format.

    -

    👉 Get it at: https://github.com/umax/trivy-plugin-sonarqube

    -

    Trivy-Streamlit (Community)

    -

    Trivy-Streamlit is a Streamlit application that allows you to quickly parse the results from a Trivy JSON report.

    -

    👉 Get it at: https://github.com/mfreeman451/trivy-streamlit

    -

    Trivy-Vulnerability-Explorer (Community)

    -

    This project is a web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table.

    -

    👉 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer

    -

    plopsec.com (Community)

    -

    This project is a web application designed to help you visualize Trivy image scan reports. It enriches the data with additional exploitability metrics from EPSS, Metasploit, and Exploit-DB, updated daily.

    -

    👉 Get it at: https://plopsec.com | https://github.com/pl0psec/plopsec.com

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/getting-started/faq/index.html b/v0.58.0/getting-started/faq/index.html deleted file mode 100644 index b622b0b709c8..000000000000 --- a/v0.58.0/getting-started/faq/index.html +++ /dev/null @@ -1,7968 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FAQ - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    FAQ

    - -

    FAQ

    -

    How to pronounce the name "Trivy"?

    -

    tri is pronounced like trigger, vy is pronounced like envy.

    -

    Does Trivy support X?

    -

    Check out the Scanning coverage page.

    -

    Is there a paid version of Trivy?

    -

    If you liked Trivy, you will love Aqua which builds on top of Trivy to provide even more enhanced capabilities for a complete security management offering.
    -You can find a high level comparison table specific to Trivy users here.
    -In addition check out the https://aquasec.com website for more information about our products and services. -If you'd like to contact Aqua or request a demo, please use this form: https://www.aquasec.com/demo

    -

    How to generate multiple reports?

    -

    See here.

    -

    How to run Trivy under air-gapped environment?

    -

    See here.

    -

    Why trivy fs and trivy repo does not scan JAR files for vulnerabilities?

    -

    See here.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/getting-started/index.html b/v0.58.0/getting-started/index.html deleted file mode 100644 index 27da34219159..000000000000 --- a/v0.58.0/getting-started/index.html +++ /dev/null @@ -1,7944 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - First steps - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    First steps with Trivy

    -

    Get Trivy

    -

    Trivy is available in most common distribution channels. The complete list of installation options is available in the Installation page. Here are a few popular examples:

    - -

    Trivy is integrated with many popular platforms and applications. The complete list of integrations is available in the Ecosystem page. Here are a few popular options examples:

    - -

    General usage

    -

    Trivy's Command Line Interface pattern follows its major concepts: targets (what you want to scan), and scanners (what you want to scan for):

    -
    trivy <target> [--scanners <scanner1,scanner2>] <subject>
    -
    -

    Examples

    -

    Scan a container image from registry, with the default scanner which is Vulnerabilities scanner:

    -
    trivy image python:3.4-alpine
    -
    - - -

    Scan a local code repository, for vulnerabilities, exposed secrets and misconfigurations:

    -
    trivy fs --scanners vuln,secret,misconfig /path/to/myproject
    -
    - - -

    Scan a Kubernetes cluster, with all available scanners, and show a summary report:

    -
    trivy k8s --report summary cluster
    -
    -

    trivy-k8s

    -

    For a more complete introduction, check out the basic Trivy Demo: https://github.com/itaysk/trivy-demo

    -

    Learn more

    -

    Now that you up and ready, here are some resources to help you deepen your knowledge:

    - -

    Want more? Check out Aqua

    -

    If you liked Trivy, you will love Aqua which builds on top of Trivy to provide even more enhanced capabilities for a complete security management offering.
    -You can find a high level comparison table specific to Trivy users here.
    -In addition, check out the https://aquasec.com website for more information about our products and services. -If you'd like to contact Aqua or request a demo, please use this form: https://www.aquasec.com/demo

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/getting-started/installation/index.html b/v0.58.0/getting-started/installation/index.html deleted file mode 100644 index 84ce3025250b..000000000000 --- a/v0.58.0/getting-started/installation/index.html +++ /dev/null @@ -1,8245 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Installation - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Installing Trivy

    -

    In this section you will find an aggregation of the different ways to install Trivy. Installation options are labeled as either "Official" or "Community". Official installations are developed by the Trivy team and supported by it. Community installations could be developed by anyone from the Trivy community, and collected here for your convenience. For support or questions about community installations, please contact the original developers.

    -
    -

    Note

    -

    If you are looking to integrate Trivy into another system, such as CI/CD, IDE, Kubernetes, etc, please see Ecosystem section to explore integrations of Trivy with other tools.

    -
    -

    Container image (Official)

    -

    Use one of the official Trivy images:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    RegistryRepositoryLink
    Docker Hubdocker.io/aquasec/trivyhttps://hub.docker.com/r/aquasec/trivy
    GitHub Container Registry (GHCR)ghcr.io/aquasecurity/trivyhttps://github.com/orgs/aquasecurity/packages/container/package/trivy
    AWS Elastic Container Registry (ECR)public.ecr.aws/aquasecurity/trivyhttps://gallery.ecr.aws/aquasecurity/trivy
    -
    -

    Tip

    -

    It is advisable to mount a persistent cache dir on the host into the Trivy container.

    -
    -
    -

    Tip

    -

    For scanning container images with Trivy, mount the container engine socket from the host into the Trivy container.

    -
    -

    Example:

    -
    docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:0.58.0-1-g775f954c3 image python:3.4-alpine
    -
    -

    GitHub Release (Official)

    -
      -
    1. Download the file for your operating system/architecture from GitHub Release assets.
    2. -
    3. Unpack the downloaded archive (tar -xzf ./trivy.tar.gz).
    4. -
    5. Make sure the binary has execution bit turned on (chmod +x ./trivy).
    6. -
    -

    Install Script (Official)

    -

    For convenience, you can use the install script to download and install Trivy from GitHub Release.

    -
    curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.58.0-1-g775f954c3
    -
    -

    RHEL/CentOS (Official)

    -
    -
    -
    -

    Add repository setting to /etc/yum.repos.d.

    -
    cat << EOF | sudo tee -a /etc/yum.repos.d/trivy.repo
    -[trivy]
    -name=Trivy repository
    -baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/\$basearch/
    -gpgcheck=1
    -enabled=1
    -gpgkey=https://aquasecurity.github.io/trivy-repo/rpm/public.key
    -EOF
    -sudo yum -y update
    -sudo yum -y install trivy
    -
    -
    -
    -
    rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.58.0-1-g775f954c3/trivy_0.58.0-1-g775f954c3_Linux-64bit.rpm
    -
    -
    -
    -
    -

    Debian/Ubuntu (Official)

    -
    -
    -
    -

    Add repository setting to /etc/apt/sources.list.d.

    -
    sudo apt-get install wget gnupg
    -wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
    -echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
    -sudo apt-get update
    -sudo apt-get install trivy
    -
    -
    -
    -
    wget https://github.com/aquasecurity/trivy/releases/download/v0.58.0-1-g775f954c3/trivy_0.58.0-1-g775f954c3_Linux-64bit.deb
    -sudo dpkg -i trivy_0.58.0-1-g775f954c3_Linux-64bit.deb
    -
    -
    -
    -
    -

    Homebrew (Official)

    -

    Homebrew for macOS and Linux.

    -
    brew install trivy
    -
    -

    Windows (Official)

    -
      -
    1. Download trivy_x.xx.x_windows-64bit.zip file from releases page.
    2. -
    3. Unzip file and copy to any folder.
    4. -
    -

    Arch Linux (Community)

    -

    Arch Linux Package Repository.

    -
    sudo pacman -S trivy
    -
    -

    References: -- https://archlinux.org/packages/extra/x86_64/trivy/ -- https://gitlab.archlinux.org/archlinux/packaging/packages/trivy/-/blob/main/PKGBUILD

    -

    MacPorts (Community)

    -

    MacPorts for macOS.

    -
    sudo port install trivy
    -
    -

    References: -- https://ports.macports.org/port/trivy/details/

    -

    Nix/NixOS (Community)

    -

    Nix package manager for Linux and macOS.

    -
    -
    -
    -

    nix-env --install -A nixpkgs.trivy

    -
    -
    -
    # your other config ...
    -environment.systemPackages = with pkgs; [
    -  # your other packages ...
    -  trivy
    -];
    -
    -
    -
    -
    # your other config ...
    -home.packages = with pkgs; [
    -  # your other packages ...
    -  trivy
    -];
    -
    -
    -
    -
    -

    References:

    - -

    FreeBSD (Official)

    -

    Pkg package manager for FreeBSD.

    -
    pkg install trivy
    -
    -

    asdf/mise (Community)

    -

    asdf and mise are quite similar tools you can use to install trivy. -See their respective documentation for more information of how to install them and use them:

    - -

    The plugin used by both tools is developped here

    -
    -
    -
    -

    A basic global installation is shown below, for specific version or/and local version to a directory see "asdf" documentation.

    -
    # Install plugin
    -asdf plugin add trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git
    -
    -# Install latest version
    -asdf install trivy latest
    -
    -# Set a version globally (on your ~/.tool-versions file)
    -asdf global trivy latest
    -
    -# Now trivy commands are available
    -trivy --version
    -
    -
    -
    -

    A basic global installation is shown below, for specific version or/and local version to a directory see "mise" documentation.

    -
    # Install plugin and install latest version
    -mise install trivy@latest
    -
    -# Set a version globally (on your ~/.tool-versions file)
    -mise use -g trivy@latest
    -
    -# Now trivy commands are available
    -trivy --version
    -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/getting-started/signature-verification/index.html b/v0.58.0/getting-started/signature-verification/index.html deleted file mode 100644 index 4df089ddf08a..000000000000 --- a/v0.58.0/getting-started/signature-verification/index.html +++ /dev/null @@ -1,7940 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Signature Verification - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Signature Verification

    -

    All binaries and container images are signed by Cosign.

    -

    Verifying container image

    -

    Use the following command for keyless verification:

    -
    cosign verify aquasec/trivy:<version> \
    ---certificate-identity-regexp 'https://github\.com/aquasecurity/trivy/\.github/workflows/.+' \
    ---certificate-oidc-issuer "https://token.actions.githubusercontent.com"
    -
    -

    You should get the following output

    -
    Verification for index.docker.io/aquasec/trivy:latest --
    -The following checks were performed on each of these signatures:
    -   - The cosign claims were validated
    -   - Existence of the claims in the transparency log was verified offline
    -   - The code-signing certificate was verified using trusted certificate authority certificates
    -
    -   ....
    -
    -

    Verifying binary

    -

    Download the required tarball, associated signature and certificate files from the GitHub Release.

    -

    Use the following command for keyless verification:

    -
    cosign verify-blob <path to binray> \
    ---certificate <path to cert> \
    ---signature <path to sig> \
    ---certificate-identity-regexp 'https://github\.com/aquasecurity/trivy/\.github/workflows/.+' \
    ---certificate-oidc-issuer "https://token.actions.githubusercontent.com"
    -
    -

    You should get the following output

    -
    Verified OK
    -
    -

    Verifying a GPG signature

    -

    RPM and Deb packages are also signed by GPG.

    -

    Verifying RPM

    -

    The public key is available at https://aquasecurity.github.io/trivy-repo/rpm/public.key.

    -

    First, download and import the key:

    -
    curl https://aquasecurity.github.io/trivy-repo/rpm/public.key \
    ---output pub.key
    -rpm --import pub.key
    -rpm -q --queryformat "%{SUMMARY}\n" $(rpm -q gpg-pubkey)
    -
    -

    You should get the following output:

    -
    gpg(trivy)
    -
    -

    Then you can verify the signature:

    -
    curl -L https://github.com/aquasecurity/trivy/releases/download/<version>/<file name>.rpm \
    ---output trivy.rpm
    -rpm -K trivy.rpm
    -
    -

    You should get the following output

    -
    trivy.rpm: digests signatures OK
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/imgs/Security-Hub.jpeg b/v0.58.0/imgs/Security-Hub.jpeg deleted file mode 100644 index cece6bcc0c18..000000000000 Binary files a/v0.58.0/imgs/Security-Hub.jpeg and /dev/null differ diff --git a/v0.58.0/imgs/argocd-ui.png b/v0.58.0/imgs/argocd-ui.png deleted file mode 100644 index f9e31a958abb..000000000000 Binary files a/v0.58.0/imgs/argocd-ui.png and /dev/null differ diff --git a/v0.58.0/imgs/client-server.png b/v0.58.0/imgs/client-server.png deleted file mode 100644 index fce67eefdf0b..000000000000 Binary files a/v0.58.0/imgs/client-server.png and /dev/null differ diff --git a/v0.58.0/imgs/docker-desktop.png b/v0.58.0/imgs/docker-desktop.png deleted file mode 100644 index 3eafeb8e8941..000000000000 Binary files a/v0.58.0/imgs/docker-desktop.png and /dev/null differ diff --git a/v0.58.0/imgs/eks-benchmarks.png b/v0.58.0/imgs/eks-benchmarks.png deleted file mode 100644 index 68d931cffe37..000000000000 Binary files a/v0.58.0/imgs/eks-benchmarks.png and /dev/null differ diff --git a/v0.58.0/imgs/excalidraw/client-server.excalidraw b/v0.58.0/imgs/excalidraw/client-server.excalidraw deleted file mode 100644 index ad67667a9c4a..000000000000 --- a/v0.58.0/imgs/excalidraw/client-server.excalidraw +++ /dev/null @@ -1,1151 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 458.6370544433594, - "y": 379.5105285644531, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 381, - "versionNonce": 413251305, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "nXkZQsrtjmNqPM6SmPxrc", - "Ljv7RJF8FjyOJX3vZ2ou8", - "o_BKODe9vjtHWQsJ8F3tD", - "zTrormMP-N-W6thSxlTgK", - "fBva4zCGT2vIFPpTWC-oZ" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 427.04335021972656, - "y": 65.240966796875, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 684, - "versionNonce": 78137383, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 511.77996826171875, - "y": 407.1625671386719, - "width": 62, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 253, - "versionNonce": 788328905, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy\nServer", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 488.6784362792969, - "y": 116.34368896484375, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 456, - "versionNonce": 14330695, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 538.7528045696993, - "y": 220.23935960349465, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 1298, - "versionNonce": 267243689, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": -0.03598869040285281, - "gap": 2.911871895302724 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.04563780983822428, - "gap": 5.10864450968802 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 575.9393615722656, - "y": 254.42640686035156, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 629, - "versionNonce": 185838183, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "nXkZQsrtjmNqPM6SmPxrc", - "type": "arrow", - "x": 128.84802246093747, - "y": 395.4753877561888, - "width": 316.63877589590845, - "height": 0.1213064482017785, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2075020231, - "version": 327, - "versionNonce": 1795630503, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 316.63877589590845, - 0.1213064482017785 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "2ZWTQQ2dQDWF8xj1BLdVG", - "focus": 1.483056059007069, - "gap": 12.799499511718778 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.46421771350547186, - "gap": 12.273425031825923 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "OPRFQTrsfmF5a7us-mxkI", - "type": "draw", - "x": -60.78019714355469, - "y": 464.1100280880928, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1541066697, - "version": 569, - "versionNonce": 1115805895, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "QzKnYI7o5Yxg_7szebL6Z", - "type": "draw", - "x": -37.06263732910158, - "y": 508.8429382443428, - "width": 16.976165771484375, - "height": 16.45367431640625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2144447815, - "version": 203, - "versionNonce": 28982057, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 6.905059814453125, - -16.45367431640625 - ], - [ - 16.976165771484375, - -5.1099853515625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "qqbEan2u1uU3loTdTvQ4B", - "type": "text", - "x": -184.67498779296875, - "y": 548.9957397580147, - "width": 230, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1619652615, - "version": 833, - "versionNonce": 981018599, - "isDeleted": false, - "boundElementIds": null, - "text": "6. Analyze pulled layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "GgiFj7vEEZT-VPfKiX6oo", - "type": "rectangle", - "x": -48.80625915527344, - "y": 386.3571411073208, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1005158727, - "version": 500, - "versionNonce": 1358533383, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "nXkZQsrtjmNqPM6SmPxrc", - "2tbWET6O9G38YibdIyLpy", - "FuK6iJ6YprzRoh4wg1UHf", - "o_BKODe9vjtHWQsJ8F3tD", - "fBva4zCGT2vIFPpTWC-oZ" - ] - }, - { - "id": "qQZYQjma-4h8rOrxn5yBo", - "type": "text", - "x": 4.3366546630859375, - "y": 414.00917968153954, - "width": 57, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1918851753, - "version": 381, - "versionNonce": 56771817, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy\nClient", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "vtOTfv319aihVmgTMMbQG", - "type": "ellipse", - "x": -95.58086395263672, - "y": 68.13672637939453, - "width": 249.63902282714844, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1265127495, - "version": 929, - "versionNonce": 1316732873, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "2tbWET6O9G38YibdIyLpy", - "FuK6iJ6YprzRoh4wg1UHf" - ] - }, - { - "id": "bz64cTcmJtjZotVar2MHr", - "type": "text", - "x": -73.4975357055664, - "y": 108.37564849853516, - "width": 202, - "height": 74, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 976812969, - "version": 670, - "versionNonce": 938982727, - "isDeleted": false, - "boundElementIds": null, - "text": "Container Registries\nor\nContainer Engines", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 67 - }, - { - "id": "Z5DzSXSTeTNfyo9GRr57B", - "type": "ellipse", - "x": 871.677619934082, - "y": 347.7999496459961, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#15aabf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1020418857, - "version": 836, - "versionNonce": 845340329, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "Ljv7RJF8FjyOJX3vZ2ou8", - "zTrormMP-N-W6thSxlTgK" - ] - }, - { - "id": "SGILIw_oLMs1yuieBWcoP", - "type": "text", - "x": 898.8127059936523, - "y": 398.90267181396484, - "width": 158, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1953695719, - "version": 653, - "versionNonce": 1086225511, - "isDeleted": false, - "boundElementIds": [ - "zTrormMP-N-W6thSxlTgK" - ], - "text": "Cache Backend\n(Local or Redis)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Ljv7RJF8FjyOJX3vZ2ou8", - "type": "arrow", - "x": 635.243173087202, - "y": 408.1721813855087, - "width": 237.82178502385182, - "height": 0.48828450950475144, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 744746601, - "version": 617, - "versionNonce": 230891913, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 237.82178502385182, - -0.48828450950475144 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.4450219327551968, - "gap": 7.386666739545717 - }, - "endBinding": { - "elementId": "Z5DzSXSTeTNfyo9GRr57B", - "focus": 0.21564885268585596, - "gap": 1.0335001891177882 - }, - "startArrowhead": "arrow", - "endArrowhead": "arrow" - }, - { - "id": "BlRXUB6fETT_zZD6O1fNL", - "type": "text", - "x": -163.05282592773438, - "y": 268.6500244140625, - "width": 124, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 609582183, - "version": 841, - "versionNonce": 2090882951, - "isDeleted": false, - "boundElementIds": null, - "text": "2. Download\n manifest", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "2tbWET6O9G38YibdIyLpy", - "type": "arrow", - "x": -12.186006749219864, - "y": 221.1919311337398, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1740746569, - "version": 1437, - "versionNonce": 1574439017, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "vtOTfv319aihVmgTMMbQG", - "focus": 0.3337009650548285, - "gap": 5.11281200236435 - }, - "endBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": -0.5585687247500966, - "gap": 11.002685522310514 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2ZWTQQ2dQDWF8xj1BLdVG", - "type": "text", - "x": 141.64752197265625, - "y": 364.4148864746094, - "width": 294, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1932287977, - "version": 912, - "versionNonce": 299486887, - "isDeleted": false, - "boundElementIds": [ - "nXkZQsrtjmNqPM6SmPxrc" - ], - "text": "3. Ask missing layers in cache", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "pIwVlwytOx1ZJ4aOCvtRF", - "type": "text", - "x": 636.46630859375, - "y": 352.5987548828125, - "width": 246, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 973317671, - "version": 871, - "versionNonce": 1819087689, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Return existing layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "FuK6iJ6YprzRoh4wg1UHf", - "type": "arrow", - "x": 75.37933138554581, - "y": 220.52838743256788, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1148774855, - "version": 1487, - "versionNonce": 722952647, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "vtOTfv319aihVmgTMMbQG", - "focus": -0.36784928325571326, - "gap": 5.485033392258245 - }, - "endBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": 0.4745035772454494, - "gap": 11.666229223482446 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "jgdyeMn1ZO33kPci2KoGL", - "type": "text", - "x": 94.91287231445312, - "y": 265.060302734375, - "width": 162, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1318802377, - "version": 872, - "versionNonce": 1037943337, - "isDeleted": false, - "boundElementIds": null, - "text": "5. Pull only\n missing layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "o_BKODe9vjtHWQsJ8F3tD", - "type": "arrow", - "x": 128.61206957157697, - "y": 440.13062341766545, - "width": 316.63877589590845, - "height": 0.1213064482017785, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 20958471, - "version": 415, - "versionNonce": 1769312487, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 316.63877589590845, - 0.1213064482017785 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": 0.030966433153118762, - "gap": 8.19887682255353 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.16596748618058757, - "gap": 13.386208975873956 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "6DaFskX4dI8KM57tYJKwz", - "type": "text", - "x": 151.09302660282708, - "y": 409.41115607163283, - "width": 259, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 221555433, - "version": 1091, - "versionNonce": 1058379017, - "isDeleted": false, - "boundElementIds": null, - "text": "7. Send the analysis result", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "zTrormMP-N-W6thSxlTgK", - "type": "arrow", - "x": 639.0015349036082, - "y": 455.7986607407429, - "width": 233.13104569613938, - "height": 0.2533468001336132, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1122927111, - "version": 471, - "versionNonce": 377543687, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 233.13104569613938, - 0.2533468001336132 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.4608119841777207, - "gap": 11.145028555951967 - }, - "endBinding": { - "elementId": "Z5DzSXSTeTNfyo9GRr57B", - "focus": -0.42458037983475105, - "gap": 8.237658674598492 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2sst3d11OgZLJZ3vdmH15", - "type": "text", - "x": 709.851318359375, - "y": 424.4541015625, - "width": 82, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1801175527, - "version": 1132, - "versionNonce": 865078249, - "isDeleted": false, - "boundElementIds": null, - "text": "8. Store", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "QsQ0GcuViNzFPK5QPICis", - "type": "text", - "x": 408.48883056640625, - "y": 561.8040618896484, - "width": 254, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 773954023, - "version": 992, - "versionNonce": 419481159, - "isDeleted": false, - "boundElementIds": null, - "text": "9. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "fBva4zCGT2vIFPpTWC-oZ", - "type": "arrow", - "x": 448.39657694205636, - "y": 484.4299201560043, - "width": 322.1210694778896, - "height": 0.5052042161862573, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 184790569, - "version": 677, - "versionNonce": 151709097, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -322.1210694778896, - -0.5052042161862573 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -1.0131990709910756, - "gap": 10.240477501303019 - }, - "endBinding": { - "elementId": "GgiFj7vEEZT-VPfKiX6oo", - "focus": 0.8669472708483955, - "gap": 5.862314715143327 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "PALQlCWrOXdjqBkRKhS6D", - "type": "draw", - "x": 523.952392578125, - "y": 487.95794677734375, - "width": 72.486083984375, - "height": 62.78338623046875, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#15aabf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 273802089, - "version": 310, - "versionNonce": 230581607, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -23.2962646484375, - 36.8623046875 - ], - [ - -3.4830322265625, - 59.561767578125 - ], - [ - 29.205810546875, - 62.78338623046875 - ], - [ - 49.1898193359375, - 49.74090576171875 - ], - [ - 45.6522216796875, - 21.439453125 - ], - [ - 24.2618408203125, - 1.5714111328125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "vP9i2PUtjapBX142LXX7m", - "type": "draw", - "x": 552.87939453125, - "y": 504.59832763671875, - "width": 16.5072021484375, - "height": 18.1295166015625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#15aabf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 786227753, - "version": 48, - "versionNonce": 2144487561, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.4810791015625, - -18.1295166015625 - ], - [ - 16.5072021484375, - -13.106201171875 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "2XUWMZRUNlhKGsJGNjK9k", - "type": "text", - "x": 154.5665283203125, - "y": 450.849365234375, - "width": 258, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 826013511, - "version": 1180, - "versionNonce": 1404772487, - "isDeleted": false, - "boundElementIds": null, - "text": "10. Return the scan result", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/v0.58.0/imgs/excalidraw/fs.excalidraw b/v0.58.0/imgs/excalidraw/fs.excalidraw deleted file mode 100644 index bd97566531aa..000000000000 --- a/v0.58.0/imgs/excalidraw/fs.excalidraw +++ /dev/null @@ -1,397 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 528.53466796875, - "y": 377.9640197753906, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 274, - "versionNonce": 942385065, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 496.9409637451172, - "y": 63.6944580078125, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 595, - "versionNonce": 1870840679, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 585.4711608886719, - "y": 418.1110534667969, - "width": 48, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 119, - "versionNonce": 1368050313, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 558.5760498046875, - "y": 114.79718017578125, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 368, - "versionNonce": 2034482823, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 608.6504180950899, - "y": 218.69285081443215, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 1069, - "versionNonce": 2093125993, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": -0.035986229233252585, - "gap": 2.9120411440381986 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.04563780983822369, - "gap": 5.10864450968802 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 637.9371185302734, - "y": 248.28482055664062, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 360, - "versionNonce": 326653351, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "zdNQvzJczyD9GSExNdKS1", - "type": "draw", - "x": 513.9153137207031, - "y": 461.14288330078125, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1270145927, - "version": 459, - "versionNonce": 1094761993, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "YK7xYiSKb1RwCCobsRAXm", - "type": "text", - "x": 391.5774230957031, - "y": 541.0142517089844, - "width": 280, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2027931817, - "version": 510, - "versionNonce": 1538345895, - "isDeleted": false, - "boundElementIds": null, - "text": "3. Traverse directories\nand look for necessary files", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Z_DiM_TKY2bBa4Q5VEWgI", - "type": "text", - "x": 684.9671020507812, - "y": 621.1561279296875, - "width": 160, - "height": 25, - "angle": 0, - "strokeColor": "#1864ab", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1365660617, - "version": 564, - "versionNonce": 2113117703, - "isDeleted": false, - "boundElementIds": null, - "text": "Local Filesystem", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "kqEATPhet5tYxzkEOFZng", - "type": "text", - "x": 571.0751342773438, - "y": 494.0994567871094, - "width": 254, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 130557095, - "version": 654, - "versionNonce": 2037434313, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "K0XdIaMYVmUP2kGc8Oe1O", - "type": "rectangle", - "x": 360.9377136230469, - "y": 357.07373046875, - "width": 495.45401000976557, - "height": 297.8450317382812, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1367853545, - "version": 339, - "versionNonce": 314224297, - "isDeleted": false, - "boundElementIds": null - }, - { - "id": "_vOsyHICDRWn01MF3g7rB", - "type": "draw", - "x": 539.7380981445312, - "y": 501.50762939453125, - "width": 16.976165771484375, - "height": 16.45367431640625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1322966281, - "version": 82, - "versionNonce": 244034663, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 6.905059814453125, - -16.45367431640625 - ], - [ - 16.976165771484375, - -5.1099853515625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/v0.58.0/imgs/excalidraw/image.excalidraw b/v0.58.0/imgs/excalidraw/image.excalidraw deleted file mode 100644 index 005aa44462a7..000000000000 --- a/v0.58.0/imgs/excalidraw/image.excalidraw +++ /dev/null @@ -1,504 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 528.53466796875, - "y": 359.7196350097656, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 235, - "versionNonce": 865905065, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 382.4654998779297, - "y": 70.28388977050781, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 442, - "versionNonce": 1305668297, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 585.4711608886719, - "y": 399.8666687011719, - "width": 48, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 82, - "versionNonce": 463601353, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 445.5017395019531, - "y": 121.72871398925781, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 306, - "versionNonce": 1721298503, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 497.981827043938, - "y": 226.98470679602065, - "width": 90.39040277767413, - "height": 127.08286800676547, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 591, - "versionNonce": 1564262983, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 90.39040277767413, - 127.08286800676547 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": 0.41046776258752976, - "gap": 4.7596344319156 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.1341309277800711, - "gap": 5.652060206979513 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 181.22366333007812, - "y": 252.094970703125, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 281, - "versionNonce": 1175555431, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "P3WUTj2Q9se-JE7t3AUeq", - "type": "ellipse", - "x": 635.5376052856445, - "y": 68.77783966064453, - "width": 286.11024475097656, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1633931305, - "version": 684, - "versionNonce": 1011691465, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo" - ] - }, - { - "id": "2q_e-oMWU2gv7ZEClixAx", - "type": "text", - "x": 680.7248458862305, - "y": 102.90502166748047, - "width": 186, - "height": 74, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 866083559, - "version": 676, - "versionNonce": 1669555559, - "isDeleted": false, - "boundElementIds": null, - "text": "Container Registry\nor\nContainer Engine", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 67 - }, - { - "id": "JinTKutXOSTzURP969rwo", - "type": "arrow", - "x": 725.3393330640303, - "y": 216.94283962355922, - "width": 69.9915382406898, - "height": 134.02688987715163, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1348821927, - "version": 938, - "versionNonce": 1580551495, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -69.9915382406898, - 134.02688987715163 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "P3WUTj2Q9se-JE7t3AUeq", - "focus": 0.10510087993199528, - "gap": 1.4587528984692284 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": 0.0931277668871816, - "gap": 8.74990550905477 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "kHnEt-AjbEzMxB61VSDc2", - "type": "text", - "x": 723.4168395996094, - "y": 258.063232421875, - "width": 295, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1080814281, - "version": 613, - "versionNonce": 1064224615, - "isDeleted": false, - "boundElementIds": null, - "text": "2. Pull missing layers in cache", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "zdNQvzJczyD9GSExNdKS1", - "type": "draw", - "x": 524.4000854492188, - "y": 435.25982666015625, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1270145927, - "version": 331, - "versionNonce": 1090245193, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "13A9Y6sL_9DQ1KskiX5Oj", - "type": "draw", - "x": 545.8597412109375, - "y": 483.20318603515625, - "width": 25.76263427734375, - "height": 16.2581787109375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 788909033, - "version": 85, - "versionNonce": 991433415, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 13.24993896484375, - -16.2581787109375 - ], - [ - 25.76263427734375, - -5.01812744140625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "YK7xYiSKb1RwCCobsRAXm", - "type": "text", - "x": 261.88555908203125, - "y": 379.65887451171875, - "width": 249, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2027931817, - "version": 255, - "versionNonce": 809279785, - "isDeleted": false, - "boundElementIds": null, - "text": "3. Analyze layers &\nStore informatin in cache", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Z_DiM_TKY2bBa4Q5VEWgI", - "type": "text", - "x": 404.58673095703125, - "y": 522.828125, - "width": 144, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1365660617, - "version": 327, - "versionNonce": 2016944615, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Apply layers", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "kqEATPhet5tYxzkEOFZng", - "type": "text", - "x": 598.8711547851562, - "y": 480.22222900390625, - "width": 257, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 130557095, - "version": 539, - "versionNonce": 562048487, - "isDeleted": false, - "boundElementIds": null, - "text": "5. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/v0.58.0/imgs/excalidraw/overview.excalidraw b/v0.58.0/imgs/excalidraw/overview.excalidraw deleted file mode 100644 index 2762654df7f2..000000000000 --- a/v0.58.0/imgs/excalidraw/overview.excalidraw +++ /dev/null @@ -1,466 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "type": "rectangle", - "version": 788, - "versionNonce": 555477386, - "isDeleted": false, - "id": "BkXuq_6BxgqZGZWc8oCtu", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 599.653076171875, - "y": 734.7542114257812, - "strokeColor": "#000000", - "backgroundColor": "#fd7e14", - "width": 1227.452155219184, - "height": 151.39703369140625, - "seed": 1632394695, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177570112, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 713, - "versionNonce": 44400470, - "isDeleted": false, - "id": "YQURTHNPSe05RPSlYRcok", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1118.2101508246528, - "y": 763.5906914605034, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 88, - "height": 45, - "seed": 891391049, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177702292, - "link": null, - "locked": false, - "fontSize": 36, - "fontFamily": 1, - "text": "Trivy", - "baseline": 32, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "Trivy" - }, - { - "type": "text", - "version": 1191, - "versionNonce": 1166344150, - "isDeleted": false, - "id": "6dpF2EyZBtYgO6MrvGj0-", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 875.3033447265625, - "y": 820.7327100965712, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 612, - "height": 36, - "seed": 687997545, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177705177, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Vulnerability/Misconfiguration/Secret Scanner", - "baseline": 25, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "Vulnerability/Misconfiguration/Secret Scanner" - }, - { - "type": "rectangle", - "version": 858, - "versionNonce": 1118008458, - "isDeleted": false, - "id": "cpnTMy7L2AUg9IDJppF4H", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 600.9835205078125, - "y": 635.5783640543619, - "strokeColor": "#000000", - "backgroundColor": "#fab005", - "width": 335.3091227213542, - "height": 82.36856587727866, - "seed": 77164935, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1077, - "versionNonce": 1122201878, - "isDeleted": false, - "id": "9-blmNVtLesthMSY_f60t", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 649.8531494140625, - "y": 660.223378499349, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 224, - "height": 36, - "seed": 860091815, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Container Image", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "top", - "containerId": null, - "originalText": "Container Image" - }, - { - "type": "rectangle", - "version": 1118, - "versionNonce": 1679315786, - "isDeleted": false, - "id": "gugZxhi7ThlcjWY_MFO7q", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 954.3485412597656, - "y": 635.849225362142, - "strokeColor": "#000000", - "backgroundColor": "#be4bdb", - "width": 409.35879516601574, - "height": 82.97188822428383, - "seed": 1232790121, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1300, - "versionNonce": 1187044950, - "isDeleted": false, - "id": "K48gtpesBxIGJxLTnI2CB", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1084.4311319986978, - "y": 660.9795074462891, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 139, - "height": 36, - "seed": 449264361, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Filesystem", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "top", - "containerId": null, - "originalText": "Filesystem" - }, - { - "type": "rectangle", - "version": 1204, - "versionNonce": 688085514, - "isDeleted": false, - "id": "La6f87LDZ0uEIZB947bXo", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1375.0136108398438, - "y": 636.5654322306316, - "strokeColor": "#000000", - "backgroundColor": "#12b886", - "width": 452.76554361979186, - "height": 80.08313496907543, - "seed": 2005637801, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1432, - "versionNonce": 1593746326, - "isDeleted": false, - "id": "aOgRPVQ81jhOfkvzjWTMF", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1498.8465237087673, - "y": 658.0244835747612, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 201, - "height": 36, - "seed": 1284472935, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177872265, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Git Repository", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "top", - "containerId": null, - "originalText": "Git Repository" - }, - { - "type": "rectangle", - "version": 2792, - "versionNonce": 183831882, - "isDeleted": false, - "id": "10WjipxoLx2zzSI91pXbR", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 599.7894943723566, - "y": 905.6027750791251, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "width": 344.482180700969, - "height": 83.67398764683533, - "seed": 1813731484, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177825759, - "link": null, - "locked": false - }, - { - "type": "rectangle", - "version": 2771, - "versionNonce": 617525398, - "isDeleted": false, - "id": "M7Cngti6H0_kawKRN8yJ6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 963.2554264391833, - "y": 904.2447769132434, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 402.42137951281796, - "height": 86.03696372105414, - "seed": 1260603804, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177777585, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1057, - "versionNonce": 405881110, - "isDeleted": false, - "id": "Iq57wFRtO1a8AU0rT6lRD", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1046.152429428344, - "y": 930.8676815998951, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 218, - "height": 36, - "seed": 1329695396, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177655817, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Misconfiguration", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": null, - "originalText": "Misconfiguration" - }, - { - "type": "text", - "version": 883, - "versionNonce": 969949898, - "isDeleted": false, - "id": "_cm6xpfcL9Yv2XBK5MBZF", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 681.3134368986982, - "y": 931.5212932384402, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 161, - "height": 36, - "seed": 807441828, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177624726, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Vulnerability", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": null, - "originalText": "Vulnerability" - }, - { - "type": "rectangle", - "version": 2874, - "versionNonce": 1934391254, - "isDeleted": false, - "id": "Fq7meULupm1A9leboPlko", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1389.3043677318824, - "y": 903.8533384764222, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "width": 437.15079032010976, - "height": 84.42746665074158, - "seed": 230693534, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177785481, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1121, - "versionNonce": 110517002, - "isDeleted": false, - "id": "OUGk8nZzvgcKUHhKUcQov", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 1556.0451356485157, - "y": 930.8040952304675, - "strokeColor": "#000000", - "backgroundColor": "#82c91e", - "width": 91, - "height": 36, - "seed": 2044527454, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1652177636085, - "link": null, - "locked": false, - "fontSize": 28, - "fontFamily": 1, - "text": "Secret", - "baseline": 25, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": null, - "originalText": "Secret" - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - }, - "files": {} -} \ No newline at end of file diff --git a/v0.58.0/imgs/excalidraw/repo.excalidraw b/v0.58.0/imgs/excalidraw/repo.excalidraw deleted file mode 100644 index 72fcf1b47905..000000000000 --- a/v0.58.0/imgs/excalidraw/repo.excalidraw +++ /dev/null @@ -1,631 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "ribsikcWWSf8Aw4M6BOYJ", - "type": "rectangle", - "x": 458.6370544433594, - "y": 379.5105285644531, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 698826281, - "version": 360, - "versionNonce": 899087049, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "nXkZQsrtjmNqPM6SmPxrc" - ] - }, - { - "id": "GkrbG--OvBT9zJ-w8E5oQ", - "type": "ellipse", - "x": 427.04335021972656, - "y": 65.240966796875, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#fa5252", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 995070601, - "version": 679, - "versionNonce": 1333899847, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY" - ] - }, - { - "id": "KPLvdnBVoU3U5XGhCch-x", - "type": "text", - "x": 515.5735473632812, - "y": 419.6575622558594, - "width": 48, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 938497417, - "version": 202, - "versionNonce": 677296553, - "isDeleted": false, - "boundElementIds": null, - "text": "Trivy", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "Ry65W-Cczzy8M9JsouEgZ", - "type": "text", - "x": 488.6784362792969, - "y": 116.34368896484375, - "width": 89, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1676815783, - "version": 451, - "versionNonce": 490852711, - "isDeleted": false, - "boundElementIds": null, - "text": "GitHub\n(trivy-db)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "eJn9MVaNlcyj8-YPfrBSY", - "type": "arrow", - "x": 538.7528045696993, - "y": 220.23935960349465, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1741763111, - "version": 1292, - "versionNonce": 764124297, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "GkrbG--OvBT9zJ-w8E5oQ", - "focus": -0.03598869040285281, - "gap": 2.911871895302724 - }, - "endBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.04563780983822428, - "gap": 5.10864450968802 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "2P02jU3j2eEc92lH0YSwm", - "type": "text", - "x": 190.61294555664062, - "y": 255.17030334472656, - "width": 327, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 501371753, - "version": 569, - "versionNonce": 2012286087, - "isDeleted": false, - "boundElementIds": null, - "text": "1. Download Trivy DB\n(including vulnerability information)", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "YK7xYiSKb1RwCCobsRAXm", - "type": "text", - "x": 588.7474975585938, - "y": 488.1255798339844, - "width": 280, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2027931817, - "version": 628, - "versionNonce": 30461609, - "isDeleted": false, - "boundElementIds": null, - "text": "3. Traverse directories\nand look for necessary files", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "Z_DiM_TKY2bBa4Q5VEWgI", - "type": "text", - "x": 877.162353515625, - "y": 618.5094604492188, - "width": 160, - "height": 25, - "angle": 0, - "strokeColor": "#1864ab", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1365660617, - "version": 647, - "versionNonce": 760156423, - "isDeleted": false, - "boundElementIds": null, - "text": "Local Filesystem", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - }, - { - "id": "K0XdIaMYVmUP2kGc8Oe1O", - "type": "rectangle", - "x": 360.9377136230469, - "y": 357.07373046875, - "width": 695.5669860839844, - "height": 297.8450317382812, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1367853545, - "version": 417, - "versionNonce": 1598611913, - "isDeleted": false, - "boundElementIds": null - }, - { - "id": "9cBakj4Z-FKXwYYdweyW1", - "type": "ellipse", - "x": 774.155647277832, - "y": 56.2083175778389, - "width": 215.20677185058594, - "height": 152.14088439941406, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1010956009, - "version": 673, - "versionNonce": 825999529, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "vGa683rpZ9AztfvrVvEyD" - ] - }, - { - "id": "5y2AKGYkXhCldwQOecwl6", - "type": "text", - "x": 806.7732543945312, - "y": 106.18511658906937, - "width": 147, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1289267591, - "version": 83, - "versionNonce": 1127203721, - "isDeleted": false, - "boundElementIds": null, - "text": "Remote\nGit Repository", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "vGa683rpZ9AztfvrVvEyD", - "type": "arrow", - "x": 884.4609964246083, - "y": 220.86864013003574, - "width": 0.45618097890837817, - "height": 154.16252445127046, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1762737031, - "version": 1200, - "versionNonce": 457627015, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 0.45618097890837817, - 154.16252445127046 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "9cBakj4Z-FKXwYYdweyW1", - "focus": -0.022674122391029432, - "gap": 12.541597764893623 - }, - "endBinding": { - "elementId": "4_okkFmweGK_2DBTmRp4i", - "focus": 0.047202684587572305, - "gap": 3.295263653270979 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "4_okkFmweGK_2DBTmRp4i", - "type": "rectangle", - "x": 796.4703521728516, - "y": 378.3264282345772, - "width": 169.21945190429688, - "height": 104.2457275390625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#4c6ef5", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 853231143, - "version": 387, - "versionNonce": 1096837737, - "isDeleted": false, - "boundElementIds": [ - "eJn9MVaNlcyj8-YPfrBSY", - "JinTKutXOSTzURP969rwo", - "vGa683rpZ9AztfvrVvEyD", - "nXkZQsrtjmNqPM6SmPxrc" - ] - }, - { - "id": "zvgwnUmSms_XcbMDespIP", - "type": "text", - "x": 847.181640625, - "y": 404.5675476193428, - "width": 72, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1769283399, - "version": 307, - "versionNonce": 1392544935, - "isDeleted": false, - "boundElementIds": null, - "text": "Git\nProject", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "f0kayc0oXZazxPJKizaM1", - "type": "text", - "x": 916.8968811035156, - "y": 253.85886842012405, - "width": 258, - "height": 50, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 49135625, - "version": 649, - "versionNonce": 1150891337, - "isDeleted": false, - "boundElementIds": null, - "text": "2. Clone Git Repository\n to local temp directory", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 43 - }, - { - "id": "nXkZQsrtjmNqPM6SmPxrc", - "type": "arrow", - "x": 640.9059448242188, - "y": 429.34260255098343, - "width": 146.4581298828125, - "height": 0.93572998046875, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2075020231, - "version": 93, - "versionNonce": 1421238215, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 146.4581298828125, - -0.93572998046875 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "ribsikcWWSf8Aw4M6BOYJ", - "focus": -0.031650787945314215, - "gap": 13.0494384765625 - }, - "endBinding": { - "elementId": "4_okkFmweGK_2DBTmRp4i", - "focus": 0.050151997400131744, - "gap": 9.106277465820312 - }, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "OPRFQTrsfmF5a7us-mxkI", - "type": "draw", - "x": 446.98912048339844, - "y": 467.28928834199905, - "width": 72.64572143554688, - "height": 72.18890380859375, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 1541066697, - "version": 504, - "versionNonce": 1115999975, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - -39.526153564453125, - 16.35540771484375 - ], - [ - -32.219512939453125, - 72.170166015625 - ], - [ - 30.40386962890625, - 72.18890380859375 - ], - [ - 33.11956787109375, - 32.5743408203125 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "QzKnYI7o5Yxg_7szebL6Z", - "type": "draw", - "x": 472.81190490722656, - "y": 507.65403443574905, - "width": 16.976165771484375, - "height": 16.45367431640625, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "round", - "seed": 2144447815, - "version": 127, - "versionNonce": 807483145, - "isDeleted": false, - "boundElementIds": null, - "points": [ - [ - 0, - 0 - ], - [ - 6.905059814453125, - -16.45367431640625 - ], - [ - 16.976165771484375, - -5.1099853515625 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null - }, - { - "id": "qqbEan2u1uU3loTdTvQ4B", - "type": "text", - "x": 376.983642578125, - "y": 561.5254028439522, - "width": 254, - "height": 25, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1619652615, - "version": 718, - "versionNonce": 1190681095, - "isDeleted": false, - "boundElementIds": null, - "text": "4. Detect security issues", - "fontSize": 20, - "fontFamily": 1, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 18 - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - } -} \ No newline at end of file diff --git a/v0.58.0/imgs/fs.png b/v0.58.0/imgs/fs.png deleted file mode 100644 index 2a6acb83d058..000000000000 Binary files a/v0.58.0/imgs/fs.png and /dev/null differ diff --git a/v0.58.0/imgs/gitlab-codequality.png b/v0.58.0/imgs/gitlab-codequality.png deleted file mode 100644 index b7069b8af7c1..000000000000 Binary files a/v0.58.0/imgs/gitlab-codequality.png and /dev/null differ diff --git a/v0.58.0/imgs/image.png b/v0.58.0/imgs/image.png deleted file mode 100644 index e014f0c7b653..000000000000 Binary files a/v0.58.0/imgs/image.png and /dev/null differ diff --git a/v0.58.0/imgs/logo-horizontal.svg b/v0.58.0/imgs/logo-horizontal.svg deleted file mode 100644 index 9cdd1b594dd9..000000000000 --- a/v0.58.0/imgs/logo-horizontal.svg +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/v0.58.0/imgs/logo-white.svg b/v0.58.0/imgs/logo-white.svg deleted file mode 100644 index f546d23b3358..000000000000 --- a/v0.58.0/imgs/logo-white.svg +++ /dev/null @@ -1,3124 +0,0 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - - o2fP3CYLc0HTkrm0lY1xu0zMha0ey7rdZNm2T5Y96/OLnNmM862zcbx3fycRz5bhW6t5Hvdqo06v -J7I07En0+z+PgN5I89Au6iz0QpqCHefwrr/YoWlf6u4yGq8bDWQJ2H8s+X7P5F6to8hHG4Ea9iZW -xJ80anj3OPL9nsa8G+db93HAc3YN4ZsnyhS8n1gXccB0P4ZPjXaBs8toAOPqpVPvncCDoz00SWjb -BNr5mT65WqZvrXZJ81uXM+4222bG1RHf2TWEcj1Gj22O2WujY/LcZhk+uJmHUc/3UOb1lzk0mXdZ -m13ryjJ5bH2GD87L4LnVMXhr9Awf24eRS6uzal926c5cl7V5KxPIRuso4vmbwjuap3HP+zzy2TuI -ebeOuK4ro9fmaf7e7CDKP7uo8vATYRLaS6Xfe+iS8N8Y3v2awLhvU0jnawTnuk0hndcB49lMpN+b -ysSkXVR5aNMAvnmbwblf5DnodxD1Pgxe2owDnrOJLgftpc/wzQQK7hptFtpKn987qRNs90Dq2TiH -dfYOop59853zM31w9YwfXF20ediVQL3dIUnBblBk4I3zrbNlANtmF7hedsaBw4vezZ0hdKOzbr2M -azFo4BsmfPEtBg38LgMzKwuD+TvTzoTZuDB7atts3B/jaWMduJk2LCaQbcwmMY5rA6aTX+7QymL0 -2LTZt5uM97ENnAyDBl7mdYHXYBiyclyxLF5XzEVuFuMdwwauAcIEPub1lcWzyWL61rQyhG1cmcI2 -7oxh2yxzyLZ1eeNq+Q8D49oLGLgP0+DSNtbBRa1MzAVNHsum+Q5ZN5os60aTuaxtO3C6wwbewcIX -pzdosNlQ52xpaVVhMTlA20O7wITFRMVUxcRVxVTFhMXERcVE9VYzUTFZaTFxaVUx3VRSTFRMVEw/ -R6xmCusdLLCpwfWxXWiQk6FmqmJKEJWTx7anh6Z1cDeVdcWBiSpLC2uqC0trSyqHjokqS2uLqUpr -aw+NjGmt7itHzmnL4UB1NUWFhYWVdTXV1WWllTXVZdVlRVdlZWVlZbWVpUWVtXVVxTWFRdXVxTWF -lUW1lcV1NXVFxXVFtXV1hUVlpTV11aWVZVVF1aVldUU1ZVVFZWXVpaXFRdXVhZXFYYtrK2uLS4uL -qivryoqLiotLy2pqa4tqa2urisqq6upqC+sKq0vrampLyyrrqutqi4PVllbXltXVlpaVllXW1ZWW -FtcVlawgpy3HQlXWlRaWlpVWV1dbjoWrqa2tKq0qrS0urakqrSu1rS0rLjqrC0xVfeuKi2pra4vr -qmqramsrq6tqy2prq6pqi2uL6kprympra8pqi2tqy2pra2vrSmpri2oKa2sLawvrqiprKyvrSuuK -qwsLq6tra0pLa2tra2uryuqKqoprC2tqa2vr6iqLSsvKasuKi2pqa2sLqwurampLK+sKa6tKS2oq -a0tqKitrSwtra+tqS+tqa2vrSmpLa4pqq2pKq2uqS6tLq2uKawuLaypLS6ura0pLS2uLamtKS0tL -S2srS6urKitLa2trKktLayoLCyvrCktrS2tK60rLauqKqmrqSkury8rKwpXVVVZXF9aV1haV1taV -1JWWlZbWlFWWlZVWlpXWFpcWVhXWlJXWlpWWVhYX1RUXFteWFZdWVpXVlhaVFpVWVldWV1dWVlYW -lVUWF1VXVhYXV1ZW1dVWVtVU1laWFVZW1pRWltZV1lbWlFZWFxZXVlfXVBbX1VRW1lYW19YUVpbW -FFYWVlZW1tbVVZdVlpZVVtdWFtcVV1ZWlVYXVxfXVhVX1hYXFtYWldUV1hWW1taVFJZVFlYVVtZU -FdZWVhUWFlYVVhYVFgcqrCuuKSqsriyuKyysqSyuq62tqquqrK4qLq0urKktLSqtrGKYplLmIvWw -BIA08EkClndUxpJ9TJiAKgrZ5EQEcopp6AMHphdHDU1vjgI0D3vA2ETssYpZ6KOG5mGPFpyJOFg3 -xTtSNcM5PmiKb6BuKuoIBZUksugpIgpcJJQqtmKV2B/essRDUrnyK2NkMQscB0BbN06ALMM4FkPS -llAvnAL+KLxcnkngZVsNONOPEw96YeJAfIjn8B1ew214DcfhNzyHB8EQcSchJn6AyABvwOTE4bQU -oJB4gjkYrwDLQkCKDVQJeABj4iEZJmTisAOPaiCYDwhDDVMB8KBhbKwEDBFLAeTQ8BJLSr8mSSr/ -Yo14Xi4hBF/BQv8FQIqs+eJKWiejD0zPRR6gmog7QmiCdYzwVNRBKlo5BHE0cgjjpyJsZydiENJM -Qx4vLgdhb2Aa9tCBaagDh6dYh6smDylndwjo8GtjHTOfAaZw/ZhIhwfjGBqChDRW4HdkWXxCggQc -C8kAn/ph4lA0SJwJhogbZXm40EsOL+I/vIgfcaQeKE5DcPCC2M2QJbQ38F+hAn8yasCNaBRwIc7E -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 -oCQNjTQGKKDGwTHUplKAo/rmQxQFZxKjtfVodPYNVRHDuD6UOTwAXRJZwGhp4Po9h4XVbx/+MDYH -ALfdu9+4/5GZnrSiMBQYXHduBF3M7Do6NEWCeFO+dNSWpqgV80xD7ypIj4tqyRjoUu7ANXodg6bZ -YG8XQxtngXzFdHpzKsAn0NBxFOQ1vQBhylz7zOSbojA2BlOy6GANJPqgkwGWUbrtKp6np4oarXIw -SUE8gpC9YNaIOdYHclFoGNP1ZyAodrNJpuK3qTZhmpfxSTD26e9dlnDLuPf/ia8Qrf7WNUFruosu -cER5x5K8JwhODqCNGLGUQJWG3ykKei73iMJwYsvqoXDWrIkHDmSa0lfjWJA27OL8kOxEHFgYmK// -8air3g2id4SBDBaIG95ECHoUJTDvjz+9DgkJY9YIRS8UgoiKfuZIyJNH2CQEV7AQsKQCvRc/znVk -kfTc7csxZBDUZYUhxK5oAWrx6xQwLVxF3q4SxCP9u8nBa+Qvut1HHrap7h8fwvSQLrK5ZDvsO2OK -Wiqmpo+9zizEMSMImjMhShf6tHtwSMwUh7Isb9tVxfaWLHH0wgjqdulhmHEAay+RLofs/r7mB6tq -4gQ+sdQFcjwEj3DcZ8ybgjV2JV4smKN4INfIkbyRBwAA7Ad8Z3gHZ38H/3CKQaZf3r3e9ZcYqPut -vFZ86LKrF074/WYWY05TxvO4IYhg1sijSbsMVDU7dil7wi7qDeDDNOwJAHQKqDJhZGM5MDU1MC1l -Y2UwLTQxMzctOTFmNC0xN2M0MTVmZWI2ZWVkNTliODUwZC01NjBlLTQzNjgtYmE3NS1iODYyZTBm -YmQ3NDQgNjM4LjI1MjM3MjNkZTBiNTAtYWQ2MS00NzVmLWI0MTYtNDk3NDMwYmExZjgwOTI0OWEz -OTUtNDBiYi00YjVhLTkxZDMtYmMzM2NhNDlhMGUyMy40NjEyNTUwMTMuIEEFyyEiPK/2b5795nSQ -BlCtZhpYq5HmeaC5I+e3mao5IrTNqQTfThDoBqQNOeCvwLpQOYMQgljDWOean5oxmIYH3NoN2gWy -JmrHSno0ph88+OW3c/SY4ADufA/sOhk27tQGjjVXgOc3pyk8mDWj8d9EBOoGFqYB8gMLp2HQf3PP -ES6BCPTmG1hLj9b0g5cK0QU2dIwAxDttMTgzZTQzZjg0LTRmY2QtNDQ1Mi04ZTNmLThkYTE3ZWNi -NjIzODJlZGI4NjVkLTg1M2MtNDk4YS1hZjMyLWE2NzZlMWUzOWZlNm1sMTBfU1ZHRmlsdGVyDS8g -Og0vWE1MTm9kZSA6DShmeG1sbm9kZS1ub2RlbmFtdmFsdTEgL0ludHR5cC9BcnJheWVUdXJidWxl -bmM7Y2hpbGRyZW4vcmVzdWx0KHR1cmIyYXR0cmlidXRlOyAsc3RpdGNoVGlsZXMobm9TYmFzZUZy -ZXF1ZW5jeTAuMDVudW1PY3RhdjJ0ZmVDb21wb3NpdG9wZXJhdG9yKGluaW5Tb3VyY2VHcmFwaGlj -eDAleGgxMHl3d2lkKUFJX19pZG9iamVjdC9EZWYgOzRmcmFjdGFsTm9pczRHYXVzc2lhbkJsdTFi -MmREZXZpZmVPZmZzZW9kZGRTcGVjdWxhckxpZ2h0aW5nUG9pbnRMLTUwMC16LTJ6c3BlY091c3Vy -ZmFjZXR5bGwtY29sb3I6d2hFeHBvbmVudCgxQ29uc3RhbGl0UGFpYXJpdGhtZXRrazRrM2szMTAx -MjEyTWVyZ05vZC0yMTR5NEJldmVsU2hhZG93TW9ycGhvbG9neWFkaWxhcmFkaXUxLmJibmItZG5i -Mm41RGlzcGxhY2VtZW50TWFwKGJuczN4Q2hhbm5lbFNlbGVjUnlBQ29sb3JNYXRyaTQ0MW1hbmlt -YWNjdW11KG5vbmNhbGNNKGxpbmVhZDVmcm9tdG81dG9yZXN0YXJhbHdheWZpbGxmcmVlemVOZGRp -dHJlYmVnMHM1NTRuY2M4Y2NjY2NjYzhjY2MxY2NjbmIoLTU0MUNvb2xCRF82NmVyRXJvZDY2NF8o -N3JlcGVhdEQoaW5kZWZpbnNwbGkxcmVtb3ZSMSAxOzIwIDE1OzIwMCAyMDA7IDE1IDIwOzEgMSBj -blBpeGVsUGxheTUwIDU7MjAgMjA7RGlmZnVzZTV5ZWxsb3c7Z3JlZW47Ymx1ZTtpbmRpZ287dmlv -bGV0O3JlZDtvcmFuRGlhemltdWVsZXY2ZDExbDFyZWQ1MDEwMTAxMjJucmVkNjg4LTEzNDIwLjAu -MTVudGE4eDU0ZGRvbkZsb29mbG9vZGJsYWNrOyBvcGFjaXR5OnNDbjM1bjFuMDEwMUdyYXkoME94 -LUNvbXBCbHVyVDFuZW50VHJhbnNmRnVuY3RhYmxlVjJGdW5jRy43IDBCMUNvbXBYZmVyRmlyZUEt -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 -yoYSYWyu/bml55/3q1drZU967z91a298mv+p36cST3pv41sf9/QqrRW9Wvzu9srb1/btee2N9336 -W0rrfSqr7TstlfZ6zu/Z1htxvZS6W+yXfq799KesPq3nrrdnz27aM/u8uFaLZb3Y2vpNcX3s9Nqv -Lqm999/OpvhK/JTOt1i6Z4lL2CJh062X0306FRK7ocRtG4ybsSlsUiWn9XO/19u1Ttw/s8+Z7Xe0 -Xj3TOT3T+dPeOyfG7/Lb4n5vb/r/OMvrf2HZljCY+FQIQ40+0WODNK5B6Am/CyhPXEACQBXlUPo8 -ksbE5XKII230eSKtE3oFKrHBLUaEubMdZ/fOVOkz7Y2Ztr1WnJ9v7m7b104rvWNj1IUpDFvRypst -m2u7xBZVwtg6dVFYxqirukVhLa9FXfZWijOV1sJKVdro1U2X2KcBvJHJ+zJzUgy99sZ5LaZ+3YrT -rej3NmUR26c77XyiU9knZpe0Unc8661z1kprpZROCouzUqXu/+7/xtSKl/Y/VZp39pzus7tpd8/p -Ptv7WrHndJ+2r511zlox184PrdKttx/pR2tZirHttForYivSbN1OK1KLwqJbkVbbdlZKq62YKt1W -Sa14q72RUq9uRbditZXCYrWitaxYKYtIrb3RRnspLForWstaF8u2k9b67pfW29k2nRfjx3nmSRvX -tvn+W6+Sjjht22hhlnGPc0ZMo/XGqCtaCrOyW6X8lkVh2aOVtxStx/xUJvYV/y0bf8Z/6or/0b4V -/+NP6Vb8+fktCrOokv0ffdkVw22kfdeM2GPbSOtIKNJIn1bdKcWOrbVivyi2WxYX2y/3imXH7NRG -A4XBxKZITTEiTLy4vhW/9InXWvHfik6FYKLHzlZsp0IYp9fG9rasditeK/q0nF6bc5Y5d2zPH31S -pXijTyoTm0RduS/NFBavFT/+jDV6T4y6onvEb8Wcs2x/mePPeHHG/ZZFYfipUnS38FMhsdupU8On -LfBAnReGJ0z4eSYGmtH2cUK6beM8GVRRT19WbPP/a4y2E0fjQlmnmd6gClTheqdnK5vC/DaW7hSW -JbVKLm2sT2UfTPvSGe3n2HndZRKd6kAVqAJVoApUgSpQBapAFagCVaAKVIEqUAWqQBWoAlWgCgNV -oIoqgSpLjT6xY1MbFIm65sz9nmVX6RTW1BWfzpb1Y63Us7TR5pY02r+19sunLvoR1w== - - - a+O0KIy6flo+rfrWpC2xW9e95XULXytSi7rifKvSOuV9q8ppu+WlRNVl9VinFa1Tor6e+1rZk8I8 -Y2tFmu+UXq+kluxpac4yP4VFay1qRZy/WtHWWSW1dWaKUdfPWiX9+ZhK6j+zpE6JfHZu2Y4prFJY -tPOvdLcsLKsV/eW/FbOVZbtFierPt6xb863rlpyfabfst96isHixW5mtOC2lsr71VLYV8bQidesW -VaKyT/y+1uXMjTHOt+df6qSF2+ctyDZxNLpMKM4LlRpQn7hUo05TeQH+siudsy3F1Ge2uNbG1t6v -ddr2iafbjCv+mfPEtun8Seekd15v+nY+dgsnWuv0J/bum3H+vtUpre304pmpZ3rrbFp95rYV51sp -rbmdTkzbsXv3pG5tZ0vttH2vWzypvRNP2TRX+28tmOjXwokT//RJ37bFNTv+TOvjiW/TS7s6bTtz -nfXxvG0vtmBizhZOrD5l56+12m87H9OMf17aN7eV7RbTpn97VtkxX3qd0q7uFkyk0y2cOKvTKmtt -bDHt6rP+rX3dfWZbL85z4pw74n/6T2vOc16Mc+c87cVPH+N//znnxHTijO2d/W/n4745v1fabm32 -jC/+ip22vbbmPOdn92zBxLZwIq4+61vc1OfFczbuO7N998du3WmlmE7qtfp0bNu7vT6dPqn/9KYY -27fU7eeMsb1N53QLJlZq4cRvl33zxD8rxvi/2+K2+OettSvF2fPnWpvWSm+3WzCxP/fTmSnu/plx -u/1ZLaUWTrT0uuzYten0TNv+bX8672w8K7VZNr233nmz54yxWzBxuv23YKJft3Qmt7oFE7O1862l -95v67HwtxV7/Vir71kq9540Xvzud+O/3Z3rl/fn21mrBRNqNc1PZ8T6tbX++xXXm+e24G9OeGP/s -nC19t9/ubZ9ar9Pefvu3qcWSXgsmOq7z+yXurvbmLCdt/+x5WkuvtWAizm7hxKZ+J+5uWut075mz -7evWM664zu5K/7q722o9+317MXY551s48X/mLPHfd/wZY59Oc7Vgor1ecU8rO1771tb6F+dbqa2W -VkxnTwsmXuoWTrz0LZ1Jlte7cfv9b4uz7Jj98e3uad9O/+6WnS2c6PT63/737qaztsUZ03/P+cqO -dlowEb+FE+/8Ot8942x/fleMu5t+xu10fvZ77cWyv+u3zd+VWjAxTwsnzuyWzqRpvvg//7Utu2Ja -MX18P9Nr570333/8d17P2HoWdlpIZlGrY9nxbWe37fdPHObSn9X2V3zxxDhrcFlLq308+9Z3iS1u -7LXTtI/zn91xtW87/tan9dKet9aaH7vtkdaJGE5nMqGyjwATEQZFBeATwtDCUOMyjFGnAeWJS0Vd -IAi5U0bSMh6hKdY4gMdx4qeFp4v511brjb9eSm21+D97z/k504pztt65PUuvFnv+KaXH9ogU2oKN -Avw0jqh9HknDxFGXmRhoovWOC22ZiROB2UVFW/CBIlFmCsDniYS+bFQpBwzmwdDAUzR5X2bWfwwm -eqay47/Fb6fsSwiSvPt1yrbCLkFp40oiYYYhEmYYEV9cb9uufnG22TruSy+VjbHX3JnWOy+mtlbZ -noa2YAszTuuEdJdMOUSGSRQQ40MkaZ0EoQtOhXKIDPXLOEBQ6y7AUaeZtMynhVop2zKdvSMSsklE -reR9Itetc+L6ld6mjefLjvT+u/+7rZ8ptbZttZjGenPbiaetU3aVPWXn+tUbv//tmbH/pXPKrthO -Kme19XFnenu254krtvPil/PzvD49z8fUXvr/9NavlzqutOIrP9N657Tu/dQ7R5rttfavtV7ppD6/ -5pvne32cKXX79e+3ndNvV6/WI0X0rxdfi6/PS7+zv51OnepoBaJ24jDulgyTLYANoPkCoCEy7ePc -wRvcdbp0UybBT+s+74q3QXi6mIw2sJsIN41KZAhFGomkidqCDYvctqlEBtOWSY+d13XeFp5EGgNN -haIEjDqNw4xGF522QKOBG5RDZDBFBNR6tdKzrfZK94gdLzhu23Dctgm306jzrvDLMCqREhAnkYoP -le+Ce23E+0KPaAMzzIgoCz1caAM3jkrstodY0RZsoUgrZQUqkcHDAT3EbgCvq6hQYO4Zp61RwyYU -g8eOHSuVjh0rN1biTyiGCcUACjNuA7Idq+cCNfiy0IZpXAhuHwY0cYkzVtlxzio70tgTimFCMbyL -gDl2jjXMuE3tOLs9+oRimFAyMlRKmeaJnyYSZhoWK9oppPM0IrgQZpcIePowI24TdRpGtCKXeaIv -E7liRQQUEZ08jTDjNlGGpljbJ5QVGSqj7uR1ogxNccZKZPi00XcRPy0k6zKLKAKePkykLrot5MRh -YM+1OohZGKUGiNRSDT6yQczCKo1V3ovr9JxlXz62Tq/XOp3df7GVTXXAk8gjgTLtu4QMNI2/bi+u -jnHXt0p0zqazJ52z6bxyLl3M7a6y4vvzZ7bqW9VfUgqT7Z+tKu3Tx7VaOd+K86WHstD6Mkwo0/iu -V85Y6Vt5RXfiv95PleqV9EXf1lrpjykRzVRWt7CFffTO+OIqvSTbLSzSx06VppxWxF8xiVGnStJa -iyp1pNhW6ZRoOoXlnKX9t+hL9+i00o/Z2pY2v6zTstOisLZWdiu/dR2r8n/K+/Hzv/TZEjt1ucSy -rSk90kxd9qzyvb39y67oidRM85SXxsf5ykrzuzWhLrez/+Wdcj52ianrfVbs1PXWmlb0SV1uTY9e -5fvMuGWmrvkuaZyz6ZTU5cdvizbO1FZqRZytl9RaS+W0Ys2dXb7lVGluqMtt/Sux5d8v34o00nov -9f+XN0q38sq39nJZY77RShqf2q+y5fXuOWX2SGt9Sl2R0n+ZpfWZ5f2uVVqqlPPFLuu9n+MGCaP1 -RlpffvQ7e94qH1RtcKAKVHGzX16n1sqbva+8L6c7fnldvlvTVpldTite2vPe+BbFRZxxfeoup+XX -nQYODmIsYBDgEPAsKhXdKUFHJNjgOMIByME/FiCCB6lmwGZD4+PiIjnAIV1fR3vjBIbuiqqEOCIu -GC5JHUDCpqwTVEGSs4+CxLpdJancrpKAmDgUCfaxcJCATI7TyRBImCxI+nbVdzMJEo8RyEFSURMH -GRSJgQQiDhKvHxYkDhdFQdJwu0oS3kyCxOsowCC5F0VB0hdFQUKZoAoSAyKQg+Ri8w6SAwsVS/IM -3UBBAJHoEkWFoFgeWum3aEuS+Vg4SCrK83CiSCQJhEFiyhywJAUWKpYEQoooEoSJAYrksnkHSSij -syQl8L8PxEKMTckQQqH4DrcZaQwzNQ/ejL9wQOpfQBCCxQXiQihQsfDAEK8oi48CDAKVBQXM9Egm -KjICYBYUzQnzaRmEBgtBwSAVghJBASIxQ5EISkbCBKkk9NngyA8PUcUKGaDpivUQ3sBoEpG5UCgA -gjkgLwE0f0BCgAESFazIijJ5KgSFocNS6Q0TMki4kY1BUkcgB4nmg8NBgkkgDBKPFFEk2MKWZOKD -w0FCv49BImI7Fso/ZAygb0GpNILJ6S8X9WPiOb6Lke4QRhTXNIB0KggkLPKKKkkkI33isAcCDdmm -MDc6MAvFglQIyqinANfbgFgDDJSsAYsnxswECRIZgoBHYdQQIBcRdCRTISiZDoVRL1hQKl0JcURQ -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 -bnGL2wRlixvNY3XcJ+Cg4xA+b+HmQYbHPWjILBwFlpkkIFAwWoIicDdBShV9ij1KYNw2FkCmb2Zn -Fj4qFcg0j4qUaUqeSmQi0ET1N4UvxqHi5n2Eoi+ekBYAllHqKB+haIZWJm6eS9y6ipD0he5GQP6g -aEbhw2ncs6lxMQsYtwsZpgSKKg+ibhmBAJZMkc0UZdXkMTJW+mJPIWoOxHowlYCAAE4ECiKVT8O3 -mQIFkUrcOFSm4zaRXDgzioeRDIDTIltFEHC0Twfh8QCrF/ipvDDCD+g9VKGWMVSMRUAiwIICCFFB -yFxIT6MJEYWHBlilfVLWirguTq0l8Y7b7AG1abAXAx3lgbvgTCRxuxP0UFnkcTOJQ8eJKEIL96Gv -jtNMHDrOhNCxIKhmIP+IhwuOOAaLywgoJjBuBQ2jPHeBcYEE3aj0SU7yQe7OSF7xOJELECZEwano -2UNWIbDwWD4hwSAyTNxoD4KHy6gncQvFbQPj4UAQS7Wl+HTc5EINgaNM7dOQEjYNngTfqKDfwJ4c -JxQ4AY09V/fp2GVjupFmnm7tnRJj+tYpvp2ttJduHEfu2dnnxNRzdJ70Uoff631/XowlzdRz0G5L -6cyfcct56cX+fbHLm6mXM8Zuq8tqaf2+706p57j0L+4scaUbafb3nbPOWan/xN0Y4/mU9rxva534 -bi9a532/tV6Z88V1dr1/c77veTp11IszfnrvxP82W/mzKf1L8ZyVdrazYluf0mlnrV4r9Smb1ov7 -ev0qba4ezlVeWh3f16+dNbe9M3emV+a2MMf1624fX4o9TGungs78GGP5dl73bF92xdVim6nTaq/X -mmetG8lx7Td+69R+y6b1Wktz55642pf/7k+r/M7Uf17sVmKvG8mR+yd+Sen1tjT7zyvzvdLOiy29 -+D3X7yzvnbZSO7H8n5dOSm29PeXbeS+mnbFjnGl/lfn/5um5c/2Zp8Xv8j693Y5xbc+BJ661f1aJ -56x/qcwU11np7c+0ZZ7Tc9h6s30qu+L/DLNN67V/pVOca5bT4v5toxLGMIYxjGEM4/9/rZRmb5lz -dXzN9LrtbOXNtXH3pU/xtLS/v97pluLG9Fp3K9/a++3U/lfpXe3snO/Es96J8b3YWultN5bjs89L -3W3bS6vb6Vh6W8fT7PZmbGdtaTHN3jV/bitr22xnpvVr04un2+3loO23dsY+b0tcq+fAndtefH9i -KrNbp3XmO92ppE0903wvxhvJ4V0/2695fn68wRz23eLqOSrOuWfGtG0YwxjGMIYxjGFkOWidk3a9 -tVbPcak3rVZaSx2eZa3Voz0rfVsl/WznnbNpnk2rz3/7+GKf2d/il2/r41vnzT5r5+vVSnwptZ/b -XjunU4e1uFba/bNKbKvnmJS+Xyr/r3ul1l3aWz0Hzdbalo7p9pq49mfPMt/qOWbfSt2z41onprht -04olxbctnflJtmK31HM4rvZS+fQ3GK5Z3lor/uzW0jCGMYxhDOMG8zAgLHBC8HQCR2FCQRhSAE8+ -P0/61H7Oful9pxbjOi9mOWr1mWudtF6ZZ3XM2hPn2p/nvT+rw+t0+nnep00xvtX652u/biSH46/Z -6dss86wbyfEZu81/u+uUs59e+jhntxLPp279ykqp58Buc/WXs1aH55ndZtzzNrX/T6e8tG4sB3bv -aTGltm+u9O/1jCduWmu1tVaca/VKPUe2M7vLptVDD+joLYPkoLhjmyA52tHV0Y6NIsMTum+YAdDi -FrePkiokKg+br6Sn0QAiixUnZLIh0EFKzDwOl4zC5wIBM5spzP9Xff9LL24ft58VMwvN96/j9snP -s3xfWz6LV6H4R4nbqfJxRqAA2sO+xS0Wi0WquIHouSgUFTcQK3FzVShfqmTAEph1JpmYjJOBVCQo -HDgUl18m5uyhi9sTrCS1kAZRMd0MaREvGVCb/0oEUgLklk7Ayv1BIDI9AQiPY8QIXqDJBXhCob4a -0OrQ5xMQA2UwAQEzlScf8mQgnI7CEAByAjQHkClBo6BFfAvEUHFCDPe7aIA8biYJkMctbpEPyeKV -L0Z5rsEz6hdDhIMgC5Dpq6VmE67B4Bn1zIuU/LsRF3yYIBF0cfMeqtAWt40AtIjvIFCbr1giFC0L -QAQcyMrCAUkQgCQMQAsByIxbRBfULpTkTS4V3YUqputkkooOVUxXaQWYhKtWf3LSMgDjw1hYWFwj -IXYKw0/3ESxbmQIOurh9C51R1QQsdK1fgNj4TA4sEz4MZYHwmbzL8hCC66SBfK8HE14zcFIqG4TV -hPKVuq87DRo3DYK4cRpKqg2B6HIA+pgOWFbB49CxsBoCPfMy0jxkfBw6Na7VwpRAjoKg9aMKmoVb -0JSoRVY1edBjpc8hQTJoZDLz0siA1UUTsXgmGRSICuA0eGynihEIdJnOLJEcBBYuMixAg0po8bgV -jAIw+rVggfD1xrWguRjUWk3rNkrgvUxAfmBAu0mjmNrnwoqIW9xKWeRxAq8LCqeJ0EKT0f1c7oFI -lp80oYObB5DpM0Xc5QEmHg/GDYa6jFrhIaPgH1z1klQbMwH8GVio0CB8JtVm/sIL9FBbbXQoHfvG -zSKZ6GbC6co0OCqUvpOE7KTRaD0ONAIX1OqIDC0O0gAx7x1OF3H7XGhE3DhUpuMWc4gbWKL9SbI6 -zgBVsnDyATLhEDzscbIK+1VoaGjkJMmP2+lidNJIwFgCNwUY0zd5gSzHaD0eHD0yBxqOISXqWkGq -cZtpZGwaVJEZEzQl0EPCaHWsscs7EE34nBsrfZE/eGlKJYduSgym51Op083MZnGL2zfIuE0DD3uc -QMBBFxHAZeEkk7hFOk8NgQGp/lRBs/AYzAv5DCUx+RwVSh+m4CTqAo2QqD9JpOK04lg8bnGLAdvH -wBNjjFvLYqURgJiL5mjNYjVaa2bhaFmsNFq1laMFgBXNYpu1XhermYLnkcIYxjCGMYzUUk+559ry -zsYYN33p+HP93E2r55yt/fk2f37anR2Xvn9feutTeZt6DvsUX2vdqXXQauek9O2teMpM/17vjGm/ -9c5X4vxeJ30qP0/P4dhW68D+/7Pi7jslxdbzvLcxpRb79May8ZwUY3mpnZnaOt8nfetV1reOv/Sz -ldS+20yt15butuektKd9+/ennLf6/SpvW0d1/65W5js9B3XvOTOduObcTzFu6pheefH0HPQ6tf/S -tt1eDr+X0mo7W5/S8/Qctimltsp3Sz3/xNlWLGfTz1nSacMYxjCG0Tt/rrSztDlfp7POfDF+em+t -lDq2NNfG+a/s23jWnp4tvhdfn//5Uge10u9tXOv1O6etMtufFv+dt6XPmWlXS/va7HLmWZ9aSXN1 -XNs9sbR1evn9vleH0/v9dOJ6r8R01kmzrLluL9wvK825273aW2XGudbcXmfNk9r8mN6bZfbpOWq9 -9doqKa355sbTw48tzpR+vtdpvpXSfK91iuul71bin//+ts6ab5Z04jvrzPhSl5POimlLt/Pev+7f -Ntfa3hLPusEy9UltxV/DGMYwhjGMYQyj9Upr27cV98SN86RtvU78tPu+xe4/vzO9ubo79nq7uk/P -9K+kd3q11knnrBXja6ltK23f7eXoWt9604kt/ffOLa3jtrbWia/LxjZTTOdfmfur9/uljoyxtdIf -T7c540ul+71uu+KJM64by1Hv/ezX0m6XmM72+/PdZe3ruDhfn5V2buuebXX8/Wkf53ylvf6Ob6We -rexst5fja7X4vu1J88a63bPO252v/Xd5sXW4rfVpT5+zylyn53N6nrXKia2j+r3uVV6LreM7+x/L -ii2u1NJ577Uwx2Oabb3U3eJ6uz+HMYxhDKNbb1y/731KvauVtuY77bxNcZ2O57X/+M7aN/djmat/ -255dHRN7Z+y4Tjnr9NxO2rZiarvtxPlWz1Ria7eX42Z887RPu9KN5ahYUjrbtvyL6XR7bZ31Pb+V -9VoHrvQ2tj9n5+rdbqec12Ls2O2d80r707uV2klzltbajdW5LW6v0i2+c9Zpr73WG2fs/+0v277n -sG27P+f+9p7u3/hajO2t0tr37sS5G+Ovk2b596+dFeNq781ZNn7Pkb1Wij1XSfF7OHvOs94859OM -r8y0rZ21b9swhjGMYQxjGMPY2Zv4rX2vO/aMvb78z3d6vvNi/NjaOzOV9rvp/faKc/0VbBYzTebj -i+W0/9Pfel8uLQ0BKGzEEFoT4GReLnZmfLm0XhYZqxqrhXC5XKweT3svldVz7e6mktLpObKDVjpd -Pp1exY7d7ctc7/Zy3Glp9af40o3lsO9f7ZV15nfcvvV+vvln7jyl289OJ6VT+s/Pt9v23F4Oime2 -tt5a75XXf1K3edqNRe/T+tdKr7TtbEprdXzf2S5xtjRbb9z3JaXVcTs7zt7Zr+fw2/MztdX6S+s5 -d3WKu/GlVv60tdp5pa3f1158L83W4vy1v3qOx7Va+//Vcb9rzk+pbdqY+qVT+qzby+HTXq+5/99z -5M//+eI76wZzOJ393fTp9X/bsymWlN4w0lnrRZGxClFgq9nqdLm0NFauhBYALkgCqxnFauPgtbqo -XWQU1GarWgJFhqd1ccLZ2llro9pp4zmz44sAYLBiL07IP+PP1z9bmZq1ahktzuXSomlcvF6ey+Vi -Ra/jjVVx9a6yYuq4dGb8U35vrFtn+6z2Su9qnVLL8nt9urvXpjPbe6f9jF+6rY5Mq2dq8ddvWemc -l2I53y2etumtVOJbK2EMYxjDGMYwhvEVRlgYwxjGMIYxjGEMYxjDCLu3MZ349XJMfKf7Y/yVzqbW -rzfGn2W/dcxbZ/0qr79j+7St4+JaZ/vseVtez+25/mzal1o5m+aeE2NK/85ccX08sw== - - - 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 -sZWZn4SSBvdvaZYgKg== - - - diff --git a/v0.58.0/imgs/logo.png b/v0.58.0/imgs/logo.png deleted file mode 100644 index 08943b5accaa..000000000000 Binary files a/v0.58.0/imgs/logo.png and /dev/null differ diff --git a/v0.58.0/imgs/overview.png b/v0.58.0/imgs/overview.png deleted file mode 100644 index 777c32d939d2..000000000000 Binary files a/v0.58.0/imgs/overview.png and /dev/null differ diff --git a/v0.58.0/imgs/repo.png b/v0.58.0/imgs/repo.png deleted file mode 100644 index 80b80689d02f..000000000000 Binary files a/v0.58.0/imgs/repo.png and /dev/null differ diff --git a/v0.58.0/imgs/secret-demo.gif b/v0.58.0/imgs/secret-demo.gif deleted file mode 100644 index 085606ccb563..000000000000 Binary files a/v0.58.0/imgs/secret-demo.gif and /dev/null differ diff --git a/v0.58.0/imgs/trivy-aws.png b/v0.58.0/imgs/trivy-aws.png deleted file mode 100644 index 5e748fea5757..000000000000 Binary files a/v0.58.0/imgs/trivy-aws.png and /dev/null differ diff --git a/v0.58.0/imgs/trivy-k8s.png b/v0.58.0/imgs/trivy-k8s.png deleted file mode 100644 index d9060bdda1b9..000000000000 Binary files a/v0.58.0/imgs/trivy-k8s.png and /dev/null differ diff --git a/v0.58.0/index.html b/v0.58.0/index.html deleted file mode 100644 index b9548c20371a..000000000000 --- a/v0.58.0/index.html +++ /dev/null @@ -1,7930 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    - - -
    -
    -
    -
    -
    -
    - -

    - The all-in-one open source security scanner -

    -

    - Use Trivy to find vulnerabilities (CVE) & misconfigurations (IaC) across code repositories, binary artifacts, container images, Kubernetes clusters, and more. All in one tool! -

    - Get started - Read the Docs -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - -
    -
    -
    -
    It's all about the community!
    -
    Trivy is praised by professionals worldwide. Are you a Trivy fan as well? We'd love to hear from you! -
    - -
    - -
    -
    - -
    - -
    -
    -
    Sam White, GitLab
    - -
    "Trivy was a clear leader in the market as far as features, functionality, and capabilities"
    -
    -
    -
    - -
    -
    -
    Ariadne Conill, Alpine Security
    -
    @ariadneconill
    -
    ...the tl;dr is basically Aqua's Trivy is the best one, all of the other ones are a waste of time
    -
    -
    -
    - -
    -
    -
    Harbor Team
    - -
    "Trivy takes container image scanning to higher levels of usability and performance."
    -
    -
    -
    - -
    -
    -
    Milind Gadre, Mirantis
    - -
    "After evaluating several leading options for open source vulnerability scanning, Trivy really stood out"
    -
    -
    -
    - -
    -
    -
    Jerry Gambli
    -
    @JGamblin
    -
    The way the @AquaSecTeam team has turned Trivy into the best open-source vulnerability scanner in such a short time is really amazing.
    -
    -
    -
    - -
    - -
    - -
    -
    -
    Yaney
    - -
    "Trivy is, by far, the best open-source tool for cloud-native security that I have ever used"
    -
    -
    -
    - -
    -
    -
    Ulises Galeano, MasterCard
    - -
    "This tool just keeps getting better and better..."
    -
    -
    -
    - -
    -
    -
    Damian Naprawa
    - -
    "So happy to see collaboration between @Azure and @AquaSecTeam on scanning container images in Azure Container Registry CI/CD workflows using such a great tool - Trivy."
    -
    -
    -
    - -
    -
    -
    Mustafa Akin, Resmo
    - -
    "I love how Trivy democratized dependency scanning to the masses as a free and extremely easy to use tool, with also a permissive license. This used to be a gated community with predatory security vendors charging premium, and they were not half as good as Trivy."
    -
    -
    -
    - -
    -
    -
    dynaptik, Deutsche Bahn
    - -
    "Trivy easily for what it brings to the table (secret scanning, vuln scan, license check) and little effort required. Bang for the buck it's pretty amazing"
    -
    -
    -
    - -
    - -
    - -
    -
    -
    Cristiano Corrado, Wise
    - -
    "The discovery process led us to evaluate multiple open-source tools ... The final decision was to use Trivy"
    -
    -
    -
    - -
    -
    -
    Saim Safdar
    - -
    "my favorite @Docker extension. (Trivy)"
    -
    -
    -
    - -
    -
    -
    Jonathan Gonzalez V., CloudNativePG
    - -
    "Thanks @AquaSecTeam for creating Trivy and help us to improve @CloudNativePg security"
    -
    -
    -
    - -
    -
    -
    Andy Roberts, Vista
    - -
    "I've tried a few and all have pros/cons but I found that Trivy is the best of them"
    -
    -
    -
    - -
    -
    -
    Ali Faraj, Antigen Security
    - -
    "Trivy from Aqua Security is my new favorite tool... It's such a powerful tool with the ability to generate SBOMs, find vulnerabilities, misconfigurations, and secrets!"
    -
    -
    -
    - -
    -
    - -
    - -
    -
    - - - - -
    - - - - - -
    -
    - - - - - - - - - - - - - - - -
    - -
    - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/overrides/home.html b/v0.58.0/overrides/home.html deleted file mode 100644 index bb73736d80d2..000000000000 --- a/v0.58.0/overrides/home.html +++ /dev/null @@ -1,244 +0,0 @@ -{% extends "main.html" %} - -{% block content %} - -{% endblock %} - -{% block hero %} - - - -
    - - -
    -
    -
    -
    -
    -
    - -

    - The all-in-one open source security scanner -

    -

    - Use Trivy to find vulnerabilities (CVE) & misconfigurations (IaC) across code repositories, binary artifacts, container images, Kubernetes clusters, and more. All in one tool! -

    - Get started - Read the Docs -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - -
    -
    -
    -
    It's all about the community!
    -
    Trivy is praised by professionals worldwide. Are you a Trivy fan as well? We'd love to hear from you! -
    - -
    - -
    -
    - -
    - -
    -
    -
    Sam White, GitLab
    - -
    "Trivy was a clear leader in the market as far as features, functionality, and capabilities"
    -
    -
    -
    - -
    -
    -
    Ariadne Conill, Alpine Security
    -
    @ariadneconill
    -
    ...the tl;dr is basically Aqua's Trivy is the best one, all of the other ones are a waste of time
    -
    -
    -
    - -
    -
    -
    Harbor Team
    - -
    "Trivy takes container image scanning to higher levels of usability and performance."
    -
    -
    -
    - -
    -
    -
    Milind Gadre, Mirantis
    - -
    "After evaluating several leading options for open source vulnerability scanning, Trivy really stood out"
    -
    -
    -
    - -
    -
    -
    Jerry Gambli
    -
    @JGamblin
    -
    The way the @AquaSecTeam team has turned Trivy into the best open-source vulnerability scanner in such a short time is really amazing.
    -
    -
    -
    - -
    - -
    - -
    -
    -
    Yaney
    - -
    "Trivy is, by far, the best open-source tool for cloud-native security that I have ever used"
    -
    -
    -
    - -
    -
    -
    Ulises Galeano, MasterCard
    - -
    "This tool just keeps getting better and better..."
    -
    -
    -
    - -
    -
    -
    Damian Naprawa
    - -
    "So happy to see collaboration between @Azure and @AquaSecTeam on scanning container images in Azure Container Registry CI/CD workflows using such a great tool - Trivy."
    -
    -
    -
    - -
    -
    -
    Mustafa Akin, Resmo
    - -
    "I love how Trivy democratized dependency scanning to the masses as a free and extremely easy to use tool, with also a permissive license. This used to be a gated community with predatory security vendors charging premium, and they were not half as good as Trivy."
    -
    -
    -
    - -
    -
    -
    dynaptik, Deutsche Bahn
    - -
    "Trivy easily for what it brings to the table (secret scanning, vuln scan, license check) and little effort required. Bang for the buck it's pretty amazing"
    -
    -
    -
    - -
    - -
    - -
    -
    -
    Cristiano Corrado, Wise
    - -
    "The discovery process led us to evaluate multiple open-source tools ... The final decision was to use Trivy"
    -
    -
    -
    - -
    -
    -
    Saim Safdar
    - -
    "my favorite @Docker extension. (Trivy)"
    -
    -
    -
    - -
    -
    -
    Jonathan Gonzalez V., CloudNativePG
    - -
    "Thanks @AquaSecTeam for creating Trivy and help us to improve @CloudNativePg security"
    -
    -
    -
    - -
    -
    -
    Andy Roberts, Vista
    - -
    "I've tried a few and all have pros/cons but I found that Trivy is the best of them"
    -
    -
    -
    - -
    -
    -
    Ali Faraj, Antigen Security
    - -
    "Trivy from Aqua Security is my new favorite tool... It's such a powerful tool with the ability to generate SBOMs, find vulnerabilities, misconfigurations, and secrets!"
    -
    -
    -
    - -
    -
    - -
    - -
    -
    - - - - -
    - -{% endblock %} \ No newline at end of file diff --git a/v0.58.0/overrides/main.html b/v0.58.0/overrides/main.html deleted file mode 100644 index 7b574b0f5354..000000000000 --- a/v0.58.0/overrides/main.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends "base.html" %} - -{% block extrahead %} - -{% set title = config.site_name %} -{% if page and page.title and not page.is_homepage %} - {% set title = config.site_name ~ " - " ~ page.title | striptags %} -{% endif %} - -{% set image = config.site_url ~ 'assets/images/illustrations/banner.png' %} - - - - - - - - - - - -{% endblock %} - -{% block outdated %} -You're not viewing the latest version of the documentation. - - Click here to go to latest. - -{% endblock %} \ No newline at end of file diff --git a/v0.58.0/search/search_index.json b/v0.58.0/search/search_index.json deleted file mode 100644 index a74f0dd5a200..000000000000 --- a/v0.58.0/search/search_index.json +++ /dev/null @@ -1 +0,0 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"commercial/compare/","title":"Aqua Security is the home of Trivy","text":"

    Trivy is proudly maintained by Aqua Security. If you liked Trivy, you will love Aqua which builds on top of Trivy to provide even more enhanced capabilities for a complete security management offering. In this page you can find a high level comparison between Trivy Open Source and Aqua's commercial product. If you'd like to learn more or request a demo, click here to contact us.

    "},{"location":"commercial/compare/#user-experience","title":"User experience","text":"Feature Trivy OSS Aqua Interface CLI tool CLI tool Enterprise-grade web application SaaS or on-prem Search & Discover - Easily search for security issues across all workloads and infrastructure in your organization Visually discover risks across your organization User management - Multi account Granular permissions (RBAC) Single Sign On (SSO) Support Some skills required for setup and integration Best effort community support Personal onboarding by Aqua Customer Success SLA backed professional support Scalability & Availability Single scan at a time Centralized scanning service supports concurrent scans efficiently Highly available production grade architecture Rate limiting Assets hosted on public free infrastructure and could be rate limited Assets hosted on Aqua infrastructure and does not have limitations"},{"location":"commercial/compare/#vulnerability-scanning","title":"Vulnerability scanning","text":"Feature Trivy OSS Aqua Vulnerabilities sources Based on open source vulnerability feeds Based on open source and commercial vulnerability feeds New Vulnerabilities SLA No SLA Commercial level SLA Package managers Find packages in lock files Find packages in lock files or reconstructed lock files Vulnerability management Manually ignore specific vulnerabilities by ID or property Advanced vulnerability management solution Vulnerability tracking and suppression Incident lifecycle management Vulnerability prioritization Manually triage by severity Multiple prioritization tools: Accessibility of the affected resources Exploitability of the vulnerability Open Source packages health and trustworthiness score Affected image layers Reachability analysis - Analyze source code to eliminate vulnerabilities of unused dependencies Contextual vulnerabilities - Reduce irrelevant vulnerabilities based on environmental factors (e.g. Spring4Shell not relevant due to JDK version) Compiled binaries Find embedded dependencies in Go and Rust binaries Find SBOM by hash in public Sigstore In addition, identify popular applications"},{"location":"commercial/compare/#container-scanning","title":"Container scanning","text":"Feature Trivy OSS Aqua Windows containers - Support scanning windows containers Scan container registries - Connect to any container registries and automatically scan it Private registries Standard registry authenticationCloud authentication with ECR, GCR, ACR Supports registry specific authentication schemes Layer cache Local cache directory Scalable Cloud cache"},{"location":"commercial/compare/#advanced-scanning","title":"Advanced scanning","text":"Feature Trivy OSS Aqua Malware scanning - Scan container images for malware Sandbox scanning - Use DTA (Dynamic threat analysis) to run and test container images' behavior to detect sophisticated threats SAST (code scanning) - Analyze source code for security issues and vulnerabilities"},{"location":"commercial/compare/#policy-and-enforcement","title":"Policy and enforcement","text":"Feature Trivy OSS Aqua Kubernetes admission - Validating Kubernetes Admission based on automatic or user defined policy CI/CD policies Can fail the entire build on any finding Granular policies to fail builds based on custom criteria Container engine - Block incompliant images from running at container engine level Block vulnerable packages - vShield \u2013 monitor and block usage of vulnerable packages"},{"location":"commercial/compare/#secrets-scanning","title":"Secrets scanning","text":"Feature Trivy OSS Aqua Detected patterns Basic patterns Advanced patterns Leaked secrets validation - Automatically checks if leaked secrets are valid and usable"},{"location":"commercial/compare/#iaccspm-scanning","title":"IaC/CSPM scanning","text":"Feature Trivy OSS Aqua Infrastructure as Code (IaC) Many popular languages as detailed here In addition, Build Pipeline configuration scanning Checks customization Create custom checks with Rego Create custom checks in no-code interface Customize existing checks with organizational preferences Cloud scanning AWS (subset of services) AWS, Azure, GCP, Alibaba Cloud, Oracle Cloud Compliance frameworks CIS, NSA, vendor guides More than 25 compliance programs Custom compliance Create in YAML Create in a web UI Remediation advice Basic AI powered specialized remediation guides"},{"location":"commercial/compare/#kubernetes-scanning","title":"Kubernetes scanning","text":"Feature Trivy OSS Aqua Scan initiation CLI / Kubernetes Operator Kubernetes Operator / Management web application Results consumption kubectl / CRD / Prometheus exporter In addition, Advanced UI dashboards, Automatic notifications and incident management flows Cluster discovery Kubeconfig Automatic discovery thorough cloud onboarding Workload image scanning Scanning in cluster, requires capacity planning Scanning offloaded to Aqua service, little impact on scanned clusters Cluster scanning CIS, NSA, PSS More than 25 compliance programs Scope Single cluster Multi cluster, Cloud relationship Scalability Reports limited by in-cluster etcd storage (size and number of reports) Cloud-based storage (unlimited scalability)"},{"location":"commercial/contact/","title":"Contact Us","text":""},{"location":"community/principles/","title":"Trivy Project Principles","text":"

    This document outlines the guiding principles and governance framework for the Trivy project.

    "},{"location":"community/principles/#core-principles","title":"Core Principles","text":"

    Trivy is a security scanner focused on static analysis and designed with simplicity and security at its core. All new proposals to the project must adhere to the following principles.

    "},{"location":"community/principles/#static-analysis-no-runtime-required","title":"Static Analysis (No Runtime Required)","text":"

    Trivy operates without requiring container or VM image startups, eliminating the need for Docker or similar runtimes, except for scanning images stored within a container runtime. This approach enhances security and efficiency by minimizing dependencies.

    "},{"location":"community/principles/#external-dependency-free-single-binary","title":"External Dependency Free (Single Binary)","text":"

    Operating as a single binary, Trivy is independent of external environments and avoids executing external OS commands or processes. If specific functionality, like Maven's, is needed, Trivy opts for internal reimplementations or processing outputs of the tool without direct execution of external tools.

    This approach obviously requires more effort but significantly reduces security risks associated with executing OS commands and dependency errors due to external environment versions. Simplifying the scanner's use by making it operational immediately upon binary download facilitates easier initiation of scans.

    "},{"location":"community/principles/#no-setup-required","title":"No Setup Required","text":"

    Trivy must be ready to use immediately after installation. It's unacceptable for Trivy not to function without setting up a database or writing configuration files by default. Such setups should only be necessary for users requiring specific customizations.

    Security often isn't a top priority for many organizations and can be easily deferred. Trivy aims to lower the barrier to entry by simplifying the setup process, making it easier for users to start securing their projects.

    "},{"location":"community/principles/#security-focus","title":"Security Focus","text":"

    Trivy prioritizes the identification of security issues, excluding features unrelated to security, such as performance metrics or content listings of container images. It can, however, produce and output intermediate representations like SBOMs for comprehensive security assessments.

    Trivy serves as a tool with opinions on security, used to warn users about potential issues.

    "},{"location":"community/principles/#detecting-unintended-states","title":"Detecting Unintended States","text":"

    Trivy is designed to detect unintended vulnerable states in projects, such as the use of vulnerable versions of dependencies or misconfigurations in Infrastructure as Code (IaC) that may unintentionally expose servers to the internet. The focus is on identifying developer mistakes or undesirable states, not on detecting intentional attacks, such as malicious images and malware.

    "},{"location":"community/principles/#out-of-scope-features","title":"Out of Scope Features","text":"

    Aqua Security offers a premium version with several features not available in the open-source Trivy project. While detailed information can be found here, it's beneficial to highlight specific functionalities frequently inquired about:

    "},{"location":"community/principles/#runtime-security","title":"Runtime Security","text":"

    As mentioned in the Core Principles, Trivy is a static analysis security scanner, making runtime security outside its scope. Runtime security needs are addressed by Tracee or the commercial version of Aqua Security.

    "},{"location":"community/principles/#intentional-attacks","title":"Intentional Attacks","text":"

    As mentioned in the Core Principles, detection of intentional attacks, such as malware or malicious container images, is not covered by Trivy and is supported in the commercial version.

    "},{"location":"community/principles/#user-interface","title":"User Interface","text":"

    Trivy primarily operates via CLI for displaying results, with a richer UI available in the commercial version.

    "},{"location":"community/contribute/discussion/","title":"Discussions","text":"

    Thank you for taking interest in contributing to Trivy!

    Trivy uses GitHub Discussion for bug reports, feature requests, and questions. If maintainers decide to accept a new feature or confirm that it is a bug, they will close the discussion and create a GitHub Issue associated with that discussion.

    • Feel free to open discussions for any reason. When you open a new discussion, you'll have to select a discussion category as described below.
    • Please spend a small amount of time giving due diligence to the issue/discussion tracker. Your discussion might be a duplicate. If it is, please add your comment to the existing issue/discussion.
    • Remember that users might search for your issue/discussion in the future, so please give it a meaningful title to help others.
    • The issue should clearly explain the reason for opening, the proposal if you have any, and any relevant technical information.

    There are 4 categories:

    • \ud83d\udca1 Ideas
      • Share ideas for new features
    • \ud83d\udd0e False Detection
      • Report false positives/negatives
    • \ud83d\udc1b Bugs
      • Report something that is not working as expected
    • \ud83d\ude4f Q&A
      • Ask the community for help

    Note

    If you find any false positives or false negatives, please make sure to report them under the \"False Detection\" category, not \"Bugs\".

    "},{"location":"community/contribute/discussion/#false-detection","title":"False detection","text":"

    Trivy depends on multiple data sources. Sometime these databases contain mistakes.

    If Trivy can't detect any CVE-IDs or shows false positive result, at first please follow the next steps:

    1. Run Trivy with -f json that shows data sources.
    2. According to the shown data source, make sure that the security advisory in the data source is correct.

    If the data source is correct and Trivy shows wrong results, please raise an issue on Trivy.

    "},{"location":"community/contribute/discussion/#github-advisory-database","title":"GitHub Advisory Database","text":"

    Visit here and search CVE-ID.

    If you find a problem, it'll be nice to fix it: How to contribute to a GitHub security advisory

    "},{"location":"community/contribute/discussion/#gitlab-advisory-database","title":"GitLab Advisory Database","text":"

    Visit here and search CVE-ID.

    If you find a problem, it'll be nice to fix it: Create an issue to GitLab Advisory Database

    "},{"location":"community/contribute/discussion/#red-hat-cve-database","title":"Red Hat CVE Database","text":"

    Visit here and search CVE-ID.

    "},{"location":"community/contribute/issue/","title":"Issues","text":"

    Thank you for taking interest in contributing to Trivy!

    Trivy uses GitHub Discussion for bug reports, feature requests, and questions.

    Warning

    Issues created by non-maintainers will be immediately closed.

    "},{"location":"community/contribute/pr/","title":"Pull Requests","text":"

    Thank you for taking interest in contributing to Trivy!

    1. Every Pull Request should have an associated GitHub issue link in the PR description. Note that issues are created by Trivy maintainers based on feedback provided in a GitHub discussion. Please refer to the issue and discussion pages for explanation about this process. If you think your change is trivial enough, you can skip the issue and instead add justification and explanation in the PR description.
    2. Your PR is more likely to be accepted if it focuses on just one change.
    3. There's no need to add or tag reviewers.
    4. If a reviewer commented on your code or asked for changes, please remember to respond with comment. Do not mark discussion as resolved. It's up to reviewer to mark it resolved (in case if suggested fix addresses problem properly). PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).
    5. Please include a comment with the results before and after your change.
    6. Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!).
    7. If your PR affects the user experience in some way, please update the README.md and the CLI help accordingly.
    "},{"location":"community/contribute/pr/#development","title":"Development","text":"

    Install the necessary tools for development by following their respective installation instructions.

    • Go
    • Mage
    "},{"location":"community/contribute/pr/#build","title":"Build","text":"

    After making changes to the Go source code, build the project with the following command:

    $ mage build\n$ ./trivy -h\n
    "},{"location":"community/contribute/pr/#lint","title":"Lint","text":"

    You must pass the linter checks:

    $ mage lint:run\n

    Additionally, you need to have run go mod tidy, so execute the following command as well:

    $ mage tidy\n

    To autofix linters use the following command:

    $ mage lint:fix\n

    "},{"location":"community/contribute/pr/#unit-tests","title":"Unit tests","text":"

    Your PR must pass all the unit tests. You can test it as below.

    $ mage test:unit\n
    "},{"location":"community/contribute/pr/#integration-tests","title":"Integration tests","text":"

    Your PR must pass all the integration tests. You can test it as below.

    $ mage test:integration\n
    "},{"location":"community/contribute/pr/#documentation","title":"Documentation","text":"

    If you update CLI flags, you need to generate the CLI references. The test will fail if they are not up-to-date.

    $ mage docs:generate\n

    You can build the documents as below and view it at http://localhost:8000.

    $ mage docs:serve\n
    "},{"location":"community/contribute/pr/#title","title":"Title","text":"

    It is not that strict, but we use the title conventions in this repository. Each commit message doesn't have to follow the conventions as long as it is clear and descriptive since it will be squashed and merged.

    "},{"location":"community/contribute/pr/#format-of-the-title","title":"Format of the title","text":"
    <type>(<scope>): <subject>\n

    The type and scope should always be lowercase as shown below.

    Allowed <type> values:

    • feat for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version.
    • fix for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version.
    • perf for performance improvements. Such commit will trigger a release bumping a PATCH version.
    • docs for changes to the documentation.
    • style for formatting changes, missing semicolons, etc.
    • refactor for refactoring production code, e.g. renaming a variable.
    • test for adding missing tests, refactoring tests; no production code change.
    • build for updating build configuration, development tools or other changes irrelevant to the user.
    • chore for updates that do not apply to the above, such as dependency updates.
    • ci for changes to CI configuration files and scripts
    • revert for revert to a previous commit

    Allowed <scope> values:

    checks:

    • vuln
    • misconf
    • secret
    • license

    mode:

    • image
    • fs
    • repo
    • sbom
    • k8s
    • server
    • aws
    • vm
    • plugin

    os:

    • alpine
    • redhat
    • alma
    • rocky
    • azure
    • oracle
    • debian
    • ubuntu
    • amazon
    • suse
    • photon
    • distroless

    language:

    • ruby
    • php
    • python
    • nodejs
    • rust
    • dotnet
    • java
    • go
    • elixir
    • dart
    • julia

    vuln:

    • os
    • lang

    config:

    • kubernetes
    • dockerfile
    • terraform
    • cloudformation

    container

    • docker
    • podman
    • containerd
    • oci

    cli:

    • cli
    • flag

    SBOM:

    • cyclonedx
    • spdx
    • purl

    others:

    • helm
    • report
    • db
    • parser
    • deps

    The <scope> can be empty (e.g. if the change is a global or difficult to assign to a single component), in which case the parentheses are omitted.

    Breaking changes

    A PR, introducing a breaking API change, needs to append a ! after the type/scope.

    "},{"location":"community/contribute/pr/#example-titles","title":"Example titles","text":"
    feat(alma): add support for AlmaLinux\n
    feat(vuln)!: delete the existing CLI flag\n
    fix(oracle): handle advisories with ksplice versions\n
    docs(misconf): add comparison with Conftest and TFsec\n
    chore(deps): bump go.uber.org/zap from 1.19.1 to 1.20.0\n

    NOTE: please do not use chore(deps): update fanal and something like that if you add new features or fix bugs in Trivy-related projects. The PR title should describe what the PR adds or fixes even though it just updates the dependency in Trivy.

    "},{"location":"community/contribute/pr/#commits","title":"Commits","text":""},{"location":"community/contribute/pr/#understand-where-your-pull-request-belongs","title":"Understand where your pull request belongs","text":"

    Trivy is composed of several repositories that work together:

    • Trivy is the client-side, user-facing, command line tool.
    • vuln-list is a vulnerability database, aggregated from different sources, and normalized for easy consumption. Think of this as the \"server\" side of the trivy command line tool. There should be no pull requests to this repo
    • vuln-list-update is the code that maintains the vuln-list database.
    • trivy-db maintains the vulnerability database pulled by Trivy CLI.
    • go-dep-parser is a library for parsing lock files such as package-lock.json and Gemfile.lock.
    "},{"location":"community/contribute/checks/overview/","title":"Contribute Rego Checks","text":"

    The following guide provides an overview of contributing checks to the default checks in Trivy.

    All of the checks in Trivy can be found in the trivy-checks repository on GitHub. Before you begin writing a check, ensure:

    1. The check does not already exist as part of the default checks in the trivy-checks repository.
    2. The pull requests in the trivy-checks repository to see whether someone else is already contributing the check that you wanted to add.
    3. The issues in Trivy to see whether any specific checks are missing in Trivy that you can contribute.

    If anything is unclear, please start a discussion and we will do our best to help.

    "},{"location":"community/contribute/checks/overview/#check-structure","title":"Check structure","text":"

    Checks are written in Rego and follow a particular structure in Trivy. Below is an example check for AWS:

    # METADATA\n# title: \"RDS IAM Database Authentication Disabled\"\n# description: \"Ensure IAM Database Authentication is enabled for RDS database instances to manage database access\"\n# scope: package\n# schemas:\n# - input: schema[\"aws\"]\n# related_resources:\n# - https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth.html\n# custom:\n#   id: AVD-AWS-0176\n#   avd_id: AVD-AWS-0176\n#   provider: aws\n#   service: rds\n#   severity: MEDIUM\n#   short_code: enable-iam-auth\n#   recommended_action: \"Modify the PostgreSQL and MySQL type RDS instances to enable IAM database authentication.\"\n#   input:\n#     selector:\n#     - type: cloud\n#       subtypes:\n#         - service: rds\n#           provider: aws\n\npackage builtin.aws.rds.aws0176\n\ndeny[res] {\n    instance := input.aws.rds.instances[_]\n    instance.engine.value == [\"postgres\", \"mysql\"][_]\n    not instance.iamauthenabled.value\n    res := result.new(\"Instance does not have IAM Authentication enabled\", instance.iamauthenabled)\n}\n
    "},{"location":"community/contribute/checks/overview/#verify-the-provider-and-service-exists","title":"Verify the provider and service exists","text":"

    Every check for a cloud service references a cloud provider. The list of providers are found in the Trivy repository.

    Before writing a new check for a cloud provider, you need to verify if the cloud provider or resource type that your check targets is supported by Trivy. If it's not, you'll need to add support for it. Additionally, if the provider that you want to target exists, you need to check whether the service your policy will target is supported. As a reference you can take a look at the AWS provider here.

    Note

    New Kubernetes and Dockerfile checks do not require any additional provider definitions. You can find an example of a Dockerfile check here and a Kubernetes check here.

    "},{"location":"community/contribute/checks/overview/#add-support-for-a-new-service-in-an-existing-provider","title":"Add Support for a New Service in an existing Provider","text":"

    Please reference the documentation on adding Support for a New Service.

    This guide also showcases how to add new properties for an existing Service.

    "},{"location":"community/contribute/checks/overview/#create-a-new-rego-file","title":"Create a new .rego file","text":"

    The following directory in the trivy-checks repository contains all of our custom checks. Depending on what type of check you want to create, you will need to nest a new .rego file in either of the subdirectories:

    • cloud: All checks related to cloud providers and their services
    • docker: Docker specific checks
    • kubernetes: Kubernetes specific checks
    "},{"location":"community/contribute/checks/overview/#check-package-name","title":"Check Package name","text":"

    Have a look at the existing package names in the built in checks.

    The package name should be in the format builtin.PROVIDER.SERVICE.ID, e.g. builtin.aws.rds.aws0176.

    "},{"location":"community/contribute/checks/overview/#generating-an-id","title":"Generating an ID","text":"

    Every check has a custom ID that is referenced throughout the metadata of the check to uniquely identify the check. If you plan to contribue your check back into the trivy-checks repository, it will require a valid ID.

    Running make id in the root of the trivy-checks repository will provide you with the next available ID for your rule.

    "},{"location":"community/contribute/checks/overview/#check-schemas","title":"Check Schemas","text":"

    Rego Checks for Trivy can utilise Schemas to map the input to specific objects. The schemas available are listed here..

    More information on using the builtin schemas is provided in the main documentation.

    "},{"location":"community/contribute/checks/overview/#check-metadata","title":"Check Metadata","text":"

    The metadata is the top section that starts with # METADATA, and has to be placed on top of the check. You can copy and paste from another check as a starting point. This format is effectively yaml within a Rego comment, and is defined as part of Rego itself.

    For detailed information on each component of the Check Metadata, please refer to the main documentation.

    Note that while the Metadata is optional in your own custom checks for Trivy, if you are contributing your check to the Trivy builtin checks, the Metadata section will be required.

    "},{"location":"community/contribute/checks/overview/#writing-rego-rules","title":"Writing Rego Rules","text":"

    Rules are defined using OPA Rego. You can find a number of examples in the checks directory (Link). The OPA documentation is a great place to start learning Rego. You can also check out the Rego Playground to experiment with Rego, and join the OPA Slack.

    deny[res] {\n    instance := input.aws.rds.instances[_]\n    instance.engine.value == [\"postgres\", \"mysql\"][_]\n    not instance.iamauthenabled.value\n    res := result.new(\"Instance does not have IAM Authentication enabled\", instance.iamauthenabled)\n}\n

    The rule should return a result, which can be created using result.new. This function does not need to be imported, it is defined internally and provided at runtime. The first argument is the message to display and the second argument is the resource that the issue was detected on.

    It is possible to pass any rego variable that references a field of the input document.

    "},{"location":"community/contribute/checks/overview/#generate-docs","title":"Generate docs","text":"

    Finally, you'll want to generate documentation for your newly added rule. Please run make docs in the trivy-checks directory to generate the documentation for your new policy and submit a PR for us to take a look at.

    "},{"location":"community/contribute/checks/overview/#adding-tests","title":"Adding Tests","text":"

    All Rego checks need to have tests. There are many examples of these in the checks directory for each check (Link). More information on how to write tests for Rego checks is provided in the custom misconfiguration section of the docs.

    "},{"location":"community/contribute/checks/overview/#example-pr","title":"Example PR","text":"

    You can see a full example PR for a new rule being added here: https://github.com/aquasecurity/defsec/pull/1000.

    "},{"location":"community/contribute/checks/service-support/","title":"Add Service Support","text":"

    A service refers to a service by a cloud provider. This section details how to add a new service to an existing provider. All contributions need to be made to the trivy repository.

    "},{"location":"community/contribute/checks/service-support/#prerequisites","title":"Prerequisites","text":"

    Before you begin, verify that the provider does not already have the service that you plan to add.

    "},{"location":"community/contribute/checks/service-support/#adding-a-new-service-to-an-existing-provider","title":"Adding a new service to an existing provider","text":"

    Adding a new service involves two steps. The service will need a data structure to store information about the required resources that will be scanned. Additionally, the service will require one or more adapters to convert the scan targetes as input(s) into the aforementioned data structure.

    "},{"location":"community/contribute/checks/service-support/#create-a-new-file-in-the-provider-directory","title":"Create a new file in the provider directory","text":"

    In this example, we are adding the CodeBuild service to the AWS provider.

    First, create a new directory and file for your new service under the provider directory: e.g. aws/codebuild/codebuild.go

    The CodeBuild service will require a structure struct to hold the information on the input that is scanned. The input is the CodeBuild resource that a user configured and wants to scan for misconfiguration.

    type CodeBuild struct {\n    Projects []Project\n}\n

    The CodeBuild service manages Project resources. The Project struct has been added to hold information about each Project resources; Project Resources in turn manage ArtifactSettings:

    type Project struct {\n    Metadata                  iacTypes.Metadata\n    ArtifactSettings          ArtifactSettings\n    SecondaryArtifactSettings []ArtifactSettings\n}\n\ntype ArtifactSettings struct {\n    Metadata          iacTypes.Metadata\n    EncryptionEnabled iacTypes.BoolValue\n}\n

    The iacTypes.Metadata struct is embedded in all of the Trivy types and provides a common set of metadata for all resources. This includes the file and line number where the resource was defined and the name of the resource.

    A resource in this example Project can have a name and can optionally be encrypted. Instead of using raw string and bool types respectively, we use the trivy types iacTypes.Metadata and iacTypes.BoolValue. These types wrap the raw values and provide additional metadata about the value. For instance, whether it was set by the user and the file and line number where the resource was defined.

    Have a look at the other providers and services in the iac/providers directory in Trivy.

    Next you'll need to add a reference to your new service struct in the provider struct at pkg/iac/providers/aws/aws.go:

    type AWS struct {\n    ...\n    CodeBuild      codebuild.CodeBuild\n    ...\n}\n
    "},{"location":"community/contribute/checks/service-support/#update-adapters","title":"Update Adapters","text":"

    Now you'll need to update all of the adapters which populate the struct of the provider that you have been using. Following the example above, if you want to add support for CodeBuild in Terraform, you'll need to update the Terraform AWS adatper as shown here: trivy/pkg/iac/adapters/terraform/aws/codebuild/adapt.go.

    Another example for updating the adapters is provided in the following PR. Additionally, please refer to the respective Terraform documentation on the provider to which you are adding the service. For instance, the Terraform documentation for AWS CodeBuild is provided here.

    "},{"location":"community/contribute/checks/service-support/#create-a-new-schema-for-your-provider","title":"Create a new Schema for your provider","text":"

    Once the new service has been added to the provider, you need to create the schema for the service as part of the provider schema.

    This process has been automated with mage commands. In the Trivy root directory run mage schema:generate to generate the schema for your new service and mage schema:verify.

    "},{"location":"community/maintainer/backporting/","title":"Backporting Process","text":"

    This document outlines the backporting process for Trivy, including when to create patch releases and how to perform the backporting.

    "},{"location":"community/maintainer/backporting/#when-to-create-patch-releases","title":"When to Create Patch Releases","text":"

    In general, small changes should not be backported and should be included in the next minor release. However, patch releases should be made in the following cases:

    • Fixes for HIGH or CRITICAL vulnerabilities in Trivy itself or Trivy's dependencies
    • Fixes for bugs that cause panic during Trivy execution or otherwise interfere with normal usage

    In these cases, the fixes should be backported using the procedure described below. At the maintainer's discretion, other bug fixes may be included in the patch release containing these hotfixes.

    "},{"location":"community/maintainer/backporting/#versioning","title":"Versioning","text":"

    Trivy follows Semantic Versioning, using version numbers in the format MAJOR.MINOR.PATCH. When creating a patch release, the PATCH part of the version number is incremented. For example, if a fix is being distributed for v0.50.0, the patch release would be v0.50.1.

    "},{"location":"community/maintainer/backporting/#backporting-procedure","title":"Backporting Procedure","text":"
    1. A release branch (e.g., release/v0.50) is automatically created when a new minor version is released.
    2. Create a pull request (PR) against the main branch with the necessary fixes. If the fixes are already merged into the main branch, skip this step.
    3. Once the PR with the fixes is merged, comment @aqua-bot backport <release-branch> on the PR (e.g., @aqua-bot backport release/v0.50). This will trigger the automated backporting process using GitHub Actions.
    4. The automated process will create a new PR with the backported changes. Ensure that all tests pass for this PR.
    5. Once the tests pass, merge the automatically created PR into the release branch.
    6. Merge a release PR on the release branch and release the patch version.

    Note

    Even if a conflict occurs, a PR is created by forceful commit, in which case the conflict should be resolved manually. If you want to re-run a backport of the same PR, close the existing PR, delete the branch and re-run it.

    "},{"location":"community/maintainer/backporting/#example","title":"Example","text":"

    To better understand the backporting procedure, let's walk through an example using the releases of v0.50.

    gitGraph:\n  commit id:\"Feature 1\"\n  commit id:\"v0.50.0 release\" tag:\"v0.50.0\"\n\n  branch \"release/v0.50\"\n\n  checkout main\n  commit id:\"Bugfix 1\"\n\n  checkout \"release/v0.50\"\n  cherry-pick id:\"Bugfix 1\"\n\n  checkout main\n  commit id:\"Feature 2\"\n  commit id:\"Bugfix 2\"\n  commit id:\"Feature 3\"\n\n  checkout \"release/v0.50\"\n  cherry-pick id:\"Bugfix 2\"\n  commit id:\"v0.50.1 release\" tag:\"v0.50.1\"
    "},{"location":"community/maintainer/help-wanted/","title":"Overview","text":"

    We use two labels help wanted and good first issue to identify issues that have been specially groomed for new contributors. The good first issue label is a subset of help wanted label, indicating that members have committed to providing extra assistance for new contributors. All good first issue items also have the help wanted label.

    "},{"location":"community/maintainer/help-wanted/#help-wanted","title":"Help Wanted","text":"

    Items marked with the help wanted label need to ensure that they are:

    • Low Barrier to Entry

    It should be tractable for new contributors. Documentation on how that type of change should be made should already exist.

    • Clear Task

    The task is agreed upon and does not require further discussions in the community. Call out if that area of code is untested and requires new fixtures.

    API / CLI behavior is decided and included in the OP issue, for example: \"The new command syntax is trivy --format yaml IMAGE_NAME\"_ with expected validations called out.

    • Goldilocks priority

    Not too high that a core contributor should do it, but not too low that it isn't useful enough for a core contributor to spend time to review it, answer questions, help get it into a release, etc.

    • Up-To-Date

    Often these issues become obsolete and have already been done, are no longer desired, no longer make sense, have changed priority or difficulty , etc.

    "},{"location":"community/maintainer/help-wanted/#good-first-issue","title":"Good First Issue","text":"

    Items marked with the good first issue label are intended for first-time contributors. It indicates that members will keep an eye out for these pull requests and shepherd it through our processes.

    These items need to ensure that they follow the guidelines for help wanted labels (above) in addition to meeting the following criteria:

    • No Barrier to Entry

    The task is something that a new contributor can tackle without advanced setup, or domain knowledge.

    • Solution Explained

    The recommended solution is clearly described in the issue.

    • Provides Context

    If background knowledge is required, this should be explicitly mentioned and a list of suggested readings included.

    • Gives Examples

    Link to examples of similar implementations so new contributors have a reference guide for their changes.

    • Identifies Relevant Code

    The relevant code and tests to be changed should be linked in the issue.

    • Ready to Test

    There should be existing tests that can be modified, or existing test cases fit to be copied. If the area of code doesn't have tests, before labeling the issue, add a test fixture. This prep often makes a great help wanted task!

    "},{"location":"community/maintainer/release-flow/","title":"Release Flow","text":""},{"location":"community/maintainer/release-flow/#overview","title":"Overview","text":"

    Trivy adopts conventional commit messages, and Release Please automatically creates a release PR based on the messages of the merged commits. This release PR is automatically updated every time a new commit is added to the release branch.

    If a commit has the prefix feat:, a PR is automatically created to increment the minor version, and if a commit has the prefix fix:, a PR is created to increment the patch version. When the PR is merged, GitHub Actions automatically creates a version tag and the release is performed. For detailed behavior, please refer to the GitHub Actions configuration.

    Note

    Commits with prefixes like chore or build are not considered releasable, and no release PR is created. To include such commits in a release, you need to either include commits with feat or fix prefixes or perform a manual release as described below.

    "},{"location":"community/maintainer/release-flow/#flow","title":"Flow","text":"

    The release flow consists of the following main steps:

    1. Creating the release PR (automatically or manually)
    2. Drafting the release notes in GitHub Discussions
    3. Merging the release PR
    4. Updating the release notes in GitHub Discussions
    5. Navigating to the release notes in GitHub Releases page
    "},{"location":"community/maintainer/release-flow/#automatic-release-pr-creation","title":"Automatic Release PR Creation","text":"

    When a releasable commit (a commit with feat or fix prefix) is merged, a release PR is automatically created. These Release PRs are kept up-to-date as additional work is merged. When it's ready to tag a release, simply merge the release PR. See the Release Please documentation for more information.

    The title of the PR will be in the format release: v${version} [${branch}] (e.g., release: v0.51.0 [main]). The format of the PR title is important for identifying the release commit, so it should not be changed.

    The release/vX.Y release branches are also subject to automatic release PR creation for patch releases. The PR title will be like release: v0.51.1 [release/v0.51].

    "},{"location":"community/maintainer/release-flow/#manual-release-pr-creation","title":"Manual Release PR Creation","text":"

    If you want to release commits like chore, a release PR is not automatically created, so you need to manually trigger the creation of a release PR. The Release Please workflow supports workflow_dispatch and can be triggered manually. Click \"Run workflow\" in the top right corner and specify the release branch. In Trivy, the following branches are the release branches.

    • main
    • release/vX.Y (e.g. release/v0.51)

    Specify the release version (without the v prefix) and click \"Run workflow\" to create a release PR for the specified version.

    "},{"location":"community/maintainer/release-flow/#drafting-the-release-notes","title":"Drafting the Release Notes","text":"

    Next, create release notes for this version. Draft a new post in GitHub Discussions, and maintainers edit these release notes (e.g., https://github.com/aquasecurity/trivy/discussions/6605). Currently, the creation of this draft is done manually. For patch version updates, this step can be skipped since they only involve bug fixes.

    "},{"location":"community/maintainer/release-flow/#merging-the-release-pr","title":"Merging the Release PR","text":"

    Once the draft of the release notes is complete, merge the release PR. When the PR is merged, a tag is automatically created, and GoReleaser releases binaries, container images, etc.

    "},{"location":"community/maintainer/release-flow/#updating-the-release-notes","title":"Updating the Release Notes","text":"

    If the release completes without errors, a page for the release notes is created in GitHub Discussions (e.g., https://github.com/aquasecurity/trivy/discussions/6622). Copy the draft release notes, adjust the formatting, and finalize the release notes.

    "},{"location":"community/maintainer/release-flow/#navigating-to-the-release-notes","title":"Navigating to the Release Notes","text":"

    To navigate to the release highlights and summary in GitHub Discussions, place a link in the GitHub Releases page as below:

    ## \u26a1Release highlights and summary\u26a1\n\n\ud83d\udc49 https://github.com/aquasecurity/trivy/discussions/6838\n\n## Changelog\nhttps://github.com/aquasecurity/trivy/blob/main/CHANGELOG.md#0520-2024-06-03\n

    Replace URLs with appropriate ones.

    Example: https://github.com/aquasecurity/trivy/releases/tag/v0.52.0

    The release is now complete.

    "},{"location":"community/maintainer/triage/","title":"Triage","text":"

    Triage is an important part of maintaining the health of the trivy repo. A well organized repo allows maintainers to prioritize feature requests, fix bugs, and respond to users facing difficulty with the tool as quickly as possible.

    Triage includes:

    • Labeling issues
    • Responding to issues
    • Closing issues
    "},{"location":"community/maintainer/triage/#daily-triage","title":"Daily Triage","text":"

    Daily triage has two goals:

    1. Responsiveness for new issues
    2. Responsiveness when explicitly requested information was provided

    It covers:

    1. Issues without a kind/ or triage/ label
    2. Issues without a priority/ label
    3. triage/needs-information issues which the user has followed up on, and now require a response.
    "},{"location":"community/maintainer/triage/#categorization","title":"Categorization","text":"

    The most important level of categorizing the issue is defining what type it is. We typically want at least one of the following labels on every issue, and some issues may fall into multiple categories:

    • triage/support - The default for most incoming issues
    • kind/bug - When it\u2019s a bug or we aren\u2019t delivering the best user experience

    Other possibilities: - kind/feature- Identify new feature requests - kind/testing - Update or fix unit/integration tests - kind/cleanup - Cleaning up/refactoring the codebase - kind/documentation - Updates or additions to trivy documentation

    If the issue is specific to a driver for OS packages or libraries:

    co/[driver for OS packages]

    • co/alpine
    • co/amazon
    • co/debian
    • co/oracle
    • co/photon
    • co/redhat
    • co/suse
    • co/ubuntu

    co/[driver for libraries of programming languages]

    • co/bundler
    • co/cargo
    • co/composer
    • co/npm
    • co/yarn
    • co/pipenv
    • co/poetry

    Help wanted?

    Good First Issue - bug has a proposed solution, can be implemented w/o further discussion.

    Help wanted - if the bug could use help from a contributor

    "},{"location":"community/maintainer/triage/#prioritization","title":"Prioritization","text":"

    If the issue is not triage/support, it needs a priority label.

    priority/critical-urgent - someones top priority ASAP, such as security issue, user-visible bug, or build breakage. Rarely used.

    priority/important-soon: in time for the next two releases. It should be attached to a milestone.

    priority/important-longterm: 2-4 releases from now

    priority/backlog: agreed that this would be good to have, but no one is available at the moment. Consider tagging as help wanted

    priority/awaiting-more-evidence: may be useful, but there is not yet enough support.

    "},{"location":"community/maintainer/triage/#weekly-triage","title":"Weekly Triage","text":"

    Weekly triage has three goals:

    1. Catching up on unresponded issues
    2. Reviewing and closing PR\u2019s
    3. Closing stale issues
    "},{"location":"community/maintainer/triage/#post-release-triage","title":"Post-Release Triage","text":"

    Post-release triage occurs after a major release (around every 4-6 weeks). It focuses on:

    1. Closing bugs that have been resolved by the release
    2. Reprioritizing bugs that have not been resolved by the release
    3. Letting users know if we believe that there is still an issue

    This includes reviewing:

    1. Every issue that hasn\u2019t been touched in the last 2 days
    2. Re-evaluation of long-term issues
    3. Re-evaluation of short-term issues
    "},{"location":"community/maintainer/triage/#responding-to-issues","title":"Responding to Issues","text":""},{"location":"community/maintainer/triage/#needs-more-information","title":"Needs More Information","text":"

    A sample response to ask for more info:

    I don\u2019t yet have a clear way to replicate this issue. Do you mind adding some additional details. Here is additional information that would be helpful:

    * The exact trivy command line used

    * The exact image you want to scan

    * The full output of the trivy command, preferably with --debug for extra logging.

    Thank you for sharing your experience!

    Then: Label with triage/needs-information.

    "},{"location":"community/maintainer/triage/#issue-might-be-resolved","title":"Issue might be resolved","text":"

    If you think a release may have resolved an issue, ask the author to see if their issue has been resolved:

    Could you please check to see if trivy addresses this issue? We've made some changes with how this is handled, and improved the trivy logs output to help us debug tricky cases like this.

    Then: Label with triage/needs-information.

    "},{"location":"community/maintainer/triage/#closing-with-care","title":"Closing with Care","text":"

    Issues typically need to be closed for the following reasons:

    • The issue has been addressed
    • The issue is a duplicate of an existing issue
    • There has been a lack of information over a long period of time

    In any of these situations, we aim to be kind when closing the issue, and offer the author action items should they need to reopen their issue or still require a solution.

    Samples responses for these situations include:

    "},{"location":"community/maintainer/triage/#issue-has-been-addressed","title":"Issue has been addressed","text":"

    @author: I believe this issue is now addressed by trivy v1.0.0, as it . If you still see this issue with trivy v1.0 or higher, please reopen this issue.

    Thank you for reporting this issue!

    Then: Close the issue

    "},{"location":"community/maintainer/triage/#duplicate-issue","title":"Duplicate Issue","text":"

    This issue appears to be a duplicate of #X, do you mind if we move the conversation there?

    This way we can centralize the content relating to the issue. If you feel that this issue is not in fact a duplicate, please re-open it. If you have additional information to share, please add it to the new issue.

    Thank you for reporting this!

    Then: Label with triage/duplicate and close the issue.

    "},{"location":"community/maintainer/triage/#lack-of-information","title":"Lack of Information","text":"

    If an issue hasn't been active for more than four weeks, and the author has been pinged at least once, then the issue can be closed.

    Hey @author -- hopefully it's OK if I close this - there wasn't enough information to make it actionable, and some time has already passed. If you are able to provide additional details, you may reopen it at any point.

    Here is additional information that may be helpful to us:

    * Whether the issue occurs with the latest trivy release

    * The exact trivy command line used

    * The exact image you want to scan

    * The full output of the trivy command, preferably with --debug for extra logging.

    Thank you for sharing your experience!

    Then: Close the issue.

    "},{"location":"community/maintainer/triage/#help-wanted-issues","title":"Help Wanted issues","text":"

    We use two labels help wanted and good first issue to identify issues that have been specially groomed for new contributors.

    We have specific guidelines for how to use these labels. If you see an issue that satisfies these guidelines, you can add the help wanted label and the good first issue label. Please note that adding the good first issue label must also add the help wanted label.

    If an issue has these labels but does not satisfy the guidelines, please ask for more details to be added to the issue or remove the labels.

    "},{"location":"docs/","title":"Docs","text":"

    Welcome to the Trivy documentation! Here you can find complete and thorough information about every aspect of Trivy, how to use it, features available, and configuration options.

    \ud83d\udc48 Please use the left side navigation browse the different topics.

    "},{"location":"docs/advanced/air-gap/","title":"Connectivity and Network considerations","text":"

    Trivy requires internet connectivity in order to function normally. If your organizations blocks or restricts network traffic, that could prevent Trivy from working correctly. This document explains Trivy's network connectivity requirements, and how to configure Trivy to work in restricted networks environments, including completely air-gapped environments.

    The following table lists all external resources that are required by Trivy:

    External Resource Feature Details Vulnerability Database Vulnerability scanning Trivy DB Java Vulnerability Database Java vulnerability scanning Trivy Java DB Checks Bundle Misconfigurations scanning Trivy Checks VEX Hub VEX Hub VEX Hub Maven Central / Remote Repositories Java vulnerability scanning Java Scanner/Remote Repositories

    Note

    Trivy is an open source project that relies on public free infrastructure. In case of extreme load, you may encounter rate limiting when Trivy attempts to connect to external resources.

    The rest of this document details each resource's connectivity requirements and network related considerations.

    "},{"location":"docs/advanced/air-gap/#oci-databases","title":"OCI Databases","text":"

    Trivy's Vulnerability, Java, and Checks Bundle are packaged as OCI images and stored in public container registries.

    "},{"location":"docs/advanced/air-gap/#connectivity-requirements","title":"Connectivity requirements","text":"

    The specific registries and locations are detailed in the databases document.

    Communication with OCI Registries follows the OCI Distribution spec.

    The following hosts are known to be used by the default container registries:

    Registry Hosts Additional info Google Artifact Registry
    • mirror.gcr.io
    • googlecode.l.googleusercontent.com
    Google's IP addresses GitHub Container Registry
    • ghcr.io
    • pkg-containers.githubusercontent.com
    GitHub's IP addresses"},{"location":"docs/advanced/air-gap/#self-hosting","title":"Self-hosting","text":"

    You can host Trivy's databases in your own container registry. Please refer to Self-hosting document for a detailed guide.

    "},{"location":"docs/advanced/air-gap/#embedded-checks","title":"Embedded Checks","text":"

    Checks Bundle is embedded in the Trivy binary (at build time), and will be used as a fallback if the external database is not available. This means that you can still scan for misconfigurations in an air-gapped environment using the database from the time of the Trivy release you are using.

    "},{"location":"docs/advanced/air-gap/#vex-hub","title":"VEX Hub","text":""},{"location":"docs/advanced/air-gap/#connectivity-requirements_1","title":"Connectivity Requirements","text":"

    VEX Hub is hosted as at https://github.com/aquasecurity/vexhub.

    Trivy is fetching VEX Hub GitHub Repository directly using simple HTTPS requests.

    The following hosts are known to be used by GitHub's services:

    • api.github.com
    • codeload.github.com

    For more information about GitHub connectivity (including specific IP addresses), please refer to GitHub's connectivity troubleshooting guide.

    "},{"location":"docs/advanced/air-gap/#self-hosting_1","title":"Self-hosting","text":"

    You can host a copy of VEX Hub on your own internal server. Please refer to the self-hosting document for a detailed guide.

    "},{"location":"docs/advanced/air-gap/#maven-central-remote-repositories","title":"Maven Central / Remote Repositories","text":"

    Trivy might call out to Maven central or other remote repositories to fetch in order to correctly identify Java packages during a vulnerability scan.

    "},{"location":"docs/advanced/air-gap/#connectivity-requirements_2","title":"Connectivity requirements","text":"

    Trivy might attempt to connect (over HTTPS) to the following URLs:

    • https://repo.maven.apache.org/maven2
    "},{"location":"docs/advanced/air-gap/#offline-mode","title":"Offline mode","text":"

    There's no way to leverage Maven Central in a network-restricted environment, but you can prevent Trivy from trying to connect to it by using the --offline-scan flag.

    "},{"location":"docs/advanced/modules/","title":"Modules","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy provides a module feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. It changes the behavior during scanning by WebAssembly.

    "},{"location":"docs/advanced/modules/#overview","title":"Overview","text":"

    Trivy modules are add-on tools that integrate seamlessly with Trivy. They provide a way to extend the core feature set of Trivy, but without updating the Trivy binary.

    • They can be added and removed from a Trivy installation without impacting the core Trivy tool.
    • They can be written in any programming language supporting WebAssembly.
    • It supports only TinyGo at the moment.

    You can write your own detection logic.

    • Evaluate complex vulnerability conditions like Spring4Shell
    • Detect a shell script communicating with malicious domains
    • Detect malicious python install script (setup.py)
    • Even detect misconfigurations in WordPress setting
    • etc.

    Then, you can update the scan result however you want.

    • Change a severity
    • Remove a vulnerability
    • Add a new vulnerability
    • etc.

    Modules should be distributed in OCI registries like GitHub Container Registry.

    Warning

    WebAssembly doesn't allow file access and network access by default. Modules can read required files only, but cannot overwrite them. WebAssembly is sandboxed and secure by design, but Trivy modules available in public are not audited for security. You should install and run third-party modules at your own risk even though

    Under the hood Trivy leverages wazero to run WebAssembly modules without CGO.

    "},{"location":"docs/advanced/modules/#installing-a-module","title":"Installing a Module","text":"

    A module can be installed using the trivy module install command. This command takes an url. It will download the module and install it in the module cache.

    Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy will now search XDG_DATA_HOME for the location of the Trivy modules cache. The preference order is as follows:

    • XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir
    • $HOME/.trivy/plugins

    For example, to download the WebAssembly module, you can execute the following command:

    $ trivy module install ghcr.io/aquasecurity/trivy-module-spring4shell\n
    "},{"location":"docs/advanced/modules/#using-modules","title":"Using Modules","text":"

    Once the module is installed, Trivy will load all available modules in the cache on the start of the next Trivy execution. The modules may inject custom logic into scanning and change the result. You can run Trivy as usual and modules are loaded automatically.

    You will see the log messages about WASM modules.

    $ trivy image ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8\n2022-06-12T12:57:13.210+0300    INFO    Loading ghcr.io/aquasecurity/trivy-module-spring4shell/spring4shell.wasm...\n2022-06-12T12:57:13.596+0300    INFO    Registering WASM module: spring4shell@v1\n...\n2022-06-12T12:57:14.865+0300    INFO    Module spring4shell: Java Version: 8, Tomcat Version: 8.5.77\n2022-06-12T12:57:14.865+0300    INFO    Module spring4shell: change CVE-2022-22965 severity from CRITICAL to LOW\n\nJava (jar)\n\nTotal: 9 (UNKNOWN: 1, LOW: 3, MEDIUM: 2, HIGH: 3, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                           Library                            \u2502    Vulnerability    \u2502 Severity \u2502 Installed Version \u2502     Fixed Version      \u2502                           Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 org.springframework.boot:spring-boot (helloworld.war)        \u2502 CVE-2022-22965      \u2502 LOW      \u2502 2.6.3             \u2502 2.5.12, 2.6.6          \u2502 spring-framework: RCE via Data Binding on JDK 9+           \u2502\n\u2502                                                              \u2502                     \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2022-22965                 \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n...(snip)...\n

    In the above example, the Spring4Shell module changed the severity from CRITICAL to LOW because the application doesn't satisfy one of conditions.

    "},{"location":"docs/advanced/modules/#uninstalling-modules","title":"Uninstalling Modules","text":"

    Specify a module repository with trivy module uninstall command.

    $ trivy module uninstall ghcr.io/aquasecurity/trivy-module-spring4shell\n
    "},{"location":"docs/advanced/modules/#building-modules","title":"Building Modules","text":"

    It supports TinyGo only at the moment.

    "},{"location":"docs/advanced/modules/#tinygo","title":"TinyGo","text":"

    Trivy provides Go SDK including three interfaces. Your own module needs to implement either or both Analyzer and PostScanner in addition to Module.

    type Module interface {\n    Version() int\n    Name() string\n}\n\ntype Analyzer interface {\n    RequiredFiles() []string\n    Analyze(filePath string) (*serialize.AnalysisResult, error)\n}\n\ntype PostScanner interface {\n    PostScanSpec() serialize.PostScanSpec\n    PostScan(serialize.Results) (serialize.Results, error)\n}\n

    In the following tutorial, it creates a WordPress module that detects a WordPress version and a critical vulnerability accordingly.

    Tips

    You can use logging functions such as Debug and Info for debugging. See examples for the detail.

    "},{"location":"docs/advanced/modules/#initialize-your-module","title":"Initialize your module","text":"

    Replace the repository name with yours.

    $ go mod init github.com/aquasecurity/trivy-module-wordpress\n
    "},{"location":"docs/advanced/modules/#module-interface","title":"Module interface","text":"

    Version() returns your module version and should be incremented after updates. Name() returns your module name.

    package main\n\nconst (\n    version = 1\n    name = \"wordpress-module\"\n)\n\ntype WordpressModule struct{\n    // Cannot define fields as modules can't keep state.\n}\n\nfunc (WordpressModule) Version() int {\n    return version\n}\n\nfunc (WordpressModule) Name() string {\n    return name\n}\n

    Info

    A struct cannot have any fields. Each method invocation is performed in different states.

    "},{"location":"docs/advanced/modules/#analyzer-interface","title":"Analyzer interface","text":"

    If you implement the Analyzer interface, Analyze method is called when the file path is matched to file patterns returned by RequiredFiles(). A file pattern must be a regular expression. The syntax detail is here.

    Analyze takes the matched file path, then the file can be opened by os.Open().

    const typeWPVersion = \"wordpress-version\"\n\nfunc (WordpressModule) RequiredFiles() []string {\n    return []string{\n        `wp-includes\\/version.php`,\n    }\n}\n\nfunc (WordpressModule) Analyze(filePath string) (*serialize.AnalysisResult, error) {\n    f, err := os.Open(filePath) // e.g. filePath: /usr/src/wordpress/wp-includes/version.php\n    if err != nil {\n        return nil, err\n    }\n    defer f.Close()\n\n    var wpVersion string\n    scanner := bufio.NewScanner(f)\n    for scanner.Scan() {\n        line := scanner.Text()\n        if !strings.HasPrefix(line, \"$wp_version=\") {\n            continue\n        }\n\n        ss := strings.Split(line, \"=\")\n        if len(ss) != 2 {\n            return nil, fmt.Errorf(\"invalid wordpress version: %s\", line)\n        }\n\n        // NOTE: it is an example; you actually need to handle comments, etc\n        ss[1] = strings.TrimSpace(ss[1])\n        wpVersion = strings.Trim(ss[1], `\";`)\n    }\n\n    if err = scanner.Err(); err != nil {\n        return nil, err\n    }\n\n    return &serialize.AnalysisResult{\n        CustomResources: []serialize.CustomResource{\n            {\n                Type:     typeWPVersion,\n                FilePath: filePath,\n                Data:     wpVersion,\n            },\n        },\n    }, nil\n}\n

    Tips

    Trivy caches analysis results according to the module version. We'd recommend cleaning the cache or changing the module version every time you update Analyzer.

    "},{"location":"docs/advanced/modules/#postscanner-interface","title":"PostScanner interface","text":"

    PostScan is called after scanning and takes the scan result as an argument from Trivy. In post scanning, your module can perform one of three actions:

    • Insert
      • Add a new security finding
      • e.g. Add a new vulnerability and misconfiguration
    • Update
      • Update the detected vulnerability and misconfiguration
      • e.g. Change a severity
    • Delete
      • Delete the detected vulnerability and misconfiguration
      • e.g. Remove Spring4Shell because it is not actually affected.

    PostScanSpec() returns which action the module does. If it is Update or Delete, it also needs to return IDs such as CVE-ID and misconfiguration ID, which your module wants to update or delete.

    serialize.Results contains the filtered results matching IDs you specified. Also, it includes CustomResources with the values your Analyze returns, so you can modify the scan result according to the custom resources.

    func (WordpressModule) PostScanSpec() serialize.PostScanSpec {\n    return serialize.PostScanSpec{\n        Action: api.ActionInsert, // Add new vulnerabilities\n    }\n}\n\nfunc (WordpressModule) PostScan(results serialize.Results) (serialize.Results, error) {\n    // e.g. results\n    // [\n    //   {\n    //     \"Target\": \"\",\n    //     \"Class\": \"custom\",\n    //     \"CustomResources\": [\n    //       {\n    //         \"Type\": \"wordpress-version\",\n    //         \"FilePath\": \"/usr/src/wordpress/wp-includes/version.php\",\n    //         \"Layer\": {\n    //           \"DiffID\": \"sha256:057649e61046e02c975b84557c03c6cca095b8c9accd3bd20eb4e432f7aec887\"\n    //         },\n    //         \"Data\": \"5.7.1\"\n    //       }\n    //     ]\n    //   }\n    // ]   \n    var wpVersion int\n    for _, result := range results {\n        if result.Class != types.ClassCustom {\n            continue\n        }\n\n        for _, c := range result.CustomResources {\n            if c.Type != typeWPVersion {\n                continue\n            }\n            wpVersion = c.Data.(string)\n            wasm.Info(fmt.Sprintf(\"WordPress Version: %s\", wpVersion))\n\n            ...snip...\n\n            if affectedVersion.Check(ver) {\n                vulnerable = true\n            }\n            break\n        }\n    }\n\n    if vulnerable {\n        // Add CVE-2020-36326\n        results = append(results, serialize.Result{\n            Target: wpPath,\n            Class:  types.ClassLangPkg,\n            Type:   \"wordpress\",\n            Vulnerabilities: []types.DetectedVulnerability {\n                {\n                    VulnerabilityID:  \"CVE-2020-36326\",\n                    PkgName:          \"wordpress\",\n                    InstalledVersion: wpVersion,\n                    FixedVersion:     \"5.7.2\",\n                    Vulnerability: dbTypes.Vulnerability{\n                        Title:    \"PHPMailer 6.1.8 through 6.4.0 allows object injection through Phar Deserialization via addAttachment with a UNC pathname.\",\n                        Severity: \"CRITICAL\",\n                    },\n                },\n            },\n        })\n    }\n    return results, nil\n}\n

    The new vulnerability will be added to the scan results. This example shows how the module inserts a new finding. If you are interested in Update, you can see an example of Spring4Shell.

    In the Delete action, PostScan needs to return results you want to delete. If PostScan returns an empty, Trivy will not delete anything.

    "},{"location":"docs/advanced/modules/#build","title":"Build","text":"

    Follow the install guide and install TinyGo.

    $ tinygo build -o wordpress.wasm -scheduler=none -target=wasi --no-debug wordpress.go\n

    Put the built binary to the module directory that is under the home directory by default.

    $ mkdir -p ~/.trivy/modules\n$ cp wordpress.wasm ~/.trivy/modules\n
    "},{"location":"docs/advanced/modules/#distribute-your-module","title":"Distribute Your Module","text":"

    You can distribute your own module in OCI registries. Please follow the oras installation instruction.

    oras push ghcr.io/aquasecurity/trivy-module-wordpress:latest wordpress.wasm:application/vnd.module.wasm.content.layer.v1+wasm\nUploading 3daa3dac086b wordpress.wasm\nPushed ghcr.io/aquasecurity/trivy-module-wordpress:latest\nDigest: sha256:6416d0199d66ce52ced19f01d75454b22692ff3aa7737e45f7a189880840424f\n
    "},{"location":"docs/advanced/modules/#examples","title":"Examples","text":"
    • Spring4Shell
    • WordPress
    "},{"location":"docs/advanced/self-hosting/","title":"Self-Hosting Trivy's Databases","text":"

    This document explains how to host Trivy's external dependencies in your own infrastructure to prevent external network access. If you haven't already, please familiarize yourself with the Databases document that explains about the different databases used by Trivy and the different configuration options that control them. This guide assumes you are already familiar with the concepts explained there.

    "},{"location":"docs/advanced/self-hosting/#oci-databases","title":"OCI databases","text":"

    The following Trivy Databases are packaged as OCI images:

    • trivy-db
    • trivy-java-db
    • trivy-checks

    To host these databases in your own infrastructure:

    "},{"location":"docs/advanced/self-hosting/#make-a-local-copy","title":"Make a local copy","text":"

    Use any container registry manipulation tool (e.g , crane to copy the images to your destination registry.

    Note

    You will need to keep the databases updated in order to maintain relevant scanning results over time.

    "},{"location":"docs/advanced/self-hosting/#configure-trivy","title":"Configure Trivy","text":"

    Use the appropriate database location flags to change the db-repository location:

    • --db-repository
    • --java-db-repository
    • --checks-bundle-repository
    "},{"location":"docs/advanced/self-hosting/#authentication","title":"Authentication","text":"

    If the registry requires authentication, you can configure it as described in the private registry authentication document.

    "},{"location":"docs/advanced/self-hosting/#oci-media-types","title":"OCI Media Types","text":"

    When serving, proxying, or manipulating Trivy's databases, note that the media type of the OCI layer is not a standard container image type:

    DB Media Type Reference trivy-db application/vnd.aquasec.trivy.db.layer.v1.tar+gzip https://github.com/aquasecurity/trivy-db/pkgs/container/trivy-db trivy-java-db application/vnd.aquasec.trivy.javadb.layer.v1.tar+gzip https://github.com/aquasecurity/trivy-java-db/pkgs/container/trivy-java-db trivy-checks application/vnd.oci.image.manifest.v1+json https://github.com/aquasecurity/trivy-checks/pkgs/container/trivy-checks"},{"location":"docs/advanced/self-hosting/#manual-cache-population","title":"Manual cache population","text":"

    Trivy uses a local cache directory to store the database files, as described in the cache document. You can download the databases files and surgically populate the Trivy cache directory with them.

    "},{"location":"docs/advanced/self-hosting/#downloading-the-db-files","title":"Downloading the DB files","text":"

    On a machine with internet access, pull the database container archive from the public registry into your local workspace:

    Note that these examples operate in the current working directory.

    Using ORASUsing Trivy

    This example uses ORAS, but you can use any other container registry manipulation tool.

    oras pull ghcr.io/aquasecurity/trivy-db:2\n

    You should now have a file called db.tar.gz. Next, extract it to reveal the db files:

    tar -xzf db.tar.gz\n

    This example uses Trivy to pull the database container archive. The --cache-dir flag makes Trivy download the database files into our current working directory. The --download-db-only flag tells Trivy to only download the database files, not to scan any images.

    trivy image --cache-dir . --download-db-only\n

    You should now have 2 new files, metadata.json and trivy.db. These are the Trivy DB files, copy them over to the air-gapped environment.

    "},{"location":"docs/advanced/self-hosting/#populating-the-trivy-cache","title":"Populating the Trivy Cache","text":"

    In order to populate the cache, you need to identify the location of the cache directory. If it is under the default location, you can run the following command to find it:

    trivy -h | grep cache\n

    For the example, we will assume the TRIVY_CACHE_DIR variable holds the cache location:

    TRIVY_CACHE_DIR=/home/user/.cache/trivy\n

    Put the Trivy DB files in the Trivy cache directory under a db subdirectory:

    # ensure cache db directory exists\nmkdir -p ${TRIVY_CACHE_DIR}/db\n# copy the db files\ncp /path/to/trivy.db /path/to/metadata.json ${TRIVY_CACHE_DIR}/db/\n
    "},{"location":"docs/advanced/self-hosting/#java-db-adaptations","title":"Java DB adaptations","text":"

    For Java DB the process is the same, except for the following:

    1. Image location is ghcr.io/aquasecurity/trivy-java-db:1
    2. Archive file name is javadb.tar.gz
    3. DB file name is trivy-java.db
    "},{"location":"docs/advanced/self-hosting/#vex-hub","title":"VEX Hub","text":""},{"location":"docs/advanced/self-hosting/#make-a-local-copy_1","title":"Make a local copy","text":"

    To make a copy of VEX Hub in a location that is accessible to Trivy.

    1. Download the VEX Hub archive from: https://github.com/aquasecurity/vexhub/archive/refs/heads/main.zip.
    2. Download the VEX Hub Repository Manifest file from: https://github.com/aquasecurity/vexhub/blob/main/vex-repository.json.
    3. Create or identify an internal HTTP server that can serve the VEX Hub repository in your environment (e.g https://server.local).
    4. Make the downloaded archive file available for serving from your server (e.g https://server.local/main.zip).
    5. Modify the downloaded manifest file's Location URL field to the URL of the archive file on your server (e.g url: https://server.local/main.zip).
    6. Make the manifest file available for serving from your server under the /.well-known path (e.g https://server.local/.well-known/vex-repository.json).
    "},{"location":"docs/advanced/self-hosting/#configure-trivy_1","title":"Configure Trivy","text":"

    To configure Trivy to use the local VEX Repository:

    1. Locate your Trivy VEX configuration file by running trivy vex repo init. Make the following changes to the file.
    2. Disable the default VEX Hub repo (enabled: false)
    3. Add your internal VEX Hub repository as a custom repository with the URL pointing to your local server (e.g url: https://server.local).
    "},{"location":"docs/advanced/self-hosting/#authentication_1","title":"Authentication","text":"

    If your server requires authentication, you can configure it as described in the VEX Repository Authentication document.

    "},{"location":"docs/advanced/container/embed-in-dockerfile/","title":"Embed in Dockerfile","text":"

    Scan your image as part of the build process by embedding Trivy in the Dockerfile. This approach can be used to update Dockerfiles currently using Aqua\u2019s Microscanner.

    $ cat Dockerfile\nFROM alpine:3.7\n\nRUN apk add curl \\\n    && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \\\n    && trivy rootfs --exit-code 1 --no-progress /\n\n$ docker build -t vulnerable-image .\n
    Alternatively you can use Trivy in a multistage build. Thus avoiding the insecure curl | sh. Also the image is not changed.
    [...]\n# Run vulnerability scan on build image\nFROM build AS vulnscan\nCOPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy\nRUN trivy rootfs --exit-code 1 --no-progress /\n[...]\n

    "},{"location":"docs/advanced/container/unpacked-filesystem/","title":"Unpacked Filesystem","text":"

    Scan an unpacked container image filesystem.

    In this case, Trivy works the same way when scanning containers

    $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -\n$ trivy rootfs /tmp/rootfs\n
    Result
    2021-03-08T05:22:26.378Z        INFO    Need to update DB\n2021-03-08T05:22:26.380Z        INFO    Downloading DB...\n20.37 MiB / 20.37 MiB [-------------------------------------------------------------------------------------------------------------------------------------] 100.00% 8.24 MiB p/s 2s\n2021-03-08T05:22:30.134Z        INFO    Detecting Alpine vulnerabilities...\n\n/tmp/rootfs (alpine 3.10.2)\n===========================\nTotal: 20 (UNKNOWN: 0, LOW: 2, MEDIUM: 10, HIGH: 8, CRITICAL: 0)\n\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n| libcrypto1.1 | CVE-2020-1967    | HIGH     | 1.1.1c-r0         | 1.1.1g-r0     | openssl: Segmentation                 |\n|              |                  |          |                   |               | fault in SSL_check_chain              |\n|              |                  |          |                   |               | causes denial of service              |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1967  |\n+              +------------------+          +                   +---------------+---------------------------------------+\n|              | CVE-2021-23839   |          |                   | 1.1.1j-r0     | openssl: incorrect SSLv2              |\n|              |                  |          |                   |               | rollback protection                   |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23839 |\n+              +------------------+          +                   +               +---------------------------------------+\n|              | CVE-2021-23840   |          |                   |               | openssl: integer                      |\n|              |                  |          |                   |               | overflow in CipherUpdate              |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23840 |\n+              +------------------+          +                   +               +---------------------------------------+\n|              | CVE-2021-23841   |          |                   |               | openssl: NULL pointer dereference     |\n|              |                  |          |                   |               | in X509_issuer_and_serial_hash()      |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23841 |\n+              +------------------+----------+                   +---------------+---------------------------------------+\n|              | CVE-2019-1547    | MEDIUM   |                   | 1.1.1d-r0     | openssl: side-channel weak            |\n|              |                  |          |                   |               | encryption vulnerability              |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1547  |\n+              +------------------+          +                   +               +---------------------------------------+\n|              | CVE-2019-1549    |          |                   |               | openssl: information                  |\n|              |                  |          |                   |               | disclosure in fork()                  |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1549  |\n+              +------------------+          +                   +---------------+---------------------------------------+\n|              | CVE-2019-1551    |          |                   | 1.1.1d-r2     | openssl: Integer overflow in RSAZ     |\n|              |                  |          |                   |               | modular exponentiation on x86_64      |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1551  |\n+              +------------------+          +                   +---------------+---------------------------------------+\n|              | CVE-2020-1971    |          |                   | 1.1.1i-r0     | openssl: EDIPARTYNAME                 |\n|              |                  |          |                   |               | NULL pointer de-reference             |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1971  |\n+              +------------------+----------+                   +---------------+---------------------------------------+\n|              | CVE-2019-1563    | LOW      |                   | 1.1.1d-r0     | openssl: information                  |\n|              |                  |          |                   |               | disclosure in PKCS7_dataDecode        |\n|              |                  |          |                   |               | and CMS_decrypt_set1_pkey             |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1563  |\n+--------------+------------------+----------+                   +---------------+---------------------------------------+\n| libssl1.1    | CVE-2020-1967    | HIGH     |                   | 1.1.1g-r0     | openssl: Segmentation                 |\n|              |                  |          |                   |               | fault in SSL_check_chain              |\n|              |                  |          |                   |               | causes denial of service              |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1967  |\n+              +------------------+          +                   +---------------+---------------------------------------+\n|              | CVE-2021-23839   |          |                   | 1.1.1j-r0     | openssl: incorrect SSLv2              |\n|              |                  |          |                   |               | rollback protection                   |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23839 |\n+              +------------------+          +                   +               +---------------------------------------+\n|              | CVE-2021-23840   |          |                   |               | openssl: integer                      |\n|              |                  |          |                   |               | overflow in CipherUpdate              |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23840 |\n+              +------------------+          +                   +               +---------------------------------------+\n|              | CVE-2021-23841   |          |                   |               | openssl: NULL pointer dereference     |\n|              |                  |          |                   |               | in X509_issuer_and_serial_hash()      |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-23841 |\n+              +------------------+----------+                   +---------------+---------------------------------------+\n|              | CVE-2019-1547    | MEDIUM   |                   | 1.1.1d-r0     | openssl: side-channel weak            |\n|              |                  |          |                   |               | encryption vulnerability              |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1547  |\n+              +------------------+          +                   +               +---------------------------------------+\n|              | CVE-2019-1549    |          |                   |               | openssl: information                  |\n|              |                  |          |                   |               | disclosure in fork()                  |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1549  |\n+              +------------------+          +                   +---------------+---------------------------------------+\n|              | CVE-2019-1551    |          |                   | 1.1.1d-r2     | openssl: Integer overflow in RSAZ     |\n|              |                  |          |                   |               | modular exponentiation on x86_64      |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1551  |\n+              +------------------+          +                   +---------------+---------------------------------------+\n|              | CVE-2020-1971    |          |                   | 1.1.1i-r0     | openssl: EDIPARTYNAME                 |\n|              |                  |          |                   |               | NULL pointer de-reference             |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-1971  |\n+              +------------------+----------+                   +---------------+---------------------------------------+\n|              | CVE-2019-1563    | LOW      |                   | 1.1.1d-r0     | openssl: information                  |\n|              |                  |          |                   |               | disclosure in PKCS7_dataDecode        |\n|              |                  |          |                   |               | and CMS_decrypt_set1_pkey             |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2019-1563  |\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n| musl         | CVE-2020-28928   | MEDIUM   | 1.1.22-r3         | 1.1.22-r4     | In musl libc through 1.2.1,           |\n|              |                  |          |                   |               | wcsnrtombs mishandles particular      |\n|              |                  |          |                   |               | combinations of destination buffer... |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-28928 |\n+--------------+                  +          +                   +               +                                       +\n| musl-utils   |                  |          |                   |               |                                       |\n|              |                  |          |                   |               |                                       |\n|              |                  |          |                   |               |                                       |\n|              |                  |          |                   |               |                                       |\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n
    "},{"location":"docs/advanced/private-registries/","title":"Overview","text":"

    Trivy can download images from a private registry without the need for installing Docker or any other 3rd party tools. This makes it easy to run within a CI process.

    "},{"location":"docs/advanced/private-registries/#login","title":"Login","text":"

    You can log in to a private registry using the trivy registry login command. It uses the Docker configuration file (~/.docker/config.json) to store the credentials under the hood, and the configuration file path can be configured by DOCKER_CONFIG environment variable.

    $ cat ~/my_password.txt | trivy registry login --username foo --password-stdin ghcr.io\n$ trivy image ghcr.io/your/private_image\n
    "},{"location":"docs/advanced/private-registries/#passing-credentials","title":"Passing Credentials","text":"

    You can also provide your credentials when scanning.

    $ TRIVY_USERNAME=YOUR_USERNAME TRIVY_PASSWORD=YOUR_PASSWORD trivy image YOUR_PRIVATE_IMAGE\n

    Warning

    When passing credentials via environment variables or CLI flags, Trivy will attempt to use these credentials for all registries encountered during scanning, regardless of the target registry. This can potentially lead to unintended credential exposure. To mitigate this risk:

    1. Set credentials cautiously and only when necessary.
    2. Prefer using trivy registry login to pre-configure credentials with specific registries, which ensures credentials are only sent to appropriate registries.

    Trivy also supports providing credentials through CLI flags:

    $ TRIVY_PASSWORD=YOUR_PASSWORD trivy image --username YOUR_USERNAME YOUR_PRIVATE_IMAGE\n

    Warning

    The CLI flag --password is available, but its use is not recommended for security reasons.

    You can also store your credentials in trivy.yaml. For more information, please refer to the documentation.

    It can handle multiple sets of credentials as well:

    $ export TRIVY_USERNAME=USERNAME1,USERNAME2\n$ export TRIVY_PASSWORD=PASSWORD1,PASSWORD2\n$ trivy image YOUR_PRIVATE_IMAGE\n

    In the example above, Trivy attempts to use two pairs of credentials:

    • USERNAME1/PASSWORD1
    • USERNAME2/PASSWORD2

    Please note that the number of usernames and passwords must be the same.

    Note

    --password-stdin doesn't support comma-separated passwords.

    "},{"location":"docs/advanced/private-registries/acr/","title":"Requirements","text":"

    None, Trivy uses Azure SDK for Go. You don't need to install az command.

    "},{"location":"docs/advanced/private-registries/acr/#privileges","title":"Privileges","text":"

    Service principal must have the AcrPull permissions.

    "},{"location":"docs/advanced/private-registries/acr/#creation-of-a-service-principal","title":"Creation of a service principal","text":"
    export SP_DATA=$(az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope \"/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.ContainerRegistry/registries/<registry_name>\")\n
    "},{"location":"docs/advanced/private-registries/acr/#usage","title":"Usage","text":"
    # must set TRIVY_USERNAME empty char\nexport AZURE_CLIENT_ID=$(echo $SP_DATA | jq -r '.appId')\nexport AZURE_CLIENT_SECRET=$(echo $SP_DATA | jq -r '.password')\nexport AZURE_TENANT_ID=$(echo $SP_DATA | jq -r '.tenant')\n
    "},{"location":"docs/advanced/private-registries/acr/#testing","title":"Testing","text":"

    You can test credentials in the following manner.

    docker run -it --rm -v /tmp:/tmp \\\n  -e AZURE_CLIENT_ID -e AZURE_CLIENT_SECRET -e AZURE_TENANT_ID \\\n  aquasec/trivy image your_special_project.azurecr.io/your_special_image:your_special_tag\n
    "},{"location":"docs/advanced/private-registries/docker-hub/","title":"Docker Hub","text":"

    See here for the detail. You don't need to provide a credential when download from public repository.

    "},{"location":"docs/advanced/private-registries/ecr/","title":"AWS ECR (Elastic Container Registry)","text":"

    Trivy uses AWS SDK. You don't need to install aws CLI tool. You can use AWS CLI's ENV Vars.

    "},{"location":"docs/advanced/private-registries/ecr/#aws-private-registry-permissions","title":"AWS private registry permissions","text":"

    You may need to grant permissions to allow Trivy to pull images from private ECR.

    It depends on how you want to provide AWS Role to trivy.

    • IAM Role Service account
    • Kube2iam or Kiam
    "},{"location":"docs/advanced/private-registries/ecr/#iam-role-service-account","title":"IAM Role Service account","text":"

    Add the AWS role in trivy's service account annotations:

    trivy:\n\n  serviceAccount:\n    annotations: {}\n      # eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME\n
    "},{"location":"docs/advanced/private-registries/ecr/#kube2iam-or-kiam","title":"Kube2iam or Kiam","text":"

    Add the AWS role to pod's annotations:

    podAnnotations: {}\n  ## kube2iam/kiam annotation\n  # iam.amazonaws.com/role: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME\n
    "},{"location":"docs/advanced/private-registries/gcr/","title":"Requirements","text":"

    None, Trivy uses Google Cloud SDK. You don't need to install gcloud command.

    "},{"location":"docs/advanced/private-registries/gcr/#privileges","title":"Privileges","text":"

    Credential file must have the roles/storage.objectViewer permissions. More information can be found in Google's documentation

    "},{"location":"docs/advanced/private-registries/gcr/#json-file-format","title":"JSON File Format","text":"

    The JSON file specified should have the following format provided by google's service account mechanisms:

    {\n  \"type\": \"service_account\",\n  \"project_id\": \"your_special_project\",\n  \"private_key_id\": \"XXXXXXXXXXXXXXXXXXXXxx\",\n  \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nNONONONO\\n-----END PRIVATE KEY-----\\n\",\n  \"client_email\": \"somedude@your_special_project.iam.gserviceaccount.com\",\n  \"client_id\": \"1234567890\",\n  \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n  \"token_uri\": \"https://oauth2.googleapis.com/token\",\n  \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\n  \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/somedude%40your_special_project.iam.gserviceaccount.com\"\n}\n
    "},{"location":"docs/advanced/private-registries/gcr/#usage","title":"Usage","text":"

    If you want to use target project's repository, you can set them via GOOGLE_APPLICATION_CREDENTIALS.

    # must set TRIVY_USERNAME empty char\nexport GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json\n

    "},{"location":"docs/advanced/private-registries/gcr/#testing","title":"Testing","text":"

    You can test credentials in the following manner (assuming they are in /tmp on host machine).

    docker run -it --rm -v /tmp:/tmp\\\n  -e GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json\\\n  aquasec/trivy image gcr.io/your_special_project/your_special_image:your_special_tag\n
    "},{"location":"docs/advanced/private-registries/self/","title":"Self-Hosted","text":"

    BasicAuth server needs TRIVY_USERNAME and TRIVY_PASSWORD.

    export TRIVY_USERNAME={USERNAME}\nexport TRIVY_PASSWORD={PASSWORD}\n\n# if you want to use 80 port, use NonSSL\nexport TRIVY_NON_SSL=true\n
    "},{"location":"docs/compliance/compliance/","title":"Built-in Compliance Reports","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy\u2019s compliance flag lets you curate a specific set of checks into a report. In a typical Trivy scan, there are hundreds of different checks for many different components and configurations, but sometimes you already know which specific checks you are interested in. Often this would be an industry accepted set of checks such as CIS, or some vendor specific guideline, or your own organization policy that you want to comply with. These are all possible using the flexible compliance infrastructure that's built into Trivy. Compliance reports are defined as simple YAML documents that select checks to include in the report.

    "},{"location":"docs/compliance/compliance/#usage","title":"Usage","text":"

    Compliance report is currently supported in the following targets (trivy sub-commands):

    • trivy image
    • trivy k8s

    Add the --compliance flag to the command line, and set it's value to desired report. For example: trivy k8s cluster --compliance k8s-nsa (see below for built-in and custom reports)

    "},{"location":"docs/compliance/compliance/#options","title":"Options","text":"

    The following flags are compatible with --compliance flag and allows customizing it's output:

    flag effect --report summary shows a summary of the results. for every control shows the number of failed checks. --report all shows fully detailed results. for every control shows where it failed and why. --format table shows results in textual table format (good for human readability). --format json shows results in json format (good for machine readability)."},{"location":"docs/compliance/compliance/#built-in-compliance","title":"Built-in compliance","text":"

    Trivy has a number of built-in compliance reports that you can asses right out of the box. to specify a built-in compliance report, select it by ID like trivy --compliance <compliance_id>.

    For the list of built-in compliance reports, please see the relevant section:

    • Docker compliance
    • Kubernetes compliance
    • AWS compliance
    "},{"location":"docs/compliance/compliance/#contribute-a-built-in-compliance-report","title":"Contribute a Built-in Compliance Report","text":""},{"location":"docs/compliance/compliance/#define-a-compliance-spec-based-on-cis-benchmark-or-other-specs","title":"Define a Compliance spec, based on CIS benchmark or other specs","text":"

    Here is an example for CIS compliance report:

    ---\nspec:\n  id: k8s-cis-1.23\n  title: CIS Kubernetes Benchmarks v1.23\n  description: CIS Kubernetes Benchmarks\n  platform: k8s\n  type: cis\n  version: '1.23'\n  relatedResources:\n  - https://www.cisecurity.org/benchmark/kubernetes\n  controls:\n  - id: 1.1.1\n    name: Ensure that the API server pod specification file permissions are set to\n      600 or more restrictive\n    description: Ensure that the API server pod specification file has permissions\n      of 600 or more restrictive\n    checks:\n    - id: AVD-KCV-0073\n    commands:\n    - id: CMD-0001\n    severity: HIGH\n
    "},{"location":"docs/compliance/compliance/#compliance-id","title":"Compliance ID","text":"

    ID field is the name used to execute the compliance scan via trivy example:

    trivy k8s --compliance k8s-cis-1.23\n

    ID naming convention: {platform}-{type}-{version}

    "},{"location":"docs/compliance/compliance/#compliance-platform","title":"Compliance Platform","text":"

    The platform field specifies the type of platform on which to run this compliance report. Supported platforms:

    • k8s (native kubernetes cluster)
    • eks (elastic kubernetes service)
    • aks (azure kubernetes service)
    • gke (google kubernetes engine)
    • rke2 (rancher kubernetes engine v2)
    • ocp (OpenShift Container Platform)
    • docker (docker engine)
    • aws (amazon web services)
    "},{"location":"docs/compliance/compliance/#compliance-type","title":"Compliance Type","text":"

    The type field specifies the kind compliance report.

    • cis (Center for Internet Security)
    • nsa (National Security Agency)
    • pss (Pod Security Standards)
    "},{"location":"docs/compliance/compliance/#compliance-version","title":"Compliance Version","text":"

    The version field specifies the version of the compliance report.

    • 1.23
    "},{"location":"docs/compliance/compliance/#compliance-check-id","title":"Compliance Check ID","text":"

    Specify the check ID that needs to be evaluated based on the information collected from the command data output to assess the control.

    Example of how to define check data under checks folder:

    # METADATA\n# title: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive\"\n# description: \"Ensure that the kubelet.conf file has permissions of 600 or more restrictive.\"\n# scope: package\n# schemas:\n# - input: schema[\"kubernetes\"]\n# related_resources:\n# - https://www.cisecurity.org/benchmark/kubernetes\n# custom:\n#   id: KCV0073\n#   avd_id: AVD-KCV-0073\n#   severity: HIGH\n#   short_code: ensure-kubelet.conf-file-permissions-600-or-more-restrictive.\n#   recommended_action: \"Change the kubelet.conf file permissions to 600 or more restrictive if exist\"\n#   input:\n#     selector:\n#     - type: kubernetes\npackage builtin.kubernetes.KCV0073\n\nimport data.lib.kubernetes\n\ntypes := [\"master\", \"worker\"]\n\nvalidate_kubelet_file_permission(sp) := {\"kubeletConfFilePermissions\": violation} {\n sp.kind == \"NodeInfo\"\n sp.type == types[_]\n violation := {permission | permission = sp.info.kubeletConfFilePermissions.values[_]; permission > 600}\n count(violation) > 0\n}\n\ndeny[res] {\n output := validate_kubelet_file_permission(input)\n msg := \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive\"\n res := result.new(msg, output)\n}\n
    "},{"location":"docs/compliance/compliance/#compliance-command-id","title":"Compliance Command ID","text":"

    Note: This field is not mandatory, it is relevant to k8s compliance report when node-collector is in use

    Specify the command ID (#ref) that needs to be executed to collect the information required to evaluate the control.

    Example of how to define command data under commands folder

    ---\n- id: CMD-0001\n  key: kubeletConfFilePermissions\n  title: kubelet.conf file permissions\n  nodeType: worker\n  audit: stat -c %a $kubelet.kubeconfig\n  platfroms:\n    - k8s\n    - aks\n
    "},{"location":"docs/compliance/compliance/#command-id","title":"Command ID","text":"

    Find the next command ID by running the command on trivy-checks project.

    make command-id\n
    "},{"location":"docs/compliance/compliance/#command-key","title":"Command Key","text":"
    • Re-use an existing key or specifiy a new one (make sure key name has no spaces)

    Note: The key value should match the key name evaluated by the Rego check.

    "},{"location":"docs/compliance/compliance/#command-title","title":"Command Title","text":"

    Represent the purpose of the command

    "},{"location":"docs/compliance/compliance/#command-nodetype","title":"Command NodeType","text":"

    Specify the node type on which the command is supposed to run.

    • worker
    • master
    "},{"location":"docs/compliance/compliance/#command-audit","title":"Command Audit","text":"

    Specify here the shell command to be used please make sure to add error supression (2>/dev/null)

    "},{"location":"docs/compliance/compliance/#command-platforms","title":"Command Platforms","text":"

    The list of platforms that support this command. Name should be taken from this list Platforms

    "},{"location":"docs/compliance/compliance/#command-config-files","title":"Command Config Files","text":"

    The commands use a configuration file that helps obtain the paths to binaries and configuration files based on different platforms (e.g., Rancher, native Kubernetes, etc.).

    For example:

    kubelet:\n    bins:\n      - kubelet\n      - hyperkube kubelet\n    confs:\n      - /etc/kubernetes/kubelet-config.yaml\n      - /var/lib/kubelet/config.yaml\n
    "},{"location":"docs/compliance/compliance/#commands-files-location","title":"Commands Files Location","text":"

    Currently checks files location are :https://github.com/aquasecurity/trivy-checks/tree/main/checks

    Command files location: https://github.com/aquasecurity/trivy-checks/tree/main/commands under command file

    Note: command config files will be located under https://github.com/aquasecurity/trivy-checks/tree/main/commands as well

    "},{"location":"docs/compliance/compliance/#node-collector-output","title":"Node-collector output","text":"

    The node collector will read commands and execute each command, and incorporate the output into the NodeInfo resource.

    example:

    {\n  \"apiVersion\": \"v1\",\n  \"kind\": \"NodeInfo\",\n  \"metadata\": {\n    \"creationTimestamp\": \"2023-01-04T11:37:11+02:00\"\n  },\n  \"type\": \"master\",\n  \"info\": {\n    \"adminConfFileOwnership\": {\n      \"values\": [\n        \"root:root\"\n      ]\n    },\n    \"adminConfFilePermissions\": {\n      \"values\": [\n        600\n      ]\n    }\n    ...\n  }\n}\n
    "},{"location":"docs/compliance/compliance/#custom-compliance","title":"Custom compliance","text":"

    You can create your own custom compliance report. A compliance report is a simple YAML document in the following format:

    spec:\n  id: \"k8s-myreport\" # report unique identifier. this should not container spaces.\n  title: \"My custom Kubernetes report\" # report title. Any one-line title.\n  description: \"Describe your report\" # description of the report. Any text.\n  relatedResources :\n    - https://some.url # useful references. URLs only.\n  version: \"1.0\" # spec version (string)\n  controls:\n    - name: \"Non-root containers\" # Name for the control (appears in the report as is). Any one-line name.\n      description: 'Check that container is not running as root' # Description (appears in the report as is). Any text.\n      id: \"1.0\" # control identifier (string)\n      checks:   # list of existing Trivy checks that define the control\n        - id: AVD-KSV-0012 # check ID. Must start with `AVD-` or `CVE-` \n      severity: \"MEDIUM\" # Severity for the control (note that checks severity isn't used)\n    - name: \"Immutable container file systems\"\n      description: 'Check that container root file system is immutable'\n      id: \"1.1\"\n      checks:\n        - id: AVD-KSV-0014\n      severity: \"LOW\"\n

    The check id field (controls[].checks[].id) is referring to existing check by it's \"AVD ID\". This AVD ID is easily located in the check's source code metadata header, or by browsing Aqua vulnerability DB, specifically in the Misconfigurations and Vulnerabilities sections.

    Once you have a compliance spec, you can select it by file path: trivy --compliance @</path/to/compliance.yaml> (note the @ indicating file path instead of report id).

    "},{"location":"docs/compliance/contrib-compliance/","title":"Custom Compliance Spec","text":"

    Trivy supports several different compliance specs. The details on compliance scanning with Trivy are provided in the compliance documentation. All of the Compliance Specs currently available in Trivy can be found in the trivy-checks/pkg/specs/compliance/ directory (Link).

    New checks are based on the custom compliance report detailed in the main documentation. If you would like to create your custom compliance report, please reference the information in the main documentation. This section details how community members can contribute new Compliance Specs to Trivy.

    All compliance specs in Trivy are based on formal compliance reports such as CIS Benchmarks.

    "},{"location":"docs/compliance/contrib-compliance/#contributing-new-compliance-specs","title":"Contributing new Compliance Specs","text":"

    Compliance specs can be based on new compliance reports becoming available e.g. a new CIS Benchmark version, or identifying missing compliance specs that Trivy users would like to access.

    "},{"location":"docs/compliance/contrib-compliance/#create-a-new-compliance-spec","title":"Create a new Compliance Spec","text":"

    The existing compliance specs in Trivy are located under the trivy-checks/pkg/specs/compliance/ directory (Link).

    Create a new file under trivy-checks/specs/compliance/ and name the file in the format of \"provider-resource-spectype-version.yaml\". For example, the file name for AWS CIS Benchmarks for EKS version 1.4 is: aws-eks-cis-1.4.yaml. Note that if the compliance spec is not specific to a provider, the provider field can be ignored.

    "},{"location":"docs/compliance/contrib-compliance/#minimum-spec-structure","title":"Minimum spec structure","text":"

    The structure of the compliance spec is detailed in the main documentation.

    The first section in the spec is focused on the metadata of the spec. Replace all the fields of the metadata with the information relevant to the compliance spec that will be added. This information can be taken from the official report e.g. the CIS Benchmark report.

    "},{"location":"docs/compliance/contrib-compliance/#populating-the-control-section","title":"Populating the control section","text":"

    Compliance specs detail a set of checks that should pass so that the resource is compliant with the official benchmark specifications. There are two ways in which Trivy compliance checks can enforce the compliance specification:

    1. The check is available in Trivy, as part of the trivy-checks and can be referenced in the Compliance Spec
    2. The check is not available in Trivy and a manual check has to be added to the Compliance Spec

    Additional information is provided below.

    "},{"location":"docs/compliance/contrib-compliance/#1-referencing-a-check-that-is-already-part-of-trivy","title":"1. Referencing a check that is already part of Trivy","text":"

    Trivy has a comprehensive list of checks as part of its misconfiguration scanning. These can be found in the trivy-checks/checks directory (Link). If the check is present, the AVD_ID and other information from the check has to be used.

    Note: Take a look at the more generic compliance specs that are already available in Trivy. If you are adding new compliance spec to Kubernetes e.g. AWS EKS CIS Benchmarks, chances are high that the check you would like to add to the new spec has already been defined in the general k8s-ci-v.000.yaml compliance spec. The same applies for creating specific Cloud Provider Compliance Specs and the generic compliance specs available.

    For example, the following check is detailed in the AWS EKS CIS v1.4 Benchmark: 3.1.2 Ensure that the kubelet kubeconfig file ownership is set to root:root (Manual)

    This check can be found in the general K8s CIS Compliance Benchmark: k8s-cis-1.23.yaml (Link)

    Thus, we can use the information already present:

      - id: 3.1.2\n    name: Ensure that the kubelet service file ownership is set to root:root (Manual)\n    description: Ensure that the kubelet service file ownership is set to root:root\n    checks:\n      - id: AVD-KCV-0070\n    severity: HIGH\n
    • The ID, name, and description is taken directly from the AWS EKS CIS Benchmarks
    • The check and severity are taken from the existing complaince check in the k8s-cis-1.23.yaml
    "},{"location":"docs/compliance/contrib-compliance/#2-referencing-a-check-manually-that-is-not-part-of-the-trivy-default-checks","title":"2. Referencing a check manually that is not part of the Trivy default checks","text":"

    If the check does not already exist in the Aqua Vulnerability Database (AVD) and is not part of the trivy-checks, the fields in the compliance spec for the check have to be populated manually. This is done by referencing the information in the official compliance specification.

    Below is the beginning of the information of the EKS CIS Benchmarks v1.4.0:

    The corresponding check in the control section will look like this:

      - id: 2.1.1\n    name: Enable audit Logs (Manual)\n    description: |\n      Control plane logs provide visibility into operation of the EKS Control plane components systems. \n      The API server audit logs record all accepted and rejected requests in the cluster. \n      When enabled via EKS configuration the control plane logs for a cluster are exported to a CloudWatch \n      Log Group for persistence.\n    checks: null\n    severity: MEDIUM\n
    • Again, the id, name and description are taken directly from the EKS CIS Benchmarks v1.4.0
    • The checks is in this case null as the check is not currently present in the AVD and does not have a check in the trivy policies repository
    • Since the check does not exist in Trivy, the severity will be MEDIUM. However, in some cases, the compliance report e.g. the CIS Benchmark report will specify the severity
    "},{"location":"docs/compliance/contrib-compliance/#contributing-new-checks-to-trivy-checks","title":"Contributing new checks to trivy-checks","text":"

    All of the checks in trivy-policies can be referenced in the compliance specs. To write new Rego checks for Trivy, please take a look at the contributing documentation for checks.

    "},{"location":"docs/compliance/contrib-compliance/#test-the-compliance-spec","title":"Test the Compliance Spec","text":"

    To test the compliance check, pass the new path into the Trivy scan through the --compliance flag. For instance, to pass the check to the Trivy Kubernetes scan use the following command structure:

    trivy k8s cluster --compliance @</path/to/compliance.yaml> --report summary\n

    Note: The @ is required before the filepath.

    "},{"location":"docs/configuration/","title":"Configuration","text":"

    Trivy's settings can be configured in any of the following methods, which will apply in the following precedence:

    1. CLI flags (overrides all other settings)
    2. Environment variables (overrides config file settings)
    3. Configuration file
    "},{"location":"docs/configuration/#cli-flags","title":"CLI Flags","text":"

    You can view the list of available flags by adding the --help flag to a Trivy command, or by exploring the CLI reference.

    "},{"location":"docs/configuration/#environment-variables","title":"Environment Variables","text":"

    Any CLI option can be set as an environment variable. The environment variable name are similar to the CLI option name, with the following augmentations:

    • Add TRIVY_ prefix
    • All uppercase letters
    • Replace - with _

    For example:

    • --debug => TRIVY_DEBUG
    • --cache-dir => TRIVY_CACHE_DIR
    $ TRIVY_DEBUG=true TRIVY_SEVERITY=CRITICAL trivy image alpine:3.15\n
    "},{"location":"docs/configuration/#configuration-file","title":"Configuration File","text":"

    Any setting can be set in a YAML file. By default, config file named trivy.yaml is read from the current directory where Trivy is run. To load configuration from a different file, use the --config flag and specify the config path to load: trivy --config /etc/trivy/myconfig.yaml.

    The structure and settings of the YAML config file is documented in the Config file document.

    "},{"location":"docs/configuration/cache/","title":"Cache","text":"

    The cache directory includes

    • Cache of previous scans (Scan cache).
    • Vulnerability Database1
    • Java Index Database2
    • Misconfiguration Checks3
    • VEX Repositories

    The cache option is common to all scanners.

    "},{"location":"docs/configuration/cache/#clear-caches","title":"Clear Caches","text":"

    trivy clean subcommand removes caches.

    $ trivy clean --scan-cache\n
    Result
    2024-06-21T21:58:21+04:00       INFO    Removing scan cache...\n

    If you want to delete cached vulnerability databases, use --vuln-db. You can also delete all caches with --all. See trivy clean --help for details.

    "},{"location":"docs/configuration/cache/#cache-directory","title":"Cache Directory","text":"

    Specify where the cache is stored with --cache-dir.

    $ trivy --cache-dir /tmp/trivy/ image python:3.4-alpine3.9\n
    "},{"location":"docs/configuration/cache/#scan-cache-backend","title":"Scan Cache Backend","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy utilizes a scan cache to store analysis results, such as package lists. It supports three types of backends for this cache:

    • Local File System (fs)
      • The cache path can be specified by --cache-dir
    • Memory (memory)
    • Redis (redis://)
      • redis://[HOST]:[PORT]
      • TTL can be configured via --cache-ttl
    "},{"location":"docs/configuration/cache/#local-file-system","title":"Local File System","text":"

    The local file system backend is the default choice for container and VM image scans. When scanning container images, it stores analysis results on a per-layer basis, using layer IDs as keys. This approach enables faster scans of the same container image or different images that share layers.

    Note

    Internally, this backend uses BoltDB, which has an important limitation: only one process can access the cache at a time. Subsequent processes attempting to access the cache will be locked. For more details on this limitation, refer to the troubleshooting guide.

    "},{"location":"docs/configuration/cache/#memory","title":"Memory","text":"

    The memory backend stores analysis results in memory, which means the cache is discarded when the process ends. This makes it useful in scenarios where caching is not required or desired. It serves as the default for repository, filesystem and SBOM scans and can also be employed for container image scans when caching is unnecessary.

    To use the memory backend for a container image scan, you can use the following command:

    $ trivy image debian:11 --cache-backend memory\n
    "},{"location":"docs/configuration/cache/#redis","title":"Redis","text":"

    The Redis backend is particularly useful when you need to share the cache across multiple Trivy instances. You can set up Trivy to use a Redis backend with a command like this:

    $ trivy server --cache-backend redis://localhost:6379\n

    This approach allows for centralized caching, which can be beneficial in distributed or high-concurrency environments.

    If you want to use TLS with Redis, you can enable it by specifying the --redis-tls flag.

    $ trivy server --cache-backend redis://localhost:6379 --redis-tls\n

    Trivy also supports for connecting to Redis with your certificates. You need to specify --redis-ca , --redis-cert , and --redis-key options.

    $ trivy server --cache-backend redis://localhost:6379 \\\n  --redis-ca /path/to/ca-cert.pem \\\n  --redis-cert /path/to/cert.pem \\\n  --redis-key /path/to/key.pem\n
    1. Downloaded when scanning for vulnerabilities\u00a0\u21a9

    2. Downloaded when scanning jar/war/par/ear files\u00a0\u21a9

    3. Downloaded when scanning for misconfigurations\u00a0\u21a9

    "},{"location":"docs/configuration/db/","title":"Trivy Databases","text":"

    When you install Trivy, the installed artifact contains the scanner engine but is lacking relevant security information needed to make security detections and recommendations. These so called \"databases\" are automatically fetched and maintained by Trivy as needed, so normally you shouldn't notice or worry about them. This document elaborates on the database management mechanism and its configuration options.

    Trivy relies on the following databases:

    DB Artifact name Contents Purpose Vulnerabilities DB trivy-db CVE information collected from various feeds used only for vulnerability scanning Java DB trivy-java-db Index of Java artifacts and their hash digest used to identify Java artifacts only in JAR scanning Checks Bundle trivy-checks Logic of misconfiguration checks used only in misconfiguration/IaC scanning

    Note

    This is not an exhaustive list of Trivy's external connectivity requirements. There are additional external resources which may be required by specific Trivy features. To learn about external connectivity requirements, see the Advanced Network Scenarios.

    "},{"location":"docs/configuration/db/#locations","title":"Locations","text":"

    Trivy's databases are published to the following locations:

    Registry Image Address Link GHCR ghcr.io/aquasecurity/trivy-db https://ghcr.io/aquasecurity/trivy-db ghcr.io/aquasecurity/trivy-java-db https://ghcr.io/aquasecurity/trivy-java-db ghcr.io/aquasecurity/trivy-checks https://ghcr.io/aquasecurity/trivy-checks Docker Hub aquasec/trivy-db https://hub.docker.com/r/aquasec/trivy-db aquasec/trivy-java-db https://hub.docker.com/r/aquasec/trivy-java-db aquasec/trivy-checks https://hub.docker.com/r/aquasec/trivy-checks AWS ECR public.ecr.aws/aquasecurity/trivy-db https://gallery.ecr.aws/aquasecurity/trivy-db public.ecr.aws/aquasecurity/trivy-java-db https://gallery.ecr.aws/aquasecurity/trivy-java-db public.ecr.aws/aquasecurity/trivy-checks https://gallery.ecr.aws/aquasecurity/trivy-checks

    In addition, images are also available via pull-through cache registries like Google Container Registry Mirror.

    "},{"location":"docs/configuration/db/#default-locations","title":"Default Locations","text":"

    Trivy will attempt to pull images from the following registries in the order specified.

    1. mirror.gcr.io/aquasec
    2. ghcr.io/aquasecurity

    You can specify additional alternative repositories as explained in the configuring database locations section.

    "},{"location":"docs/configuration/db/#db-management-configuration","title":"DB Management Configuration","text":""},{"location":"docs/configuration/db/#database-locations","title":"Database Locations","text":"

    You can configure Trivy to download databases from alternative locations by using the flags:

    • --db-repository
    • --java-db-repository
    • --checks-bundle-repository

    The value should be an image address in a container registry.

    For example:

    trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db alpine\n

    The flags accepts multiple values, which can be used to specify multiple alternative repository locations. In case of a transient errors (e.g. status 429 or 5xx), Trivy will fall back to alternative registries in the order specified.

    For example:

    trivy image --db-repository my.registry.local/trivy-db --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db alpine\n

    The Checks Bundle registry location option does not support fallback through multiple options. This is because in case of a failure pulling the Checks Bundle, Trivy will use the embedded checks as a fallback.

    Note

    Setting the repository location flags override the default values which include the official db locations. In case you want to preserve the default locations, you should include them in the list the you set as repository locations.

    Note

    When pulling trivy-db or trivy-java-db, if image tag is not specified, Trivy defaults to the db schema number instead of the latest tag.

    "},{"location":"docs/configuration/db/#skip-updates","title":"Skip updates","text":"

    You can configure Trivy to not attempt to download any or all database(s), using the flags:

    • --skip-db-update
    • --skip-java-db-update
    • --skip-check-update

    For example:

    trivy image --skip-db-update --skip-java-db-update --skip-check-update alpine\n
    "},{"location":"docs/configuration/db/#only-update","title":"Only update","text":"

    You can ask Trivy to only update the database without performing a scan. This action will ensure Trivy is up to date, and populate Trivy's database cache for subsequent scans.

    • --download-db-only
    • --download-java-db-only

    For example:

    trivy image --download-db-only\n

    Note that currently there is no option to download only the Checks Bundle.

    "},{"location":"docs/configuration/db/#remove-databases","title":"Remove Databases","text":"

    trivy clean command removes caches and databases. You can select which cache component to remove:

    option description -a/--all remove all caches --checks-bundle remove checks bundle --java-db remove Java database --scan-cache remove scan cache (container and VM image analysis results) --vuln-db remove vulnerability database

    Example:

    $ trivy clean --vuln-db --java-db\n2024-06-24T11:42:31+06:00       INFO    Removing vulnerability database...\n2024-06-24T11:42:31+06:00       INFO    Removing Java database...\n
    "},{"location":"docs/configuration/filtering/","title":"Filtering","text":"

    Trivy provides various methods for filtering the results.

    flowchart LR\n  Issues(\"Detected\\nIssues\") --> Severity\n\n  subgraph Filtering\n    subgraph Prioritization\n        direction TB\n        Severity(\"By Severity\") --> Status(\"By Status\")\n    end\n    subgraph Suppression\n        Status --> Ignore(\"By Finding IDs\")\n        Ignore --> Rego(\"By Rego\")\n        Rego --> VEX(\"By VEX\")\n    end\n  end\n  VEX --> Results

    Similar to the functionality of filtering results, you can also limit the sub-targets for each scanner. For information on these settings, please refer to the scanner-specific documentation (vulnerability , misconfiguration, etc.).

    "},{"location":"docs/configuration/filtering/#prioritization","title":"Prioritization","text":"

    You can filter the results by

    • Severity
    • Status
    "},{"location":"docs/configuration/filtering/#by-severity","title":"By Severity","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    Use --severity option.

    $ trivy image --severity HIGH,CRITICAL ruby:2.4.0\n
    Result
    2019-05-16T01:51:46.255+0900    INFO    Updating vulnerability database...\n2019-05-16T01:51:49.213+0900    INFO    Detecting Debian vulnerabilities...\n\nruby:2.4.0 (debian 8.7)\n=======================\nTotal: 1785 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1680, CRITICAL: 105)\n\n+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+\n|           LIBRARY           | VULNERABILITY ID | SEVERITY |     INSTALLED VERSION     |          FIXED VERSION           |                      TITLE                      |\n+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+\n| apt                         | CVE-2019-3462    | CRITICAL | 1.0.9.8.3                 | 1.0.9.8.5                        | Incorrect sanitation of the                     |\n|                             |                  |          |                           |                                  | 302 redirect field in HTTP                      |\n|                             |                  |          |                           |                                  | transport method of...                          |\n+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+\n| bash                        | CVE-2019-9924    | HIGH     | 4.3-11                    | 4.3-11+deb8u2                    | bash: BASH_CMD is writable in                   |\n|                             |                  |          |                           |                                  | restricted bash shells                          |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2016-7543    |          |                           | 4.3-11+deb8u1                    | bash: Specially crafted                         |\n|                             |                  |          |                           |                                  | SHELLOPTS+PS4 variables allows                  |\n|                             |                  |          |                           |                                  | command substitution                            |\n+-----------------------------+------------------+          +---------------------------+----------------------------------+-------------------------------------------------+\n| binutils                    | CVE-2017-8421    |          | 2.25-5                    |                                  | binutils: Memory exhaustion in                  |\n|                             |                  |          |                           |                                  | objdump via a crafted PE file                   |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2017-14930   |          |                           |                                  | binutils: Memory leak in                        |\n|                             |                  |          |                           |                                  | decode_line_info                                |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2017-7614    |          |                           |                                  | binutils: NULL                                  |\n|                             |                  |          |                           |                                  | pointer dereference in                          |\n|                             |                  |          |                           |                                  | bfd_elf_final_link function                     |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2014-9939    |          |                           |                                  | binutils: buffer overflow in                    |\n|                             |                  |          |                           |                                  | ihex.c                                          |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2017-13716   |          |                           |                                  | binutils: Memory leak with the                  |\n|                             |                  |          |                           |                                  | C++ symbol demangler routine                    |\n|                             |                  |          |                           |                                  | in libiberty                                    |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2018-12699   |          |                           |                                  | binutils: heap-based buffer                     |\n|                             |                  |          |                           |                                  | overflow in finish_stab in                      |\n|                             |                  |          |                           |                                  | stabs.c                                         |\n+-----------------------------+------------------+          +---------------------------+----------------------------------+-------------------------------------------------+\n| bsdutils                    | CVE-2015-5224    |          | 2.25.2-6                  |                                  | util-linux: File name                           |\n|                             |                  |          |                           |                                  | collision due to incorrect                      |\n|                             |                  |          |                           |                                  | mkstemp use                                     |\n+                             +------------------+          +                           +----------------------------------+-------------------------------------------------+\n|                             | CVE-2016-2779    |          |                           |                                  | util-linux: runuser tty hijack                  |\n|                             |                  |          |                           |                                  | via TIOCSTI ioctl                               |\n+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+\n
    trivy config --severity HIGH,CRITICAL examples/misconf/mixed\n
    Result
    2022-05-16T13:50:42.718+0100    INFO    Detected config files: 3\n\nDockerfile (dockerfile)\n=======================\nTests: 17 (SUCCESSES: 16, FAILURES: 1)\nFailures: 1 (HIGH: 1, CRITICAL: 0)\n\nHIGH: Last USER command in Dockerfile should not be 'root'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.\n\nSee https://avd.aquasec.com/misconfig/ds002\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Dockerfile:3\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   3 [ USER root\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n\ndeployment.yaml (kubernetes)\n============================\nTests: 8 (SUCCESSES: 8, FAILURES: 0)\nFailures: 0 (HIGH: 0, CRITICAL: 0)\n\n\nmain.tf (terraform)\n===================\nTests: 1 (SUCCESSES: 0, FAILURES: 1)\nFailures: 1 (HIGH: 0, CRITICAL: 1)\n\nCRITICAL: Classic resources should not be used.\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nAWS Classic resources run in a shared environment with infrastructure owned by other AWS customers. You should run\nresources in a VPC instead.\n\nSee https://avd.aquasec.com/misconfig/avd-aws-0081\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n main.tf:2-4\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   2 \u250c resource \"aws_db_security_group\" \"sg\" {\n   3 \u2502\n   4 \u2514 }\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n
    "},{"location":"docs/configuration/filtering/#by-status","title":"By Status","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License

    Trivy supports the following vulnerability statuses:

    • unknown
    • not_affected: this package is not affected by this vulnerability on this platform
    • affected: this package is affected by this vulnerability on this platform, but there is no patch released yet
    • fixed: this vulnerability is fixed on this platform
    • under_investigation: it is currently unknown whether or not this vulnerability affects this package on this platform, and it is under investigation
    • will_not_fix: this package is affected by this vulnerability on this platform, but there is currently no intention to fix it (this would primarily be for flaws that are of Low or Moderate impact that pose no significant risk to customers)
    • fix_deferred: this package is affected by this vulnerability on this platform, and may be fixed in the future
    • end_of_life: this package has been identified to contain the impacted component, but analysis to determine whether it is affected or not by this vulnerability was not performed

    Note that vulnerabilities with the unknown, not_affected or under_investigation status are not detected. These are only defined for comprehensiveness, and you will not have the opportunity to specify these statuses.

    Some statuses are supported in limited distributions.

    OS Fixed Affected Under Investigation Will Not Fix Fix Deferred End of Life Debian \u2713 \u2713 \u2713 \u2713 RHEL \u2713 \u2713 \u2713 \u2713 \u2713 \u2713 Other OSes \u2713 \u2713

    To ignore vulnerabilities with specific statuses, use the --ignore-status <list_of_statuses> option.

    $ trivy image --ignore-status affected,fixed ruby:2.4.0\n
    Result
    2019-05-16T12:50:14.786+0900    INFO    Detecting Debian vulnerabilities...\n\nruby:2.4.0 (debian 8.7)\n=======================\nTotal: 527 (UNKNOWN: 0, LOW: 276, MEDIUM: 83, HIGH: 158, CRITICAL: 10)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502           Library           \u2502  Vulnerability   \u2502 Severity \u2502    Status    \u2502     Installed Version      \u2502 Fixed Version \u2502                            Title                             \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 binutils                    \u2502 CVE-2014-9939    \u2502 CRITICAL \u2502 will_not_fix \u2502 2.25-5                     \u2502               \u2502 binutils: buffer overflow in ihex.c                          \u2502\n\u2502                             \u2502                  \u2502          \u2502              \u2502                            \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2014-9939                    \u2502\n\u2502                             \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u2502                            \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                             \u2502 CVE-2017-6969    \u2502          \u2502              \u2502                            \u2502               \u2502 binutils: Heap-based buffer over-read in readelf when        \u2502\n\u2502                             \u2502                  \u2502          \u2502              \u2502                            \u2502               \u2502 processing corrupt RL78 binaries                             \u2502\n\u2502                             \u2502                  \u2502          \u2502              \u2502                            \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2017-6969                    \u2502\n\u2502                             \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u2502                            \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n...\n

    Tip

    To skip all unfixed vulnerabilities, you can use the --ignore-unfixed flag . It is a shorthand of --ignore-status affected,will_not_fix,fix_deferred,end_of_life. It displays \"fixed\" vulnerabilities only.

    $ trivy image --ignore-unfixed ruby:2.4.0\n
    "},{"location":"docs/configuration/filtering/#suppression","title":"Suppression","text":"

    You can filter the results by

    • Finding IDs
    • Rego
    • Vulnerability Exploitability Exchange (VEX)

    To show the suppressed results, use the --show-suppressed flag.

    Note

    It's exported as ExperimentalModifiedFindings in the JSON output.

    $ trivy image --vex debian11.csaf.vex --ignorefile .trivyignore.yaml --show-suppressed debian:11\n...\n\nSuppressed Vulnerabilities (Total: 9)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502    Library    \u2502 Vulnerability \u2502 Severity \u2502    Status    \u2502                  Statement                  \u2502      Source       \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 libdb5.3      \u2502 CVE-2019-8457 \u2502 CRITICAL \u2502 not_affected \u2502 vulnerable_code_not_in_execute_path         \u2502 CSAF VEX          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 bsdutils      \u2502 CVE-2022-0563 \u2502 LOW      \u2502 ignored      \u2502 Accept the risk                             \u2502 .trivyignore.yaml \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u2502 libblkid1     \u2502               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u2502 libmount1     \u2502               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u2502 libsmartcols1 \u2502               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u2502 libuuid1      \u2502               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u2502 mount         \u2502               \u2502          \u2502              \u2502                                             \u2502                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u2502\n\u2502 tar           \u2502 CVE-2005-2541 \u2502          \u2502              \u2502 The vulnerable configuration is not enabled \u2502                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u2502\n\u2502 util-linux    \u2502 CVE-2022-0563 \u2502          \u2502              \u2502 Accept the risk                             \u2502                   \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/configuration/filtering/#by-finding-ids","title":"By Finding IDs","text":"

    Trivy supports the .trivyignore and .trivyignore.yaml ignore files.

    "},{"location":"docs/configuration/filtering/#trivyignore","title":".trivyignore","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License
    $ cat .trivyignore\n# Accept the risk\nCVE-2018-14618\n\n# Accept the risk until 2023-01-01\nCVE-2019-14697 exp:2023-01-01\n\n# No impact in our settings\nCVE-2019-1543\n\n# Ignore misconfigurations\nAVD-DS-0002\n\n# Ignore secrets\ngeneric-unwanted-rule\naws-account-id\n
    $ trivy image python:3.4-alpine3.9\n
    Result
    2019-05-16T12:53:10.076+0900    INFO    Updating vulnerability database...\n2019-05-16T12:53:28.134+0900    INFO    Detecting Alpine vulnerabilities...\n\npython:3.4-alpine3.9 (alpine 3.9.2)\n===================================\nTotal: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n
    "},{"location":"docs/configuration/filtering/#trivyignoreyaml","title":".trivyignore.yaml","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    When the extension of the specified ignore file is either .yml or .yaml, Trivy will load the file as YAML. For the .trivyignore.yaml file, you can set ignored IDs separately for vulnerabilities, misconfigurations, secrets, or licenses1.

    Available fields:

    Field Required Type Description id \u2713 string The identifier of the vulnerability, misconfiguration, secret, or license1. paths2 string array The list of file paths to ignore. If paths is not set, the ignore finding is applied to all files. purls string array The list of PURLs to ignore packages. If purls is not set, the ignore finding is applied to all packages. This field is currently available only for vulnerabilities. expired_at date (yyyy-mm-dd) The expiration date of the ignore finding. If expired_at is not set, the ignore finding is always valid. statement string The reason for ignoring the finding. (This field is not used for filtering.)
    $ cat .trivyignore.yaml\nvulnerabilities:\n  - id: CVE-2022-40897\n    paths:\n      - \"usr/local/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/METADATA\"\n    statement: Accept the risk\n  - id: CVE-2023-2650\n  - id: CVE-2023-3446\n  - id: CVE-2023-3817\n    purls:\n      - \"pkg:deb/debian/libssl1.1\"\n  - id: CVE-2023-29491\n    expired_at: 2023-09-01\n\nmisconfigurations:\n  - id: AVD-DS-0001\n  - id: AVD-DS-0002\n    paths:\n      - \"docs/Dockerfile\"\n    statement: The image needs root privileges\n\nsecrets:\n  - id: aws-access-key-id\n  - id: aws-secret-access-key\n    paths:\n      - \"foo/bar/aws.secret\"\n\nlicenses:\n  - id: GPL-3.0 # License name is used as ID\n    paths:\n      - \"usr/share/gcc/python/libstdcxx/v6/__init__.py\"\n

    Since this feature is experimental, you must explicitly specify the YAML file path using the --ignorefile flag. Once this functionality is stable, the YAML file will be loaded automatically.

    $ trivy image --ignorefile ./.trivyignore.yaml python:3.9.16-alpine3.16\n
    Result
    2023-08-31T11:10:27.155+0600    INFO    Vulnerability scanning is enabled\n2023-08-31T11:10:27.155+0600    INFO    Secret scanning is enabled\n2023-08-31T11:10:27.155+0600    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning\n2023-08-31T11:10:27.155+0600    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/scanner/secret/#recommendation for faster secret detection\n2023-08-31T11:10:29.164+0600    INFO    Detected OS: alpine\n2023-08-31T11:10:29.164+0600    INFO    Detecting Alpine vulnerabilities...\n2023-08-31T11:10:29.169+0600    INFO    Number of language-specific files: 1\n2023-08-31T11:10:29.170+0600    INFO    Detecting python-pkg vulnerabilities...\n\npython:3.9.16-alpine3.16 (alpine 3.16.5)\n========================================\nTotal: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n
    "},{"location":"docs/configuration/filtering/#by-rego","title":"By Rego","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Rego is a policy language that allows you to express decision logic in a concise syntax. Rego is part of the popular Open Policy Agent (OPA) CNCF project. For advanced filtering, Trivy allows you to use Rego language to filter vulnerabilities.

    Use the --ignore-policy flag which takes a path to a Rego file that defines the filtering policy. The Rego package name must be trivy and it must include a \"rule\" named ignore which determines if each individual scan result should be excluded (ignore=true) or not (ignore=false). The input for the evaluation is each DetectedVulnerability and DetectedMisconfiguration.

    A practical way to observe the filtering policy input in your case, is to run a scan with the --format json option and look at the resulting structure:

    trivy image -f json centos:7\n\n...\n  \"Results\": [\n    {\n      \"Target\": \"centos:7 (centos 7.9.2009)\",\n      \"Class\": \"os-pkgs\",\n      \"Type\": \"centos\",\n      \"Vulnerabilities\": [\n        {\n          \"VulnerabilityID\": \"CVE-2015-5186\",\n          \"PkgID\": \"audit-libs@2.8.5-4.el7.x86_64\",\n          \"PkgName\": \"audit-libs\",\n          \"InstalledVersion\": \"2.8.5-4.el7\",\n          \"Layer\": {\n            \"Digest\": \"sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc\",\n            \"DiffID\": \"sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02\"\n          },\n          \"SeveritySource\": \"redhat\",\n          \"PrimaryURL\": \"https://avd.aquasec.com/nvd/cve-2015-5186\",\n          \"Title\": \"log terminal emulator escape sequences handling\",\n          \"Description\": \"Audit before 2.4.4 in Linux does not sanitize escape characters in filenames.\",\n          \"Severity\": \"MEDIUM\",\n          \"CweIDs\": [\n            \"CWE-20\"\n          ],\n...\n

    Each individual Vulnerability, Misconfiguration, License and Secret (under Results.Vulnerabilities, Results.Misconfigurations, Results.Licenses, Results.Secrets) is evaluated for exclusion or inclusion by the ignore rule.

    The following is a Rego ignore policy that filters out every vulnerability with a specific CWE ID (as seen in the JSON example above):

    package trivy\n\ndefault ignore = false\n\nignore {\n    input.CweIDs[_] == \"CWE-20\"\n}\n
    trivy image --ignore-policy examples/ignore-policies/basic.rego centos:7\n

    For more advanced use cases, there is a built-in Rego library with helper functions that you can import into your policy using: import data.lib.trivy. More info about the helper functions are in the library here.

    You can create a whitelist of checks using Rego, see the detailed example. Additional examples are available here.

    "},{"location":"docs/configuration/filtering/#by-vulnerability-exploitability-exchange-vex","title":"By Vulnerability Exploitability Exchange (VEX)","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License

    Please refer to the VEX documentation for the details.

    1. license name is used as id for .trivyignore.yaml files.\u00a0\u21a9\u21a9

    2. This doesn't work for os package licenses (e.g. apk, dpkg, rpm). For projects which manage dependencies through a dependency file (e.g. go.mod, yarn.lock) path should point to that particular file.\u00a0\u21a9

    "},{"location":"docs/configuration/others/","title":"Others","text":""},{"location":"docs/configuration/others/#enabledisable-scanners","title":"Enable/Disable Scanners","text":"

    You can enable/disable scanners with the --scanners flag.

    Supported values:

    • vuln
    • misconfig
    • secret
    • license

    For example, container image scanning enables vulnerability and secret scanners by default. If you don't need secret scanning, it can be disabled.

    $ trivy image --scanners vuln alpine:3.15\n
    "},{"location":"docs/configuration/others/#exit-code","title":"Exit Code","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    By default, Trivy exits with code 0 even when security issues are detected. Use the --exit-code option if you want to exit with a non-zero exit code.

    $ trivy image --exit-code 1 python:3.4-alpine3.9\n
    Result
    2019-05-16T12:51:43.500+0900    INFO    Updating vulnerability database...\n2019-05-16T12:52:00.387+0900    INFO    Detecting Alpine vulnerabilities...\n\npython:3.4-alpine3.9 (alpine 3.9.2)\n===================================\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)\n\n+---------+------------------+----------+-------------------+---------------+--------------------------------+\n| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |\n+---------+------------------+----------+-------------------+---------------+--------------------------------+\n| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |\n|         |                  |          |                   |               | with long nonces               |\n+---------+------------------+----------+-------------------+---------------+--------------------------------+\n

    This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found.

    $ trivy image --exit-code 0 --severity MEDIUM,HIGH ruby:2.4.0\n$ trivy image --exit-code 1 --severity CRITICAL ruby:2.4.0\n
    "},{"location":"docs/configuration/others/#exit-on-eol","title":"Exit on EOL","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License

    Sometimes you may surprisingly get 0 vulnerabilities in an old image:

    • Enabling --ignore-unfixed option while all packages have no fixed versions.
    • Scanning a rather outdated OS (e.g. Ubuntu 10.04).

    An OS at the end of service/life (EOL) usually gets into this situation, which is definitely full of vulnerabilities. --exit-on-eol can fail scanning on EOL OS with a non-zero code. This flag is available with the following targets.

    • Container images (trivy image)
    • Virtual machine images (trivy vm)
    • SBOM (trivy sbom)
    • Root filesystem (trivy rootfs)
    $ trivy image --exit-on-eol 1 alpine:3.10\n
    Result
    2023-03-01T11:07:15.455+0200    INFO    Vulnerability scanning is enabled\n...\n2023-03-01T11:07:17.938+0200    WARN    This OS version is no longer supported by the distribution: alpine 3.10.9\n2023-03-01T11:07:17.938+0200    WARN    The vulnerability detection may be insufficient because security updates are not provided\n\nalpine:3.10 (alpine 3.10.9)\n===========================\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library  \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                            Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 apk-tools \u2502 CVE-2021-36159 \u2502 CRITICAL \u2502 2.10.6-r0         \u2502 2.10.7-r0     \u2502 libfetch before 2021-07-26, as used in apk-tools, xbps, and \u2502\n\u2502           \u2502                \u2502          \u2502                   \u2502               \u2502 other products, mishandles...                               \u2502\n\u2502           \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2021-36159                  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n2023-03-01T11:07:17.941+0200    ERROR   Detected EOL OS: alpine 3.10.9\n

    This option is useful for CI/CD. The following example will fail when a critical vulnerability is found or the OS is EOSL:

    $ trivy image --exit-code 1 --exit-on-eol 1 --severity CRITICAL alpine:3.16.3\n
    "},{"location":"docs/configuration/reporting/","title":"Reporting","text":""},{"location":"docs/configuration/reporting/#format","title":"Format","text":"

    Trivy supports the following formats:

    • Table
    • JSON
    • SARIF
    • Template
    • SBOM
    • GitHub dependency snapshot
    "},{"location":"docs/configuration/reporting/#table-default","title":"Table (Default)","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713
    $ trivy image -f table golang:1.12-alpine\n
    "},{"location":"docs/configuration/reporting/#show-origins-of-vulnerable-dependencies","title":"Show origins of vulnerable dependencies","text":"Scanner Supported Vulnerability \u2713 Misconfiguration Secret License

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Modern software development relies on the use of third-party libraries. Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph. In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree. To make this task simpler Trivy can show a dependency origin tree with the --dependency-tree flag. This flag is only available with the --format table flag.

    The following OS package managers are currently supported:

    OS Package Managers apk dpkg rpm

    The following languages are currently supported:

    Language File Node.js package-lock.json pnpm-lock.yaml yarn.lock .NET packages.lock.json Python poetry.lock Ruby Gemfile.lock Rust cargo-auditable binaries Go go.mod PHP composer.lock Java pom.xml *gradle.lockfile *.sbt.lock Dart pubspec.lock

    This tree is the reverse of the dependency graph. However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update.

    In table output, it looks like:

    $ trivy fs --severity HIGH,CRITICAL --dependency-tree /path/to/your_node_project\n\npackage-lock.json (npm)\n=======================\nTotal: 2 (HIGH: 1, CRITICAL: 1)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502     Library      \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                           Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 follow-redirects \u2502 CVE-2022-0155  \u2502 HIGH     \u2502 1.14.6            \u2502 1.14.7        \u2502 follow-redirects: Exposure of Private Personal Information \u2502\n\u2502                  \u2502                \u2502          \u2502                   \u2502               \u2502 to an Unauthorized Actor                                   \u2502\n\u2502                  \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-0155                  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 glob-parent      \u2502 CVE-2020-28469 \u2502 CRITICAL \u2502 3.1.0             \u2502 5.1.2         \u2502 nodejs-glob-parent: Regular expression denial of service   \u2502\n\u2502                  \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2020-28469                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nDependency Origin Tree (Reversed)\n=================================\npackage-lock.json\n\u251c\u2500\u2500 follow-redirects@1.14.6, (HIGH: 1, CRITICAL: 0)\n\u2502   \u2514\u2500\u2500 axios@0.21.4\n\u2514\u2500\u2500 glob-parent@3.1.0, (HIGH: 0, CRITICAL: 1)\n    \u2514\u2500\u2500 chokidar@2.1.8\n        \u2514\u2500\u2500 watchpack-chokidar2@2.0.1\n            \u2514\u2500\u2500 watchpack@1.7.5\n                \u2514\u2500\u2500 webpack@4.46.0\n                    \u2514\u2500\u2500 cra-append-sw@2.7.0\n

    Vulnerable dependencies are shown in the top level of the tree. Lower levels show how those vulnerabilities are introduced. In the example above axios@0.21.4 included in the project directly depends on the vulnerable follow-redirects@1.14.6. Also, glob-parent@3.1.0 with some vulnerabilities is included through chain of dependencies that is added by cra-append-sw@2.7.0.

    Then, you can try to update axios@0.21.4 and cra-append-sw@2.7.0 to resolve vulnerabilities in follow-redirects@1.14.6 and glob-parent@3.1.0.

    "},{"location":"docs/configuration/reporting/#json","title":"JSON","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713
    $ trivy image -f json -o results.json golang:1.12-alpine\n
    Result
    2019-05-16T01:46:31.777+0900    INFO    Updating vulnerability database...\n2019-05-16T01:47:03.007+0900    INFO    Detecting Alpine vulnerabilities...\n
    JSON
    [\n  {\n    \"Target\": \"php-app/composer.lock\",\n    \"Vulnerabilities\": null\n  },\n  {\n    \"Target\": \"node-app/package-lock.json\",\n    \"Vulnerabilities\": [\n      {\n        \"VulnerabilityID\": \"CVE-2018-16487\",\n        \"PkgName\": \"lodash\",\n        \"InstalledVersion\": \"4.17.4\",\n        \"FixedVersion\": \"\\u003e=4.17.11\",\n        \"Title\": \"lodash: Prototype pollution in utilities function\",\n        \"Description\": \"A prototype pollution vulnerability was found in lodash \\u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.\",\n        \"Severity\": \"HIGH\",\n        \"References\": [\n          \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487\",\n        ]\n      }\n    ]\n  },\n  {\n    \"Target\": \"trivy-ci-test (alpine 3.7.1)\",\n    \"Vulnerabilities\": [\n      {\n        \"VulnerabilityID\": \"CVE-2018-16840\",\n        \"PkgName\": \"curl\",\n        \"InstalledVersion\": \"7.61.0-r0\",\n        \"FixedVersion\": \"7.61.1-r1\",\n        \"Title\": \"curl: Use-after-free when closing \\\"easy\\\" handle in Curl_close()\",\n        \"Description\": \"A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. \",\n        \"Severity\": \"HIGH\",\n        \"References\": [\n          \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840\",\n        ]\n      },\n      {\n        \"VulnerabilityID\": \"CVE-2019-3822\",\n        \"PkgName\": \"curl\",\n        \"InstalledVersion\": \"7.61.0-r0\",\n        \"FixedVersion\": \"7.61.1-r2\",\n        \"Title\": \"curl: NTLMv2 type-3 header stack buffer overflow\",\n        \"Description\": \"libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. \",\n        \"Severity\": \"HIGH\",\n        \"References\": [\n          \"https://curl.haxx.se/docs/CVE-2019-3822.html\",\n          \"https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E\"\n        ]\n      },\n      {\n        \"VulnerabilityID\": \"CVE-2018-16839\",\n        \"PkgName\": \"curl\",\n        \"InstalledVersion\": \"7.61.0-r0\",\n        \"FixedVersion\": \"7.61.1-r1\",\n        \"Title\": \"curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()\",\n        \"Description\": \"Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.\",\n        \"Severity\": \"HIGH\",\n        \"References\": [\n          \"https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5\",\n        ]\n      },\n      {\n        \"VulnerabilityID\": \"CVE-2018-19486\",\n        \"PkgName\": \"git\",\n        \"InstalledVersion\": \"2.15.2-r0\",\n        \"FixedVersion\": \"2.15.3-r0\",\n        \"Title\": \"git: Improper handling of PATH allows for commands to be executed from the current directory\",\n        \"Description\": \"Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.\",\n        \"Severity\": \"HIGH\",\n        \"References\": [\n          \"https://usn.ubuntu.com/3829-1/\",\n        ]\n      },\n      {\n        \"VulnerabilityID\": \"CVE-2018-17456\",\n        \"PkgName\": \"git\",\n        \"InstalledVersion\": \"2.15.2-r0\",\n        \"FixedVersion\": \"2.15.3-r0\",\n        \"Title\": \"git: arbitrary code execution via .gitmodules\",\n        \"Description\": \"Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \\\"git clone\\\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.\",\n        \"Severity\": \"HIGH\",\n        \"References\": [\n          \"http://www.securitytracker.com/id/1041811\",\n        ]\n      }\n    ]\n  },\n  {\n    \"Target\": \"python-app/Pipfile.lock\",\n    \"Vulnerabilities\": null\n  },\n  {\n    \"Target\": \"ruby-app/Gemfile.lock\",\n    \"Vulnerabilities\": null\n  },\n  {\n    \"Target\": \"rust-app/Cargo.lock\",\n    \"Vulnerabilities\": null\n  }\n]\n

    VulnerabilityID, PkgName, InstalledVersion, and Severity in Vulnerabilities are always filled with values, but other fields might be empty.

    "},{"location":"docs/configuration/reporting/#sarif","title":"SARIF","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    SARIF (Static Analysis Results Interchange Format) complying with SARIF 2.1.0 OASIS standard can be generated with the --format sarif flag.

    $ trivy image --format sarif -o report.sarif  golang:1.12-alpine\n

    This SARIF file can be uploaded to several platforms, including:

    • GitHub code scanning results, and there is a Trivy GitHub Action for automating this process
    • SonarQube
    "},{"location":"docs/configuration/reporting/#github-dependency-snapshot","title":"GitHub dependency snapshot","text":"

    Trivy supports the following packages:

    • OS packages
    • Language-specific packages

    GitHub dependency snapshots can be generated with the --format github flag.

    $ trivy image --format github -o report.gsbom alpine\n

    This snapshot file can be submitted to your GitHub repository.

    "},{"location":"docs/configuration/reporting/#template","title":"Template","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713"},{"location":"docs/configuration/reporting/#custom-template","title":"Custom Template","text":"
    $ trivy image --format template --template \"{{ range . }} {{ .Target }} {{ end }}\" golang:1.12-alpine\n
    Result
    2020-01-02T18:02:32.856+0100    INFO    Detecting Alpine vulnerabilities...\n golang:1.12-alpine (alpine 3.10.2)\n

    You can compute different figures within the template using sprig functions. As an example you can summarize the different classes of issues:

    $ trivy image --format template --template '{{- $critical := 0 }}{{- $high := 0 }}{{- range . }}{{- range .Vulnerabilities }}{{- if  eq .Severity \"CRITICAL\" }}{{- $critical = add $critical 1 }}{{- end }}{{- if  eq .Severity \"HIGH\" }}{{- $high = add $high 1 }}{{- end }}{{- end }}{{- end }}Critical: {{ $critical }}, High: {{ $high }}' golang:1.12-alpine\n
    Result
    Critical: 0, High: 2\n

    For other features of sprig, see the official sprig documentation.

    "},{"location":"docs/configuration/reporting/#load-templates-from-a-file","title":"Load templates from a file","text":"

    You can load templates from a file prefixing the template path with an @.

    $ trivy image --format template --template \"@/path/to/template\" golang:1.12-alpine\n
    "},{"location":"docs/configuration/reporting/#default-templates","title":"Default Templates","text":"

    If Trivy is installed using rpm then default templates can be found at /usr/local/share/trivy/templates.

    "},{"location":"docs/configuration/reporting/#junit","title":"JUnit","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License

    In the following example using the template junit.tpl XML can be generated.

    $ trivy image --format template --template \"@contrib/junit.tpl\" -o junit-report.xml  golang:1.12-alpine\n

    "},{"location":"docs/configuration/reporting/#asff","title":"ASFF","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License

    Trivy also supports an ASFF template for reporting findings to AWS Security Hub

    "},{"location":"docs/configuration/reporting/#html","title":"HTML","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License
    $ trivy image --format template --template \"@contrib/html.tpl\" -o report.html golang:1.12-alpine\n

    The following example shows use of default HTML template when Trivy is installed using rpm.

    $ trivy image --format template --template \"@/usr/local/share/trivy/templates/html.tpl\" -o report.html golang:1.12-alpine\n
    "},{"location":"docs/configuration/reporting/#sbom","title":"SBOM","text":"

    See here for details.

    "},{"location":"docs/configuration/reporting/#output","title":"Output","text":"

    Trivy supports the following output destinations:

    • File
    • Plugin
    "},{"location":"docs/configuration/reporting/#file","title":"File","text":"

    By specifying --output <file_path>, you can output the results to a file. Here is an example:

    $ trivy image --format json --output result.json debian:12\n
    "},{"location":"docs/configuration/reporting/#plugin","title":"Plugin","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Plugins capable of receiving Trivy's results via standard input, called \"output plugin\", can be seamlessly invoked using the --output flag.

    $ trivy <target> [--format <format>] --output plugin=<plugin_name> [--output-plugin-arg <plugin_flags>] <target_name>\n

    This is useful for cases where you want to convert the output into a custom format, or when you want to send the output somewhere. For more details, please check here.

    "},{"location":"docs/configuration/reporting/#converting","title":"Converting","text":"

    To generate multiple reports, you can generate the JSON report first and convert it to other formats with the convert subcommand.

    $ trivy image --format json -o result.json --list-all-pkgs debian:11\n$ trivy convert --format cyclonedx --output result.cdx result.json\n

    Note

    Please note that if you want to convert to a format that requires a list of packages, such as SBOM, you need to add the --list-all-pkgs flag when outputting in JSON.

    Filtering options such as --severity are also available with convert.

    # Output all severities in JSON\n$ trivy image --format json -o result.json --list-all-pkgs debian:11\n\n# Output only critical issues in table format\n$ trivy convert --format table --severity CRITICAL result.json\n

    Note

    JSON reports from \"trivy k8s\" are not yet supported.

    "},{"location":"docs/configuration/skipping/","title":"Skipping Files and Directories","text":"

    This section details ways to specify the files and directories that Trivy should not scan.

    "},{"location":"docs/configuration/skipping/#skip-files","title":"Skip Files","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    By default, Trivy traverses directories and searches for all necessary files for scanning. You can skip files that you don't maintain using the --skip-files flag, or the equivalent Trivy YAML config option.

    Using the --skip-files flag:

    $ trivy image --skip-files \"/Gemfile.lock\" --skip-files \"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock\" quay.io/fluentd_elasticsearch/fluentd:v2.9.0\n

    Using the Trivy YAML configuration:

    image:\n  skip-files:\n    - foo\n    - \"testdata/*/bar\"\n

    It's possible to specify globs as part of the value.

    $ trivy image --skip-files \"./testdata/*/bar\" .\n

    This will skip any file named bar in the subdirectories of testdata.

    $ trivy config --skip-files \"./foo/**/*.tf\" .\n

    This will skip any files with the extension .tf in subdirectories of foo at any depth.

    "},{"location":"docs/configuration/skipping/#skip-directories","title":"Skip Directories","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret \u2713 License \u2713

    By default, Trivy traverses directories and searches for all necessary files for scanning. You can skip directories that you don't maintain using the --skip-dirs flag, or the equivalent Trivy YAML config option.

    Using the --skip-dirs flag:

    $ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs \"/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0\" quay.io/fluentd_elasticsearch/fluentd:v2.9.0\n

    Using the Trivy YAML configuration:

    image:\n  skip-dirs:\n    - foo/bar/\n    - \"**/.terraform\"\n

    It's possible to specify globs as part of the value.

    $ trivy image --skip-dirs \"./testdata/*\" .\n

    This will skip all subdirectories of the testdata directory.

    $ trivy config --skip-dirs \"**/.terraform\" .\n

    This will skip subdirectories at any depth named .terraform/. (Note: this will match ./foo/.terraform or ./foo/bar/.terraform, but not ./.terraform.)

    Tip

    Glob patterns work with any trivy subcommand (image, config, etc.) and can be specified to skip both directories (with --skip-dirs) and files (with --skip-files).

    "},{"location":"docs/configuration/skipping/#advanced-globbing","title":"Advanced globbing","text":"

    Trivy also supports bash style extended glob pattern matching.

    $ trivy image --skip-files \"**/foo\" image:tag\n

    This will skip the file foo that happens to be nested under any parent(s).

    "},{"location":"docs/configuration/skipping/#file-patterns","title":"File patterns","text":"Scanner Supported Vulnerability \u2713 Misconfiguration \u2713 Secret License \u27131

    When a directory is given as an input, Trivy will recursively look for and test all files based on file patterns. The default file patterns are here.

    In addition to the default file patterns, the --file-patterns option takes regexp patterns to look for your files. For example, it may be useful when your file name of Dockerfile doesn't match the default patterns.

    This can be repeated for specifying multiple file patterns.

    A file pattern contains the analyzer it is used for, and the pattern itself, joined by a semicolon. For example:

    --file-patterns \"dockerfile:.*.docker\" --file-patterns \"kubernetes:*.tpl\" --file-patterns \"pip:requirements-.*\\.txt\"\n

    The prefixes are listed here

    1. Only work with the license-full flag)\u00a0\u21a9

    "},{"location":"docs/coverage/","title":"Scanning Coverage","text":"

    Trivy can detect security issues in many different platforms, languages and configuration files. This section gives a general overview of that coverage, and can help answer the frequently asked question \"Does Trivy support X?\". For more detailed information about the specific platforms and languages, check the relevant documentation.

    • OS Packages
    • Language-specific Packages
    • IaC files
    • Kubernetes clusters
    "},{"location":"docs/coverage/kubernetes/","title":"Kubernetes","text":"

    When scanning a Kubernetes cluster, Trivy differentiates between the following:

    1. Cluster infrastructure (e.g api-server, kubelet, addons)
    2. Cluster configuration (e.g Roles, ClusterRoles).
    3. Application workloads (e.g nginx, postgresql).

    Whenever Trivy scans either of these Kubernetes resources, the container image is scanned separately to the Kubernetes resource definition (the YAML manifest) that defines the resource. When scanning any of the above, the container image is scanned separately to the Kubernetes resource definition (the YAML manifest) that defines the resource.

    Container image is scanned for:

    • Vulnerabilities
    • Misconfigurations
    • Exposed secrets

    Kubernetes resource definition is scanned for:

    • Vulnerabilities - partially supported through KBOM scanning
    • Misconfigurations
    • Exposed secrets

    To learn more, please see the documentation for Kubernetes scanning.

    "},{"location":"docs/coverage/iac/","title":"Infrastructure as Code","text":""},{"location":"docs/coverage/iac/#scanner","title":"Scanner","text":"

    Trivy scans Infrastructure as Code (IaC) files for

    • Misconfigurations
    • Secrets
    "},{"location":"docs/coverage/iac/#supported-configurations","title":"Supported configurations","text":"Config type File patterns Kubernetes *.yml, *.yaml, *.json Docker Dockerfile, Containerfile Terraform *.tf, *.tf.json, *.tfvars Terraform Plan tfplan, *.tfplan, *.json CloudFormation *.yml, *.yaml, *.json Azure ARM Template *.json Helm *.yaml, *.tpl, *.tar.gz, etc. YAML *.yaml, *.yml JSON *.json"},{"location":"docs/coverage/iac/azure-arm/","title":"Azure ARM Template","text":"

    Trivy supports the scanners listed in the table below.

    Scanner Supported Misconfiguration \u2713 Secret \u2713

    It supports the following configurations:

    Format Supported ARM template \u2713 Bicep \u27131

    To scan Bicep codes, you need to convert them into ARM templates first.

    az bicep build -f main.bicep\nor\nbicep build main.bicep\n
    "},{"location":"docs/coverage/iac/azure-arm/#misconfiguration","title":"Misconfiguration","text":"

    Trivy recursively searches directories and scans all found Azure ARM templates.

    "},{"location":"docs/coverage/iac/azure-arm/#secret","title":"Secret","text":"

    The secret scan is performed on plain text files, with no special treatment for Azure ARM templates.

    1. Bicep is not natively supported. It needs to be converted into Azure ARM templates.\u00a0\u21a9

    "},{"location":"docs/coverage/iac/cloudformation/","title":"CloudFormation","text":"

    Trivy supports the scanners listed in the table below.

    Scanner Supported Misconfiguration \u2713 Secret \u2713

    It supports the following formats.

    Format Supported JSON \u2713 YAML \u2713"},{"location":"docs/coverage/iac/cloudformation/#misconfiguration","title":"Misconfiguration","text":"

    Trivy recursively searches directories and scans all found CloudFormation files. It evaluates properties, functions, and other elements within CloudFormation files to detect misconfigurations.

    "},{"location":"docs/coverage/iac/cloudformation/#value-overrides","title":"Value Overrides","text":"

    You can provide cf-params with path to CloudFormation Parameters file to Trivy to scan your CloudFormation code with parameters.

    trivy config --cf-params params.json ./infrastructure/cf\n

    You can check a CloudFormation Parameters Example

    "},{"location":"docs/coverage/iac/cloudformation/#secret","title":"Secret","text":"

    The secret scan is performed on plain text files, with no special treatment for CloudFormation.

    "},{"location":"docs/coverage/iac/docker/","title":"Docker","text":"

    Trivy supports the scanners listed in the table below.

    Scanner Supported Misconfiguration \u2713 Secret \u2713

    It supports the following configurations.

    Config Supported Dockerfile \u2713 Containerfile \u2713 Compose -"},{"location":"docs/coverage/iac/docker/#misconfiguration","title":"Misconfiguration","text":"

    Trivy recursively searches directories and scans all found Docker files.

    "},{"location":"docs/coverage/iac/docker/#secret","title":"Secret","text":"

    The secret scan is performed on plain text files, with no special treatment for Dockerfile.

    "},{"location":"docs/coverage/iac/helm/","title":"Helm","text":"

    Trivy supports two types of Helm scanning, templates and packaged charts. The following scanners are supported.

    Format Misconfiguration Secret Template \u2713 \u2713 Chart \u2713 -"},{"location":"docs/coverage/iac/helm/#misconfiguration","title":"Misconfiguration","text":"

    Trivy recursively searches directories and scans all found Helm files.

    It evaluates variables, functions, and other elements within Helm templates and resolve the chart to Kubernetes manifests then run the Kubernetes checks. See here for more details on the built-in checks.

    "},{"location":"docs/coverage/iac/helm/#value-overrides","title":"Value overrides","text":"

    There are a number of options for overriding values in Helm charts. When override values are passed to the Helm scanner, the values will be used during the Manifest rendering process and will become part of the scanned artifact.

    "},{"location":"docs/coverage/iac/helm/#setting-inline-value-overrides","title":"Setting inline value overrides","text":"

    Overrides can be set inline on the command line

    trivy config --helm-set securityContext.runAsUser=0 ./charts/mySql\n
    "},{"location":"docs/coverage/iac/helm/#setting-value-file-overrides","title":"Setting value file overrides","text":"

    Overrides can be in a file that has the key=value set.

    # Example override file (overrides.yaml)\n\nsecurityContext:\n  runAsUser: 0\n
    trivy config --helm-values overrides.yaml ./charts/mySql\n
    "},{"location":"docs/coverage/iac/helm/#setting-value-as-explicit-string","title":"Setting value as explicit string","text":"

    the --helm-set-string is the same as --helm-set but explicitly retains the value as a string

    trivy config --helm-set-string name=false ./infrastructure/tf\n
    "},{"location":"docs/coverage/iac/helm/#setting-specific-values-from-files","title":"Setting specific values from files","text":"

    Specific override values can come from specific files

    trivy config --helm-set-file environment=dev.values.yaml ./charts/mySql\n
    "},{"location":"docs/coverage/iac/helm/#secret","title":"Secret","text":"

    The secret scan is performed on plain text files, with no special treatment for Helm. Secret scanning is not conducted on the contents of packaged Charts, such as tar or tar.gz.

    "},{"location":"docs/coverage/iac/kubernetes/","title":"Kubernetes","text":"

    Trivy supports the scanners listed in the table below.

    Scanner Supported Misconfiguration \u2713 Secret \u2713

    In addition to raw YAML and JSON, it supports the following templates:

    Template Supported Helm \u2713 Kustomize \u27131

    Note

    Trivy does not support Kustomize overlays, so it scans files defined in the base. Or, you can scan the output of kustomize build.

    "},{"location":"docs/coverage/iac/kubernetes/#misconfiguration","title":"Misconfiguration","text":"

    Trivy recursively searches directories and scans all found Kubernetes files.

    "},{"location":"docs/coverage/iac/kubernetes/#secret","title":"Secret","text":"

    The secret scan is performed on plain text files, with no special treatment for Kubernetes. This means that Base64 encoded secrets are not scanned, and only secrets written in plain text are detected.

    1. Kustomize is not natively supported.\u00a0\u21a9

    "},{"location":"docs/coverage/iac/terraform/","title":"Terraform","text":"

    Trivy supports the scanners listed in the table below.

    Scanner Supported Misconfiguration \u2713 Secret \u2713

    It supports the following formats:

    Format Supported JSON \u2713 HCL \u2713 Plan Snapshot \u2713 Plan JSON \u2713

    Trivy can scan Terraform Plan files (snapshots) or their JSON representations. To create a Terraform Plan and scan it, run the following command:

    terraform plan --out tfplan\ntrivy config tfplan\n

    To scan a Terraform Plan representation in JSON format, run the following command:

    terraform show -json tfplan > tfplan.json\ntrivy config tfplan.json\n

    "},{"location":"docs/coverage/iac/terraform/#misconfiguration","title":"Misconfiguration","text":"

    Trivy recursively searches directories and scans all found Terraform files. It also evaluates variables, imports, and other elements within Terraform files to detect misconfigurations.

    "},{"location":"docs/coverage/iac/terraform/#value-overrides","title":"Value Overrides","text":"

    You can provide tf-vars files to Trivy to override default values specified in the Terraform HCL code.

    trivy config --tf-vars dev.terraform.tfvars ./infrastructure/tf\n
    "},{"location":"docs/coverage/iac/terraform/#exclude-downloaded-terraform-modules","title":"Exclude Downloaded Terraform Modules","text":"

    By default, downloaded modules are also scanned. If you don't want to scan them, you can use the --tf-exclude-downloaded-modules flag.

    trivy config --tf-exclude-downloaded-modules ./configs\n
    "},{"location":"docs/coverage/iac/terraform/#secret","title":"Secret","text":"

    The secret scan is performed on plain text files, with no special treatment for Terraform.

    "},{"location":"docs/coverage/iac/terraform/#limitations","title":"Limitations","text":""},{"location":"docs/coverage/iac/terraform/#terraform-plan-json","title":"Terraform Plan JSON","text":""},{"location":"docs/coverage/iac/terraform/#for-each-and-count-objects-in-expression","title":"For each and count objects in expression","text":"

    The plan created by Terraform does not provide complete information about references in expressions that use each or count objects. For this reason, in some situations it is not possible to establish references between resources that are needed for checks when detecting misconfigurations. An example of such a configuration is:

    locals {\n  buckets = toset([\"test\"])\n}\n\nresource \"aws_s3_bucket\" \"this\" {\n  for_each = local.buckets\n  bucket = each.key\n}\n\nresource \"aws_s3_bucket_acl\" \"this\" {\n  for_each = local.buckets\n  bucket = aws_s3_bucket.this[each.key].id\n  acl    = \"private\"\n}\n

    With this configuration, the plan will not contain information about which attribute of the aws_s3_bucket resource is referenced by the aws_s3_bucket_acl resource.

    See more here.

    "},{"location":"docs/coverage/language/","title":"Programming Language","text":"

    Trivy supports programming languages for

    • SBOM
    • Vulnerabilities
    • Licenses
    "},{"location":"docs/coverage/language/#supported-languages","title":"Supported languages","text":"

    The files analyzed vary depending on the target. This is because Trivy primarily categorizes targets into two groups:

    • Pre-build
    • Post-build

    If the target is a pre-build project, like a code repository, Trivy will analyze files used for building, such as lock files. On the other hand, when the target is a post-build artifact, like a container image, Trivy will analyze installed package metadata like .gemspec, binary files, and so on.

    Language File Image4 Rootfs5 Filesystem6 Repository7 Ruby Gemfile.lock - - \u2705 \u2705 gemspec \u2705 \u2705 - - Python Pipfile.lock - - \u2705 \u2705 poetry.lock - - \u2705 \u2705 requirements.txt - - \u2705 \u2705 egg package1 \u2705 \u2705 - - wheel package2 \u2705 \u2705 - - PHP composer.lock - - \u2705 \u2705 installed.json \u2705 \u2705 - - Node.js package-lock.json - - \u2705 \u2705 yarn.lock - - \u2705 \u2705 pnpm-lock.yaml - - \u2705 \u2705 package.json \u2705 \u2705 - - .NET packages.lock.json \u2705 \u2705 \u2705 \u2705 packages.config \u2705 \u2705 \u2705 \u2705 .deps.json \u2705 \u2705 \u2705 \u2705 *Packages.props9 \u2705 \u2705 \u2705 \u2705 Java JAR/WAR/PAR/EAR3 \u2705 \u2705 - - pom.xml - - \u2705 \u2705 *gradle.lockfile - - \u2705 \u2705 *.sbt.lock - - \u2705 \u2705 Go Binaries built by Go \u2705 \u2705 - - go.mod - - \u2705 \u2705 Rust Cargo.lock \u2705 \u2705 \u2705 \u2705 Binaries built with cargo-auditable \u2705 \u2705 - - C/C++ conan.lock - - \u2705 \u2705 Elixir mix.lock8 - - \u2705 \u2705 Dart pubspec.lock - - \u2705 \u2705 Swift Podfile.lock - - \u2705 \u2705 Package.resolved - - \u2705 \u2705 Julia Manifest.toml \u2705 \u2705 \u2705 \u2705

    The path of these files does not matter.

    Example: Dockerfile

    1. *.egg-info, *.egg-info/PKG-INFO, *.egg and EGG-INFO/PKG-INFO \u21a9

    2. .dist-info/META-DATA \u21a9

    3. *.jar, *.war, *.par and *.ear \u21a9

    4. \u2705 means \"enabled\" and - means \"disabled\" in the image scanning\u00a0\u21a9

    5. \u2705 means \"enabled\" and - means \"disabled\" in the rootfs scanning\u00a0\u21a9

    6. \u2705 means \"enabled\" and - means \"disabled\" in the filesystem scanning\u00a0\u21a9

    7. \u2705 means \"enabled\" and - means \"disabled\" in the git repository scanning\u00a0\u21a9

    8. To scan a filename other than the default filename use file-patterns \u21a9

    9. Directory.Packages.props and legacy Packages.props file names are supported\u00a0\u21a9

    "},{"location":"docs/coverage/language/c/","title":"C/C++","text":"

    Trivy supports Conan C/C++ Package Manager (v1 and v2 with limitations).

    The following scanners are supported.

    Package manager SBOM Vulnerability License Conan \u2713 \u2713 \u27131

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Conan (lockfile v1) conan.lock2 \u2713 Excluded \u2713 \u2713 Conan (lockfile v2) conan.lock2 \u2713 3 Excluded - \u2713"},{"location":"docs/coverage/language/c/#conan","title":"Conan","text":"

    In order to detect dependencies, Trivy searches for conan.lock1.

    "},{"location":"docs/coverage/language/c/#licenses","title":"Licenses","text":"

    The Conan lock file doesn't contain any license information. To obtain licenses we parse the conanfile.py files from the conan v1 cache directory and conan v2 cache directory. To correctly detection licenses, ensure that the cache directory contains all dependencies used.

    1. The local cache should contain the dependencies used. See licenses.\u00a0\u21a9\u21a9

    2. conan.lock is default name. To scan a custom filename use file-patterns.\u00a0\u21a9\u21a9

    3. For conan.lock in version 2, indirect dependencies are included in analysis but not flagged explicitly in dependency tree\u00a0\u21a9

    "},{"location":"docs/coverage/language/dart/","title":"Dart","text":"

    Trivy supports Dart.

    The following scanners are supported.

    Package manager SBOM Vulnerability License Dart \u2713 \u2713 -

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Detection Priority Dart pubspec.lock \u2713 Included \u2713 - \u2713"},{"location":"docs/coverage/language/dart/#dart_1","title":"Dart","text":"

    In order to detect dependencies, Trivy searches for pubspec.lock.

    Trivy marks indirect dependencies, but pubspec.lock file doesn't have options to separate root and dev transitive dependencies. So Trivy includes all dependencies in report.

    "},{"location":"docs/coverage/language/dart/#sdk-dependencies","title":"SDK dependencies","text":"

    Dart uses version 0.0.0 for SDK dependencies (e.g. Flutter). It is not possible to accurately determine the versions of these dependencies. Trivy just treats them as 0.0.0.

    If --detection-priority comprehensive is passed, Trivy uses the minimum version of the constraint for the SDK. For example, in the following case, the version of flutter would be 3.3.0:

    flutter:\n  dependency: \"direct main\"\n  description: flutter\n  source: sdk\n  version: \"0.0.0\"\nsdks:\n  dart: \">=2.18.0 <3.0.0\"\n  flutter: \"^3.3.0\"\n
    "},{"location":"docs/coverage/language/dart/#dependency-tree","title":"Dependency tree","text":"

    To build dependency tree Trivy parses cache directory. Currently supported default directories and PUB_CACHE environment (absolute path only).

    Note

    Make sure the cache directory contains all the dependencies installed in your application. To download missing dependencies, use dart pub get command.

    "},{"location":"docs/coverage/language/dotnet/","title":".NET","text":"

    Trivy supports .NET core and NuGet package managers.

    The following scanners are supported.

    Artifact SBOM Vulnerability License .Net Core \u2713 \u2713 - NuGet \u2713 \u2713 \u2713

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position .Net Core *.deps.json \u2713 Excluded - \u2713 NuGet packages.config \u2713 Excluded - - NuGet *Packages.props - Excluded - - NuGet packages.lock.json \u2713 Included \u2713 \u2713"},{"location":"docs/coverage/language/dotnet/#depsjson","title":"*.deps.json","text":"

    Trivy parses *.deps.json files. Trivy currently excludes dev dependencies from the report.

    Note

    Trivy only includes runtime dependencies in the report.

    "},{"location":"docs/coverage/language/dotnet/#packagesconfig","title":"packages.config","text":"

    Trivy only finds dependency names and versions from packages.config files. To build dependency graph, it is better to use packages.lock.json files.

    "},{"location":"docs/coverage/language/dotnet/#packagesprops","title":"*Packages.props","text":"

    Trivy parses *Packages.props files. Both legacy Packages.props and modern Directory.Packages.props are supported.

    "},{"location":"docs/coverage/language/dotnet/#license-detection","title":"license detection","text":"

    packages.config files don't have information about the licenses used. Trivy uses *.nuspec files from global packages folder to detect licenses.

    Note

    The licenseUrl field is deprecated. Trivy doesn't parse this field and only checks the license field (license expression type only).

    Currently only the default path and NUGET_PACKAGES environment variable are supported.

    "},{"location":"docs/coverage/language/dotnet/#packageslockjson","title":"packages.lock.json","text":"

    Don't forgot to enable lock files in your project.

    Tip

    Please make sure your lock file is up-to-date after modifying dependencies.

    "},{"location":"docs/coverage/language/dotnet/#license-detection_1","title":"license detection","text":"

    Same as packages.config

    "},{"location":"docs/coverage/language/elixir/","title":"Elixir","text":"

    Trivy supports Hex repository for Elixir.

    The following scanners are supported.

    Package manager SBOM Vulnerability License hex \u2713 \u2713 -

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position hex mix.lock1 \u2713 Excluded - \u2713"},{"location":"docs/coverage/language/elixir/#hex","title":"Hex","text":"

    In order to detect dependencies, Trivy searches for mix.lock1.

    Configure your project to use mix.lock1 file.

    1. mix.lock is default name. To scan a custom filename use file-patterns \u21a9\u21a9\u21a9

    "},{"location":"docs/coverage/language/golang/","title":"Go","text":""},{"location":"docs/coverage/language/golang/#overview","title":"Overview","text":"

    Trivy supports two types of Go scanning, Go Modules and binaries built by Go.

    The following scanners are supported.

    Artifact SBOM Vulnerability License Modules \u2713 \u2713 \u2713 Binaries \u2713 \u2713 -

    The table below provides an outline of the features Trivy offers.

    Artifact Offline1 Dev dependencies Dependency graph Stdlib Detection Priority Modules \u2705 Include \u2705 \u2705 \u2705 Binaries \u2705 Exclude - \u2705 Not needed

    Note

    When scanning Go projects (go.mod or binaries built with Go), Trivy scans only dependencies of the project, and does not detect vulnerabilities of application itself. For example, when scanning the Docker project (Docker's source code with go.mod or the Docker binary), Trivy might find vulnerabilities in Go modules that Docker depends on, but won't find vulnerabilities of Docker itself. Moreover, when scanning the Trivy project, which happens to use Docker, Docker's vulnerabilities might be detected as dependencies of Trivy.

    "},{"location":"docs/coverage/language/golang/#data-sources","title":"Data Sources","text":"

    The data sources are listed here. Trivy uses Go Vulnerability Database for standard library and uses GitHub Advisory Database for other Go modules.

    "},{"location":"docs/coverage/language/golang/#go-module","title":"Go Module","text":"

    Depending on Go versions, the required files are different.

    Version Required files Offline >=1.17 go.mod \u2705 <1.17 go.mod, go.sum \u2705

    In Go 1.17+ projects, Trivy uses go.mod for direct/indirect dependencies. On the other hand, it uses go.mod for direct dependencies and go.sum for indirect dependencies in Go 1.16 or less.

    Go 1.17+ holds actually needed indirect dependencies in go.mod, and it reduces false detection. go.sum in Go 1.16 or less contains all indirect dependencies that are even not needed for compiling. If you want to have better detection, please consider updating the Go version in your project.

    Note

    The Go version doesn't mean your Go tool version, but the Go version in your go.mod.

    module github.com/aquasecurity/trivy\n\ngo 1.18\n\nrequire (\n        github.com/CycloneDX/cyclonedx-go v0.5.0\n        ...\n)\n

    To update the Go version in your project, you need to run the following command.

    $ go mod tidy -go=1.18\n
    "},{"location":"docs/coverage/language/golang/#gomod-main","title":"Main Module","text":"

    Trivy scans only dependencies of the project, and does not detect vulnerabilities of the main module. For example, when scanning the Docker project (Docker's source code with go.mod), Trivy might find vulnerabilities in Go modules that Docker depends on, but won't find vulnerabilities of Docker itself. Moreover, when scanning the Trivy project, which happens to use Docker, Docker's vulnerabilities might be detected as dependencies of Trivy.

    "},{"location":"docs/coverage/language/golang/#gomod-stdlib","title":"Standard Library","text":"

    Detecting the version of Go used in the project can be tricky. The go.mod file include hints that allows Trivy to guess the Go version but it eventually depends on the Go tool version in the build environment. Since this strategy is not fully deterministic and accurate, it is enabled only in --detection-priority comprehensive mode. When enabled, Trivy detects stdlib version as the minimum between the go and the toolchain directives in the go.mod file. To obtain reproducible scan results Trivy doesn't check the locally installed version of Go.

    Note

    Trivy detects stdlib only for Go 1.21 or higher.

    The version from the go line (for Go 1.20 or early) is not a minimum required version. For details, see this.

    It possibly produces false positives. See the caveat for details.

    "},{"location":"docs/coverage/language/golang/#license","title":"License","text":"

    To identify licenses, you need to download modules to local cache beforehand, such as go mod download, go mod tidy, etc. Trivy traverses $GOPATH/pkg/mod and collects those extra information.

    "},{"location":"docs/coverage/language/golang/#dependency-graph","title":"Dependency Graph","text":"

    Same as licenses, you need to download modules to local cache beforehand.

    "},{"location":"docs/coverage/language/golang/#go-binary","title":"Go Binary","text":"

    Trivy scans Go binaries when it encounters them during scans such as container images or file systems. When scanning binaries built by Go, Trivy finds dependencies and Go version information as embedded in the binary by Go tool at build time.

    $ trivy rootfs ./your_binary\n

    Note

    It doesn't work with UPX-compressed binaries.

    "},{"location":"docs/coverage/language/golang/#main-module","title":"Main Module","text":"

    Go binaries installed using the go install command contains correct (semver) version for the main module and therefor are detected by Trivy. In other cases, Go uses the (devel) version2. In this case, Trivy will attempt to parse any -ldflags as it's a common practice to pass versions this way. If unsuccessful, the version will be empty3.

    "},{"location":"docs/coverage/language/golang/#go-binary-stdlib","title":"Standard Library","text":"

    Trivy detects the Go version used to compile the binary and detects its vulnerabilities in the standard libraries. It possibly produces false positives. See the caveat for details.

    "},{"location":"docs/coverage/language/golang/#caveats","title":"Caveats","text":""},{"location":"docs/coverage/language/golang/#stdlib-vulnerabilities","title":"Stdlib Vulnerabilities","text":"

    Trivy does not know if or how you use stdlib functions, therefore it is possible that stdlib vulnerabilities are not applicable to your use case. There are a few ways to mitigate this:

    1. Analyze vulnerability reachability using a tool such as govulncheck. This will ensure that reported vulnerabilities are applicable to your project.
    2. Suppress non-applicable vulnerabilities using either ignore file for self-use or VEX Hub for public use.
    "},{"location":"docs/coverage/language/golang/#empty-version","title":"Empty Version","text":"

    As described in the Main Module section, the main module of Go binaries might have an empty version. Also, dependencies replaced with local ones will have an empty version.

    1. It doesn't require the Internet access.\u00a0\u21a9

    2. See https://github.com/aquasecurity/trivy/issues/1837#issuecomment-1832523477 \u21a9

    3. See https://github.com/golang/go/issues/63432#issuecomment-1751610604 \u21a9

    "},{"location":"docs/coverage/language/java/","title":"Java","text":"

    Trivy supports four types of Java scanning: JAR/WAR/PAR/EAR, pom.xml, *gradle.lockfile and *.sbt.lock files.

    Each artifact supports the following scanners:

    Artifact SBOM Vulnerability License JAR/WAR/PAR/EAR \u2713 \u2713 - pom.xml \u2713 \u2713 \u2713 *gradle.lockfile \u2713 \u2713 \u2713 *.sbt.lock \u2713 \u2713 -

    The following table provides an outline of the features Trivy offers.

    Artifact Internet access Dev dependencies Dependency graph Position Detection Priority JAR/WAR/PAR/EAR Trivy Java DB Include - - Not needed pom.xml Maven repository 1 Exclude \u2713 \u27137 - *gradle.lockfile - Exclude \u2713 \u2713 Not needed *.sbt.lock - Exclude - \u2713 Not needed

    These may be enabled or disabled depending on the target. See here for the detail.

    "},{"location":"docs/coverage/language/java/#jarwarparear","title":"JAR/WAR/PAR/EAR","text":"

    To find information about your JAR2 file, Trivy parses pom.properties and MANIFEST.MF files in your JAR2 file and takes required properties3.

    If those files don't exist or don't contain enough information - Trivy will try to find this JAR2 file in trivy-java-db. The Java DB will be automatically downloaded/updated when any JAR2 file is found. It is stored in the cache directory.

    EXPERIMENTAL

    Finding JARs in trivy-java-db is an experimental function.

    Base JAR2 may contain inner JARs2 within itself. To find information about these JARs2, the same logic is used as for the base JAR2.

    table format only contains the name of root JAR2 . To get the full path to inner JARs2 use the json format.

    "},{"location":"docs/coverage/language/java/#pomxml","title":"pom.xml","text":"

    Trivy parses your pom.xml file and tries to find files with dependencies from these local locations.

    • project directory4
    • relativePath field5
    • local repository directory6.
    "},{"location":"docs/coverage/language/java/#remote-repositories","title":"remote repositories","text":"

    If your machine doesn't have the necessary files - Trivy tries to find the information about these dependencies in the remote repositories:

    • repositories from pom files
    • maven central repository

    Trivy reproduces Maven's repository selection and priority:

    • for snapshot artifacts:
      • check only snapshot repositories from pom files (if exists)
    • for other artifacts:
      • check release repositories from pom files (if exists)
      • check maven central

    Note

    Trivy only takes information about packages. We don't take a list of vulnerabilities for packages from the maven repository. Information about data sources for Java you can see here.

    You can disable connecting to the maven repository with the --offline-scan flag. The --offline-scan flag does not affect the Trivy database. The vulnerability database will be downloaded anyway.

    Warning

    Trivy may skip some dependencies (that were not found on your local machine) when the --offline-scan flag is passed.

    "},{"location":"docs/coverage/language/java/#supported-scopes","title":"supported scopes","text":"

    Trivy only scans import, compile, runtime and empty maven scopes. Other scopes and Optional dependencies are not currently being analyzed.

    "},{"location":"docs/coverage/language/java/#empty-dependency-version","title":"empty dependency version","text":"

    There are cases when Trivy cannot determine the version of dependencies:

    • Unable to determine the version from the parent because the parent is not reachable;
    • The dependency uses a hard requirement with more than one version.

    In these cases, Trivy uses an empty version for the dependency.

    Warning

    Trivy doesn't detect child dependencies for dependencies without a version.

    "},{"location":"docs/coverage/language/java/#maven-invoker-plugin","title":"maven-invoker-plugin","text":"

    Typically, the integration tests directory (**/[src|target]/it/*/pom.xml) of maven-invoker-plugin doesn't contain actual pom.xml files and should be skipped to avoid noise.

    Trivy marks dependencies from these files as the development dependencies and skip them by default. If you need to show them, use the --include-dev-deps flag.

    "},{"location":"docs/coverage/language/java/#gradlelock","title":"Gradle.lock","text":"

    gradle.lock files only contain information about used dependencies.

    Note

    All necessary files are checked locally. Gradle file scanning doesn't require internet access.

    "},{"location":"docs/coverage/language/java/#dependency-tree","title":"Dependency-tree","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy finds child dependencies from *.pom files in the cache8 directory.

    But there is no reliable way to determine direct dependencies (even using other files). Therefore, we mark all dependencies as indirect to use logic to guess direct dependencies and build a dependency tree.

    "},{"location":"docs/coverage/language/java/#licenses","title":"Licenses","text":"

    Trity also can detect licenses for dependencies.

    Make sure that you have cache8 directory to find licenses from *.pom dependency files.

    "},{"location":"docs/coverage/language/java/#sbt","title":"SBT","text":"

    build.sbt.lock files only contain information about used dependencies. This requires a lockfile generated using the sbt-dependency-lock plugin.

    Note

    All necessary files are checked locally. SBT file scanning doesn't require internet access.

    1. Uses maven repository to get information about dependencies. Internet access required.\u00a0\u21a9

    2. It means *.jar, *.war, *.par and *.ear file\u00a0\u21a9\u21a9\u21a9\u21a9\u21a9\u21a9\u21a9\u21a9\u21a9\u21a9

    3. ArtifactID, GroupID and Version \u21a9

    4. e.g. when parent pom.xml file has ../pom.xml path\u00a0\u21a9

    5. When you use dependency path in relativePath field in pom.xml file\u00a0\u21a9

    6. /Users/<username>/.m2/repository (for Linux and Mac) and C:/Users/<username>/.m2/repository (for Windows) by default\u00a0\u21a9

    7. To avoid confusion, Trivy only finds locations for direct dependencies from the base pom.xml file.\u00a0\u21a9

    8. The supported directories are $GRADLE_USER_HOME/caches and $HOME/.gradle/caches (%HOMEPATH%\\.gradle\\caches for Windows).\u00a0\u21a9\u21a9

    "},{"location":"docs/coverage/language/julia/","title":"Julia","text":""},{"location":"docs/coverage/language/julia/#features","title":"Features","text":"

    Trivy supports Pkg.jl, which is the Julia package manager. The following scanners are supported.

    Package manager SBOM Vulnerability License Pkg.jl \u2713 - -

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies License Dependency graph Position Pkg.jl Manifest.toml \u2705 Excluded1 - \u2705 \u2705"},{"location":"docs/coverage/language/julia/#pkgjl","title":"Pkg.jl","text":"

    Trivy searches for Manifest.toml to detect dependencies.

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in Manifest.toml, Trivy parses Project.toml, which should be located next to Project.toml. If you want to see the dependency tree, please ensure that Project.toml is present.

    Scanning Manifest.toml and Project.toml together also removes developer dependencies.

    Dependency extensions are currently ignored.

    1. When you scan Manifest.toml and Project.toml together.\u00a0\u21a9

    "},{"location":"docs/coverage/language/nodejs/","title":"Node.js","text":"

    Trivy supports four types of Node.js package managers: npm, Yarn, pnpm and Bun1.

    The following scanners are supported.

    Artifact SBOM Vulnerability License npm \u2713 \u2713 \u2713 Yarn \u2713 \u2713 \u2713 pnpm \u2713 \u2713 \u2713 Bun \u2713 \u2713 \u2713

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position npm package-lock.json \u2713 Excluded \u2713 \u2713 Yarn yarn.lock \u2713 Excluded \u2713 \u2713 pnpm pnpm-lock.yaml \u2713 Excluded \u2713 - Bun yarn.lock \u2713 Excluded \u2713 \u2713

    In addition, Trivy scans installed packages with package.json.

    File Dependency graph Position License package.json - - \u2705

    These may be enabled or disabled depending on the target. See here for the detail.

    "},{"location":"docs/coverage/language/nodejs/#package-managers","title":"Package managers","text":"

    Trivy parses your files generated by package managers in filesystem/repository scanning.

    Tip

    Please make sure your lock file is up-to-date after modifying package.json.

    "},{"location":"docs/coverage/language/nodejs/#npm","title":"npm","text":"

    Trivy parses package-lock.json. To identify licenses, you need to download dependencies to node_modules beforehand. Trivy analyzes node_modules for licenses.

    By default, Trivy doesn't report development dependencies. Use the --include-dev-deps flag to include them.

    "},{"location":"docs/coverage/language/nodejs/#yarn","title":"Yarn","text":"

    Trivy parses yarn.lock, which doesn't contain information about development dependencies. Trivy also uses package.json file to handle aliases.

    To exclude devDependencies and allow aliases, package.json also needs to be present next to yarn.lock.

    Trivy analyzes .yarn (Yarn 2+) or node_modules (Yarn Classic) folder next to the yarn.lock file to detect licenses.

    By default, Trivy doesn't report development dependencies. Use the --include-dev-deps flag to include them.

    "},{"location":"docs/coverage/language/nodejs/#pnpm","title":"pnpm","text":"

    Trivy parses pnpm-lock.yaml, then finds production dependencies and builds a tree of dependencies with vulnerabilities. To identify licenses, you need to download dependencies to node_modules beforehand. Trivy analyzes node_modules for licenses.

    "},{"location":"docs/coverage/language/nodejs/#lock-file-v9-version","title":"lock file v9 version","text":"

    Trivy supports Dev field for pnpm-lock.yaml v9 or later. Use the --include-dev-deps flag to include the developer's dependencies in the result.

    "},{"location":"docs/coverage/language/nodejs/#bun","title":"Bun","text":"

    Trivy supports scanning yarn.lock files generated by Bun. You can use the command bun install -y to generate a Yarn-compatible yarn.lock.

    Note

    bun.lockb is not supported.

    "},{"location":"docs/coverage/language/nodejs/#packages","title":"Packages","text":"

    Trivy parses the manifest files of installed packages in container image scanning and so on.

    "},{"location":"docs/coverage/language/nodejs/#packagejson","title":"package.json","text":"

    Trivy searches for package.json files under node_modules and identifies installed packages. It only extracts package names, versions and licenses for those packages.

    1. yarn.lock must be generated\u00a0\u21a9

    "},{"location":"docs/coverage/language/php/","title":"PHP","text":"

    Trivy supports Composer, which is a tool for dependency management in PHP.

    The following scanners are supported.

    Package manager SBOM Vulnerability License Composer \u2713 \u2713 \u2713

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Composer composer.lock \u2713 Excluded \u2713 \u2713 Composer installed.json \u2713 Excluded - \u2713"},{"location":"docs/coverage/language/php/#composerlock","title":"composer.lock","text":"

    In order to detect dependencies, Trivy searches for composer.lock.

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in composer.lock, Trivy parses composer.json, which should be located next to composer.lock. If you want to see the dependency tree, please ensure that composer.json is present.

    "},{"location":"docs/coverage/language/php/#installedjson","title":"installed.json","text":"

    Trivy also supports dependency detection for installed.json files. By default, you can find this file at path_to_app/vendor/composer/installed.json.

    "},{"location":"docs/coverage/language/python/","title":"Python","text":"

    Trivy supports three types of Python package managers: pip, Pipenv and Poetry. The following scanners are supported for package managers.

    Package manager SBOM Vulnerability License pip \u2713 \u2713 \u2713 Pipenv \u2713 \u2713 - Poetry \u2713 \u2713 -

    In addition, Trivy supports three formats of Python packages: egg, wheel and conda. The following scanners are supported for Python packages.

    Packaging SBOM Vulnerability License Egg \u2713 \u2713 \u2713 Wheel \u2713 \u2713 \u2713 Conda \u2713 - -

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Detection Priority pip requirements.txt - Include - \u2713 \u2713 Pipenv Pipfile.lock \u2713 Include - \u2713 Not needed Poetry poetry.lock \u2713 Exclude \u2713 - Not needed Packaging Dependency graph Egg \u2713 Wheel \u2713

    These may be enabled or disabled depending on the target. See here for the detail.

    "},{"location":"docs/coverage/language/python/#package-managers","title":"Package managers","text":"

    Trivy parses your files generated by package managers in filesystem/repository scanning.

    "},{"location":"docs/coverage/language/python/#pip","title":"pip","text":""},{"location":"docs/coverage/language/python/#dependency-detection","title":"Dependency detection","text":"

    By default, Trivy only parses version specifiers with == comparison operator and without .*.

    Using the --detection-priority comprehensive option ensures that the tool establishes a minimum version, which is particularly useful in scenarios where identifying the exact version is challenging. In such case Trivy parses specifiers >=,~= and a trailing .*.

    keyring >= 4.1.1            # Minimum version 4.1.1\nMopidy-Dirble ~= 1.1        # Minimum version 1.1\npython-gitlab==2.0.*        # Minimum version 2.0.0\n
    Also, there is a way to convert unsupported version specifiers - use the pip freeze command.

    $ cat requirements.txt \nboto3~=1.24.60\nclick>=8.0\njson-fix==0.5.*\n$ pip install -r requirements.txt\n...\n$ pip freeze > requirements.txt \n$ cat requirements.txt \nboto3==1.24.96\nbotocore==1.27.96\nclick==8.1.7\njmespath==1.0.1\njson-fix==0.5.2\npython-dateutil==2.8.2\ns3transfer==0.6.2\nsetuptools==69.0.2\nsix==1.16.0\nurllib3==1.26.18\nwheel==0.42.0\n

    requirements.txt files usually contain only the direct dependencies and not contain the transitive dependencies. Therefore, Trivy scans only for the direct dependencies with requirements.txt.

    To detect transitive dependencies as well, you need to generate requirements.txt with pip freeze.

    $ cat requirements.txt # it will only find `requests@2.28.2`.\nrequests==2.28.2 \n$ pip install -r requirements.txt\n...\n\n$ pip freeze > requirements.txt   \n$ cat requirements.txt # it will also find the transitive dependencies of `requests@2.28.2`.\ncertifi==2022.12.7\ncharset-normalizer==3.1.0\nidna==3.4\nPyJWT==2.1.0\nrequests==2.28.2\nurllib3==1.26.15\n

    pip freeze also helps to resolve extras(optional) dependencies (like package[extras]=0.0.0).

    requirements.txt files don't contain information about dependencies used for development. Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

    "},{"location":"docs/coverage/language/python/#license-detection","title":"License detection","text":"

    requirements.txt files don't contain information about licenses. Therefore, Trivy checks METADATA files from lib/site-packages directory.

    Trivy uses 3 ways to detect site-packages directory:

    • Checks VIRTUAL_ENV environment variable.
    • Detects path to python1 binary and checks ../lib/pythonX.Y/site-packages directory.
    • Detects path to python1 binary and checks ../../lib/site-packages directory.
    "},{"location":"docs/coverage/language/python/#pipenv","title":"Pipenv","text":"

    Trivy parses Pipfile.lock. Pipfile.lock files don't contain information about dependencies used for development. Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

    License detection is not supported for Pipenv.

    "},{"location":"docs/coverage/language/python/#poetry","title":"Poetry","text":"

    Trivy uses poetry.lock to identify dependencies and find vulnerabilities. To build the correct dependency graph, pyproject.toml also needs to be present next to poetry.lock.

    License detection is not supported for Poetry.

    "},{"location":"docs/coverage/language/python/#packaging","title":"Packaging","text":"

    Trivy parses the manifest files of installed packages in container image scanning and so on. See here for the detail.

    "},{"location":"docs/coverage/language/python/#egg","title":"Egg","text":"

    Trivy looks for *.egg-info, *.egg-info/PKG-INFO, *.egg and EGG-INFO/PKG-INFO to identify Python packages.

    "},{"location":"docs/coverage/language/python/#wheel","title":"Wheel","text":"

    Trivy looks for .dist-info/META-DATA to identify Python packages.

    1. Trivy checks python, python3, python2 and python.exe file names.\u00a0\u21a9\u21a9

    "},{"location":"docs/coverage/language/ruby/","title":"Ruby","text":"

    Trivy supports Bundler and RubyGems. The following scanners are supported for Cargo.

    Package manager SBOM Vulnerability License Bundler \u2713 \u2713 - RubyGems \u2713 \u2713 \u2713

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Bundler Gemfile.lock \u2713 Included \u2713 \u2713 RubyGems .gemspec - Included - -"},{"location":"docs/coverage/language/ruby/#bundler","title":"Bundler","text":"

    Trivy searches for Gemfile.lock to detect dependencies.

    "},{"location":"docs/coverage/language/ruby/#rubygems","title":"RubyGems","text":"

    .gemspec files doesn't contains transitive dependencies. You need to scan each .gemspec file separately.

    "},{"location":"docs/coverage/language/rust/","title":"Rust","text":"

    Trivy supports Cargo, which is the Rust package manager. The following scanners are supported for Cargo.

    Package manager SBOM Vulnerability License Cargo \u2713 \u2713 -

    In addition, it supports binaries built with cargo-auditable.

    Artifact SBOM Vulnerability License Binaries \u2713 \u2713 -"},{"location":"docs/coverage/language/rust/#features","title":"Features","text":"

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Cargo Cargo.lock \u2713 Excluded1 \u2713 \u2713 Artifact Transitive dependencies Dev dependencies Dependency graph Position Binaries \u2713 Excluded - -"},{"location":"docs/coverage/language/rust/#cargo","title":"Cargo","text":"

    Trivy searches for Cargo.lock to detect dependencies.

    Trivy also supports dependency trees; however, to display an accurate tree, it needs to know whether each package is a direct dependency of the project. Since this information is not included in Cargo.lock, Trivy parses Cargo.toml, which should be located next to Cargo.lock. If you want to see the dependency tree, please ensure that Cargo.toml is present.

    Scan Cargo.lock and Cargo.toml together also removes developer dependencies.

    "},{"location":"docs/coverage/language/rust/#binaries","title":"Binaries","text":"

    Trivy scans binaries built with cargo-auditable. If such a binary exists, Trivy will identify it as being built with cargo-audit and scan it.

    1. When you scan Cargo.lock and Cargo.toml together.\u00a0\u21a9

    "},{"location":"docs/coverage/language/swift/","title":"Swift","text":"

    Trivy supports CocoaPods and Swift package managers.

    The following scanners are supported.

    Package manager SBOM Vulnerability License Swift \u2713 \u2713 - CocoaPods \u2713 \u2713 -

    The following table provides an outline of the features Trivy offers.

    Package manager File Transitive dependencies Dev dependencies Dependency graph Position Swift Package.resolved \u2713 Included - \u2713 CocoaPods Podfile.lock \u2713 Included \u2713 -

    These may be enabled or disabled depending on the target. See here for the detail.

    "},{"location":"docs/coverage/language/swift/#swift_1","title":"Swift","text":"

    Trivy parses Package.resolved file to find dependencies. Don't forget to update (swift package update command) this file before scanning.

    "},{"location":"docs/coverage/language/swift/#cocoapods","title":"CocoaPods","text":"

    CocoaPods uses package names in PodFile.lock, but GitHub Advisory Database (GHSA) Trivy relies on uses Git URLs. We parse the CocoaPods Specs to match package names and links.

    Limitation

    Since GHSA holds only Git URLs, such as github.com/apple/swift-nio, Trivy can't identify affected submodules, and detect all submodules maintained by the same URL. For example, SwiftNIOHTTP1 and SwiftNIOWebSocket both are maintained under github.com/apple/swift-nio, and Trivy detect CVE-2022-3215 for both of them, even though only SwiftNIOHTTP1 is actually affected.

    "},{"location":"docs/coverage/os/","title":"OS","text":""},{"location":"docs/coverage/os/#scanner","title":"Scanner","text":"

    Trivy supports operating systems for

    • SBOM
    • Vulnerabilities
    • Licenses
    "},{"location":"docs/coverage/os/#supported-os","title":"Supported OS","text":"OS Supported Versions Package Managers Alpine Linux 2.2 - 2.7, 3.0 - 3.20, edge apk Wolfi Linux (n/a) apk Chainguard (n/a) apk Red Hat Enterprise Linux 6, 7, 8 dnf/yum/rpm CentOS1 6, 7, 8 dnf/yum/rpm AlmaLinux 8, 9 dnf/yum/rpm Rocky Linux 8, 9 dnf/yum/rpm Oracle Linux 5, 6, 7, 8 dnf/yum/rpm Azure Linux (CBL-Mariner) 1.0, 2.0, 3.0 tdnf/dnf/yum/rpm Amazon Linux 1, 2, 2023 dnf/yum/rpm openSUSE Leap 42, 15 zypper/rpm openSUSE Tumbleweed (n/a) zypper/rpm SUSE Linux Enterprise 11, 12, 15 zypper/rpm SUSE Linux Enterprise Micro 5, 6 zypper/rpm Photon OS 1.0, 2.0, 3.0, 4.0 tndf/yum/rpm Debian GNU/Linux 7, 8, 9, 10, 11, 12 apt/dpkg Ubuntu All versions supported by Canonical apt/dpkg OSs with installed Conda - conda"},{"location":"docs/coverage/os/#supported-container-images","title":"Supported container images","text":"Container image Supported Versions Package Managers Google Distroless2 Any apt/dpkg Bitnami Any -

    Each page gives more details.

    1. CentOS Stream is not supported\u00a0\u21a9

    2. https://github.com/GoogleContainerTools/distroless \u21a9

    "},{"location":"docs/coverage/os/alma/","title":"AlmaLinux","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/alma/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    "},{"location":"docs/coverage/os/alma/#vulnerability","title":"Vulnerability","text":"

    AlmaLinux offers its own security advisories, and these are utilized when scanning AlmaLinux for vulnerabilities.

    "},{"location":"docs/coverage/os/alma/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/alma/#fixed-version","title":"Fixed Version","text":"

    When looking at fixed versions, it's crucial to consider the patches supplied by AlmaLinux. For example, for CVE-2023-0464, the fixed version for AlmaLinux 9 is listed as 3.0.7-16.el9_2 in their advisory. Note that this is different from the upstream fixed version, which is 3.0.9, 3.1.1, and son on. Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    "},{"location":"docs/coverage/os/alma/#severity","title":"Severity","text":"

    Trivy calculates the severity of an issue based on the severity provided by AlmaLinux. If the severity is not provided or defined yet by AlmaLinux, the severity from the NVD is taken into account.

    Using CVE-2023-0464 as an example, while it is rated as \"High\" in NVD, AlmaLinux has marked as \"moderate\". As a result, Trivy will display it as \"Medium\".

    The table below is the mapping of AlmaLinux's severity to Trivy's severity levels.

    AlmaLinux Trivy Low Low Moderate Medium Important High Critical Critical"},{"location":"docs/coverage/os/alma/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for AlmaLinux.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/alma/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/alpine/","title":"Alpine Linux","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/alpine/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through apk.

    "},{"location":"docs/coverage/os/alpine/#vulnerability","title":"Vulnerability","text":"

    Alpine Linux offers its own security advisories, and these are utilized when scanning Alpine for vulnerabilities.

    "},{"location":"docs/coverage/os/alpine/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/alpine/#fixed-version","title":"Fixed Version","text":"

    When looking at fixed versions, it's crucial to consider the patches supplied by Alpine. For example, for CVE-2023-0464, the fixed version for Alpine Linux is listed as 3.1.0-r1 in the secfixes. Note that this is different from the upstream fixed version, which is 3.1.1. Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    "},{"location":"docs/coverage/os/alpine/#severity","title":"Severity","text":"

    For Alpine vulnerabilities, the severity is determined using the values set by NVD.

    "},{"location":"docs/coverage/os/alpine/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Alpine.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/alpine/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of APK packages.

    "},{"location":"docs/coverage/os/amazon/","title":"Amazon Linux","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/amazon/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    "},{"location":"docs/coverage/os/amazon/#vulnerability","title":"Vulnerability","text":"

    Amazon Linux offers its own security advisories, and these are utilized when scanning Amazon Linux for vulnerabilities.

    "},{"location":"docs/coverage/os/amazon/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/amazon/#fixed-version","title":"Fixed Version","text":"

    When looking at fixed versions, it's crucial to consider the patches supplied by Amazon. For example, for CVE-2023-0464, the fixed version for Amazon Linux 2023 is listed as 3.0.8-1.amzn2023.0.2 in ALAS2023-2023-181. Note that this is different from the upstream fixed version, which is 3.0.9, 3.1.1, and so on. Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    "},{"location":"docs/coverage/os/amazon/#severity","title":"Severity","text":"

    Trivy determines vulnerability severity based on the severity metric provided by Amazon. For example, the security patch for CVE-2023-0464 in Amazon Linux 2023 is provided as ALAS2023-2023-181. Its severity is rated as \"Medium\". Thus, even though it's evaluated as \"HIGH\" in the NVD, Trivy displays it with a severity of \"MEDIUM\".

    The table below is the mapping of Amazon's severity to Trivy's severity levels.

    Amazon Trivy Low Low Medium Medium Important High Critical Critical"},{"location":"docs/coverage/os/amazon/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Amazon Linux.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/amazon/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/azure/","title":"Azure Linux (CBL-Mariner)","text":"

    CBL-Mariner was rebranded to Azure Linux for version 3.0 onwards.

    Trivy supports the following scanners for OS packages.

    Version SBOM Vulnerability License 1.0 \u2714 \u2714 \u2714 1.0 (Distroless) \u2714 \u2714 2.0 \u2714 \u2714 \u2714 2.0 (Distroless) \u2714 \u2714 3.0 \u2714 \u2714 \u2714 3.0 (Distroless) \u2714 \u2714

    The following table provides an outline of the targets Trivy supports.

    Version Container image Virtual machine Arch 1.0 \u2714 \u2714 amd64, arm64 2.0 \u2714 \u2714 amd64, arm64 3.0 \u2714 \u2714 amd64, arm64

    The table below outlines the features offered by Trivy.

    Feature Supported Detect unfixed vulnerabilities \u2713 Dependency graph \u2713"},{"location":"docs/coverage/os/azure/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as tdnf, dnf and yum.

    "},{"location":"docs/coverage/os/azure/#vulnerability","title":"Vulnerability","text":"

    Azure Linux offers its own security advisories, and these are utilized when scanning Azure Linux for vulnerabilities.

    "},{"location":"docs/coverage/os/azure/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/azure/#fixed-version","title":"Fixed Version","text":"

    Trivy takes fixed versions from Azure Linux OVAL.

    "},{"location":"docs/coverage/os/azure/#severity","title":"Severity","text":"

    Trivy calculates the severity of an issue based on the severity provided in Azure Linux OVAL.

    "},{"location":"docs/coverage/os/azure/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Azure Linux.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/azure/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    Note

    License detection is not supported for Azure Linux Distroless images.

    "},{"location":"docs/coverage/os/centos/","title":"CentOS","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities \u2713 Dependency graph \u2713"},{"location":"docs/coverage/os/centos/#sbom","title":"SBOM","text":"

    Same as RHEL.

    "},{"location":"docs/coverage/os/centos/#vulnerability","title":"Vulnerability","text":"

    CentOS does not provide straightforward machine-readable security advisories. As a result, Trivy utilizes the security advisories from Red Hat Enterprise Linux (RHEL) for detecting vulnerabilities in CentOS. This approach might lead to situations where, even though Trivy displays a fixed version, CentOS might not have the patch available yet. Since patches released for RHEL often become available in CentOS after some time, it's usually just a matter of waiting.

    Note

    The case for CentOS Stream, which is not supported by Trivy, is entirely different from CentOS.

    As Trivy relies on Red Hat's advisories, please refer to Red Hat for details regarding vulnerability severity and status.

    "},{"location":"docs/coverage/os/centos/#license","title":"License","text":"

    Same as RHEL.

    "},{"location":"docs/coverage/os/chainguard/","title":"Chainguard","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    The table below outlines the features offered by Trivy.

    Feature Supported Detect unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/chainguard/#sbom","title":"SBOM","text":"

    Same as Alpine Linux.

    "},{"location":"docs/coverage/os/chainguard/#vulnerability","title":"Vulnerability","text":"

    Chainguard offers its own security advisories, and these are utilized when scanning Chainguard for vulnerabilities. Everything else is the same as Alpine Linux.

    "},{"location":"docs/coverage/os/chainguard/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/chainguard/#license","title":"License","text":"

    Same as Alpine Linux.

    "},{"location":"docs/coverage/os/debian/","title":"Debian","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities \u2713 Dependency graph \u2713"},{"location":"docs/coverage/os/debian/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as apt and dpkg. While there are some exceptions, like Go binaries and JAR files, it's important to note that binaries that have been custom-built using make or tools installed via curl are generally not detected.

    "},{"location":"docs/coverage/os/debian/#vulnerability","title":"Vulnerability","text":"

    Debian offers its own security advisories, and these are utilized when scanning Debian for vulnerabilities.

    "},{"location":"docs/coverage/os/debian/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/debian/#fixed-version","title":"Fixed Version","text":"

    When looking at fixed versions, it's crucial to consider the patches supplied by Debian. For example, for CVE-2023-3269, the fixed version for Debian 12 (bookworm) is listed as 6.1.37-1 in the Security Tracker. This patch is provided in DSA-5448-1. Note that this is different from the upstream fixed version, which is 6.5. Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    "},{"location":"docs/coverage/os/debian/#severity","title":"Severity","text":"

    Trivy calculates the severity of an issue based on the 'Urgency' metric found in the Security Tracker. If 'Urgency' isn't provided by Debian, the severity from the NVD is taken into account.

    Using CVE-2019-15052 as an example, while it is rated as \"Critical\" in NVD, Debian has marked its \"Urgency\" as \"Low\". As a result, Trivy will display it as \"Low\".

    "},{"location":"docs/coverage/os/debian/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Debian.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred \u2713 End of Life \u2713"},{"location":"docs/coverage/os/debian/#license","title":"License","text":"

    To identify the license of a package, Trivy checks the copyright file located at /usr/share/doc/*/copyright.

    However, this method has its limitations as the file isn't machine-readable, leading to situations where the license isn't detected. In such scenarios, the --license-full flag can be passed. It compares the contents of known licenses with the copyright file to discern the license in question. Please be aware that using this flag can increase memory usage, so it's disabled by default for efficiency.

    "},{"location":"docs/coverage/os/google-distroless/","title":"Google Distroless Images","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/google-distroless/#sbom","title":"SBOM","text":"

    Trivy detects packages pre-installed in distroless images.

    "},{"location":"docs/coverage/os/google-distroless/#vulnerability","title":"Vulnerability","text":"

    Google Distroless is based on Debian; see there for details.

    "},{"location":"docs/coverage/os/google-distroless/#license","title":"License","text":"

    Google Distroless is based on Debian; see there for details.

    "},{"location":"docs/coverage/os/oracle/","title":"Oracle Linux","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/oracle/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    "},{"location":"docs/coverage/os/oracle/#vulnerability","title":"Vulnerability","text":"

    Oracle Linux offers its own security advisories, and these are utilized when scanning Oracle Linux for vulnerabilities.

    "},{"location":"docs/coverage/os/oracle/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/oracle/#fixed-version","title":"Fixed Version","text":"

    Trivy takes fixed versions from Oracle security advisories.

    "},{"location":"docs/coverage/os/oracle/#flavors","title":"Flavors","text":"

    Trivy detects the flavor for version of the found package and finds vulnerabilities only for that flavor.

    Flavor Format Example normal version without fips and ksplice 3.6.16-4.el8 fips *_fips 10:3.6.16-4.0.1.el8_fips ksplice *.ksplice*.* 2:2.34-60.0.3.ksplice1.el9_2.7, 151.0.1.ksplice2.el8

    For example Trivy finds CVE-2021-33560 only for the normal and fips flavors. For the ksplice flavor, CVE-2021-33560 will be skipped.

    "},{"location":"docs/coverage/os/oracle/#severity","title":"Severity","text":"

    Trivy determines vulnerability severity based on the severity metric provided in Oracle security advisories. For example, the security patch for CVE-2023-0464 is provided as ELSA-2023-2645. Its severity is rated as \"MODERATE\". Thus, even though it's evaluated as \"HIGH\" in the NVD, Trivy displays it with a severity of \"MEDIUM\".

    The table below is the mapping of Oracle's threat to Trivy's severity levels.

    Oracle Trivy Low Low Moderate Medium Important High Critical Critical"},{"location":"docs/coverage/os/oracle/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Oracle Linux.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/oracle/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/photon/","title":"Photon OS","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/photon/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as tdnf and yum.

    "},{"location":"docs/coverage/os/photon/#vulnerability","title":"Vulnerability","text":"

    Photon OS offers its own security advisories, and these are utilized when scanning Photon OS for vulnerabilities.

    "},{"location":"docs/coverage/os/photon/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/photon/#fixed-version","title":"Fixed Version","text":"

    Trivy takes fixed versions from Photon CVE metadata.

    "},{"location":"docs/coverage/os/photon/#severity","title":"Severity","text":"

    Trivy determines the severity of vulnerabilities based on the CVSSv3 score provided by Photon OS. See here for the conversion table from CVSS score to severity.

    "},{"location":"docs/coverage/os/photon/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Photon OS.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/photon/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/rhel/","title":"Red Hat Enterprise Linux","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities \u2713 Dependency graph \u2713"},{"location":"docs/coverage/os/rhel/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    "},{"location":"docs/coverage/os/rhel/#vulnerability","title":"Vulnerability","text":"

    Red Hat offers its own security advisories, and these are utilized when scanning Red Hat Enterprise Linux (RHEL) for vulnerabilities.

    "},{"location":"docs/coverage/os/rhel/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/rhel/#fixed-version","title":"Fixed Version","text":"

    When looking at fixed versions, it's crucial to consider the patches supplied by Red Hat. For example, for CVE-2023-0464, the fixed version for RHEL 9 is listed as 3.0.7-16.el9_2 in their advisory. This patch is provided in RHSA-2023:3722. Note that this is different from the upstream fixed version, which is 3.0.9, 3.1.1, and so on. Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    "},{"location":"docs/coverage/os/rhel/#severity","title":"Severity","text":"

    Trivy calculates the severity of a vulnerability based on the 'Impact' metric provided by Red Hat. If the impact is not provided or defined yet by Red Hat, the severity from the NVD is taken into account.

    Using CVE-2023-0464 as an example, while it is rated as \"HIGH\" in NVD, Red Hat has marked its 'Impact' as \"Low\". As a result, Trivy will display it as \"Low\".

    The table below is the mapping of Red Hat's impact to Trivy's severity levels.

    Red Hat Trivy Low Low Moderate Medium Important High Critical Critical"},{"location":"docs/coverage/os/rhel/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for RHEL.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation \u2713 Will Not Fix \u2713 Fix Deferred \u2713 End of Life \u2713

    When a vulnerability status is listed as \"End of Life\", it means a vulnerability with the impact level assigned to this CVE is no longer covered by its current support lifecycle phase. The product has been identified to contain the impacted component, but analysis to determine whether it is affected or not by this vulnerability was not performed. Red Hat advises that the product should be assumed to be affected. Therefore, Trivy detects vulnerabilities with this status as \"End of Life\".

    On the other hand, for those marked \"Under Investigation,\" the impact is unclear as they are still being examined, so Trivy does not detect them. Once the investigation is completed, the status should be updated.

    Abstract

    Vulnerabilities with a status of \"End of Life\", where the presence or absence of impact is unclear, are detected by Trivy. However, those with a status of \"Under Investigation\" are not detected.

    "},{"location":"docs/coverage/os/rhel/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/rocky/","title":"Rocky Linux","text":"

    Trivy supports the following scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/rocky/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    "},{"location":"docs/coverage/os/rocky/#vulnerability","title":"Vulnerability","text":"

    Rocky Linux offers its own security advisories, and these are utilized when scanning Rocky Linux for vulnerabilities.

    "},{"location":"docs/coverage/os/rocky/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/rocky/#fixed-version","title":"Fixed Version","text":"

    Trivy takes fixed versions from Rocky Linux Errata, not NVD or somewhere else. See here for more details.

    Architectures

    There are cases when the vulnerability affects packages of not all architectures. For example, vulnerable packages for CVE-2023-0361 are only aarch64 packages.

    Trivy only detects vulnerabilities for packages of your architecture.

    "},{"location":"docs/coverage/os/rocky/#severity","title":"Severity","text":"

    Trivy calculates the severity of an issue based on the severity provided in Rocky Linux Errata.

    The table below is the mapping of Rocky Linux's severity to Trivy's severity levels.

    Rocky Linux Trivy Low Low Moderate Medium Important High Critical Critical"},{"location":"docs/coverage/os/rocky/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Rocky Linux.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/rocky/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/suse/","title":"SUSE","text":"

    Trivy supports the following distributions:

    • openSUSE Leap
    • openSUSE Tumbleweed
    • SUSE Linux Enterprise (SLE)
    • SUSE Linux Enterprise Micro

    Please see here for supported versions.

    Trivy supports these scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/suse/#sbom","title":"SBOM","text":"

    Trivy detects packages that have been installed through package managers such as dnf and yum.

    "},{"location":"docs/coverage/os/suse/#vulnerability","title":"Vulnerability","text":"

    SUSE offers its own security advisories, and these are utilized when scanning openSUSE/SLE for vulnerabilities.

    "},{"location":"docs/coverage/os/suse/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/suse/#license","title":"License","text":"

    Trivy identifies licenses by examining the metadata of RPM packages.

    "},{"location":"docs/coverage/os/ubuntu/","title":"Ubuntu","text":"

    Trivy supports these scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    Please see here for supported versions.

    The following table provides an outline of the features Trivy offers.

    Feature Supported Detect unfixed vulnerabilities \u2713 Dependency graph \u2713"},{"location":"docs/coverage/os/ubuntu/#sbom","title":"SBOM","text":"

    Same as Debian.

    "},{"location":"docs/coverage/os/ubuntu/#vulnerability","title":"Vulnerability","text":"

    Ubuntu offers its own security advisories, and these are utilized when scanning Ubuntu for vulnerabilities.

    "},{"location":"docs/coverage/os/ubuntu/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/ubuntu/#fixed-version","title":"Fixed Version","text":"

    When looking at fixed versions, it's crucial to consider the patches supplied by Ubuntu. As an illustration, for CVE-2023-3269, the fixed version for Ubuntu 23.04 (lunar) is listed as 6.2.0-26.26 in the Security Tracker. It's essential to recognize that this differs from the upstream fixed version, which stands at 6.5. Typically, only the upstream information gets listed on NVD, so it's important not to get confused.

    "},{"location":"docs/coverage/os/ubuntu/#severity","title":"Severity","text":"

    Trivy calculates the severity of an issue based on the 'Priority' metric found in the Security Tracker. If 'Priority' isn't provided by Ubuntu, the severity from the NVD is taken into account.

    Using CVE-2019-15052 as an example, while it is rated as \"Critical\" in NVD, Ubuntu has marked its \"Priority\" as \"Medium\". As a result, Trivy will display it as \"Medium\".

    "},{"location":"docs/coverage/os/ubuntu/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Ubuntu.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/os/ubuntu/#license","title":"License","text":"

    Same as Debian.

    "},{"location":"docs/coverage/os/wolfi/","title":"Wolfi Linux","text":"

    Trivy supports these scanners for OS packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    The table below outlines the features offered by Trivy.

    Feature Supported Detect unfixed vulnerabilities - Dependency graph \u2713"},{"location":"docs/coverage/os/wolfi/#sbom","title":"SBOM","text":"

    Same as Alpine Linux.

    "},{"location":"docs/coverage/os/wolfi/#vulnerability","title":"Vulnerability","text":"

    Wolfi Linux offers its own security advisories, and these are utilized when scanning Wolfi for vulnerabilities. Everything else is the same as Alpine Linux.

    "},{"location":"docs/coverage/os/wolfi/#data-source","title":"Data Source","text":"

    See here.

    "},{"location":"docs/coverage/os/wolfi/#license","title":"License","text":"

    Same as Alpine Linux.

    "},{"location":"docs/coverage/others/","title":"Others","text":"

    In this section we have placed images, package managers and files that we can't assign to existing sections.

    Trivy supports them for

    • SBOM
    • Vulnerabilities
    • Licenses
    "},{"location":"docs/coverage/others/#supported-elements","title":"Supported elements","text":"Element File Image1 Rootfs2 Filesystem3 Repository4 Bitnami packages /opt/bitnami/<component>/.spdx-<component>.spdx \u2705 \u2705 - - Conda <conda-root>/envs/<env>/conda-meta/<package>.json \u2705 \u2705 - - environment.yml - - \u2705 \u2705 RPM Archives *.rpm \u27055 \u27055 \u27055 \u27055
    1. \u2705 means \"enabled\" and - means \"disabled\" in the image scanning\u00a0\u21a9

    2. \u2705 means \"enabled\" and - means \"disabled\" in the rootfs scanning\u00a0\u21a9

    3. \u2705 means \"enabled\" and - means \"disabled\" in the filesystem scanning\u00a0\u21a9

    4. \u2705 means \"enabled\" and - means \"disabled\" in the git repository scanning\u00a0\u21a9

    5. Only if the TRIVY_EXPERIMENTAL_RPM_ARCHIVE env is set.\u00a0\u21a9\u21a9\u21a9\u21a9

    "},{"location":"docs/coverage/others/bitnami/","title":"Bitnami Images","text":"

    EXPERIMENTAL

    Scanning results may be inaccurate.

    While it is not an OS, this page describes the details of the container images provided by Bitnami. Bitnami images are based on Debian. Please see the Debian page for OS packages.

    Trivy supports the following scanners for Bitnami packages.

    Scanner Supported SBOM \u2713 Vulnerability \u2713 License \u2713

    The table below outlines the features offered by Trivy.

    Feature Supported Unfixed vulnerabilities - Dependency graph -"},{"location":"docs/coverage/others/bitnami/#sbom","title":"SBOM","text":"

    Trivy analyzes the SBOM information contained within the container images provided by Bitnami. The SBOM files are located at /opt/bitnami/<component>/.spdx-<component>.spdx.

    "},{"location":"docs/coverage/others/bitnami/#vulnerability","title":"Vulnerability","text":"

    Since Bitnami has its own vulnerability database, it uses these for vulnerability detection of applications and packages distributed by Bitnami.

    Note

    Trivy does not support vulnerability detection of independently compiled binaries, so even if you scan container images like nginx:1.15.2, vulnerabilities in Nginx cannot be detected. This is because main applications like Nginx are not installed by the package manager. However, in the case of Bitnami images, since these SBOMs are stored within the image, scanning bitnami/nginx:1.15.2 allows for the detection of vulnerabilities in Nginx.

    "},{"location":"docs/coverage/others/bitnami/#fixed-version","title":"Fixed Version","text":"

    Trivy refers to the Bitnami database. Please note that these may differ from the upstream fixed versions.

    "},{"location":"docs/coverage/others/bitnami/#severity","title":"Severity","text":"

    Similar to Fixed versions, it follows Bitnami's vulnerability database.

    "},{"location":"docs/coverage/others/bitnami/#status","title":"Status","text":"

    Trivy supports the following vulnerability statuses for Bitnami packages.

    Status Supported Fixed \u2713 Affected \u2713 Under Investigation Will Not Fix Fix Deferred End of Life"},{"location":"docs/coverage/others/bitnami/#license","title":"License","text":"

    If licenses are included in the SBOM distributed by Bitnami, they will be used for scanning.

    "},{"location":"docs/coverage/others/conda/","title":"Conda","text":"

    Trivy supports the following scanners for Conda packages.

    Scanner Supported SBOM \u2713 Vulnerability - License \u2713 Package manager File Transitive dependencies Dev dependencies Dependency graph Position Detection Priority Conda environment.yml - Include - \u2713 -"},{"location":"docs/coverage/others/conda/#packagejson","title":"<package>.json","text":""},{"location":"docs/coverage/others/conda/#sbom","title":"SBOM","text":"

    Trivy parses <conda-root>/envs/<env>/conda-meta/<package>.json files to find the dependencies installed in your env.

    "},{"location":"docs/coverage/others/conda/#license","title":"License","text":"

    The <package>.json files contain package license information. Trivy includes licenses for the packages it finds without having to parse additional files.

    "},{"location":"docs/coverage/others/conda/#environmentyml","title":"environment.yml1","text":""},{"location":"docs/coverage/others/conda/#sbom_1","title":"SBOM","text":"

    Trivy supports parsing environment.yml1 files to find dependency list.

    environment.yml1 files supports version range. We can't be sure about versions for these dependencies. Therefore, you need to use conda env export command to get dependency list in Conda default format before scanning environment.yml1 file.

    Note

    For dependencies in a non-Conda format, Trivy doesn't include a version of them.

    "},{"location":"docs/coverage/others/conda/#license_1","title":"License","text":"

    Trivy parses conda-meta/<package>.json files at the prefix path.

    To correctly define licenses, make sure your environment.yml1 contains prefix field and prefix directory contains package.json files.

    Note

    To get correct environment.yml1 file and fill prefix directory - use conda env export command.

    1. Trivy supports both yaml and yml extensions.\u00a0\u21a9\u21a9\u21a9\u21a9\u21a9\u21a9

    "},{"location":"docs/coverage/others/rpm/","title":"RPM Archives","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy supports the following scanners for RPM archives.

    Scanner Supported SBOM \u2713 Vulnerability \u27131 License \u2713

    The table below outlines the features offered by Trivy.

    "},{"location":"docs/coverage/others/rpm/#sbom","title":"SBOM","text":"

    Trivy analyzes RPM archives matching *.rpm. This feature is currently disabled by default but can be enabled with an environment variable, TRIVY_EXPERIMENTAL_RPM_ARCHIVE.

    TRIVY_EXPERIMENTAL_RPM_ARCHIVE=true trivy fs ./rpms --format cyclonedx --output rpms.cdx.json\n

    Note

    Currently, it works with --format cyclonedx, --format spdx or --format spdx-json.

    "},{"location":"docs/coverage/others/rpm/#vulnerability","title":"Vulnerability","text":"

    Since RPM files don't have OS information, you need to generate SBOM, fill in the OS information manually and then scan the SBOM for vulnerabilities.

    For example:

    $ TRIVY_EXPERIMENTAL_RPM_ARCHIVE=true trivy fs ./rpms -f cyclonedx -o rpms.cdx.json\n$ jq '(.components[] | select(.type == \"operating-system\")) |= (.name = \"redhat\" | .version = \"7.9\")' rpms.cdx.json > rpms-res.cdx.json\n$ trivy sbom ./rpms-res.cdx.json\n
    "},{"location":"docs/coverage/others/rpm/#license","title":"License","text":"

    If licenses are included in the RPM archive, Trivy extracts it.

    1. Need to generate SBOM first and add OS information to that SBOM\u00a0\u21a9

    "},{"location":"docs/plugin/","title":"Plugins","text":"

    Trivy provides a plugin feature to allow others to extend the Trivy CLI without the need to change the Trivy code base. This plugin system was inspired by the plugin system used in kubectl, Helm, and Conftest.

    "},{"location":"docs/plugin/#overview","title":"Overview","text":"

    Trivy plugins are add-on tools that integrate seamlessly with Trivy. They provide a way to extend the core feature set of Trivy, but without requiring every new feature to be written in Go and added to the core tool.

    • They can be added and removed from a Trivy installation without impacting the core Trivy tool.
    • They can be written in any programming language.
    • They integrate with Trivy, and will show up in Trivy help and subcommands.

    Warning

    Trivy plugins available in public are not audited for security. You should install and run third-party plugins at your own risk, since they are arbitrary programs running on your machine.

    "},{"location":"docs/plugin/#quickstart","title":"Quickstart","text":"

    Trivy helps you discover and install plugins on your machine.

    You can install and use a wide variety of Trivy plugins to enhance your experience.

    Let\u2019s get started:

    1. Download the plugin list:

      $ trivy plugin update\n
    2. Discover Trivy plugins available on the plugin index:

      $ trivy plugin search\nNAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT\naqua                 A plugin for integration with Aqua Security SaaS platform    aquasecurity\nkubectl              A plugin scanning the images of a kubernetes resource        aquasecurity\nreferrer             A plugin for OCI referrers                                   aquasecurity           \u2713\n[...]\n
    3. Choose a plugin from the list and install it:

      $ trivy plugin install referrer\n
    4. Use the installed plugin:

      $ trivy referrer --help\n
    5. Keep your plugins up-to-date:

      $ trivy plugin upgrade\n
    6. Uninstall a plugin you no longer use:

      trivy plugin uninstall referrer\n

    This is practically all you need to know to start using Trivy plugins.

    "},{"location":"docs/plugin/developer-guide/","title":"Developer Guide","text":""},{"location":"docs/plugin/developer-guide/#developing-trivy-plugins","title":"Developing Trivy plugins","text":"

    This section will guide you through the process of developing Trivy plugins. To help you get started quickly, we have published a plugin template repository. You can use this template as a starting point for your plugin development.

    "},{"location":"docs/plugin/developer-guide/#introduction","title":"Introduction","text":"

    If you are looking to start developing plugins for Trivy, read the user guide first.

    The development process involves the following steps:

    • Create a repository for your plugin, named trivy-plugin-<name>.
    • Create an executable binary that can be invoked as trivy <name>.
    • Place the executable binary in a repository.
    • Create a plugin.yaml file that describes the plugin.
    • (Submit your plugin to the Trivy plugin index.)

    After you develop a plugin with a good name following the best practices and publish it, you can submit your plugin to the Trivy plugin index.

    "},{"location":"docs/plugin/developer-guide/#naming","title":"Naming","text":"

    This section describes guidelines for naming your plugins.

    "},{"location":"docs/plugin/developer-guide/#use-trivy-plugin-prefix","title":"Use trivy-plugin- prefix","text":"

    The name of the plugin repository should be prefixed with trivy-plugin-.

    "},{"location":"docs/plugin/developer-guide/#use-lowercase-and-hyphens","title":"Use lowercase and hyphens","text":"

    Plugin names must be all lowercase and separate words with hyphens. Don\u2019t use camelCase, PascalCase, or snake_case; use kebab-case.

    • NO: trivy OpenSvc
    • YES: trivy open-svc
    "},{"location":"docs/plugin/developer-guide/#be-specific","title":"Be specific","text":"

    Plugin names should not be verbs or nouns that are generic, already overloaded, or likely to be used for broader purposes by another plugin.

    • NO: trivy sast (Too broad)
    • YES: trivy govulncheck
    "},{"location":"docs/plugin/developer-guide/#be-unique","title":"Be unique","text":"

    Find a unique name for your plugin that differentiates it from other plugins that perform a similar function.

    • NO: trivy images (Unclear how it is different from the builtin \u201cimage\" command)
    • YES: trivy registry-images (Unique name).
    "},{"location":"docs/plugin/developer-guide/#prefix-vendor-identifiers","title":"Prefix Vendor Identifiers","text":"

    Use vendor-specific strings as prefix, separated with a dash. This makes it easier to search/group plugins that are about a specific vendor.

    • NO: `trivy security-hub-aws (Makes it harder to search or locate in a plugin list)
    • YES: `trivy aws-security-hub (Will show up together with other aws-* plugins)
    "},{"location":"docs/plugin/developer-guide/#choosing-a-language","title":"Choosing a language","text":"

    Since Trivy plugins are standalone executables, you can write them in any programming language.

    If you are planning to write a plugin with Go, check out the Report struct, which is the output of Trivy scan.

    "},{"location":"docs/plugin/developer-guide/#writing-your-plugin","title":"Writing your plugin","text":"

    Each plugin has a top-level directory, and then a plugin.yaml file.

    your-plugin/\n  |\n  |- plugin.yaml\n  |- your-plugin.sh\n

    In the example above, the plugin is contained inside a directory named your-plugin. It has two files: plugin.yaml (required) and an executable script, your-plugin.sh (optional).

    "},{"location":"docs/plugin/developer-guide/#writing-a-plugin-manifest","title":"Writing a plugin manifest","text":"

    The plugin manifest is a simple YAML file named plugin.yaml. Here is an example YAML of trivy-plugin-kubectl plugin that adds support for Kubernetes scanning.

    name: \"kubectl\"\nversion: \"0.1.0\"\nrepository: github.com/aquasecurity/trivy-plugin-kubectl\nmaintainer: aquasecurity\noutput: false\nsummary: Scan kubectl resources\ndescription: |-\n  A Trivy plugin that scans the images of a kubernetes resource.\n  Usage: trivy kubectl TYPE[.VERSION][.GROUP] NAME\nplatforms:\n  - selector: # optional\n      os: darwin\n      arch: amd64\n    uri: ./trivy-kubectl # where the execution file is (local file, http, git, etc.)\n    bin: ./trivy-kubectl # path to the execution file\n  - selector: # optional\n      os: linux\n      arch: amd64\n    uri: https://github.com/aquasecurity/trivy-plugin-kubectl/releases/download/v0.1.0/trivy-kubectl.tar.gz\n    bin: ./trivy-kubectl\n

    We encourage you to copy and adapt plugin manifests of existing plugins.

    • count
    • referrer

    The plugin.yaml field should contain the following information:

    • name: The name of the plugin. This also determines how the plugin will be made available in the Trivy CLI. For example, if the plugin is named kubectl, you can call the plugin with trivy kubectl. (required)
    • version: The version of the plugin. Semantic Versioning should be used. (required)
    • repository: The repository name where the plugin is hosted. (required)
    • maintainer: The name of the maintainer of the plugin. (required)
    • output: Whether the plugin supports the output mode. (optional)
    • usage: Deprecated: use summary instead. (optional)
    • summary: A short usage description. (required)
    • description: A long description of the plugin. This is where you could provide a helpful documentation of your plugin. (required)
    • platforms: (required)
      • selector: The OS/Architecture specific variations of a execution file. (optional)
        • os: OS information based on GOOS (linux, darwin, etc.) (optional)
        • arch: The architecture information based on GOARCH (amd64, arm64, etc.) (optional)
      • uri: Where the executable file is. Relative path from the root directory of the plugin or remote URL such as HTTP and S3. (required)
      • bin: Which file to call when the plugin is executed. Relative path from the root directory of the plugin. (required)

    The following rules will apply in deciding which platform to select:

    • If both os and arch under selector match the current platform, search will stop and the platform will be used.
    • If selector is not present, the platform will be used.
    • If os matches and there is no more specific arch match, the platform will be used.
    • If no platform match is found, Trivy will exit with an error.

    After determining platform, Trivy will download the execution file from uri and store it in the plugin cache. When the plugin is called via Trivy CLI, bin command will be executed.

    "},{"location":"docs/plugin/developer-guide/#tagging-plugin-repositories","title":"Tagging plugin repositories","text":"

    If you are hosting your plugin in a Git repository, it is strongly recommended to tag your releases with a version number. By tagging your releases, Trivy can install specific versions of your plugin.

    $ trivy plugin install referrer@v0.3.0\n

    When tagging versions, you must follow the Semantic Versioning and prefix the tag with v, like v1.2.3.

    "},{"location":"docs/plugin/developer-guide/#plugin-argumentsflags","title":"Plugin arguments/flags","text":"

    The plugin is responsible for handling flags and arguments. Any arguments are passed to the plugin from the trivy command.

    "},{"location":"docs/plugin/developer-guide/#testing-plugin-installation-locally","title":"Testing plugin installation locally","text":"

    A plugin should be archived *.tar.gz. After you have archived your plugin into a .tar.gz file, you can verify that your plugin installs correctly with Trivy.

    $ tar -czvf myplugin.tar.gz plugin.yaml script.py\nplugin.yaml\nscript.py\n\n$ trivy plugin install myplugin.tar.gz\n2023-03-03T19:04:42.026+0600    INFO    Installing the plugin from myplugin.tar.gz...\n2023-03-03T19:04:42.026+0600    INFO    Loading the plugin metadata...\n\n$ trivy myplugin\nHello from Trivy demo plugin!\n
    "},{"location":"docs/plugin/developer-guide/#publishing-plugins","title":"Publishing plugins","text":"

    The plugin.yaml file is the core of your plugin, so as long as it is published somewhere, your plugin can be installed. If you choose to publish your plugin on GitHub, you can make it installable by placing the plugin.yaml file in the root directory of your repository. Users can then install your plugin with the command, trivy plugin install github.com/org/repo.

    While the uri specified in the plugin.yaml file doesn't necessarily need to point to the same repository, it's a good practice to host the executable file within the same repository when using GitHub. You can utilize GitHub Releases to distribute the executable file. For an example of how to structure your plugin repository, refer to the plugin template repository.

    "},{"location":"docs/plugin/developer-guide/#distributing-plugins-via-the-trivy-plugin-index","title":"Distributing plugins via the Trivy plugin index","text":"

    Trivy can install plugins directly by specifying a repository, like trivy plugin install github.com/aquasecurity/trivy-plugin-referrer, so you don't necessarily need to register your plugin in the Trivy plugin index. However, we would recommend distributing your plugin via the Trivy plugin index since it makes it easier for other users to find (trivy plugin search) and install your plugin (e.g. trivy plugin install kubectl).

    "},{"location":"docs/plugin/developer-guide/#pre-submit-checklist","title":"Pre-submit checklist","text":"
    • Review the plugin naming guide.
    • Ensure the plugin.yaml file has all the required fields.
    • Tag a git release with a semantic version (e.g. v1.0.0).
    • Test your plugin installation locally.
    "},{"location":"docs/plugin/developer-guide/#submitting-plugins","title":"Submitting plugins","text":"

    Submitting your plugin to the plugin index is a straightforward process. All you need to do is create a YAML file for your plugin and place it in the plugins/ directory of the index repository.

    Once you've done that, create a pull request (PR) and have it reviewed by the maintainers. Once your PR is merged, the index will be updated, and your plugin will be available for installation. The plugin index page will also be automatically updated to list your newly added plugin.

    The content of the YAML file is very simple. You only need to specify the name of your plugin and the repository where it is distributed.

    name: referrer\nrepository: github.com/aquasecurity/trivy-plugin-referrer\n

    After your PR is merged, the CI system will automatically retrieve the plugin.yaml file from your repository and update the index.yaml file. If any required fields are missing from your plugin.yaml, the CI will fail, so make sure your plugin.yaml has all the required fields before creating a PR. Once the index.yaml has been updated, running trivy plugin update will download the updated index to your local machine.

    "},{"location":"docs/plugin/user-guide/","title":"User Guide","text":""},{"location":"docs/plugin/user-guide/#discovering-plugins","title":"Discovering Plugins","text":"

    You can find a list of Trivy plugins distributed via trivy-plugin-index here. However, you can find plugins using the command line as well.

    First, refresh your local copy of the plugin index:

    $ trivy plugin update\n

    To list all plugins available, run:

    $ trivy plugin search\nNAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT\naqua                 A plugin for integration with Aqua Security SaaS platform    aquasecurity\nkubectl              A plugin scanning the images of a kubernetes resource        aquasecurity\nreferrer             A plugin for OCI referrers                                   aquasecurity           \u2713\n

    You can specify search keywords as arguments:

    $ trivy plugin search referrer\n\nNAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT\nreferrer             A plugin for OCI referrers                                   aquasecurity           \u2713\n

    It lists plugins with the keyword in the name or description.

    "},{"location":"docs/plugin/user-guide/#installing-plugins","title":"Installing Plugins","text":"

    Plugins can be installed with the trivy plugin install command:

    $ trivy plugin install referrer\n

    This command will download the plugin and install it in the plugin cache.

    Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache. The preference order is as follows:

    • XDG_DATA_HOME if set and .trivy/plugins exists within the XDG_DATA_HOME dir
    • ~/.trivy/plugins

    Furthermore, it is possible to download plugins that are not registered in the index by specifying the URL directly or by specifying the file path.

    $ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl\n
    $ trivy plugin install https://github.com/aquasecurity/trivy-plugin-kubectl/archive/refs/heads/main.zip\n
    $ trivy plugin install ./myplugin.tar.gz\n

    If the plugin's Git repository is properly tagged, you can specify the version to install like this:

    $ trivy plugin install referrer@v0.3.0\n

    Note

    The leading v in the version is required. Also, the version must follow the Semantic Versioning.

    Under the hood Trivy leverages go-getter to download plugins. This means the following protocols are supported for downloading plugins:

    • OCI Registries
    • Local Files
    • Git
    • HTTP/HTTPS
    • Mercurial
    • Amazon S3
    • Google Cloud Storage
    "},{"location":"docs/plugin/user-guide/#listing-installed-plugins","title":"Listing Installed Plugins","text":"

    To list all plugins installed, run:

    $ trivy plugin list\n
    "},{"location":"docs/plugin/user-guide/#using-plugins","title":"Using Plugins","text":"

    Once the plugin is installed, Trivy will load all available plugins in the cache on the start of the next Trivy execution. A plugin will be made in the Trivy CLI based on the plugin name. To display all plugins, you can list them by trivy --help

    $ trivy --help\nNAME:\n   trivy - A simple and comprehensive vulnerability scanner for containers\n\nUSAGE:\n   trivy [global options] command [command options] target\n\nVERSION:\n   dev\n\nScanning Commands\n  config      Scan config files for misconfigurations\n  filesystem  Scan local filesystem\n  image       Scan a container image\n\n...\n\nPlugin Commands\n  kubectl     scan kubectl resources\n  referrer    Put referrers to OCI registry\n

    As shown above, kubectl subcommand exists in the Plugin Commands section. To call the kubectl plugin and scan existing Kubernetes deployments, you can execute the following command:

    $ trivy kubectl deployment <deployment-id> -- --ignore-unfixed --severity CRITICAL\n

    Internally the kubectl plugin calls the kubectl binary to fetch information about that deployment and passes the using images to Trivy. You can see the detail here.

    If you want to omit even the subcommand, you can use TRIVY_RUN_AS_PLUGIN environment variable.

    $ TRIVY_RUN_AS_PLUGIN=kubectl trivy job your-job -- --format json\n
    "},{"location":"docs/plugin/user-guide/#installing-and-running-plugins-on-the-fly","title":"Installing and Running Plugins on the fly","text":"

    trivy plugin run installs a plugin and runs it on the fly. If the plugin is already present in the cache, the installation is skipped.

    trivy plugin run kubectl pod your-pod -- --exit-code 1\n
    "},{"location":"docs/plugin/user-guide/#upgrading-plugins","title":"Upgrading Plugins","text":"

    To upgrade all plugins that you have installed to their latest versions, run:

    $ trivy plugin upgrade\n

    To upgrade only certain plugins, you can explicitly specify their names:

    $ trivy plugin upgrade <PLUGIN1> <PLUGIN2>\n
    "},{"location":"docs/plugin/user-guide/#uninstalling-plugins","title":"Uninstalling Plugins","text":"

    Specify a plugin name with trivy plugin uninstall command.

    $ trivy plugin uninstall kubectl\n

    Here's the revised English documentation based on your requested changes:

    "},{"location":"docs/plugin/user-guide/#output-mode-support","title":"Output Mode Support","text":"

    While plugins are typically intended to be used as subcommands of Trivy, plugins supporting the output mode can be invoked as part of Trivy's built-in commands.

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy supports plugins that are compatible with the output mode, which process Trivy's output, such as by transforming the output format or sending it elsewhere. You can determine whether a plugin supports the output mode by checking the OUTPUT column in the output of trivy plugin search or trivy plugin list.

    $ trivy plugin search\nNAME                 DESCRIPTION                                                  MAINTAINER           OUTPUT\naqua                 A plugin for integration with Aqua Security SaaS platform    aquasecurity\nkubectl              A plugin scanning the images of a kubernetes resource        aquasecurity\nreferrer             A plugin for OCI referrers                                   aquasecurity           \u2713\n

    In this case, the referrer plugin supports the output mode.

    For instance, in the case of image scanning, a plugin supporting the output mode can be called as follows:

    $ trivy image --format json --output plugin=<plugin_name> [--output-plugin-arg <plugin_flags>] <image_name>\n

    Since scan results are passed to the plugin via standard input, plugins must be capable of handling standard input.

    Warning

    To avoid Trivy hanging, you need to read all data from Stdin before the plugin exits successfully or stops with an error.

    While the example passes JSON to the plugin, other formats like SBOM can also be passed (e.g., --format cyclonedx).

    If a plugin requires flags or other arguments, they can be passed using --output-plugin-arg. This is directly forwarded as arguments to the plugin. For example, --output plugin=myplugin --output-plugin-arg \"--foo --bar=baz\" translates to myplugin --foo --bar=baz in execution.

    An example of a plugin supporting the output mode is available here. It can be used as below:

    # Install the plugin first\n$ trivy plugin install count\n\n# Call the plugin supporting the output mode in image scanning\n$ trivy image --format json --output plugin=count --output-plugin-arg \"--published-after 2023-10-01\" debian:12\n
    "},{"location":"docs/plugin/user-guide/#example","title":"Example","text":"
    • kubectl
    • count
    "},{"location":"docs/references/terminology/","title":"Terminology","text":"

    This page explains the terminology system used in Trivy, helping users understand the specific terms and concepts unique to the Trivy ecosystem.

    Inclusion Criteria

    1. Core Components of Trivy

      • Primary features such as Scanner, Target
      • Essential components such as Scan Assets (trivy-db, trivy-java-db)
      • Components that users directly interact with
    2. Trivy-specific Terms

      • Terms unique to Trivy (e.g., VEX Hub)
      • Terms that have special meaning in Trivy's context (e.g., Plugin, Module)

    Exclusion Criteria

    1. General Terms

      • Common security/technical terms (e.g., CVE, CVSS, Container, Registry)
      • Standard industry terminology
    2. Implementation Details

      • Internal workings of components
      • Usage instructions (these belong in feature documentation)
    "},{"location":"docs/references/terminology/#core-concepts","title":"Core Concepts","text":""},{"location":"docs/references/terminology/#target","title":"Target","text":"

    Types of artifacts that Trivy can scan, like container images and filesystem.

    "},{"location":"docs/references/terminology/#scanner","title":"Scanner","text":"

    Trivy's built-in security scanning engines. Trivy has four main scanners:

    • Vulnerability Scanner
    • Misconfiguration Scanner
    • Secret Scanner
    • License Scanner

    Note

    SBOM is not a scanner but an output format option.

    "},{"location":"docs/references/terminology/#scan-assets","title":"Scan Assets","text":"

    External data that Trivy downloads (if needed for scanner) and uses during scanning:

    • Vulnerability Database (Trivy DB, trivy-db): Database containing vulnerability information
    • Java Index Database (Trivy Java DB, trivy-java-db): Database for Java artifact identification
    • Checks Bundle (trivy-checks): Archive containing misconfiguration detection rules
    • VEX Repository: Repository containing VEX documents
    "},{"location":"docs/references/terminology/#vulnerability-scanning","title":"Vulnerability Scanning","text":""},{"location":"docs/references/terminology/#vulnerability-database-trivy-db-trivy-db","title":"Vulnerability Database (Trivy DB, trivy-db)","text":"

    The core vulnerability database required for vulnerability detection. Contains comprehensive vulnerability information for multiple ecosystems. Distributed via OCI registry.

    Managed at https://github.com/aquasecurity/trivy-db.

    The vulnerability database is built from a GitHub repository that collects and stores vulnerability information from various data sources. This repository serves as the foundation for building the Trivy DB.

    Managed at:

    • https://github.com/aquasecurity/vuln-list
    • https://github.com/aquasecurity/vuln-list-nvd
    • https://github.com/aquasecurity/vuln-list-redhat
    • https://github.com/aquasecurity/vuln-list-debian
    • etc.
    "},{"location":"docs/references/terminology/#java-index-database-trivy-java-db-trivy-java-db","title":"Java Index Database (Trivy Java DB, trivy-java-db)","text":"

    Specialized database used for identifying Java libraries and their components during JAR/WAR/PAR/EAR scanning. Distributed via OCI registry.

    Managed at https://github.com/aquasecurity/trivy-java-db.

    "},{"location":"docs/references/terminology/#misconfiguration-scanning","title":"Misconfiguration Scanning","text":"

    When the context does not clearly indicate these terms are related to misconfiguration scanning, they may be prefixed with \"Misconfiguration\" for clarity. For example, \"Check\" may be referred to as \"Misconfiguration Check\", and \"Checks Bundle\" as \"Misconfiguration Checks Bundle\".

    "},{"location":"docs/references/terminology/#check","title":"Check","text":"

    A Rego file that defines rules for detecting misconfigurations in various types of IaC files.

    "},{"location":"docs/references/terminology/#built-in-checks","title":"Built-in Checks","text":"

    Default set of checks distributed through the trivy-checks repository, providing standard security and configuration best practices.

    "},{"location":"docs/references/terminology/#checks-bundle","title":"Checks Bundle","text":"

    A tar.gz archive containing the built-in checks, distributed via OCI registry.

    "},{"location":"docs/references/terminology/#secret-scanning","title":"Secret Scanning","text":""},{"location":"docs/references/terminology/#rule","title":"Rule","text":"

    Pattern matching rules used to detect hardcoded secrets and sensitive information. Each rule consists of:

    • Metadata (ID, Category, Title, etc.)
    • Regular expressions for matching sensitive patterns
    • Additional context for detection accuracy
    "},{"location":"docs/references/terminology/#kubernetes-integration","title":"Kubernetes Integration","text":""},{"location":"docs/references/terminology/#kbom-kubernetes-bill-of-materials","title":"KBOM (Kubernetes Bill of Materials)","text":"

    A specialized SBOM format for Kubernetes clusters that includes detailed information about the cluster's components.

    "},{"location":"docs/references/terminology/#vex-vulnerability-exploitability-exchange","title":"VEX (Vulnerability Exploitability eXchange)","text":""},{"location":"docs/references/terminology/#vex-repository","title":"VEX Repository","text":"

    A repository system that stores VEX documents following the VEX Repository Specification. VEX repositories help users manage and share information about vulnerability applicability and exploitability.

    For detailed information about VEX repositories, see the document.

    "},{"location":"docs/references/terminology/#vex-hub","title":"VEX Hub","text":"

    The default VEX repository managed by Aqua Security at https://github.com/aquasecurity/vexhub. It primarily aggregates VEX documents published by package maintainers in their source repositories. VEX Hub serves as a central point for collecting and distributing vulnerability applicability information for OSS projects.

    "},{"location":"docs/references/terminology/#cache-system","title":"Cache System","text":""},{"location":"docs/references/terminology/#cache-types","title":"Cache Types","text":"

    The cache directory contains several distinct types of data:

    • Vulnerability Database
    • Java Index Database
    • Misconfiguration Checks
    • VEX Repositories
    • Scan Cache
    "},{"location":"docs/references/terminology/#asset-cache","title":"Asset Cache","text":"

    Downloaded assets like vulnerability databases and Java index databases.

    "},{"location":"docs/references/terminology/#scan-cache","title":"Scan Cache","text":"

    A caching mechanism that stores analysis results from previous scans to speed up subsequent scans. For container image scanning, the scan cache stores analysis results including package names and versions per layer.

    For detailed information about caching, see the document.

    "},{"location":"docs/references/terminology/#plugin-system","title":"Plugin System","text":""},{"location":"docs/references/terminology/#plugin","title":"Plugin","text":"

    An add-on tool that integrates with Trivy to extend its core functionality. Plugins can be written in any programming language and integrate seamlessly with Trivy CLI, appearing in Trivy help and subcommands. They can be installed and removed independently without affecting the core Trivy installation.

    For detailed information about plugins, see the document.

    "},{"location":"docs/references/terminology/#plugin-index-trivy-plugin-index","title":"Plugin Index (trivy-plugin-index)","text":"

    A centralized registry that lists available Trivy plugins, managed at https://github.com/aquasecurity/trivy-plugin-index. The index maintains a curated list of official and community plugins, providing metadata such as plugin names, descriptions, and maintainers. It enables plugin discovery through the trivy plugin search command and facilitates automatic plugin installation and updates.

    For detailed information about the plugin index, see the document.

    "},{"location":"docs/references/terminology/#module-system","title":"Module System","text":""},{"location":"docs/references/terminology/#module","title":"Module","text":"

    A WebAssembly-based extension mechanism that allows custom scanning logic without modifying the Trivy binary. Modules can modify scan results by analyzing files or post-processing results.

    For detailed information about modules, see the document.

    "},{"location":"docs/references/troubleshooting/","title":"Troubleshooting","text":""},{"location":"docs/references/troubleshooting/#scan","title":"Scan","text":""},{"location":"docs/references/troubleshooting/#timeout","title":"Timeout","text":"

    Error

    $ trivy image ...\n...\nanalyze error: timeout: context deadline exceeded\n

    Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as --timeout 15m.

    "},{"location":"docs/references/troubleshooting/#unable-to-initialize-an-image-scanner","title":"Unable to initialize an image scanner","text":"

    Error

    $ trivy image ...\n...\n2024-01-19T08:15:33.288Z    FATAL   image scan error: scan error: unable to initialize a scanner: unable to initialize an image scanner: 4 errors occurred:\n* docker error: unable to inspect the image (ContainerImageName): Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\n* containerd error: containerd socket not found: /run/containerd/containerd.sock\n* podman error: unable to initialize Podman client: no podman socket found: stat podman/podman.sock: no such file or directory\n* remote error: GET https://index.docker.io/v2/ContainerImageName: MANIFEST_UNKNOWN: manifest unknown; unknown tag=0.1\n

    It means Trivy is unable to find the container image in the following places:

    • Docker Engine
    • containerd
    • Podman
    • A remote registry

    Please see error messages for details of each error.

    Common mistakes include the following, depending on where you are pulling images from:

    "},{"location":"docs/references/troubleshooting/#common","title":"Common","text":"
    • Typos in the image name
      • Common mistake :)
    • Forgetting to specify the registry
      • By default, it is considered to be Docker Hub ( index.docker.io ).
    "},{"location":"docs/references/troubleshooting/#docker-engine","title":"Docker Engine","text":"
    • Incorrect Docker host
      • If the Docker daemon's socket path is not /var/run/docker.sock, you need to specify the --docker-host flag or the DOCKER_HOST environment variable. The same applies when using TCP; you must specify the correct host address.
    "},{"location":"docs/references/troubleshooting/#containerd","title":"containerd","text":"
    • Incorrect containerd address
      • If you are using a non-default path, you need to specify the CONTAINERD_ADDRESS environment variable. Please refer to this documentation.
    • Incorrect namespace
      • If you are using a non-default namespace, you need to specify the CONTAINERD_NAMESPACE environment variable. Please refer to this documentation.
    "},{"location":"docs/references/troubleshooting/#podman","title":"Podman","text":"
    • Podman socket configuration
      • You need to enable the Podman socket. Please refer to this documentation.
    "},{"location":"docs/references/troubleshooting/#container-registry","title":"Container Registry","text":"
    • Unauthenticated
      • If you are using a private container registry, you need to authenticate. Please refer to this documentation.
    • Using a proxy
      • If you are using a proxy within your network, you need to correctly set the HTTP_PROXY, HTTPS_PROXY, etc., environment variables.
    • Use of a self-signed certificate in the registry
      • Because certificate verification will fail, you need to either trust that certificate or use the --insecure flag (not recommended in production).
    "},{"location":"docs/references/troubleshooting/#certification","title":"Certification","text":"

    Error

    Error: x509: certificate signed by unknown authority

    TRIVY_INSECURE can be used to allow insecure connections to a container registry when using SSL.

    $ TRIVY_INSECURE=true trivy image [YOUR_IMAGE]\n
    "},{"location":"docs/references/troubleshooting/#github-rate-limiting","title":"GitHub Rate limiting","text":"

    Error

    $ trivy image ...\n...\nAPI rate limit exceeded for xxx.xxx.xxx.xxx.\n

    Specify GITHUB_TOKEN for authentication https://developer.github.com/v3/#rate-limiting

    $ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10\n
    "},{"location":"docs/references/troubleshooting/#unable-to-open-jar-files","title":"Unable to open JAR files","text":"

    Error

    $ trivy image ...\n...\nfailed to analyze file: failed to analyze usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: unable to open usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: failed to open: unable to read the file: stream error: stream ID 9; PROTOCOL_ERROR; received from peer\n

    Currently, we're investigating this issue. As a temporary mitigation, you may be able to avoid this issue by downloading the Java DB in advance.

    $ trivy image --download-java-db-only\n2023-02-01T16:57:04.322+0900    INFO    Downloading the Java DB...\n$ trivy image [YOUR_JAVA_IMAGE]\n
    "},{"location":"docs/references/troubleshooting/#running-in-parallel-takes-same-time-as-series-run","title":"Running in parallel takes same time as series run","text":"

    When running trivy on multiple images simultaneously, it will take same time as running trivy in series. This is because of a limitation of boltdb.

    Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.

    Reference : boltdb: Opening a database.

    "},{"location":"docs/references/troubleshooting/#multiple-trivy-servers","title":"Multiple Trivy servers","text":"

    Error

    $ trivy image --server http://xxx.com:xxxx test-image\n...\n- twirp error internal: failed scan, test-image: failed to apply layers: layer cache missing: sha256:*****\n

    To run multiple Trivy servers, you need to use Redis as the cache backend so that those servers can share the cache. Follow this instruction to do so.

    "},{"location":"docs/references/troubleshooting/#problems-with-tmp-on-remote-git-repository-scans","title":"Problems with /tmp on remote Git repository scans","text":"

    Error

    FATAL repository scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: git clone error: write /tmp/fanal-remote...

    Trivy clones remote Git repositories under the /tmp directory before scanning them. If /tmp doesn't work for you, you can change it by setting the TMPDIR environment variable.

    Try:

    $ TMPDIR=/my/custom/path trivy repo ...\n
    "},{"location":"docs/references/troubleshooting/#running-out-of-space-during-image-scans","title":"Running out of space during image scans","text":"

    Error

    image scan failed:\nfailed to copy the image:\nwrite /tmp/fanal-3323732142: no space left on device\n

    Trivy uses a temporary directory during image scans. The directory path would be determined as follows:

    • On Unix systems: Use $TMPDIR if non-empty, else /tmp.
    • On Windows: Uses GetTempPath, returning the first non-empty value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.

    See this documentation for more details.

    If the image is large or the temporary directory has insufficient space, the scan will fail. You can configure the directory path to redirect Trivy to a directory with adequate storage. On Unix systems, you can set the $TMPDIR environment variable.

    $ TMPDIR=/my/custom/path trivy image ...\n

    When scanning images from a container registry, Trivy processes each layer by streaming, loading only the necessary files for the scan into memory and discarding unnecessary files. If a layer contains large files that are necessary for the scan (such as JAR files or binary files), Trivy saves them to a temporary directory (e.g. $TMPDIR) on local storage to avoid increased memory consumption. Although these files are deleted after the scan is complete, they can temporarily increase disk consumption and potentially exhaust storage. In such cases, there are currently three workarounds:

    1. Use a temporary directory with sufficient capacity

      This is the same as explained above.

    2. Specify a small value for --parallel

      By default, multiple layers are processed in parallel. If each layer contains large files, disk space may be consumed rapidly. By specifying a small value such as --parallel 1, parallelism is reduced, which can mitigate the issue.

    3. Specify --skip-files or --skip-dirs

      If the container image contains large files that do not need to be scanned, you can skip their processing by specifying --skip-files or --skip-dirs. For more details, please refer to this documentation.

    "},{"location":"docs/references/troubleshooting/#db","title":"DB","text":""},{"location":"docs/references/troubleshooting/#old-db-schema","title":"Old DB schema","text":"

    Error

    --skip-update cannot be specified with the old DB schema.

    Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow the instruction of air-gapped environment.

    "},{"location":"docs/references/troubleshooting/#error-downloading-vulnerability-db","title":"Error downloading vulnerability DB","text":"

    Error

    FATAL failed to download vulnerability DB

    If Trivy is running behind corporate firewall, refer to the necessary connectivity requirements as described here.

    "},{"location":"docs/references/troubleshooting/#denied","title":"Denied","text":"

    Error

    GET https://ghcr.io/token?scope=repository%3Aaquasecurity%2Ftrivy-db%3Apull&service=ghcr.io: DENIED: denied

    Your local GHCR (GitHub Container Registry) token might be expired. Please remove the token and try downloading the DB again.

    docker logout ghcr.io\n
    "},{"location":"docs/references/troubleshooting/#homebrew","title":"Homebrew","text":""},{"location":"docs/references/troubleshooting/#scope-error","title":"Scope error","text":"

    Error

    Error: Your macOS keychain GitHub credentials do not have sufficient scope!

    $ brew tap aquasecurity/trivy\nError: Your macOS keychain GitHub credentials do not have sufficient scope!\nScopes they need: none\nScopes they have:\nCreate a personal access token:\nhttps://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew\necho 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.zshrc\n

    Try:

    $ printf \"protocol=https\\nhost=github.com\\n\" | git credential-osxkeychain erase\n
    "},{"location":"docs/references/troubleshooting/#already-installed","title":"Already installed","text":"

    Error

    Error: aquasecurity/trivy/trivy 64 already installed

    $ brew upgrade\n...\nError: aquasecurity/trivy/trivy 64 already installed\n

    Try:

    $ brew unlink trivy && brew uninstall trivy\n($ rm -rf /usr/local/Cellar/trivy/64)\n$ brew install aquasecurity/trivy/trivy\n
    "},{"location":"docs/references/troubleshooting/#others","title":"Others","text":""},{"location":"docs/references/troubleshooting/#unknown-error","title":"Unknown error","text":"

    Try again after running trivy clean --all:

    $ trivy clean --all\n
    "},{"location":"docs/references/configuration/config-file/","title":"Config file","text":"

    Trivy can be customized by tweaking a trivy.yaml file. The config path can be overridden by the --config flag.

    An example is here.

    These samples contain default values for flags.

    "},{"location":"docs/references/configuration/config-file/#global-options","title":"Global options","text":"
    cache:\n  # Same as '--cache-dir'\n  dir: \"/path/to/cache\"\n\n# Same as '--debug'\ndebug: false\n\n# Same as '--insecure'\ninsecure: false\n\n# Same as '--quiet'\nquiet: false\n\n# Same as '--timeout'\ntimeout: 5m0s\n
    "},{"location":"docs/references/configuration/config-file/#cache-options","title":"Cache options","text":"
    cache:\n  # Same as '--cache-backend'\n  backend: \"fs\"\n\n  redis:\n    # Same as '--redis-ca'\n    ca: \"\"\n\n    # Same as '--redis-cert'\n    cert: \"\"\n\n    # Same as '--redis-key'\n    key: \"\"\n\n    # Same as '--redis-tls'\n    tls: false\n\n  # Same as '--cache-ttl'\n  ttl: 0s\n
    "},{"location":"docs/references/configuration/config-file/#clean-options","title":"Clean options","text":"
    clean:\n  # Same as '--all'\n  all: false\n\n  # Same as '--checks-bundle'\n  checks-bundle: false\n\n  # Same as '--java-db'\n  java-db: false\n\n  # Same as '--scan-cache'\n  scan-cache: false\n\n  # Same as '--vex-repo'\n  vex-repo: false\n\n  # Same as '--vuln-db'\n  vuln-db: false\n
    "},{"location":"docs/references/configuration/config-file/#clientserver-options","title":"Client/Server options","text":"
    server:\n  # Same as '--server'\n  addr: \"\"\n\n  # Same as '--custom-headers'\n  custom-headers: []\n\n  # Same as '--listen'\n  listen: \"localhost:4954\"\n\n  # Same as '--token'\n  token: \"\"\n\n  # Same as '--token-header'\n  token-header: \"Trivy-Token\"\n
    "},{"location":"docs/references/configuration/config-file/#db-options","title":"DB options","text":"
    db:\n  # Same as '--download-java-db-only'\n  download-java-only: false\n\n  # Same as '--download-db-only'\n  download-only: false\n\n  # Same as '--java-db-repository'\n  java-repository:\n   - mirror.gcr.io/aquasec/trivy-java-db:1\n   - ghcr.io/aquasecurity/trivy-java-db:1\n\n  # Same as '--skip-java-db-update'\n  java-skip-update: false\n\n  # Same as '--no-progress'\n  no-progress: false\n\n  # Same as '--db-repository'\n  repository:\n   - mirror.gcr.io/aquasec/trivy-db:2\n   - ghcr.io/aquasecurity/trivy-db:2\n\n  # Same as '--skip-db-update'\n  skip-update: false\n
    "},{"location":"docs/references/configuration/config-file/#image-options","title":"Image options","text":"
    image:\n  docker:\n    # Same as '--docker-host'\n    host: \"\"\n\n  # Same as '--image-config-scanners'\n  image-config-scanners: []\n\n  # Same as '--input'\n  input: \"\"\n\n  # Same as '--platform'\n  platform: \"\"\n\n  podman:\n    # Same as '--podman-host'\n    host: \"\"\n\n  # Same as '--removed-pkgs'\n  removed-pkgs: false\n\n  # Same as '--image-src'\n  source:\n   - docker\n   - containerd\n   - podman\n   - remote\n
    "},{"location":"docs/references/configuration/config-file/#kubernetes-options","title":"Kubernetes options","text":"
    kubernetes:\n  # Same as '--burst'\n  burst: 10\n\n  # Same as '--disable-node-collector'\n  disableNodeCollector: false\n\n  exclude:\n    # Same as '--exclude-nodes'\n    nodes: []\n\n    # Same as '--exclude-owned'\n    owned: false\n\n  # Same as '--exclude-kinds'\n  excludeKinds: []\n\n  # Same as '--exclude-namespaces'\n  excludeNamespaces: []\n\n  # Same as '--include-kinds'\n  includeKinds: []\n\n  # Same as '--include-namespaces'\n  includeNamespaces: []\n\n  # Same as '--k8s-version'\n  k8s-version: \"\"\n\n  # Same as '--kubeconfig'\n  kubeconfig: \"\"\n\n  node-collector:\n    # Same as '--node-collector-imageref'\n    imageref: \"ghcr.io/aquasecurity/node-collector:0.3.1\"\n\n    # Same as '--node-collector-namespace'\n    namespace: \"trivy-temp\"\n\n  # Same as '--qps'\n  qps: 5\n\n  # Same as '--skip-images'\n  skipImages: false\n\n  # Same as '--tolerations'\n  tolerations: []\n
    "},{"location":"docs/references/configuration/config-file/#license-options","title":"License options","text":"
    license:\n  # Same as '--license-confidence-level'\n  confidenceLevel: 0.9\n\n  forbidden:\n   - AGPL-1.0\n   - AGPL-3.0\n   - CC-BY-NC-1.0\n   - CC-BY-NC-2.0\n   - CC-BY-NC-2.5\n   - CC-BY-NC-3.0\n   - CC-BY-NC-4.0\n   - CC-BY-NC-ND-1.0\n   - CC-BY-NC-ND-2.0\n   - CC-BY-NC-ND-2.5\n   - CC-BY-NC-ND-3.0\n   - CC-BY-NC-ND-4.0\n   - CC-BY-NC-SA-1.0\n   - CC-BY-NC-SA-2.0\n   - CC-BY-NC-SA-2.5\n   - CC-BY-NC-SA-3.0\n   - CC-BY-NC-SA-4.0\n   - Commons-Clause\n   - Facebook-2-Clause\n   - Facebook-3-Clause\n   - Facebook-Examples\n   - WTFPL\n\n  # Same as '--license-full'\n  full: false\n\n  # Same as '--ignored-licenses'\n  ignored: []\n\n  notice:\n   - AFL-1.1\n   - AFL-1.2\n   - AFL-2.0\n   - AFL-2.1\n   - AFL-3.0\n   - Apache-1.0\n   - Apache-1.1\n   - Apache-2.0\n   - Artistic-1.0-cl8\n   - Artistic-1.0-Perl\n   - Artistic-1.0\n   - Artistic-2.0\n   - BSL-1.0\n   - BSD-2-Clause-FreeBSD\n   - BSD-2-Clause-NetBSD\n   - BSD-2-Clause\n   - BSD-3-Clause-Attribution\n   - BSD-3-Clause-Clear\n   - BSD-3-Clause-LBNL\n   - BSD-3-Clause\n   - BSD-4-Clause\n   - BSD-4-Clause-UC\n   - BSD-Protection\n   - CC-BY-1.0\n   - CC-BY-2.0\n   - CC-BY-2.5\n   - CC-BY-3.0\n   - CC-BY-4.0\n   - FTL\n   - ISC\n   - ImageMagick\n   - Libpng\n   - Lil-1.0\n   - Linux-OpenIB\n   - LPL-1.02\n   - LPL-1.0\n   - MS-PL\n   - MIT\n   - NCSA\n   - OpenSSL\n   - PHP-3.01\n   - PHP-3.0\n   - PIL\n   - Python-2.0\n   - Python-2.0-complete\n   - PostgreSQL\n   - SGI-B-1.0\n   - SGI-B-1.1\n   - SGI-B-2.0\n   - Unicode-DFS-2015\n   - Unicode-DFS-2016\n   - Unicode-TOU\n   - UPL-1.0\n   - W3C-19980720\n   - W3C-20150513\n   - W3C\n   - X11\n   - Xnet\n   - Zend-2.0\n   - zlib-acknowledgement\n   - Zlib\n   - ZPL-1.1\n   - ZPL-2.0\n   - ZPL-2.1\n\n  permissive: []\n\n  reciprocal:\n   - APSL-1.0\n   - APSL-1.1\n   - APSL-1.2\n   - APSL-2.0\n   - CDDL-1.0\n   - CDDL-1.1\n   - CPL-1.0\n   - EPL-1.0\n   - EPL-2.0\n   - FreeImage\n   - IPL-1.0\n   - MPL-1.0\n   - MPL-1.1\n   - MPL-2.0\n   - Ruby\n\n  restricted:\n   - BCL\n   - CC-BY-ND-1.0\n   - CC-BY-ND-2.0\n   - CC-BY-ND-2.5\n   - CC-BY-ND-3.0\n   - CC-BY-ND-4.0\n   - CC-BY-SA-1.0\n   - CC-BY-SA-2.0\n   - CC-BY-SA-2.5\n   - CC-BY-SA-3.0\n   - CC-BY-SA-4.0\n   - GPL-1.0\n   - GPL-2.0\n   - GPL-2.0-with-autoconf-exception\n   - GPL-2.0-with-bison-exception\n   - GPL-2.0-with-classpath-exception\n   - GPL-2.0-with-font-exception\n   - GPL-2.0-with-GCC-exception\n   - GPL-3.0\n   - GPL-3.0-with-autoconf-exception\n   - GPL-3.0-with-GCC-exception\n   - LGPL-2.0\n   - LGPL-2.1\n   - LGPL-3.0\n   - NPL-1.0\n   - NPL-1.1\n   - OSL-1.0\n   - OSL-1.1\n   - OSL-2.0\n   - OSL-2.1\n   - OSL-3.0\n   - QPL-1.0\n   - Sleepycat\n\n  unencumbered:\n   - CC0-1.0\n   - Unlicense\n   - 0BSD\n
    "},{"location":"docs/references/configuration/config-file/#misconfiguration-options","title":"Misconfiguration options","text":"
    misconfiguration:\n  # Same as '--checks-bundle-repository'\n  checks-bundle-repository: \"mirror.gcr.io/aquasec/trivy-checks:1\"\n\n  cloudformation:\n    # Same as '--cf-params'\n    params: []\n\n  # Same as '--config-file-schemas'\n  config-file-schemas: []\n\n  helm:\n    # Same as '--helm-api-versions'\n    api-versions: []\n\n    # Same as '--helm-kube-version'\n    kube-version: \"\"\n\n    # Same as '--helm-set'\n    set: []\n\n    # Same as '--helm-set-file'\n    set-file: []\n\n    # Same as '--helm-set-string'\n    set-string: []\n\n    # Same as '--helm-values'\n    values: []\n\n  # Same as '--include-non-failures'\n  include-non-failures: false\n\n  # Same as '--misconfig-scanners'\n  scanners:\n   - azure-arm\n   - cloudformation\n   - dockerfile\n   - helm\n   - kubernetes\n   - terraform\n   - terraformplan-json\n   - terraformplan-snapshot\n\n  terraform:\n    # Same as '--tf-exclude-downloaded-modules'\n    exclude-downloaded-modules: false\n\n    # Same as '--tf-vars'\n    vars: []\n
    "},{"location":"docs/references/configuration/config-file/#module-options","title":"Module options","text":"
    module:\n  # Same as '--module-dir'\n  dir: \"$HOME/.trivy/modules\"\n\n  # Same as '--enable-modules'\n  enable-modules: []\n
    "},{"location":"docs/references/configuration/config-file/#package-options","title":"Package options","text":"
    pkg:\n  # Same as '--include-dev-deps'\n  include-dev-deps: false\n\n  # Same as '--pkg-relationships'\n  relationships:\n   - unknown\n   - root\n   - workspace\n   - direct\n   - indirect\n\n  # Same as '--pkg-types'\n  types:\n   - os\n   - library\n
    "},{"location":"docs/references/configuration/config-file/#registry-options","title":"Registry options","text":"
    registry:\n  # Same as '--password'\n  password: []\n\n  # Same as '--password-stdin'\n  password-stdin: false\n\n  # Same as '--registry-token'\n  token: \"\"\n\n  # Same as '--username'\n  username: []\n
    "},{"location":"docs/references/configuration/config-file/#rego-options","title":"Rego options","text":"
    rego:\n  # Same as '--config-check'\n  check: []\n\n  # Same as '--config-data'\n  data: []\n\n  # Same as '--include-deprecated-checks'\n  include-deprecated-checks: false\n\n  # Same as '--check-namespaces'\n  namespaces: []\n\n  # Same as '--skip-check-update'\n  skip-check-update: false\n\n  # Same as '--trace'\n  trace: false\n
    "},{"location":"docs/references/configuration/config-file/#report-options","title":"Report options","text":"
    # Same as '--dependency-tree'\ndependency-tree: false\n\n# Same as '--exit-code'\nexit-code: 0\n\n# Same as '--exit-on-eol'\nexit-on-eol: 0\n\n# Same as '--format'\nformat: \"table\"\n\n# Same as '--ignore-policy'\nignore-policy: \"\"\n\n# Same as '--ignorefile'\nignorefile: \".trivyignore\"\n\n# Same as '--list-all-pkgs'\nlist-all-pkgs: false\n\n# Same as '--output'\noutput: \"\"\n\n# Same as '--output-plugin-arg'\noutput-plugin-arg: \"\"\n\n# Same as '--report'\nreport: \"all\"\n\nscan:\n  # Same as '--compliance'\n  compliance: \"\"\n\n  # Same as '--show-suppressed'\n  show-suppressed: false\n\n# Same as '--severity'\nseverity:\n - UNKNOWN\n - LOW\n - MEDIUM\n - HIGH\n - CRITICAL\n\n# Same as '--template'\ntemplate: \"\"\n
    "},{"location":"docs/references/configuration/config-file/#repository-options","title":"Repository options","text":"
    repository:\n  # Same as '--branch'\n  branch: \"\"\n\n  # Same as '--commit'\n  commit: \"\"\n\n  # Same as '--tag'\n  tag: \"\"\n
    "},{"location":"docs/references/configuration/config-file/#scan-options","title":"Scan options","text":"
    scan:\n  # Same as '--detection-priority'\n  detection-priority: \"precise\"\n\n  # Same as '--file-patterns'\n  file-patterns: []\n\n  # Same as '--offline-scan'\n  offline: false\n\n  # Same as '--parallel'\n  parallel: 5\n\n  # Same as '--rekor-url'\n  rekor-url: \"https://rekor.sigstore.dev\"\n\n  # Same as '--sbom-sources'\n  sbom-sources: []\n\n  # Same as '--scanners'\n  scanners:\n   - vuln\n   - secret\n\n  # Same as '--skip-dirs'\n  skip-dirs: []\n\n  # Same as '--skip-files'\n  skip-files: []\n
    "},{"location":"docs/references/configuration/config-file/#secret-options","title":"Secret options","text":"
    secret:\n  # Same as '--secret-config'\n  config: \"trivy-secret.yaml\"\n
    "},{"location":"docs/references/configuration/config-file/#vulnerability-options","title":"Vulnerability options","text":"
    vulnerability:\n  # Same as '--ignore-status'\n  ignore-status: []\n\n  # Same as '--ignore-unfixed'\n  ignore-unfixed: false\n\n  # Same as '--skip-vex-repo-update'\n  skip-vex-repo-update: false\n\n  # Same as '--vex'\n  vex: []\n
    "},{"location":"docs/references/configuration/cli/trivy/","title":"Overview","text":""},{"location":"docs/references/configuration/cli/trivy/#trivy","title":"trivy","text":"

    Unified security scanner

    "},{"location":"docs/references/configuration/cli/trivy/#synopsis","title":"Synopsis","text":"

    Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets

    trivy [global flags] command [flags] target\n
    "},{"location":"docs/references/configuration/cli/trivy/#examples","title":"Examples","text":"
      # Scan a container image\n  $ trivy image python:3.4-alpine\n\n  # Scan a container image from a tar archive\n  $ trivy image --input ruby-3.1.tar\n\n  # Scan local filesystem\n  $ trivy fs .\n\n  # Run in server mode\n  $ trivy server\n
    "},{"location":"docs/references/configuration/cli/trivy/#options","title":"Options","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n  -f, --format string             version format (json)\n      --generate-default-config   write the default config to trivy-default.yaml\n  -h, --help                      help for trivy\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy/#see-also","title":"SEE ALSO","text":"
    • trivy clean - Remove cached files
    • trivy config - Scan config files for misconfigurations
    • trivy convert - Convert Trivy JSON report into a different format
    • trivy filesystem - Scan local filesystem
    • trivy image - Scan a container image
    • trivy kubernetes - [EXPERIMENTAL] Scan kubernetes cluster
    • trivy module - Manage modules
    • trivy plugin - Manage plugins
    • trivy registry - Manage registry authentication
    • trivy repository - Scan a repository
    • trivy rootfs - Scan rootfs
    • trivy sbom - Scan SBOM for vulnerabilities and licenses
    • trivy server - Server mode
    • trivy version - Print the version
    • trivy vex - [EXPERIMENTAL] VEX utilities
    • trivy vm - [EXPERIMENTAL] Scan a virtual machine image
    "},{"location":"docs/references/configuration/cli/trivy_clean/","title":"Clean","text":""},{"location":"docs/references/configuration/cli/trivy_clean/#trivy-clean","title":"trivy clean","text":"

    Remove cached files

    trivy clean [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_clean/#examples","title":"Examples","text":"
      # Remove all caches\n  $ trivy clean --all\n\n  # Remove scan cache\n  $ trivy clean --scan-cache\n\n  # Remove vulnerability database\n  $ trivy clean --vuln-db\n
    "},{"location":"docs/references/configuration/cli/trivy_clean/#options","title":"Options","text":"
      -a, --all             remove all caches\n      --checks-bundle   remove checks bundle\n  -h, --help            help for clean\n      --java-db         remove Java database\n      --scan-cache      remove scan cache (container and VM image analysis results)\n      --vex-repo        remove VEX repositories\n      --vuln-db         remove vulnerability database\n
    "},{"location":"docs/references/configuration/cli/trivy_clean/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_clean/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_config/","title":"Config","text":""},{"location":"docs/references/configuration/cli/trivy_config/#trivy-config","title":"trivy config","text":"

    Scan config files for misconfigurations

    trivy config [flags] DIR\n
    "},{"location":"docs/references/configuration/cli/trivy_config/#options","title":"Options","text":"
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"memory\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --cf-params strings                 specify paths to override the CloudFormation parameters files\n      --check-namespaces strings          Rego namespaces\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --compliance string                 compliance report to generate\n      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files\n      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --enable-modules strings            [EXPERIMENTAL] module names to enable\n      --exit-code int                     specify exit code when any security issues are found\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for config\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --include-deprecated-checks         include deprecated checks\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --k8s-version string                specify k8s version to validate outdated api by it (example: 1.21.0)\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --module-dir string                 specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin                    password from stdin. Comma-separated passwords are not supported.\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string             registry token\n      --report string                     specify a compliance report format for the output (all,summary) (default \"all\")\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --skip-check-update                 skip fetching rego check updates\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --tf-vars strings                   specify paths to override the Terraform tfvars files\n      --trace                             enable more verbose trace output for custom queries\n      --username strings                  username. Comma-separated usernames allowed.\n
    "},{"location":"docs/references/configuration/cli/trivy_config/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_config/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_convert/","title":"Convert","text":""},{"location":"docs/references/configuration/cli/trivy_convert/#trivy-convert","title":"trivy convert","text":"

    Convert Trivy JSON report into a different format

    trivy convert [flags] RESULT_JSON\n
    "},{"location":"docs/references/configuration/cli/trivy_convert/#examples","title":"Examples","text":"
      # report conversion\n  $ trivy image --format json --output result.json --list-all-pkgs debian:11\n  $ trivy convert --format cyclonedx --output result.cdx result.json\n
    "},{"location":"docs/references/configuration/cli/trivy_convert/#options","title":"Options","text":"
          --compliance string          compliance report to generate\n      --dependency-tree            [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --exit-code int              specify exit code when any security issues are found\n      --exit-on-eol int            exit with the specified code when the OS reaches end of service/life\n  -f, --format string              format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n  -h, --help                       help for convert\n      --ignore-policy string       specify the Rego file path to evaluate each vulnerability\n      --ignorefile string          specify .trivyignore file (default \".trivyignore\")\n      --list-all-pkgs              output all packages in the JSON report regardless of vulnerability\n  -o, --output string              output file name\n      --output-plugin-arg string   [EXPERIMENTAL] output plugin arguments\n      --report string              specify a report format for the output (all,summary) (default \"all\")\n  -s, --severity strings           severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed            [EXPERIMENTAL] show suppressed vulnerabilities\n  -t, --template string            output template\n
    "},{"location":"docs/references/configuration/cli/trivy_convert/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_convert/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_filesystem/","title":"Filesystem","text":""},{"location":"docs/references/configuration/cli/trivy_filesystem/#trivy-filesystem","title":"trivy filesystem","text":"

    Scan local filesystem

    trivy filesystem [flags] PATH\n
    "},{"location":"docs/references/configuration/cli/trivy_filesystem/#examples","title":"Examples","text":"
      # Scan a local project including language-specific files\n  $ trivy fs /path/to/your_project\n\n  # Scan a single file\n  $ trivy fs ./trivy-ci-test/Pipfile.lock\n
    "},{"location":"docs/references/configuration/cli/trivy_filesystem/#options","title":"Options","text":"
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"memory\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --cf-params strings                 specify paths to override the CloudFormation parameters files\n      --check-namespaces strings          Rego namespaces\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --compliance string                 compliance report to generate\n      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files\n      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --custom-headers strings            custom headers in client mode\n      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --detection-priority string         specify the detection priority:\n                                            - \"precise\": Prioritizes precise by minimizing false positives.\n                                            - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                           (precise,comprehensive) (default \"precise\")\n      --download-db-only                  download/update vulnerability database but don't run a scan\n      --download-java-db-only             download/update Java index database but don't run a scan\n      --enable-modules strings            [EXPERIMENTAL] module names to enable\n      --exit-code int                     specify exit code when any security issues are found\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for filesystem\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed                    display only fixed vulnerabilities\n      --ignored-licenses strings          specify a list of license to ignore\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --include-deprecated-checks         include deprecated checks\n      --include-dev-deps                  include development dependencies in the report (supported: npm, yarn)\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --license-confidence-level float    specify license classifier's confidence level (default 0.9)\n      --license-full                      eagerly look for licenses in source code headers and license files\n      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --module-dir string                 specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n      --no-progress                       suppress progress bar\n      --offline-scan                      do not issue API requests to identify dependencies\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)\n      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin                    password from stdin. Comma-separated passwords are not supported.\n      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings                 list of package types (os,library) (default [os,library])\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string             registry token\n      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --report string                     specify a compliance report format for the output (all,summary) (default \"all\")\n      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])\n      --secret-config string              specify a path to config file for secret scanning (default \"trivy-secret.yaml\")\n      --server string                     server address in client mode\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-check-update                 skip fetching rego check updates\n      --skip-db-update                    skip updating vulnerability database\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n      --skip-java-db-update               skip updating Java index database\n      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --tf-vars strings                   specify paths to override the Terraform tfvars files\n      --token string                      for authentication in client/server mode\n      --token-header string               specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --trace                             enable more verbose trace output for custom queries\n      --username strings                  username. Comma-separated usernames allowed.\n      --vex strings                       [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_filesystem/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_filesystem/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_image/","title":"Image","text":""},{"location":"docs/references/configuration/cli/trivy_image/#trivy-image","title":"trivy image","text":"

    Scan a container image

    trivy image [flags] IMAGE_NAME\n
    "},{"location":"docs/references/configuration/cli/trivy_image/#examples","title":"Examples","text":"
      # Scan a container image\n  $ trivy image python:3.4-alpine\n\n  # Scan a container image from a tar archive\n  $ trivy image --input ruby-3.1.tar\n\n  # Filter by severities\n  $ trivy image --severity HIGH,CRITICAL alpine:3.15\n\n  # Ignore unfixed/unpatched vulnerabilities\n  $ trivy image --ignore-unfixed alpine:3.15\n\n  # Scan a container image in client mode\n  $ trivy image --server http://127.0.0.1:4954 alpine:latest\n\n  # Generate json result\n  $ trivy image --format json --output result.json alpine:3.15\n\n  # Generate a report in the CycloneDX format\n  $ trivy image --format cyclonedx --output result.cdx alpine:3.15\n
    "},{"location":"docs/references/configuration/cli/trivy_image/#options","title":"Options","text":"
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"fs\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --check-namespaces strings          Rego namespaces\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --compliance string                 compliance report to generate (docker-cis-1.6.0)\n      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files\n      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --custom-headers strings            custom headers in client mode\n      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --detection-priority string         specify the detection priority:\n                                            - \"precise\": Prioritizes precise by minimizing false positives.\n                                            - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                           (precise,comprehensive) (default \"precise\")\n      --docker-host string                unix domain socket path to use for docker scanning\n      --download-db-only                  download/update vulnerability database but don't run a scan\n      --download-java-db-only             download/update Java index database but don't run a scan\n      --enable-modules strings            [EXPERIMENTAL] module names to enable\n      --exit-code int                     specify exit code when any security issues are found\n      --exit-on-eol int                   exit with the specified code when the OS reaches end of service/life\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for image\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed                    display only fixed vulnerabilities\n      --ignored-licenses strings          specify a list of license to ignore\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --image-config-scanners strings     comma-separated list of what security issues to detect on container image configurations (misconfig,secret)\n      --image-src strings                 image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])\n      --include-deprecated-checks         include deprecated checks\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --input string                      input file path instead of image name\n      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --license-confidence-level float    specify license classifier's confidence level (default 0.9)\n      --license-full                      eagerly look for licenses in source code headers and license files\n      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --module-dir string                 specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n      --no-progress                       suppress progress bar\n      --offline-scan                      do not issue API requests to identify dependencies\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)\n      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin                    password from stdin. Comma-separated passwords are not supported.\n      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings                 list of package types (os,library) (default [os,library])\n      --platform string                   set platform in the form os/arch if image is multi-platform capable\n      --podman-host string                unix podman socket path to use for podman scanning\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string             registry token\n      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --removed-pkgs                      detect vulnerabilities of removed packages (only for Alpine)\n      --report string                     specify a format for the compliance report. (all,summary) (default \"summary\")\n      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])\n      --secret-config string              specify a path to config file for secret scanning (default \"trivy-secret.yaml\")\n      --server string                     server address in client mode\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-check-update                 skip fetching rego check updates\n      --skip-db-update                    skip updating vulnerability database\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n      --skip-java-db-update               skip updating Java index database\n      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --token string                      for authentication in client/server mode\n      --token-header string               specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --trace                             enable more verbose trace output for custom queries\n      --username strings                  username. Comma-separated usernames allowed.\n      --vex strings                       [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_image/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_image/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_kubernetes/","title":"Kubernetes","text":""},{"location":"docs/references/configuration/cli/trivy_kubernetes/#trivy-kubernetes","title":"trivy kubernetes","text":"

    [EXPERIMENTAL] Scan kubernetes cluster

    "},{"location":"docs/references/configuration/cli/trivy_kubernetes/#synopsis","title":"Synopsis","text":"

    Default context in kube configuration will be used unless specified

    trivy kubernetes [flags] [CONTEXT]\n
    "},{"location":"docs/references/configuration/cli/trivy_kubernetes/#examples","title":"Examples","text":"
      # cluster scanning\n  $ trivy k8s --report summary\n\n  # cluster scanning with specific namespace:\n  $ trivy k8s --include-namespaces kube-system --report summary \n\n  # cluster with specific context:\n  $ trivy k8s kind-kind --report summary \n
    "},{"location":"docs/references/configuration/cli/trivy_kubernetes/#options","title":"Options","text":"
          --burst int                         specify the maximum burst for throttle (default 10)\n      --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"fs\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --check-namespaces strings          Rego namespaces\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --compliance string                 compliance report to generate (k8s-nsa-1.0,k8s-cis-1.23,eks-cis-1.4,rke2-cis-1.24,k8s-pss-baseline-0.1,k8s-pss-restricted-0.1)\n      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files\n      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --detection-priority string         specify the detection priority:\n                                            - \"precise\": Prioritizes precise by minimizing false positives.\n                                            - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                           (precise,comprehensive) (default \"precise\")\n      --disable-node-collector            When the flag is activated, the node-collector job will not be executed, thus skipping misconfiguration findings on the node.\n      --download-db-only                  download/update vulnerability database but don't run a scan\n      --download-java-db-only             download/update Java index database but don't run a scan\n      --exclude-kinds strings             indicate the kinds exclude from scanning (example: node)\n      --exclude-namespaces strings        indicate the namespaces excluded from scanning (example: kube-system)\n      --exclude-nodes strings             indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)\n      --exclude-owned                     exclude resources that have an owner reference\n      --exit-code int                     specify exit code when any security issues are found\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,cyclonedx) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for kubernetes\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed                    display only fixed vulnerabilities\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --image-src strings                 image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])\n      --include-deprecated-checks         include deprecated checks\n      --include-kinds strings             indicate the kinds included in scanning (example: node)\n      --include-namespaces strings        indicate the namespaces included in scanning (example: kube-system)\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --k8s-version string                specify k8s version to validate outdated api by it (example: 1.21.0)\n      --kubeconfig string                 specify the kubeconfig file path to use\n      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --no-progress                       suppress progress bar\n      --node-collector-imageref string    indicate the image reference for the node-collector scan job (default \"ghcr.io/aquasecurity/node-collector:0.3.1\")\n      --node-collector-namespace string   specify the namespace in which the node-collector job should be deployed (default \"trivy-temp\")\n      --offline-scan                      do not issue API requests to identify dependencies\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)\n      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin                    password from stdin. Comma-separated passwords are not supported.\n      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings                 list of package types (os,library) (default [os,library])\n      --qps float                         specify the maximum QPS to the master from this client (default 5)\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string             registry token\n      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --report string                     specify a report format for the output (all,summary) (default \"all\")\n      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,rbac) (default [vuln,misconfig,secret,rbac])\n      --secret-config string              specify a path to config file for secret scanning (default \"trivy-secret.yaml\")\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-check-update                 skip fetching rego check updates\n      --skip-db-update                    skip updating vulnerability database\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n      --skip-images                       skip the downloading and scanning of images (vulnerabilities and secrets) in the cluster resources\n      --skip-java-db-update               skip updating Java index database\n      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --tolerations strings               specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)\n      --trace                             enable more verbose trace output for custom queries\n      --username strings                  username. Comma-separated usernames allowed.\n      --vex strings                       [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_kubernetes/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_kubernetes/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_module/","title":"Module","text":""},{"location":"docs/references/configuration/cli/trivy_module/#trivy-module","title":"trivy module","text":"

    Manage modules

    "},{"location":"docs/references/configuration/cli/trivy_module/#options","title":"Options","text":"
          --enable-modules strings   [EXPERIMENTAL] module names to enable\n  -h, --help                     help for module\n      --module-dir string        specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n
    "},{"location":"docs/references/configuration/cli/trivy_module/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_module/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    • trivy module install - Install a module
    • trivy module uninstall - Uninstall a module
    "},{"location":"docs/references/configuration/cli/trivy_module_install/","title":"Module Install","text":""},{"location":"docs/references/configuration/cli/trivy_module_install/#trivy-module-install","title":"trivy module install","text":"

    Install a module

    trivy module install [flags] REPOSITORY\n
    "},{"location":"docs/references/configuration/cli/trivy_module_install/#options","title":"Options","text":"
      -h, --help   help for install\n
    "},{"location":"docs/references/configuration/cli/trivy_module_install/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --enable-modules strings    [EXPERIMENTAL] module names to enable\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n      --module-dir string         specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_module_install/#see-also","title":"SEE ALSO","text":"
    • trivy module - Manage modules
    "},{"location":"docs/references/configuration/cli/trivy_module_uninstall/","title":"Module Uninstall","text":""},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#trivy-module-uninstall","title":"trivy module uninstall","text":"

    Uninstall a module

    trivy module uninstall [flags] REPOSITORY\n
    "},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#options","title":"Options","text":"
      -h, --help   help for uninstall\n
    "},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --enable-modules strings    [EXPERIMENTAL] module names to enable\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n      --module-dir string         specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_module_uninstall/#see-also","title":"SEE ALSO","text":"
    • trivy module - Manage modules
    "},{"location":"docs/references/configuration/cli/trivy_plugin/","title":"Plugin","text":""},{"location":"docs/references/configuration/cli/trivy_plugin/#trivy-plugin","title":"trivy plugin","text":"

    Manage plugins

    "},{"location":"docs/references/configuration/cli/trivy_plugin/#options","title":"Options","text":"
      -h, --help   help for plugin\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    • trivy plugin info - Show information about the specified plugin
    • trivy plugin install - Install a plugin
    • trivy plugin list - List installed plugin
    • trivy plugin run - Run a plugin on the fly
    • trivy plugin search - List Trivy plugins available on the plugin index and search among them
    • trivy plugin uninstall - Uninstall a plugin
    • trivy plugin update - Update the local copy of the plugin index
    • trivy plugin upgrade - Upgrade installed plugins to newer versions
    "},{"location":"docs/references/configuration/cli/trivy_plugin_info/","title":"Plugin Info","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_info/#trivy-plugin-info","title":"trivy plugin info","text":"

    Show information about the specified plugin

    trivy plugin info PLUGIN_NAME\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_info/#options","title":"Options","text":"
      -h, --help   help for info\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_info/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_info/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_install/","title":"Plugin Install","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_install/#trivy-plugin-install","title":"trivy plugin install","text":"

    Install a plugin

    trivy plugin install NAME | URL | FILE_PATH\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_install/#examples","title":"Examples","text":"
      # Install a plugin from the plugin index\n  $ trivy plugin install referrer\n\n  # Specify the version of the plugin to install\n  $ trivy plugin install referrer@v0.3.0\n\n  # Install a plugin from a URL\n  $ trivy plugin install github.com/aquasecurity/trivy-plugin-referrer\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_install/#options","title":"Options","text":"
      -h, --help   help for install\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_install/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_install/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_list/","title":"Plugin List","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_list/#trivy-plugin-list","title":"trivy plugin list","text":"

    List installed plugin

    trivy plugin list\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_list/#options","title":"Options","text":"
      -h, --help   help for list\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_list/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_list/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_run/","title":"Plugin Run","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_run/#trivy-plugin-run","title":"trivy plugin run","text":"

    Run a plugin on the fly

    trivy plugin run NAME | URL | FILE_PATH\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_run/#options","title":"Options","text":"
      -h, --help   help for run\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_run/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_run/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_search/","title":"Plugin Search","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_search/#trivy-plugin-search","title":"trivy plugin search","text":"

    List Trivy plugins available on the plugin index and search among them

    trivy plugin search [KEYWORD]\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_search/#options","title":"Options","text":"
      -h, --help   help for search\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_search/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_search/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/","title":"Plugin Uninstall","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#trivy-plugin-uninstall","title":"trivy plugin uninstall","text":"

    Uninstall a plugin

    trivy plugin uninstall PLUGIN_NAME\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#options","title":"Options","text":"
      -h, --help   help for uninstall\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_uninstall/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_update/","title":"Plugin Update","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_update/#trivy-plugin-update","title":"trivy plugin update","text":"

    Update the local copy of the plugin index

    trivy plugin update\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_update/#options","title":"Options","text":"
      -h, --help   help for update\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_update/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_update/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_plugin_upgrade/","title":"Plugin Upgrade","text":""},{"location":"docs/references/configuration/cli/trivy_plugin_upgrade/#trivy-plugin-upgrade","title":"trivy plugin upgrade","text":"

    Upgrade installed plugins to newer versions

    trivy plugin upgrade [PLUGIN_NAMES]\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_upgrade/#options","title":"Options","text":"
      -h, --help   help for upgrade\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_upgrade/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_plugin_upgrade/#see-also","title":"SEE ALSO","text":"
    • trivy plugin - Manage plugins
    "},{"location":"docs/references/configuration/cli/trivy_registry/","title":"Registry","text":""},{"location":"docs/references/configuration/cli/trivy_registry/#trivy-registry","title":"trivy registry","text":"

    Manage registry authentication

    "},{"location":"docs/references/configuration/cli/trivy_registry/#options","title":"Options","text":"
      -h, --help   help for registry\n
    "},{"location":"docs/references/configuration/cli/trivy_registry/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_registry/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    • trivy registry login - Log in to a registry
    • trivy registry logout - Log out of a registry
    "},{"location":"docs/references/configuration/cli/trivy_registry_login/","title":"Registry Login","text":""},{"location":"docs/references/configuration/cli/trivy_registry_login/#trivy-registry-login","title":"trivy registry login","text":"

    Log in to a registry

    trivy registry login SERVER [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_login/#examples","title":"Examples","text":"
      # Log in to reg.example.com\n  cat ~/my_password.txt | trivy registry login --username foo --password-stdin reg.example.com\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_login/#options","title":"Options","text":"
      -h, --help               help for login\n      --password strings   password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin     password from stdin. Comma-separated passwords are not supported.\n      --username strings   username. Comma-separated usernames allowed.\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_login/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_login/#see-also","title":"SEE ALSO","text":"
    • trivy registry - Manage registry authentication
    "},{"location":"docs/references/configuration/cli/trivy_registry_logout/","title":"Registry Logout","text":""},{"location":"docs/references/configuration/cli/trivy_registry_logout/#trivy-registry-logout","title":"trivy registry logout","text":"

    Log out of a registry

    trivy registry logout SERVER [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_logout/#examples","title":"Examples","text":"
      # Log out of reg.example.com\n  trivy registry logout reg.example.com\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_logout/#options","title":"Options","text":"
      -h, --help   help for logout\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_logout/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_registry_logout/#see-also","title":"SEE ALSO","text":"
    • trivy registry - Manage registry authentication
    "},{"location":"docs/references/configuration/cli/trivy_repository/","title":"Repository","text":""},{"location":"docs/references/configuration/cli/trivy_repository/#trivy-repository","title":"trivy repository","text":"

    Scan a repository

    trivy repository [flags] (REPO_PATH | REPO_URL)\n
    "},{"location":"docs/references/configuration/cli/trivy_repository/#examples","title":"Examples","text":"
      # Scan your remote git repository\n  $ trivy repo https://github.com/knqyf263/trivy-ci-test\n  # Scan your local git repository\n  $ trivy repo /path/to/your/repository\n
    "},{"location":"docs/references/configuration/cli/trivy_repository/#options","title":"Options","text":"
          --branch string                     pass the branch name to be scanned\n      --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"memory\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --cf-params strings                 specify paths to override the CloudFormation parameters files\n      --check-namespaces strings          Rego namespaces\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --commit string                     pass the commit hash to be scanned\n      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files\n      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --custom-headers strings            custom headers in client mode\n      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --detection-priority string         specify the detection priority:\n                                            - \"precise\": Prioritizes precise by minimizing false positives.\n                                            - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                           (precise,comprehensive) (default \"precise\")\n      --download-db-only                  download/update vulnerability database but don't run a scan\n      --download-java-db-only             download/update Java index database but don't run a scan\n      --enable-modules strings            [EXPERIMENTAL] module names to enable\n      --exit-code int                     specify exit code when any security issues are found\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for repository\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed                    display only fixed vulnerabilities\n      --ignored-licenses strings          specify a list of license to ignore\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --include-deprecated-checks         include deprecated checks\n      --include-dev-deps                  include development dependencies in the report (supported: npm, yarn)\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --license-confidence-level float    specify license classifier's confidence level (default 0.9)\n      --license-full                      eagerly look for licenses in source code headers and license files\n      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --module-dir string                 specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n      --no-progress                       suppress progress bar\n      --offline-scan                      do not issue API requests to identify dependencies\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)\n      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin                    password from stdin. Comma-separated passwords are not supported.\n      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings                 list of package types (os,library) (default [os,library])\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string             registry token\n      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])\n      --secret-config string              specify a path to config file for secret scanning (default \"trivy-secret.yaml\")\n      --server string                     server address in client mode\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-check-update                 skip fetching rego check updates\n      --skip-db-update                    skip updating vulnerability database\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n      --skip-java-db-update               skip updating Java index database\n      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update\n      --tag string                        pass the tag name to be scanned\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --tf-vars strings                   specify paths to override the Terraform tfvars files\n      --token string                      for authentication in client/server mode\n      --token-header string               specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --trace                             enable more verbose trace output for custom queries\n      --username strings                  username. Comma-separated usernames allowed.\n      --vex strings                       [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_repository/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_repository/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_rootfs/","title":"Rootfs","text":""},{"location":"docs/references/configuration/cli/trivy_rootfs/#trivy-rootfs","title":"trivy rootfs","text":"

    Scan rootfs

    trivy rootfs [flags] ROOTDIR\n
    "},{"location":"docs/references/configuration/cli/trivy_rootfs/#examples","title":"Examples","text":"
      # Scan unpacked filesystem\n  $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -\n  $ trivy rootfs /tmp/rootfs\n\n  # Scan from inside a container\n  $ docker run --rm -it alpine:3.11\n  / # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin\n  / # trivy rootfs /\n
    "},{"location":"docs/references/configuration/cli/trivy_rootfs/#options","title":"Options","text":"
          --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"memory\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --cf-params strings                 specify paths to override the CloudFormation parameters files\n      --check-namespaces strings          Rego namespaces\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --config-check strings              specify the paths to the Rego check files or to the directories containing them, applying config files\n      --config-data strings               specify paths from which data for the Rego checks will be recursively loaded\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --custom-headers strings            custom headers in client mode\n      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --detection-priority string         specify the detection priority:\n                                            - \"precise\": Prioritizes precise by minimizing false positives.\n                                            - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                           (precise,comprehensive) (default \"precise\")\n      --download-db-only                  download/update vulnerability database but don't run a scan\n      --download-java-db-only             download/update Java index database but don't run a scan\n      --enable-modules strings            [EXPERIMENTAL] module names to enable\n      --exit-code int                     specify exit code when any security issues are found\n      --exit-on-eol int                   exit with the specified code when the OS reaches end of service/life\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for rootfs\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed                    display only fixed vulnerabilities\n      --ignored-licenses strings          specify a list of license to ignore\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --include-deprecated-checks         include deprecated checks\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --license-confidence-level float    specify license classifier's confidence level (default 0.9)\n      --license-full                      eagerly look for licenses in source code headers and license files\n      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --module-dir string                 specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n      --no-progress                       suppress progress bar\n      --offline-scan                      do not issue API requests to identify dependencies\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)\n      --password strings                  password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin                    password from stdin. Comma-separated passwords are not supported.\n      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings                 list of package types (os,library) (default [os,library])\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string             registry token\n      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])\n      --secret-config string              specify a path to config file for secret scanning (default \"trivy-secret.yaml\")\n      --server string                     server address in client mode\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-check-update                 skip fetching rego check updates\n      --skip-db-update                    skip updating vulnerability database\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n      --skip-java-db-update               skip updating Java index database\n      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --tf-vars strings                   specify paths to override the Terraform tfvars files\n      --token string                      for authentication in client/server mode\n      --token-header string               specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --trace                             enable more verbose trace output for custom queries\n      --username strings                  username. Comma-separated usernames allowed.\n      --vex strings                       [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_rootfs/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_rootfs/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_sbom/","title":"SBOM","text":""},{"location":"docs/references/configuration/cli/trivy_sbom/#trivy-sbom","title":"trivy sbom","text":"

    Scan SBOM for vulnerabilities and licenses

    trivy sbom [flags] SBOM_PATH\n
    "},{"location":"docs/references/configuration/cli/trivy_sbom/#examples","title":"Examples","text":"
      # Scan CycloneDX and show the result in tables\n  $ trivy sbom /path/to/report.cdx\n\n  # Scan CycloneDX-type attestation and show the result in tables\n  $ trivy sbom /path/to/report.cdx.intoto.jsonl\n
    "},{"location":"docs/references/configuration/cli/trivy_sbom/#options","title":"Options","text":"
          --cache-backend string         [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"memory\")\n      --cache-ttl duration           cache TTL when using redis as cache backend\n      --compliance string            compliance report to generate\n      --custom-headers strings       custom headers in client mode\n      --db-repository strings        OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --detection-priority string    specify the detection priority:\n                                       - \"precise\": Prioritizes precise by minimizing false positives.\n                                       - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                      (precise,comprehensive) (default \"precise\")\n      --download-db-only             download/update vulnerability database but don't run a scan\n      --download-java-db-only        download/update Java index database but don't run a scan\n      --exit-code int                specify exit code when any security issues are found\n      --exit-on-eol int              exit with the specified code when the OS reaches end of service/life\n      --file-patterns strings        specify config file patterns\n  -f, --format string                format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n  -h, --help                         help for sbom\n      --ignore-policy string         specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings        comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed               display only fixed vulnerabilities\n      --ignored-licenses strings     specify a list of license to ignore\n      --ignorefile string            specify .trivyignore file (default \".trivyignore\")\n      --java-db-repository strings   OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --list-all-pkgs                output all packages in the JSON report regardless of vulnerability\n      --no-progress                  suppress progress bar\n      --offline-scan                 do not issue API requests to identify dependencies\n  -o, --output string                output file name\n      --output-plugin-arg string     [EXPERIMENTAL] output plugin arguments\n      --password strings             password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin               password from stdin. Comma-separated passwords are not supported.\n      --pkg-relationships strings    list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings            list of package types (os,library) (default [os,library])\n      --redis-ca string              redis ca file location, if using redis as cache backend\n      --redis-cert string            redis certificate file location, if using redis as cache backend\n      --redis-key string             redis key file location, if using redis as cache backend\n      --redis-tls                    enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string        registry token\n      --rekor-url string             [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --sbom-sources strings         [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings             comma-separated list of what security issues to detect (vuln,license) (default [vuln])\n      --server string                server address in client mode\n  -s, --severity strings             severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed              [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-db-update               skip updating vulnerability database\n      --skip-dirs strings            specify the directories or glob patterns to skip\n      --skip-files strings           specify the files or glob patterns to skip\n      --skip-java-db-update          skip updating Java index database\n      --skip-vex-repo-update         [EXPERIMENTAL] Skip VEX Repository update\n  -t, --template string              output template\n      --token string                 for authentication in client/server mode\n      --token-header string          specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --username strings             username. Comma-separated usernames allowed.\n      --vex strings                  [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_sbom/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_sbom/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_server/","title":"Server","text":""},{"location":"docs/references/configuration/cli/trivy_server/#trivy-server","title":"trivy server","text":"

    Server mode

    trivy server [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_server/#examples","title":"Examples","text":"
      # Run a server\n  $ trivy server\n\n  # Listen on 0.0.0.0:10000\n  $ trivy server --listen 0.0.0.0:10000\n
    "},{"location":"docs/references/configuration/cli/trivy_server/#options","title":"Options","text":"
          --cache-backend string     [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"fs\")\n      --cache-ttl duration       cache TTL when using redis as cache backend\n      --db-repository strings    OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --download-db-only         download/update vulnerability database but don't run a scan\n      --enable-modules strings   [EXPERIMENTAL] module names to enable\n  -h, --help                     help for server\n      --listen string            listen address in server mode (default \"localhost:4954\")\n      --module-dir string        specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n      --no-progress              suppress progress bar\n      --password strings         password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.\n      --password-stdin           password from stdin. Comma-separated passwords are not supported.\n      --redis-ca string          redis ca file location, if using redis as cache backend\n      --redis-cert string        redis certificate file location, if using redis as cache backend\n      --redis-key string         redis key file location, if using redis as cache backend\n      --redis-tls                enable redis TLS with public certificates, if using redis as cache backend\n      --registry-token string    registry token\n      --skip-db-update           skip updating vulnerability database\n      --token string             for authentication in client/server mode\n      --token-header string      specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --username strings         username. Comma-separated usernames allowed.\n
    "},{"location":"docs/references/configuration/cli/trivy_server/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_server/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_version/","title":"Version","text":""},{"location":"docs/references/configuration/cli/trivy_version/#trivy-version","title":"trivy version","text":"

    Print the version

    trivy version [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_version/#options","title":"Options","text":"
      -f, --format string   version format (json)\n  -h, --help            help for version\n
    "},{"location":"docs/references/configuration/cli/trivy_version/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_version/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/configuration/cli/trivy_vex/","title":"VEX","text":""},{"location":"docs/references/configuration/cli/trivy_vex/#trivy-vex","title":"trivy vex","text":"

    [EXPERIMENTAL] VEX utilities

    "},{"location":"docs/references/configuration/cli/trivy_vex/#options","title":"Options","text":"
      -h, --help   help for vex\n
    "},{"location":"docs/references/configuration/cli/trivy_vex/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_vex/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    • trivy vex repo - Manage VEX repositories
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo/","title":"VEX Repo","text":""},{"location":"docs/references/configuration/cli/trivy_vex_repo/#trivy-vex-repo","title":"trivy vex repo","text":"

    Manage VEX repositories

    "},{"location":"docs/references/configuration/cli/trivy_vex_repo/#examples","title":"Examples","text":"
      # Initialize the configuration file\n  $ trivy vex repo init\n\n  # List VEX repositories\n  $ trivy vex repo list\n\n  # Download the VEX repositories\n  $ trivy vex repo download\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo/#options","title":"Options","text":"
      -h, --help   help for repo\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo/#see-also","title":"SEE ALSO","text":"
    • trivy vex - [EXPERIMENTAL] VEX utilities
    • trivy vex repo download - Download the VEX repositories
    • trivy vex repo init - Initialize a configuration file
    • trivy vex repo list - List VEX repositories
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_download/","title":"VEX Download","text":""},{"location":"docs/references/configuration/cli/trivy_vex_repo_download/#trivy-vex-repo-download","title":"trivy vex repo download","text":"

    Download the VEX repositories

    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_download/#synopsis","title":"Synopsis","text":"

    Downloads enabled VEX repositories. If specific repository names are provided as arguments, only those repositories will be downloaded. Otherwise, all enabled repositories are downloaded.

    trivy vex repo download [REPO_NAMES] [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_download/#options","title":"Options","text":"
      -h, --help   help for download\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_download/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_download/#see-also","title":"SEE ALSO","text":"
    • trivy vex repo - Manage VEX repositories
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_init/","title":"VEX Init","text":""},{"location":"docs/references/configuration/cli/trivy_vex_repo_init/#trivy-vex-repo-init","title":"trivy vex repo init","text":"

    Initialize a configuration file

    trivy vex repo init [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_init/#options","title":"Options","text":"
      -h, --help   help for init\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_init/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_init/#see-also","title":"SEE ALSO","text":"
    • trivy vex repo - Manage VEX repositories
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_list/","title":"VEX List","text":""},{"location":"docs/references/configuration/cli/trivy_vex_repo_list/#trivy-vex-repo-list","title":"trivy vex repo list","text":"

    List VEX repositories

    trivy vex repo list [flags]\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_list/#options","title":"Options","text":"
      -h, --help   help for list\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_list/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_vex_repo_list/#see-also","title":"SEE ALSO","text":"
    • trivy vex repo - Manage VEX repositories
    "},{"location":"docs/references/configuration/cli/trivy_vm/","title":"VM","text":""},{"location":"docs/references/configuration/cli/trivy_vm/#trivy-vm","title":"trivy vm","text":"

    [EXPERIMENTAL] Scan a virtual machine image

    trivy vm [flags] VM_IMAGE\n
    "},{"location":"docs/references/configuration/cli/trivy_vm/#examples","title":"Examples","text":"
      # Scan your AWS AMI\n  $ trivy vm --scanners vuln ami:${your_ami_id}\n\n  # Scan your AWS EBS snapshot\n  $ trivy vm ebs:${your_ebs_snapshot_id}\n
    "},{"location":"docs/references/configuration/cli/trivy_vm/#options","title":"Options","text":"
          --aws-region string                 AWS region to scan\n      --cache-backend string              [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default \"fs\")\n      --cache-ttl duration                cache TTL when using redis as cache backend\n      --checks-bundle-repository string   OCI registry URL to retrieve checks bundle from (default \"mirror.gcr.io/aquasec/trivy-checks:1\")\n      --compliance string                 compliance report to generate\n      --config-file-schemas strings       specify paths to JSON configuration file schemas to determine that a file matches some configuration and pass the schema to Rego checks for type checking\n      --custom-headers strings            custom headers in client mode\n      --db-repository strings             OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2])\n      --dependency-tree                   [EXPERIMENTAL] show dependency origin tree of vulnerable packages\n      --detection-priority string         specify the detection priority:\n                                            - \"precise\": Prioritizes precise by minimizing false positives.\n                                            - \"comprehensive\": Aims to detect more security findings at the cost of potential false positives.\n                                           (precise,comprehensive) (default \"precise\")\n      --download-db-only                  download/update vulnerability database but don't run a scan\n      --download-java-db-only             download/update Java index database but don't run a scan\n      --enable-modules strings            [EXPERIMENTAL] module names to enable\n      --exit-code int                     specify exit code when any security issues are found\n      --exit-on-eol int                   exit with the specified code when the OS reaches end of service/life\n      --file-patterns strings             specify config file patterns\n  -f, --format string                     format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default \"table\")\n      --helm-api-versions strings         Available API versions used for Capabilities.APIVersions. This flag is the same as the api-versions flag of the helm template command. (can specify multiple or separate values with commas: policy/v1/PodDisruptionBudget,apps/v1/Deployment)\n      --helm-kube-version string          Kubernetes version used for Capabilities.KubeVersion. This flag is the same as the kube-version flag of the helm template command.\n      --helm-set strings                  specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-set-file strings             specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)\n      --helm-set-string strings           specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)\n      --helm-values strings               specify paths to override the Helm values.yaml files\n  -h, --help                              help for vm\n      --ignore-policy string              specify the Rego file path to evaluate each vulnerability\n      --ignore-status strings             comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life)\n      --ignore-unfixed                    display only fixed vulnerabilities\n      --ignorefile string                 specify .trivyignore file (default \".trivyignore\")\n      --include-non-failures              include successes, available with '--scanners misconfig'\n      --java-db-repository strings        OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])\n      --list-all-pkgs                     output all packages in the JSON report regardless of vulnerability\n      --misconfig-scanners strings        comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])\n      --module-dir string                 specify directory to the wasm modules that will be loaded (default \"$HOME/.trivy/modules\")\n      --no-progress                       suppress progress bar\n      --offline-scan                      do not issue API requests to identify dependencies\n  -o, --output string                     output file name\n      --output-plugin-arg string          [EXPERIMENTAL] output plugin arguments\n      --parallel int                      number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)\n      --pkg-relationships strings         list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])\n      --pkg-types strings                 list of package types (os,library) (default [os,library])\n      --redis-ca string                   redis ca file location, if using redis as cache backend\n      --redis-cert string                 redis certificate file location, if using redis as cache backend\n      --redis-key string                  redis key file location, if using redis as cache backend\n      --redis-tls                         enable redis TLS with public certificates, if using redis as cache backend\n      --rekor-url string                  [EXPERIMENTAL] address of rekor STL server (default \"https://rekor.sigstore.dev\")\n      --sbom-sources strings              [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)\n      --scanners strings                  comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])\n      --secret-config string              specify a path to config file for secret scanning (default \"trivy-secret.yaml\")\n      --server string                     server address in client mode\n  -s, --severity strings                  severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])\n      --show-suppressed                   [EXPERIMENTAL] show suppressed vulnerabilities\n      --skip-db-update                    skip updating vulnerability database\n      --skip-dirs strings                 specify the directories or glob patterns to skip\n      --skip-files strings                specify the files or glob patterns to skip\n      --skip-java-db-update               skip updating Java index database\n      --skip-vex-repo-update              [EXPERIMENTAL] Skip VEX Repository update\n  -t, --template string                   output template\n      --tf-exclude-downloaded-modules     exclude misconfigurations for downloaded terraform modules\n      --token string                      for authentication in client/server mode\n      --token-header string               specify a header name for token in client/server mode (default \"Trivy-Token\")\n      --vex strings                       [EXPERIMENTAL] VEX sources (\"repo\", \"oci\" or file path)\n
    "},{"location":"docs/references/configuration/cli/trivy_vm/#options-inherited-from-parent-commands","title":"Options inherited from parent commands","text":"
          --cache-dir string          cache directory (default \"/path/to/cache\")\n  -c, --config string             config path (default \"trivy.yaml\")\n  -d, --debug                     debug mode\n      --generate-default-config   write the default config to trivy-default.yaml\n      --insecure                  allow insecure server connections\n  -q, --quiet                     suppress progress bar and log output\n      --timeout duration          timeout (default 5m0s)\n  -v, --version                   show version\n
    "},{"location":"docs/references/configuration/cli/trivy_vm/#see-also","title":"SEE ALSO","text":"
    • trivy - Unified security scanner
    "},{"location":"docs/references/modes/client-server/","title":"Client/Server","text":"

    Trivy has client/server mode. Trivy server has vulnerability database and Trivy client doesn't have to download vulnerability database. It is useful if you want to scan images or files at multiple locations and do not want to download the database at every location.

    Client/Server Mode Image Rootfs Filesystem Repository Config K8s Supported \u2705 \u2705 \u2705 \u2705 - -

    Some scanners run on the client side, even in client/server mode.

    Scanner Run on Client or Server Vulnerability Server Misconfiguration Client1 Secret Client2 License Server

    Note

    Scanning of misconfigurations and licenses is performed on the client side (as in standalone mode). Otherwise, the client would need to send files to the server that may contain sensitive information.

    "},{"location":"docs/references/modes/client-server/#server","title":"Server","text":"

    At first, you need to launch Trivy server. It downloads vulnerability database automatically and continue to fetch the latest DB in the background.

    $ trivy server --listen localhost:8080\n2019-12-12T15:17:06.551+0200    INFO    Need to update DB\n2019-12-12T15:17:56.706+0200    INFO    Reopening DB...\n2019-12-12T15:17:56.707+0200    INFO    Listening localhost:8080...\n

    If you want to accept a connection from outside, you have to specify 0.0.0.0 or your ip address, not localhost.

    $ trivy server --listen 0.0.0.0:8080\n
    "},{"location":"docs/references/modes/client-server/#remote-image-scan","title":"Remote image scan","text":"

    Then, specify the server address for image command.

    $ trivy image --server http://localhost:8080 alpine:3.10\n
    Note: It's important to specify the protocol (http or https).

    Result
    alpine:3.10 (alpine 3.10.2)\n===========================\nTotal: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 2, HIGH: 0, CRITICAL: 0)\n\n+---------+------------------+----------+-------------------+---------------+\n| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |\n+---------+------------------+----------+-------------------+---------------+\n| openssl | CVE-2019-1549    | MEDIUM   | 1.1.1c-r0         | 1.1.1d-r0     |\n+         +------------------+          +                   +               +\n|         | CVE-2019-1563    |          |                   |               |\n+         +------------------+----------+                   +               +\n|         | CVE-2019-1547    | LOW      |                   |               |\n+---------+------------------+----------+-------------------+---------------+\n
    "},{"location":"docs/references/modes/client-server/#remote-scan-of-local-filesystem","title":"Remote scan of local filesystem","text":"

    Also, there is a way to scan local file system:

    $ trivy fs --server http://localhost:8080 --severity CRITICAL ./integration/testdata/fixtures/fs/pom/\n
    Note: It's important to specify the protocol (http or https).

    Result
    pom.xml (pom)\n=============\nTotal: 24 (CRITICAL: 24)\n\n+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+\n|                   LIBRARY                   | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |         FIXED VERSION          |                 TITLE                 |\n+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+\n| com.fasterxml.jackson.core:jackson-databind | CVE-2017-17485   | CRITICAL | 2.9.1             | 2.8.11, 2.9.4                  | jackson-databind: Unsafe              |\n|                                             |                  |          |                   |                                | deserialization due to                |\n|                                             |                  |          |                   |                                | incomplete black list (incomplete     |\n|                                             |                  |          |                   |                                | fix for CVE-2017-15095)...            |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2017-17485 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2018-11307   |          |                   | 2.7.9.4, 2.8.11.2, 2.9.6       | jackson-databind: Potential           |\n|                                             |                  |          |                   |                                | information exfiltration with         |\n|                                             |                  |          |                   |                                | default typing, serialization         |\n|                                             |                  |          |                   |                                | gadget from MyBatis                   |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-11307 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2018-14718   |          |                   | 2.6.7.2, 2.9.7                 | jackson-databind: arbitrary code      |\n|                                             |                  |          |                   |                                | execution in slf4j-ext class          |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14718 |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2018-14719   |          |                   |                                | jackson-databind: arbitrary           |\n|                                             |                  |          |                   |                                | code execution in blaze-ds-opt        |\n|                                             |                  |          |                   |                                | and blaze-ds-core classes             |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14719 |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2018-14720   |          |                   |                                | jackson-databind: exfiltration/XXE    |\n|                                             |                  |          |                   |                                | in some JDK classes                   |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14720 |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2018-14721   |          |                   |                                | jackson-databind: server-side request |\n|                                             |                  |          |                   |                                | forgery (SSRF) in axis2-jaxws class   |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-14721 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2018-19360   |          |                   | 2.6.7.3, 2.7.9.5, 2.8.11.3,    | jackson-databind: improper            |\n|                                             |                  |          |                   | 2.9.8                          | polymorphic deserialization           |\n|                                             |                  |          |                   |                                | in axis2-transport-jms class          |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19360 |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2018-19361   |          |                   |                                | jackson-databind: improper            |\n|                                             |                  |          |                   |                                | polymorphic deserialization           |\n|                                             |                  |          |                   |                                | in openjpa class                      |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19361 |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2018-19362   |          |                   |                                | jackson-databind: improper            |\n|                                             |                  |          |                   |                                | polymorphic deserialization           |\n|                                             |                  |          |                   |                                | in jboss-common-core class            |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-19362 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2018-7489    |          |                   | 2.7.9.3, 2.8.11.1, 2.9.5       | jackson-databind: incomplete fix      |\n|                                             |                  |          |                   |                                | for CVE-2017-7525 permits unsafe      |\n|                                             |                  |          |                   |                                | serialization via c3p0 libraries      |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2018-7489  |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-14379   |          |                   | 2.7.9.6, 2.8.11.4, 2.9.9.2     | jackson-databind: default             |\n|                                             |                  |          |                   |                                | typing mishandling leading            |\n|                                             |                  |          |                   |                                | to remote code execution              |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14379 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-14540   |          |                   | 2.9.10                         | jackson-databind:                     |\n|                                             |                  |          |                   |                                | Serialization gadgets in              |\n|                                             |                  |          |                   |                                | com.zaxxer.hikari.HikariConfig        |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14540 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-14892   |          |                   | 2.6.7.3, 2.8.11.5, 2.9.10      | jackson-databind: Serialization       |\n|                                             |                  |          |                   |                                | gadgets in classes of the             |\n|                                             |                  |          |                   |                                | commons-configuration package         |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14892 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-14893   |          |                   | 2.8.11.5, 2.9.10               | jackson-databind:                     |\n|                                             |                  |          |                   |                                | Serialization gadgets in              |\n|                                             |                  |          |                   |                                | classes of the xalan package          |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-14893 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-16335   |          |                   | 2.9.10                         | jackson-databind:                     |\n|                                             |                  |          |                   |                                | Serialization gadgets in              |\n|                                             |                  |          |                   |                                | com.zaxxer.hikari.HikariDataSource    |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16335 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-16942   |          |                   | 2.9.10.1                       | jackson-databind:                     |\n|                                             |                  |          |                   |                                | Serialization gadgets in              |\n|                                             |                  |          |                   |                                | org.apache.commons.dbcp.datasources.* |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16942 |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2019-16943   |          |                   |                                | jackson-databind:                     |\n|                                             |                  |          |                   |                                | Serialization gadgets in              |\n|                                             |                  |          |                   |                                | com.p6spy.engine.spy.P6DataSource     |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-16943 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-17267   |          |                   | 2.9.10                         | jackson-databind: Serialization       |\n|                                             |                  |          |                   |                                | gadgets in classes of                 |\n|                                             |                  |          |                   |                                | the ehcache package                   |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-17267 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-17531   |          |                   | 2.9.10.1                       | jackson-databind:                     |\n|                                             |                  |          |                   |                                | Serialization gadgets in              |\n|                                             |                  |          |                   |                                | org.apache.log4j.receivers.db.*       |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-17531 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2019-20330   |          |                   | 2.8.11.5, 2.9.10.2             | jackson-databind: lacks               |\n|                                             |                  |          |                   |                                | certain net.sf.ehcache blocking       |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2019-20330 |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2020-8840    |          |                   | 2.7.9.7, 2.8.11.5, 2.9.10.3    | jackson-databind: Lacks certain       |\n|                                             |                  |          |                   |                                | xbean-reflect/JNDI blocking           |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-8840  |\n+                                             +------------------+          +                   +--------------------------------+---------------------------------------+\n|                                             | CVE-2020-9546    |          |                   | 2.7.9.7, 2.8.11.6, 2.9.10.4    | jackson-databind: Serialization       |\n|                                             |                  |          |                   |                                | gadgets in shaded-hikari-config       |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9546  |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2020-9547    |          |                   |                                | jackson-databind: Serialization       |\n|                                             |                  |          |                   |                                | gadgets in ibatis-sqlmap              |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9547  |\n+                                             +------------------+          +                   +                                +---------------------------------------+\n|                                             | CVE-2020-9548    |          |                   |                                | jackson-databind: Serialization       |\n|                                             |                  |          |                   |                                | gadgets in anteros-core               |\n|                                             |                  |          |                   |                                | -->avd.aquasec.com/nvd/cve-2020-9548  |\n+---------------------------------------------+------------------+----------+-------------------+--------------------------------+---------------------------------------+\n
    "},{"location":"docs/references/modes/client-server/#remote-scan-of-root-filesystem","title":"Remote scan of root filesystem","text":"

    Also, there is a way to scan root file system:

    $ trivy rootfs --server http://localhost:8080 --severity CRITICAL /tmp/rootfs\n
    Note: It's important to specify the protocol (http or https).

    Result
    /tmp/rootfs (alpine 3.10.2)\n\nTotal: 1 (CRITICAL: 1)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library  \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                            Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 apk-tools \u2502 CVE-2021-36159 \u2502 CRITICAL \u2502 2.10.4-r2         \u2502 2.10.7-r0     \u2502 libfetch before 2021-07-26, as used in apk-tools, xbps, and \u2502\n\u2502           \u2502                \u2502          \u2502                   \u2502               \u2502 other products, mishandles...                               \u2502\n\u2502           \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2021-36159                  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/references/modes/client-server/#remote-scan-of-git-repository","title":"Remote scan of git repository","text":"

    Also, there is a way to scan remote git repository:

    $ trivy repo https://github.com/knqyf263/trivy-ci-test --server http://localhost:8080 \n
    Note: It's important to specify the protocol (http or https).

    Result
    Cargo.lock (cargo)\n==================\nTotal: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library  \u2502    Vulnerability    \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                            Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 ammonia   \u2502 CVE-2019-15542      \u2502 HIGH     \u2502 1.9.0             \u2502 2.1.0         \u2502 Uncontrolled recursion in ammonia                           \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2019-15542                  \u2502\n\u2502           \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502           \u2502 CVE-2021-38193      \u2502 MEDIUM   \u2502                   \u2502 2.1.3, 3.1.0  \u2502 An issue was discovered in the ammonia crate before 3.1.0   \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 for Rust....                                                \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2021-38193                  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 smallvec  \u2502 CVE-2019-15551      \u2502          \u2502 0.6.9             \u2502 0.6.10        \u2502 An issue was discovered in the smallvec crate before 0.6.10 \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 for Rust....                                                \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2019-15551                  \u2502\n\u2502           \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502           \u2502 CVE-2018-25023      \u2502 HIGH     \u2502                   \u2502 0.6.13        \u2502 An issue was discovered in the smallvec crate before 0.6.13 \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 for Rust....                                                \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2018-25023                  \u2502\n\u2502           \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u2502               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502           \u2502 GHSA-66p5-j55p-32r9 \u2502 MEDIUM   \u2502                   \u2502               \u2502 smallvec creates uninitialized value of any type            \u2502\n\u2502           \u2502                     \u2502          \u2502                   \u2502               \u2502 https://github.com/advisories/GHSA-66p5-j55p-32r9           \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nPipfile.lock (pipenv)\n=====================\nTotal: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502       Library       \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502     Fixed Version      \u2502                            Title                             \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 celery              \u2502 CVE-2021-23727 \u2502 HIGH     \u2502 4.3.0             \u2502 5.2.2                  \u2502 celery: stored command injection vulnerability may allow     \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 privileges escalation                                        \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2021-23727                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 django              \u2502 CVE-2019-6975  \u2502          \u2502 2.0.9             \u2502 1.11.19, 2.0.12, 2.1.7 \u2502 python-django: memory exhaustion in                          \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 django.utils.numberformat.format()                           \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2019-6975                    \u2502\n\u2502                     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                     \u2502 CVE-2019-3498  \u2502 MEDIUM   \u2502                   \u2502 1.11.18, 2.0.10, 2.1.5 \u2502 python-django: Content spoofing via URL path in default 404  \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 page                                                         \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2019-3498                    \u2502\n\u2502                     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                     \u2502 CVE-2021-33203 \u2502          \u2502                   \u2502 2.2.24, 3.1.12, 3.2.4  \u2502 django: Potential directory traversal via ``admindocs``      \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2021-33203                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 urllib3             \u2502 CVE-2019-11324 \u2502          \u2502 1.24.1            \u2502 1.24.2                 \u2502 python-urllib3: Certification mishandle when error should be \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 thrown                                                       \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2019-11324                   \u2502\n\u2502                     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                     \u2502 CVE-2021-33503 \u2502          \u2502                   \u2502 1.26.5                 \u2502 python-urllib3: ReDoS in the parsing of authority part of    \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 URL                                                          \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2021-33503                   \u2502\n\u2502                     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                     \u2502 CVE-2019-11236 \u2502 MEDIUM   \u2502                   \u2502 1.24.3                 \u2502 python-urllib3: CRLF injection due to not encoding the       \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 '\\r\\n' sequence leading to...                                \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2019-11236                   \u2502\n\u2502                     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                     \u2502 CVE-2020-26137 \u2502          \u2502                   \u2502 1.25.9                 \u2502 python-urllib3: CRLF injection via HTTP request method       \u2502\n\u2502                     \u2502                \u2502          \u2502                   \u2502                        \u2502 https://avd.aquasec.com/nvd/cve-2020-26137                   \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/references/modes/client-server/#authentication","title":"Authentication","text":"
    $ trivy server --listen localhost:8080 --token dummy\n
    $ trivy image --server http://localhost:8080 --token dummy alpine:3.10\n
    "},{"location":"docs/references/modes/client-server/#endpoints","title":"Endpoints","text":""},{"location":"docs/references/modes/client-server/#health","title":"Health","text":"

    Checks whether the Trivy server is running. Authentication is not required.

    Example request:

    curl -s 0.0.0.0:8080/healthz\nok\n

    Returns the 200 OK status if the request was successful.

    "},{"location":"docs/references/modes/client-server/#version","title":"Version","text":"

    Returns the version of the Trivy and all components (db, policy). Authentication is not required.

    Example request:

    curl -s 0.0.0.0:8080/version | jq\n{\n  \"Version\": \"dev\",\n  \"VulnerabilityDB\": {\n    \"Version\": 2,\n    \"NextUpdate\": \"2023-07-25T14:15:29.876639806Z\",\n    \"UpdatedAt\": \"2023-07-25T08:15:29.876640206Z\",\n    \"DownloadedAt\": \"2023-07-25T09:36:25.599004Z\"\n  },\n  \"JavaDB\": {\n    \"Version\": 1,\n    \"NextUpdate\": \"2023-07-28T01:03:52.169192565Z\",\n    \"UpdatedAt\": \"2023-07-25T01:03:52.169192765Z\",\n    \"DownloadedAt\": \"2023-07-25T09:37:48.906152Z\"\n  },\n  \"PolicyBundle\": {\n    \"Digest\": \"sha256:829832357626da2677955e3b427191212978ba20012b6eaa03229ca28569ae43\",\n    \"DownloadedAt\": \"2023-07-23T11:40:33.122462Z\"\n  }\n}\n

    Returns the 200 OK status if the request was successful.

    "},{"location":"docs/references/modes/client-server/#architecture","title":"Architecture","text":"
    1. The checks bundle is also downloaded on the client side.\u00a0\u21a9

    2. The scan result with masked secrets is sent to the server\u00a0\u21a9

    "},{"location":"docs/references/modes/standalone/","title":"Standalone","text":"

    trivy image, trivy filesystem, and trivy repo works as standalone mode.

    "},{"location":"docs/references/modes/standalone/#image","title":"Image","text":""},{"location":"docs/references/modes/standalone/#filesystem","title":"Filesystem","text":""},{"location":"docs/references/modes/standalone/#git-repository","title":"Git Repository","text":""},{"location":"docs/scanner/license/","title":"License Scanning","text":"

    Trivy scans any container image for license files and offers an opinionated view on the risk associated with the license.

    License are classified using the Google License Classification -

    • Forbidden
    • Restricted
    • Reciprocal
    • Notice
    • Permissive
    • Unencumbered
    • Unknown

    Tip

    Licenses that Trivy fails to recognize are classified as UNKNOWN. As those licenses may be in violation, it is recommended to check those unknown licenses as well.

    By default, Trivy scans licenses for packages installed by apk, apt-get, dnf, npm, pip, gem, etc. Check out the coverage document for details.

    To enable extended license scanning, you can use --license-full. In addition to package licenses, Trivy scans source code files, Markdown documents, text files and LICENSE documents to identify license usage within the image or filesystem.

    By default, Trivy only classifies licenses that are matched with a confidence level of 0.9 or more by the classifier. To configure the confidence level, you can use --license-confidence-level. This enables us to classify licenses that might be matched with a lower confidence level by the classifer.

    Note

    The full license scanning is expensive. It takes a while.

    License scanning Image Rootfs Filesystem Repository SBOM Standard \u2705 \u2705 \u270512 \u270512 \u2705 Full (--license-full) \u2705 \u2705 \u2705 \u2705 -

    License checking classifies the identified licenses and map the classification to severity.

    Classification Severity Forbidden CRITICAL Restricted HIGH Reciprocal MEDIUM Notice LOW Permissive LOW Unencumbered LOW Unknown UNKNOWN"},{"location":"docs/scanner/license/#quick-start","title":"Quick start","text":"

    This section shows how to scan license in container image and filesystem.

    "},{"location":"docs/scanner/license/#standard-scanning","title":"Standard scanning","text":"

    Specify an image name with --scanners license.

    $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15\n2022-07-13T17:28:39.526+0300    INFO    License scanning is enabled\n\nOS Packages (license)\n=====================\nTotal: 6 (UNKNOWN: 0, HIGH: 6, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502      Package      \u2502 License \u2502 Classification \u2502 Severity \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted     \u2502 HIGH     \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524         \u2502                \u2502          \u2502\n\u2502 apk-tools         \u2502         \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524         \u2502                \u2502          \u2502\n\u2502 busybox           \u2502         \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524         \u2502                \u2502          \u2502\n\u2502 musl-utils        \u2502         \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524         \u2502                \u2502          \u2502\n\u2502 scanelf           \u2502         \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524         \u2502                \u2502          \u2502\n\u2502 ssl_client        \u2502         \u2502                \u2502          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/scanner/license/#full-scanning","title":"Full scanning","text":"

    Specify --license-full

    $ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana\n2022-07-13T17:48:40.905+0300    INFO    Full license scanning is enabled\n\nOS Packages (license)\n=====================\nTotal: 20 (UNKNOWN: 9, HIGH: 11, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502      Package      \u2502      License      \u2502 Classification \u2502 Severity \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 alpine-baselayout \u2502 GPL-2.0           \u2502 Restricted     \u2502 HIGH     \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                   \u2502                \u2502          \u2502\n\u2502 apk-tools         \u2502                   \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                \u2502          \u2502\n\u2502 bash              \u2502 GPL-3.0           \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 keyutils-libs     \u2502 GPL-2.0           \u2502 Restricted     \u2502 HIGH     \u2502\n\u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                   \u2502 LGPL-2.0-or-later \u2502 Non Standard   \u2502 UNKNOWN  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                \u2502          \u2502\n\u2502 libaio            \u2502 LGPL-2.1-or-later \u2502                \u2502          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 libcom_err        \u2502 GPL-2.0           \u2502 Restricted     \u2502 HIGH     \u2502\n\u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                   \u2502 LGPL-2.0-or-later \u2502 Non Standard   \u2502 UNKNOWN  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 tzdata            \u2502 Public-Domain     \u2502 Non Standard   \u2502 UNKNOWN  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nLoose File License(s) (license)\n===============================\nTotal: 6 (UNKNOWN: 4, HIGH: 0, CRITICAL: 2)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Classification \u2502 Severity \u2502   License    \u2502                        File Location                         \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Forbidden      \u2502 CRITICAL \u2502 AGPL-3.0     \u2502 /usr/share/grafana/LICENSE                                   \u2502\n\u2502                \u2502          \u2502              \u2502                                                              \u2502\n\u2502                \u2502          \u2502              \u2502                                                              \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Non Standard   \u2502 UNKNOWN  \u2502 BSD-0-Clause \u2502 /usr/share/grafana/public/build/5069.d6aae9dd11d49c741a80.j- \u2502\n\u2502                \u2502          \u2502              \u2502 s.LICENSE.txt                                                \u2502\n\u2502                \u2502          \u2502              \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                \u2502          \u2502              \u2502 /usr/share/grafana/public/build/6444.d6aae9dd11d49c741a80.j- \u2502\n\u2502                \u2502          \u2502              \u2502 s.LICENSE.txt                                                \u2502\n\u2502                \u2502          \u2502              \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                \u2502          \u2502              \u2502 /usr/share/grafana/public/build/7889.d6aae9dd11d49c741a80.j- \u2502\n\u2502                \u2502          \u2502              \u2502 s.LICENSE.txt                                                \u2502\n\u2502                \u2502          \u2502              \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                \u2502          \u2502              \u2502 /usr/share/grafana/public/build/canvasPanel.d6aae9dd11d49c7- \u2502\n\u2502                \u2502          \u2502              \u2502 41a80.js.LICENSE.txt                                         \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/scanner/license/#configuration","title":"Configuration","text":"

    Trivy has number of configuration flags for use with license scanning;

    "},{"location":"docs/scanner/license/#ignored-licenses","title":"Ignored Licenses","text":"

    Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the --ignored-licenses flag;

    $ trivy image --scanners license --ignored-licenses MPL-2.0,MIT --severity HIGH grafana/grafana:latest\n2022-07-13T18:15:28.605Z        INFO    License scanning is enabled\n\nOS Packages (license)\n=====================\nTotal: 2 (HIGH: 2, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502      Package      \u2502 License \u2502 Classification \u2502 Severity \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 alpine-baselayout \u2502 GPL-2.0 \u2502 Restricted     \u2502 HIGH     \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524         \u2502                \u2502          \u2502\n\u2502 ssl_client        \u2502         \u2502                \u2502          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/scanner/license/#configuring-classifier-confidence-level","title":"Configuring Classifier Confidence Level","text":"

    You can use the --license-confidence-level flag to adjust the confidence level between 0.0 to 1.0 (default 0.9). For example, when you run the scanner with the default confidence level on SPDX license list data, it is able to detect only 258 licenses.

    $ trivy fs --scanners license --license-full <path/to/spdx/list/data>\n2023-04-18T10:05:13.601-0700    INFO    Full license scanning is enabled\n\nLoose File License(s) (license)\n===============================\nTotal: 258 (UNKNOWN: 70, LOW: 90, MEDIUM: 18, HIGH: 58, CRITICAL: 22)\n

    However, by configuring the confidence level to 0.8, the scanner is now able to detect 282 licenses.

    $ trivy fs --scanners license --license-full --license-confidence-level 0.8 <path/to/spdx/list/data>\n2023-04-18T10:21:39.637-0700    INFO    Full license scanning is enabled\n\nLoose File License(s) (license)\n===============================\nTotal: 282 (UNKNOWN: 81, LOW: 97, MEDIUM: 24, HIGH: 58, CRITICAL: 22)\n
    "},{"location":"docs/scanner/license/#custom-classification","title":"Custom Classification","text":"

    You can generate the default config by the --generate-default-config flag and customize the license classification. For example, if you want to forbid only AGPL-3.0, you can leave it under forbidden and move other licenses to another classification.

    $ trivy image --generate-default-config\n$ vim trivy.yaml\nlicense:\n  forbidden:\n  - AGPL-3.0\n\n  restricted:\n  - AGPL-1.0\n  - CC-BY-NC-1.0\n  - CC-BY-NC-2.0\n  - CC-BY-NC-2.5\n  - CC-BY-NC-3.0\n  - CC-BY-NC-4.0\n  - CC-BY-NC-ND-1.0\n  - CC-BY-NC-ND-2.0\n  - CC-BY-NC-ND-2.5\n  - CC-BY-NC-ND-3.0\n  - CC-BY-NC-ND-4.0\n  - CC-BY-NC-SA-1.0\n  - CC-BY-NC-SA-2.0\n  - CC-BY-NC-SA-2.5\n  - CC-BY-NC-SA-3.0\n  - CC-BY-NC-SA-4.0\n  - Commons-Clause\n  - Facebook-2-Clause\n  - Facebook-3-Clause\n  - Facebook-Examples\n  - WTFPL\n  - BCL\n  - CC-BY-ND-1.0\n  - CC-BY-ND-2.0\n  - CC-BY-ND-2.5\n  - CC-BY-ND-3.0\n  - CC-BY-ND-4.0\n  - CC-BY-SA-1.0\n  - CC-BY-SA-2.0\n  - CC-BY-SA-2.5\n  - CC-BY-SA-3.0\n  - CC-BY-SA-4.0\n  - GPL-1.0\n  - GPL-2.0\n  - GPL-2.0-with-autoconf-exception\n  - GPL-2.0-with-bison-exception\n  - GPL-2.0-with-classpath-exception\n  - GPL-2.0-with-font-exception\n  - GPL-2.0-with-GCC-exception\n  - GPL-3.0\n  - GPL-3.0-with-autoconf-exception\n  - GPL-3.0-with-GCC-exception\n  - LGPL-2.0\n  - LGPL-2.1\n  - LGPL-3.0\n  - NPL-1.0\n  - NPL-1.1\n  - OSL-1.0\n  - OSL-1.1\n  - OSL-2.0\n  - OSL-2.1\n  - OSL-3.0\n  - QPL-1.0\n  - Sleepycat\n\n  reciprocal:\n  - APSL-1.0\n  - APSL-1.1\n  - APSL-1.2\n  - APSL-2.0\n  - CDDL-1.0\n  - CDDL-1.1\n  - CPL-1.0\n  - EPL-1.0\n  - EPL-2.0\n  - FreeImage\n  - IPL-1.0\n  - MPL-1.0\n  - MPL-1.1\n  - MPL-2.0\n  - Ruby\n\n  notice:\n  - AFL-1.1\n  - AFL-1.2\n  - AFL-2.0\n  - AFL-2.1\n  - AFL-3.0\n  - Apache-1.0\n  - Apache-1.1\n  - Apache-2.0\n  - Artistic-1.0-cl8\n  - Artistic-1.0-Perl\n  - Artistic-1.0\n  - Artistic-2.0\n  - BSL-1.0\n  - BSD-2-Clause-FreeBSD\n  - BSD-2-Clause-NetBSD\n  - BSD-2-Clause\n  - BSD-3-Clause-Attribution\n  - BSD-3-Clause-Clear\n  - BSD-3-Clause-LBNL\n  - BSD-3-Clause\n  - BSD-4-Clause\n  - BSD-4-Clause-UC\n  - BSD-Protection\n  - CC-BY-1.0\n  - CC-BY-2.0\n  - CC-BY-2.5\n  - CC-BY-3.0\n  - CC-BY-4.0\n  - FTL\n  - ISC\n  - ImageMagick\n  - Libpng\n  - Lil-1.0\n  - Linux-OpenIB\n  - LPL-1.02\n  - LPL-1.0\n  - MS-PL\n  - MIT\n  - NCSA\n  - OpenSSL\n  - PHP-3.01\n  - PHP-3.0\n  - PIL\n  - Python-2.0\n  - Python-2.0-complete\n  - PostgreSQL\n  - SGI-B-1.0\n  - SGI-B-1.1\n  - SGI-B-2.0\n  - Unicode-DFS-2015\n  - Unicode-DFS-2016\n  - Unicode-TOU\n  - UPL-1.0\n  - W3C-19980720\n  - W3C-20150513\n  - W3C\n  - X11\n  - Xnet\n  - Zend-2.0\n  - zlib-acknowledgement\n  - Zlib\n  - ZPL-1.1\n  - ZPL-2.0\n  - ZPL-2.1\n\n  unencumbered:\n  - CC0-1.0\n  - Unlicense\n  - 0BSD\n\n  permissive: []\n
    1. See the list of supported language files here.\u00a0\u21a9\u21a9

    2. Some lock files require additional files (e.g. files from the cache directory) to detect licenses. Check coverage for more information.\u00a0\u21a9\u21a9

    "},{"location":"docs/scanner/secret/","title":"Secret Scanning","text":"

    Trivy scans any container image, filesystem and git repository to detect exposed secrets like passwords, api keys, and tokens. Secret scanning is enabled by default.

    Trivy will scan every plaintext file, according to builtin rules or configuration. Also, Trivy can detect secrets in compiled Python files (.pyc).

    There are plenty of builtin rules:

    • AWS access key
    • GCP service account
    • GitHub personal access token
    • GitLab personal access token
    • Slack access token
    • etc.

    You can see a full list of built-in rules and built-in allow rules.

    Tip

    If your secret is not detected properly, please make sure that your file including the secret is not in the allowed paths. You can disable allow rules via disable-allow-rules.

    "},{"location":"docs/scanner/secret/#quick-start","title":"Quick start","text":"

    This section shows how to scan secrets in container image and filesystem. Other subcommands should be the same.

    "},{"location":"docs/scanner/secret/#container-image","title":"Container image","text":"

    Specify an image name.

    $ trivy image myimage:1.0.0\n2022-04-21T18:56:44.099+0300    INFO    Detected OS: alpine\n2022-04-21T18:56:44.099+0300    INFO    Detecting Alpine vulnerabilities...\n2022-04-21T18:56:44.101+0300    INFO    Number of language-specific files: 0\n\nmyimage:1.0.0 (alpine 3.15.0)\n=============================\nTotal: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)\n\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n|   LIBRARY    | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n| busybox      | CVE-2022-28391   | CRITICAL | 1.34.1-r3         | 1.34.1-r5     | CVE-2022-28391 affecting              |\n|              |                  |          |                   |               | package busybox 1.35.0                |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-28391 |\n+--------------+------------------|          |-------------------+---------------+---------------------------------------+\n| ssl_client   | CVE-2022-28391   |          | 1.34.1-r3         | 1.34.1-r5     | CVE-2022-28391 affecting              |\n|              |                  |          |                   |               | package busybox 1.35.0                |\n|              |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-28391 |\n+--------------+------------------+----------+-------------------+---------------+---------------------------------------+\n\napp/secret.sh (secrets)\n=======================\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)\n\n+----------+-------------------+----------+---------+--------------------------------+\n| CATEGORY |    DESCRIPTION    | SEVERITY | LINE NO |             MATCH              |\n+----------+-------------------+----------+---------+--------------------------------+\n|   AWS    | AWS Access Key ID | CRITICAL |   10    | export AWS_ACCESS_KEY_ID=***** |\n+----------+-------------------+----------+---------+--------------------------------+\n

    Tip

    Trivy tries to detect a base image and skip those layers for secret scanning. A base image usually contains a lot of files and makes secret scanning much slower. If a secret is not detected properly, you can see base layers with the --debug flag.

    "},{"location":"docs/scanner/secret/#filesystem","title":"Filesystem","text":"
    $ trivy fs /path/to/your_project\n...(snip)...\n\ncerts/key.pem (secrets)\n========================\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n\n+----------------------+------------------------+----------+---------+---------------------------------+\n|       CATEGORY       |      DESCRIPTION       | SEVERITY | LINE NO |              MATCH              |\n+----------------------+------------------------+----------+---------+---------------------------------+\n| AsymmetricPrivateKey | Asymmetric Private Key |   HIGH   |    1    | -----BEGIN RSA PRIVATE KEY----- |\n+----------------------+------------------------+----------+---------+---------------------------------+\n

    Tip

    Your project may have some secrets for testing. You can skip them with --skip-dirs or --skip-files. We would recommend specifying these options so that the secret scanning can be faster if those files don't need to be scanned. Also, you can specify paths to be allowed in a configuration file. See the detail here.

    "},{"location":"docs/scanner/secret/#configuration","title":"Configuration","text":"

    This section describes secret-specific configuration. Other common options are documented here.

    Trivy has a set of builtin rules for secret scanning, which can be extended or modified by a configuration file. Trivy tries to load trivy-secret.yaml in the current directory by default. If the file doesn't exist, only built-in rules are used. You can customize the config file path via the --secret-config flag.

    Warning

    Trivy uses Golang regexp package. To use ^ and $ as symbols of begin and end of line use multi-line mode -(?m).

    "},{"location":"docs/scanner/secret/#custom-rules","title":"Custom Rules","text":"

    Trivy allows defining custom rules.

    rules:\n  - id: rule1\n    category: general\n    title: Generic Rule\n    severity: HIGH\n    path: .*\\.sh\n    keywords:\n      - secret\n    regex: (?i)(?P<key>(secret))(=|:).{0,5}['\"](?P<secret>[0-9a-zA-Z\\-_=]{8,64})['\"]\n    secret-group-name: secret\n    allow-rules:\n      - id: skip-text\n        description: skip text files\n        path: .*\\.txt\n
    id (required)
    • Unique identifier for this rule.
    category (required)
    • String used for metadata and reporting purposes.
    title (required)
    • Short human-readable title of the rule.
    severity (required)
    • How critical this rule is.
    • Allowed values:
    • CRITICAL
    • HIGH
    • MEDIUM
    • LOW
    regex (required)
    • Golang regular expression used to detect secrets.
    path (optional)
    • Golang regular expression used to match paths.
    keywords (optional, recommended)
    • Keywords are used for pre-regex check filtering.
    • Rules that contain keywords will perform a quick string compare check to make sure the keyword(s) are in the content being scanned.
    • Ideally these values should either be part of the identifier or unique strings specific to the rule's regex.
    • It is recommended to define for better performance.
    allow-rules (optional)
    • Allow rules for a single rule to reduce false positives with known secrets.
    • The details are below.
    "},{"location":"docs/scanner/secret/#allow-rules","title":"Allow Rules","text":"

    If the detected secret is matched with the specified regex, then that secret will be skipped and not detected. The same logic applies for path.

    allow-rules can be defined globally and per each rule. The fields are the same.

    rules:\n  - id: rule1\n    category: general\n    title: Generic Rule\n    severity: HIGH\n    regex: (?i)(?P<key>(secret))(=|:).{0,5}['\"](?P<secret>[0-9a-zA-Z\\-_=]{8,64})['\"]\n    allow-rules:\n      - id: skip-text\n        description: skip text files\n        path: .*\\.txt\nallow-rules:\n  - id: social-security-number\n    description: skip social security number\n    regex: 219-09-9999\n
    id (required)
    • Unique identifier for this allow rule.
    description (optional)
    • Short human-readable description of this allow rule.
    regex (optional)
    • Golang regular expression used to allow detected secrets.
    • regex or path must be specified.
    path (optional)
    • Golang regular expression used to allow matched paths.
    • regex or path must be specified.
    "},{"location":"docs/scanner/secret/#enable-rules","title":"Enable Rules","text":"

    Trivy provides plenty of out-of-box rules and allow rules, but you may not need all of them. In that case, enable-builtin-rules will be helpful. If you just need AWS secret detection, you can enable only relevant rules as shown below. It specifies AWS-related rule IDs in enable-builtin-rules. All other rules are disabled, so the scanning will be much faster. We would strongly recommend using this option if you don't need all rules.

    You can see a full list of built-in rule IDs and built-in allow rule IDs.

    enable-builtin-rules:\n  - aws-access-key-id\n  - aws-account-id\n  - aws-secret-access-key\n
    "},{"location":"docs/scanner/secret/#disable-rules","title":"Disable Rules","text":"

    Trivy offers built-in rules and allow rules, but you may want to disable some of them. For example, you don't use Slack, so Slack doesn't have to be scanned. You can specify the Slack rule IDs, slack-access-token and slack-web-hook in disable-rules so that those rules will be disabled for less false positives.

    You should specify either enable-builtin-rules or disable-rules. If they both are specified, disable-rules takes precedence. In case github-pat is specified in enable-builtin-rules and disable-rules, it will be disabled.

    In addition, there are some allow rules. Markdown files are ignored by default, but you may want to scan markdown files as well. You can disable the allow rule by adding markdown to disable-allow-rules.

    You can see a full list of built-in rule IDs and built-in allow rule IDs.

    disable-rules:\n  - slack-access-token\n  - slack-web-hook\ndisable-allow-rules:\n  - markdown\n
    "},{"location":"docs/scanner/secret/#recommendation","title":"Recommendation","text":"

    We would recommend specifying --skip-dirs for faster secret scanning. In container image scanning, Trivy walks the file tree rooted / and scans all the files other than built-in allowed paths. It will take a while if your image contains a lot of files even though Trivy tries to avoid scanning layers from a base image. If you want to make scanning faster, --skip-dirs and --skip-files helps so that Trivy will skip scanning those files and directories. You can see more options here.

    allow-rules is also helpful. See the allow-rules section.

    In addition, all the built-in rules are enabled by default, so it takes some time to scan all of them. If you don't need all those rules, you can use enable-builtin-rules or disable-rules in the configuration file. You should use enable-builtin-rules if you need only AWS secret detection, for example. All rules are disabled except for the ones you specify, so it runs very fast. On the other hand, you should use disable-rules if you just want to disable some built-in rules. See the enable-rules and disable-rules sections for the detail.

    If you don't need secret scanning, you can disable it via the --scanners flag.

    $ trivy image --scanners vuln alpine:3.15\n
    "},{"location":"docs/scanner/secret/#example","title":"Example","text":"

    trivy-secret.yaml in the working directory is loaded by default.

    $ cat trivy-secret.yaml\nrules:\n  - id: rule1\n    category: general\n    title: Generic Rule\n    severity: HIGH\n    regex: (?i)(?P<key>(secret))(=|:).{0,5}['\"](?P<secret>[0-9a-zA-Z\\-_=]{8,64})['\"]\nallow-rules:\n  - id: social-security-number\n    description: skip social security number\n    regex: 219-09-9999\n  - id: log-dir\n    description: skip log directory\n    path: ^\\/var\\/log\\/\ndisable-rules:\n  - slack-access-token\n  - slack-web-hook\ndisable-allow-rules:\n  - markdown\n\n# The following command automatically loads the above configuration.\n$ trivy image YOUR_IMAGE\n

    Also, you can customize the config file path via --secret-config.

    $ cat ./secret-config/trivy.yaml\nrules:\n  - id: rule1\n    category: general\n    title: Generic Rule\n    severity: HIGH\n    regex: (?i)(?P<key>(secret))(=|:).{0,5}['\"](?P<secret>[0-9a-zA-Z\\-_=]{8,64})['\"]\n    allow-rules:\n      - id: skip-text\n        description: skip text files\n        path: .*\\.txt\nenable-builtin-rules:\n  - aws-access-key-id\n  - aws-account-id\n  - aws-secret-access-key\ndisable-allow-rules:\n  - usr-dirs\n\n# Pass the above config with `--secret-config`.\n$ trivy fs --secret-config ./secret-config/trivy.yaml /path/to/your_project\n
    "},{"location":"docs/scanner/secret/#credit","title":"Credit","text":"

    This feature is inspired by gitleaks.

    "},{"location":"docs/scanner/vulnerability/","title":"Vulnerability Scanning","text":"

    Trivy detects known vulnerabilities in software components that it finds in the scan target.

    The following are supported:

    • OS packages
    • Language-specific packages
    • Non-packaged software
    • Kubernetes components
    "},{"location":"docs/scanner/vulnerability/#os-packages","title":"OS Packages","text":"

    Trivy is capable of automatically detecting installed OS packages when scanning container images, VM images and running hosts.

    Note

    Trivy doesn't support third-party/self-compiled packages/binaries, but official packages provided by vendors such as Red Hat and Debian.

    "},{"location":"docs/scanner/vulnerability/#supported-os","title":"Supported OS","text":"

    See here for the supported OSes.

    "},{"location":"docs/scanner/vulnerability/#data-sources","title":"Data Sources","text":"OS Source Arch Linux Vulnerable Issues Alpine Linux secdb Wolfi Linux secdb Chainguard secdb Amazon Linux Amazon Linux Security Center Debian Security Bug Tracker / OVAL Ubuntu Ubuntu CVE Tracker RHEL/CentOS OVAL / Security Data AlmaLinux AlmaLinux Product Errata Rocky Linux Rocky Linux UpdateInfo Oracle Linux OVAL Azure Linux (CBL-Mariner) OVAL OpenSUSE/SLES CVRF Photon OS Photon Security Advisory"},{"location":"docs/scanner/vulnerability/#data-source-selection","title":"Data Source Selection","text":"

    Trivy only consumes security advisories from the sources listed in the above table.

    As for packages installed from OS package managers (dpkg, yum, apk, etc.), Trivy uses the advisory database from the appropriate OS vendor.

    For example: for a python package installed from yum (Amazon linux), Trivy will only get advisories from ALAS. But for a python package installed from another source (e.g. pip), Trivy will get advisories from the GitLab and GitHub databases.

    This advisory selection is essential to avoid getting false positives because OS vendors usually backport upstream fixes, and the fixed version can be different from the upstream fixed version.

    "},{"location":"docs/scanner/vulnerability/#severity-selection","title":"Severity Selection","text":"

    The severity is taken from the selected data source since the severity from vendors is more accurate. Using CVE-2023-0464 as an example, while it is rated as \"HIGH\" in NVD, Red Hat has marked its 'Impact' as \"Low\". As a result, Trivy will display it as \"Low\".

    The severity depends on the compile option, the default configuration, etc. NVD doesn't know how the vendor distributes the software. Red Hat evaluates the severity more accurately. That's why Trivy prefers vendor scores over NVD.

    If the data source does not provide a severity, the severity is determined based on the CVSS score as follows:

    Base Score Range Severity 0.1-3.9 Low 4.0-6.9 Medium 7.0-8.9 High 9.0-10.0 Critical

    If the CVSS score is also not provided, it falls back to NVD.

    NVD and some vendors may delay severity analysis, while other vendors, such as Red Hat, are able to quickly evaluate and announce the severity of vulnerabilities. To avoid marking too many vulnerabilities as \"UNKNOWN\" severity, Trivy uses severity ratings from other vendors when the NVD information is not yet available. The order of preference for vendor severity data can be found here.

    You can reference SeveritySource in the JSON reporting format to see from where the severity is taken for a given vulnerability.

    \"SeveritySource\": \"debian\",\n

    In addition, you can see all the vendor severity ratings.

    \"VendorSeverity\": {\n  \"amazon\": 2,\n  \"cbl-mariner\": 4,\n  \"ghsa\": 4,\n  \"nvd\": 4,\n  \"photon\": 4,\n  \"redhat\": 2,\n  \"ubuntu\": 2\n}\n

    Here is the severity mapping in Trivy:

    Number Severity 0 Unknown 1 Low 2 Medium 3 High 4 Critical

    If no vendor has a severity, the UNKNOWN severity will be used.

    "},{"location":"docs/scanner/vulnerability/#unfixed-vulnerabilities","title":"Unfixed Vulnerabilities","text":"

    The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution. To hide unfixed/unfixable vulnerabilities, you can use the --ignore-unfixed flag.

    "},{"location":"docs/scanner/vulnerability/#language-specific-packages","title":"Language-specific Packages","text":""},{"location":"docs/scanner/vulnerability/#supported-languages","title":"Supported Languages","text":"

    See here for the supported languages.

    "},{"location":"docs/scanner/vulnerability/#langpkg-data-sources","title":"Data Sources","text":"Language Source Commercial Use Delay1 PHP PHP Security Advisories Database \u2705 - GitHub Advisory Database (Composer) \u2705 - Python GitHub Advisory Database (pip) \u2705 - Open Source Vulnerabilities (PyPI) \u2705 - Ruby Ruby Advisory Database \u2705 - GitHub Advisory Database (RubyGems) \u2705 - Node.js Ecosystem Security Working Group \u2705 - GitHub Advisory Database (npm) \u2705 - Java GitHub Advisory Database (Maven) \u2705 - Go GitHub Advisory Database (Go) \u2705 - Go Vulnerability Database \u2705 - Rust Open Source Vulnerabilities (crates.io) \u2705 - .NET GitHub Advisory Database (NuGet) \u2705 - C/C++ GitLab Advisories Community \u2705 1 month Dart GitHub Advisory Database (Pub) \u2705 - Elixir GitHub Advisory Database (Erlang) \u2705 - Swift GitHub Advisory Database (Swift) \u2705 -"},{"location":"docs/scanner/vulnerability/#non-packaged-software","title":"Non-packaged software","text":"

    If you have software that is not managed by a package manager, Trivy can still detect vulnerabilities in it in some cases:

    • Using SBOM from Sigstore Rekor
    • Go Binaries with embedded module information
    • Rust Binaries with embedded information
    • SBOM embedded in container images
    "},{"location":"docs/scanner/vulnerability/#kubernetes","title":"Kubernetes","text":"

    Trivy can detect vulnerabilities in Kubernetes clusters and components by scanning a Kubernetes Cluster, or a KBOM (Kubernetes bill of Material). To learn more, see the documentation for Kubernetes scanning.

    "},{"location":"docs/scanner/vulnerability/#data-sources_1","title":"Data Sources","text":"Vendor Source Kubernetes Kubernetes Official CVE feed1"},{"location":"docs/scanner/vulnerability/#databases","title":"Databases","text":"

    The information from the above sources is collected and stored in databases that Trivy uses for vulnerability scanning. Trivy automatically fetches, maintains, and caches the relevant databases when performing a vulnerability scan For more information about Trivy's Databases mechanism and configurations, refer to the Databases document.

    "},{"location":"docs/scanner/vulnerability/#detection-behavior","title":"Detection Behavior","text":"

    Trivy prioritizes precision in vulnerability detection, aiming to minimize false positives while potentially accepting some false negatives. This approach is particularly relevant in two key areas:

    • Handling Software Installed via OS Packages
    • Handling Packages with Unspecified Versions
    "},{"location":"docs/scanner/vulnerability/#handling-software-installed-via-os-packages","title":"Handling Software Installed via OS Packages","text":"

    For files installed by OS package managers, such as apt, Trivy exclusively uses advisories from the OS vendor. This means that even if a JAR file is present in a container image, if it was installed via an OS package manager (e.g., apt), Trivy will not analyze the JAR file itself and use upstream security advisories.

    For example, consider the Python requests package in Red Hat Universal Base Image 8:

    [root@987ee49dc93d /]# head -n 3 /usr/lib/python3.6/site-packages/requests-2.20.0-py3.6.egg-info/PKG-INFO\nMetadata-Version: 2.1\nName: requests\nVersion: 2.20.0\n

    Version 2.20.0 is installed, and this package is installed by dnf.

    [root@987ee49dc93d /]# rpm -ql python3-requests | grep PKG-INFO\n/usr/lib/python3.6/site-packages/requests-2.20.0-py3.6.egg-info/PKG-INFO\n

    At first glance, this might seem vulnerable to CVE-2023-32681, which affects versions of requests prior to v2.31.0. However, Red Hat backported the fix to v2.20.0-3 in RHSA-2023:4520, and the package is not vulnerable.

    • Upstream (PyPI requests): Fixed in v2.31.0
    • Red Hat (python-requests): Backported fix applied in v2.20.0-3 (RHSA-2023:4520)

    If Trivy were to detect CVE-2023-32681 in this case, it would be a false positive. This illustrates why using the correct security advisory is crucial to avoid false detections. To minimize false positives, Trivy trusts the OS vendor's advisory for software installed via OS package managers and does not use upstream advisories for these packages.

    However, this approach may lead to false negatives if the OS vendor's advisories are delayed or missing. In such cases, using --detection-priority comprehensive allows Trivy to consider upstream advisories (e.g., GitHub Advisory Database), potentially increasing false positives but reducing false negatives.

    "},{"location":"docs/scanner/vulnerability/#handling-packages-with-unspecified-versions","title":"Handling Packages with Unspecified Versions","text":"

    When a package version cannot be uniquely determined (e.g., package-a: \">=3.0\"), Trivy typically skips vulnerability detection for that package to avoid false positives. If a lock file is present with fixed versions, Trivy will use those for detection.

    To detect potential vulnerabilities even with unspecified versions, use --detection-priority comprehensive. This option makes Trivy use the minimum version in the specified range for vulnerability detection. While this may increase false positives if the actual version used is not the minimum, it helps reduce false negatives.

    "},{"location":"docs/scanner/vulnerability/#configuration","title":"Configuration","text":"

    This section describes vulnerability-specific configuration. Other common options are documented here.

    "},{"location":"docs/scanner/vulnerability/#enabling-a-subset-of-package-types","title":"Enabling a Subset of Package Types","text":"

    It's possible to only enable certain package types if you prefer. You can do so by passing the --pkg-types option. This flag takes a comma-separated list of package types.

    Available values:

    • os
      • Scan OS packages managed by the OS package manager (e.g. dpkg, yum, apk).
    • library
      • Scan language-specific packages (e.g. packages installed by pip, npm, or gem).
    $ trivy image --pkg-types os ruby:2.4.0\n
    Result
    2019-05-22T19:36:50.530+0200    \u001b[34mINFO\u001b[0m    Updating vulnerability database...\n2019-05-22T19:36:51.681+0200    \u001b[34mINFO\u001b[0m    Detecting Alpine vulnerabilities...\n2019-05-22T19:36:51.685+0200    \u001b[34mINFO\u001b[0m    Updating npm Security DB...\n2019-05-22T19:36:52.389+0200    \u001b[34mINFO\u001b[0m    Detecting npm vulnerabilities...\n2019-05-22T19:36:52.390+0200    \u001b[34mINFO\u001b[0m    Updating pipenv Security DB...\n2019-05-22T19:36:53.406+0200    \u001b[34mINFO\u001b[0m    Detecting pipenv vulnerabilities...\n\nruby:2.4.0 (debian 8.7)\n=======================\nTotal: 7 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 3, CRITICAL: 2)\n\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |              TITLE               |\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n| curl    | CVE-2018-14618   | CRITICAL | 7.61.0-r0         | 7.61.1-r0     | curl: NTLM password overflow     |\n|         |                  |          |                   |               | via integer overflow             |\n+         +------------------+----------+                   +---------------+----------------------------------+\n|         | CVE-2018-16839   | HIGH     |                   | 7.61.1-r1     | curl: Integer overflow leading   |\n|         |                  |          |                   |               | to heap-based buffer overflow in |\n|         |                  |          |                   |               | Curl_sasl_create_plain_message() |\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n| git     | CVE-2018-17456   | HIGH     | 2.15.2-r0         | 2.15.3-r0     | git: arbitrary code execution    |\n|         |                  |          |                   |               | via .gitmodules                  |\n+         +------------------+          +                   +               +----------------------------------+\n|         | CVE-2018-19486   |          |                   |               | git: Improper handling of        |\n|         |                  |          |                   |               | PATH allows for commands to be   |\n|         |                  |          |                   |               | executed from...                 |\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n| libssh2 | CVE-2019-3855    | CRITICAL | 1.8.0-r2          | 1.8.1-r0      | libssh2: Integer overflow in     |\n|         |                  |          |                   |               | transport read resulting in      |\n|         |                  |          |                   |               | out of bounds write...           |\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n| sqlite  | CVE-2018-20346   | MEDIUM   | 3.21.0-r1         | 3.25.3-r0     | CVE-2018-20505 CVE-2018-20506    |\n|         |                  |          |                   |               | sqlite: Multiple flaws in        |\n|         |                  |          |                   |               | sqlite which can be triggered    |\n|         |                  |          |                   |               | via...                           |\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n| tar     | CVE-2018-20482   | LOW      | 1.29-r1           | 1.31-r0       | tar: Infinite read loop in       |\n|         |                  |          |                   |               | sparse_dump_region function in   |\n|         |                  |          |                   |               | sparse.c                         |\n+---------+------------------+----------+-------------------+---------------+----------------------------------+\n

    Info

    This flag filters the packages themselves, so it also affects the --list-all-pkgs option and SBOM generation.

    "},{"location":"docs/scanner/vulnerability/#filtering-by-package-relationships","title":"Filtering by Package Relationships","text":"

    Trivy supports filtering vulnerabilities based on the relationship of packages within a project. This is achieved through the --pkg-relationships flag. This feature allows you to focus on vulnerabilities in specific types of dependencies, such as only those in direct dependencies.

    In Trivy, there are four types of package relationships:

    1. root: The root package being scanned
    2. direct: Direct dependencies of the root package
    3. indirect: Transitive dependencies
    4. unknown: Packages whose relationship cannot be determined

    The available relationships may vary depending on the ecosystem. To see which relationships are supported for a particular project, you can use the JSON output format and check the Relationship field:

    $ trivy repo -f json --list-all-pkgs /path/to/project\n

    To scan only the root package and its direct dependencies, you can use the flag as follows:

    $ trivy repo --pkg-relationships root,direct /path/to/project\n

    By default, all relationships are included in the scan.

    Info

    This flag filters the packages themselves, so it also affects the --list-all-pkgs option and SBOM generation.

    Warning

    As it may not provide a complete package list, --pkg-relationships cannot be used with --dependency-tree, --vex or SBOM generation.

    "},{"location":"docs/scanner/vulnerability/#detection-priority","title":"Detection Priority","text":"

    Trivy provides a --detection-priority flag to control the balance between false positives and false negatives in vulnerability detection. This concept is similar to the relationship between precision and recall in machine learning evaluation.

    $ trivy image --detection-priority {precise|comprehensive} alpine:3.15\n
    • precise: This mode prioritizes reducing false positives. It results in less noisy vulnerability reports but may miss some potential vulnerabilities.
    • comprehensive: This mode aims to detect more vulnerabilities, potentially including some that might be false positives. It provides broader coverage but may increase the noise in the results.

    The default value is precise. Also refer to the detection behavior section for more information.

    Regardless of the chosen mode, user review of detected vulnerabilities is crucial:

    • precise: Review thoroughly, considering potential missed vulnerabilities.
    • comprehensive: Carefully investigate each reported vulnerability due to increased false positive possibility.
    1. https://github.com/GoogleContainerTools/distroless \u21a9\u21a9

    "},{"location":"docs/scanner/misconfiguration/","title":"Misconfiguration Scanning","text":"

    Trivy provides built-in checks to detect configuration issues in popular Infrastructure as Code files, such as: Docker, Kubernetes, Terraform, CloudFormation, and more. In addition to built-in checks, you can write your own custom checks, as you can see here.

    "},{"location":"docs/scanner/misconfiguration/#quick-start","title":"Quick start","text":"

    Simply specify a directory containing IaC files such as Terraform, CloudFormation, Azure ARM templates, Helm Charts and Dockerfile.

    $ trivy config [YOUR_IaC_DIRECTORY]\n

    Example

    $ ls build/\nDockerfile\n$ trivy config ./build\n2022-05-16T13:29:29.952+0100    INFO    Detected config files: 1\n\nDockerfile (dockerfile)\n=======================\nTests: 23 (SUCCESSES: 22, FAILURES: 1)\nFailures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)\n\nMEDIUM: Specify a tag in the 'FROM' statement for image 'alpine'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nWhen using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.\n\nSee https://avd.aquasec.com/misconfig/ds001\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nDockerfile:1\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n1 [ FROM alpine:latest\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n

    You can also enable misconfiguration detection in container image, filesystem and git repository scanning via --scanners misconfig.

    $ trivy image --scanners misconfig IMAGE_NAME\n
    $ trivy fs --scanners misconfig /path/to/dir\n

    Note

    Misconfiguration detection is not enabled by default in image, fs and repo subcommands.

    Unlike the config subcommand, image, fs and repo subcommands can also scan for vulnerabilities and secrets at the same time. You can specify --scanners vuln,misconfig,secret to enable vulnerability and secret detection as well as misconfiguration detection.

    Example

    $ ls myapp/\nDockerfile Pipfile.lock\n$ trivy fs --scanners vuln,misconfig,secret --severity HIGH,CRITICAL myapp/\n2022-05-16T13:42:21.440+0100    INFO    Number of language-specific files: 1\n2022-05-16T13:42:21.440+0100    INFO    Detecting pipenv vulnerabilities...\n2022-05-16T13:42:21.440+0100    INFO    Detected config files: 1\n\nPipfile.lock (pipenv)\n=====================\nTotal: 1 (HIGH: 1, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Library  \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                           Title                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 httplib2 \u2502 CVE-2021-21240 \u2502 HIGH     \u2502 0.12.1            \u2502 0.19.0        \u2502 python-httplib2: Regular expression denial of service via \u2502\n\u2502          \u2502                \u2502          \u2502                   \u2502               \u2502 malicious header                                          \u2502\n\u2502          \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2021-21240                \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nDockerfile (dockerfile)\n=======================\nTests: 17 (SUCCESSES: 16, FAILURES: 1)\nFailures: 1 (HIGH: 1, CRITICAL: 0)\n\nHIGH: Last USER command in Dockerfile should not be 'root'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.\n\nSee https://avd.aquasec.com/misconfig/ds002\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nDockerfile:3\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n3 [ USER root\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n

    In the above example, Trivy detected vulnerabilities of Python dependencies and misconfigurations in Dockerfile.

    "},{"location":"docs/scanner/misconfiguration/#type-detection","title":"Type detection","text":"

    The specified directory can contain mixed types of IaC files. Trivy automatically detects config types and applies relevant checks.

    For example, the following example holds IaC files for Terraform, CloudFormation, Kubernetes, Helm Charts, and Dockerfile in the same directory.

    $ ls iac/\nDockerfile  deployment.yaml  main.tf mysql-8.8.26.tar\n$ trivy config --severity HIGH,CRITICAL ./iac\n
    Result
    2022-06-06T11:01:21.142+0100    INFO    Detected config files: 8\n\nDockerfile (dockerfile)\n\nTests: 21 (SUCCESSES: 20, FAILURES: 1)\nFailures: 1 (MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n\nHIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.\n\nSee https://avd.aquasec.com/misconfig/ds002\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n\ndeployment.yaml (kubernetes)\n\nTests: 20 (SUCCESSES: 15, FAILURES: 5)\nFailures: 5 (MEDIUM: 4, HIGH: 1, CRITICAL: 0)\n\nMEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.allowPrivilegeEscalation' to false\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nA program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.\n\nSee https://avd.aquasec.com/misconfig/ksv001\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n deployment.yaml:16-19\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  16 \u250c       - name: hello-kubernetes\n  17 \u2502         image: hello-kubernetes:1.5\n  18 \u2502         ports:\n  19 \u2514         - containerPort: 8080\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nHIGH: Deployment 'hello-kubernetes' should not specify '/var/run/docker.socker' in 'spec.template.volumes.hostPath.path'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nMounting docker.sock from the host can give the container full root access to the host.\n\nSee https://avd.aquasec.com/misconfig/ksv006\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n deployment.yaml:6-29\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   6 \u250c   replicas: 3\n   7 \u2502   selector:\n   8 \u2502     matchLabels:\n   9 \u2502       app: hello-kubernetes\n  10 \u2502   template:\n  11 \u2502     metadata:\n  12 \u2502       labels:\n  13 \u2502         app: hello-kubernetes\n  14 \u2514     spec:\n  ..   \n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nMEDIUM: Container 'hello-kubernetes' of Deployment 'hello-kubernetes' should set 'securityContext.runAsNonRoot' to true\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.\n\nSee https://avd.aquasec.com/misconfig/ksv012\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n deployment.yaml:16-19\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  16 \u250c       - name: hello-kubernetes\n  17 \u2502         image: hello-kubernetes:1.5\n  18 \u2502         ports:\n  19 \u2514         - containerPort: 8080\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nMEDIUM: Deployment 'hello-kubernetes' should not set 'spec.template.volumes.hostPath'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nHostPath volumes must be forbidden.\n\nSee https://avd.aquasec.com/misconfig/ksv023\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n deployment.yaml:6-29\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   6 \u250c   replicas: 3\n   7 \u2502   selector:\n   8 \u2502     matchLabels:\n   9 \u2502       app: hello-kubernetes\n  10 \u2502   template:\n  11 \u2502     metadata:\n  12 \u2502       labels:\n  13 \u2502         app: hello-kubernetes\n  14 \u2514     spec:\n  ..   \n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nMEDIUM: Deployment 'hello-kubernetes' should set 'securityContext.sysctl' to the allowed values\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nSysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed 'safe' subset. A sysctl is considered safe if it is namespaced in the container or the Pod, and it is isolated from other Pods or processes on the same Node.\n\nSee https://avd.aquasec.com/misconfig/ksv026\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n deployment.yaml:6-29\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   6 \u250c   replicas: 3\n   7 \u2502   selector:\n   8 \u2502     matchLabels:\n   9 \u2502       app: hello-kubernetes\n  10 \u2502   template:\n  11 \u2502     metadata:\n  12 \u2502       labels:\n  13 \u2502         app: hello-kubernetes\n  14 \u2514     spec:\n  ..   \n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n\nmysql-8.8.26.tar:templates/primary/statefulset.yaml (helm)\n\nTests: 20 (SUCCESSES: 18, FAILURES: 2)\nFailures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0)\n\nMEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.allowPrivilegeEscalation' to false\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nA program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.\n\nSee https://avd.aquasec.com/misconfig/ksv001\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  56 \u250c         - name: mysql\n  57 \u2502           image: docker.io/bitnami/mysql:8.0.28-debian-10-r23\n  58 \u2502           imagePullPolicy: \"IfNotPresent\"\n  59 \u2502           securityContext:\n  60 \u2502             runAsUser: 1001\n  61 \u2502           env:\n  62 \u2502             - name: BITNAMI_DEBUG\n  63 \u2502               value: \"false\"\n  64 \u2514             - name: MYSQL_ROOT_PASSWORD\n  ..   \n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nMEDIUM: Container 'mysql' of StatefulSet 'mysql' should set 'securityContext.runAsNonRoot' to true\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.\n\nSee https://avd.aquasec.com/misconfig/ksv012\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n mysql-8.8.26.tar:templates/primary/statefulset.yaml:56-130\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  56 \u250c         - name: mysql\n  57 \u2502           image: docker.io/bitnami/mysql:8.0.28-debian-10-r23\n  58 \u2502           imagePullPolicy: \"IfNotPresent\"\n  59 \u2502           securityContext:\n  60 \u2502             runAsUser: 1001\n  61 \u2502           env:\n  62 \u2502             - name: BITNAMI_DEBUG\n  63 \u2502               value: \"false\"\n  64 \u2514             - name: MYSQL_ROOT_PASSWORD\n  ..   \n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n

    You can see the config type next to each file name.

    Example

    Dockerfile (dockerfile)\n=======================\nTests: 23 (SUCCESSES: 22, FAILURES: 1)\nFailures: 1 (HIGH: 1, CRITICAL: 0)\n\n...\n\ndeployment.yaml (kubernetes)\n============================\nTests: 28 (SUCCESSES: 15, FAILURES: 13)\nFailures: 13 (MEDIUM: 4, HIGH: 1, CRITICAL: 0)\n\n...\n\nmain.tf (terraform)\n===================\nTests: 23 (SUCCESSES: 14, FAILURES: 9)\nFailures: 9 (HIGH: 6, CRITICAL: 1)\n\n...\n\nbucket.yaml (cloudformation)\n============================\nTests: 9 (SUCCESSES: 3, FAILURES: 6)\nFailures: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 4, CRITICAL: 0)\n\n...\n\nmysql-8.8.26.tar:templates/primary/statefulset.yaml (helm)\n==========================================================\nTests: 20 (SUCCESSES: 18, FAILURES: 2)\nFailures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0)\n
    "},{"location":"docs/scanner/misconfiguration/#configuration","title":"Configuration","text":"

    This section describes misconfiguration-specific configuration. Other common options are documented here.

    "},{"location":"docs/scanner/misconfiguration/#external-connectivity","title":"External connectivity","text":"

    Trivy needs to connect to the internet to download the checks bundle. If you are running Trivy in an air-gapped environment, or an tightly controlled network, please refer to the Advanced Network Scenarios document.

    "},{"location":"docs/scanner/misconfiguration/#enabling-a-subset-of-misconfiguration-scanners","title":"Enabling a subset of misconfiguration scanners","text":"

    It's possible to only enable certain misconfiguration scanners if you prefer. You can do so by passing the --misconfig-scanners option. This flag takes a comma-separated list of configuration scanner types.

    trivy config --misconfig-scanners=terraform,dockerfile .\n

    Will only scan for misconfigurations that pertain to Terraform and Dockerfiles.

    "},{"location":"docs/scanner/misconfiguration/#loading-custom-checks","title":"Loading custom checks","text":"

    You can load check files or directories including your custom checks using the --config-check flag. This can be repeated for specifying multiple files or directories.

    trivy config --config-check custom-policy/policy --config-check combine/policy --config-check policy.rego --namespaces user myapp\n

    You can load checks bundle as OCI Image from a Container Registry using the --checks-bundle-repository flag.

    trivy config --checks-bundle-repository myregistry.local/mychecks --namespaces user myapp\n
    "},{"location":"docs/scanner/misconfiguration/#scan-arbitrary-json-and-yaml-configurations","title":"Scan arbitrary JSON and YAML configurations","text":"

    By default, scanning JSON and YAML configurations is disabled, since Trivy does not contain built-in checks for these configurations. To enable it, pass the json or yaml to --misconfig-scanners. See Enabling a subset of misconfiguration scanners for more information. Trivy will pass each file as is to the checks input.

    Example

    $ cat iac/serverless.yaml\nservice: serverless-rest-api-with-pynamodb\n\nframeworkVersion: \">=2.24.0\"\n\nplugins:\n  - serverless-python-requirements\n...\n\n$ cat serverless.rego\n# METADATA\n# title: Serverless Framework service name not starting with \"aws-\"\n# description: Ensure that Serverless Framework service names start with \"aws-\"\n# schemas:\n#   - input: schema[\"serverless-schema\"]\n# custom:\n#   id: SF001\n#   severity: LOW\npackage user.serverless001\n\ndeny[res] {\n    not startswith(input.service, \"aws-\")\n    res := result.new(\n        sprintf(\"Service name %q is not allowed\", [input.service]),\n        input.service\n    )\n}\n\n$ trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user ./iac\nserverless.yaml (yaml)\n\nTests: 4 (SUCCESSES: 3, FAILURES: 1)\nFailures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n\nLOW: Service name \"serverless-rest-api-with-pynamodb\" is not allowed\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nEnsure that Serverless Framework service names start with \"aws-\"\n

    Note

    In the case above, the custom check specified has a metadata annotation for the input schema input: schema[\"serverless-schema\"]. This allows Trivy to type check the input IaC files provided.

    Optionally, you can also pass schemas using the config-file-schemas flag. Trivy will use these schemas for file filtering and type checking in Rego checks.

    Example

    $ trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user --config-file-schemas ./serverless-schema.json ./iac\n

    If the --config-file-schemas flag is specified Trivy ensures that each input IaC config file being scanned is type-checked against the schema. If the input file does not match any of the passed schemas, it will be ignored.

    If the schema is specified in the check metadata and is in the directory specified in the --config-check argument, it will be automatically loaded as specified here, and will only be used for type checking in Rego.

    Note

    If a user specifies the --config-file-schemas flag, all input IaC config files are ensured that they pass type-checking. It is not required to pass an input schema in case type checking is not required. This is helpful for scenarios where you simply want to write a Rego check and pass in IaC input for it. Such a use case could include scanning for a new service which Trivy might not support just yet.

    Tip

    It is also possible to specify multiple input schemas with --config-file-schema flag as it can accept a comma seperated list of file paths or a directory as input. In the case of multiple schemas being specified, all of them will be evaluated against all the input files.

    "},{"location":"docs/scanner/misconfiguration/#passing-custom-data","title":"Passing custom data","text":"

    You can pass directories including your custom data through --data option. This can be repeated for specifying multiple directories.

    cd examples/misconf/custom-data\ntrivy config --config-check ./my-check --data ./data --namespaces user ./configs\n

    For more details, see Custom Data.

    "},{"location":"docs/scanner/misconfiguration/#passing-namespaces","title":"Passing namespaces","text":"

    By default, Trivy evaluates checks defined in builtin.*. If you want to evaluate custom checks in other packages, you have to specify package prefixes through --namespaces option. This can be repeated for specifying multiple packages.

    trivy config --config-check ./my-check --namespaces main --namespaces user ./configs\n
    "},{"location":"docs/scanner/misconfiguration/#private-terraform-registries","title":"Private Terraform registries","text":"

    Trivy can download Terraform code from private registries. To pass credentials you must use the TF_TOKEN_ environment variables. You cannot use a .terraformrc or terraform.rc file, these are not supported by trivy yet.

    From the Terraform docs:

    Environment variable names should have the prefix TF_TOKEN_ added to the domain name, with periods encoded as underscores. For example, the value of a variable named TF_TOKEN_app_terraform_io will be used as a bearer authorization token when the CLI makes service requests to the hostname app.terraform.io.

    You must convert domain names containing non-ASCII characters to their punycode equivalent with an ACE prefix. For example, token credentials for \u4f8b\u3048\u3070.com must be set in a variable called TF_TOKEN_xn--r8j3dr99h_com.

    Hyphens are also valid within host names but usually invalid as variable names and may be encoded as double underscores. For example, you can set a token for the domain name caf\u00e9.fr as TF_TOKEN_xn--caf-dma_fr or TF_TOKEN_xn_cafdmafr.

    If multiple variables evaluate to the same hostname, Trivy will choose the environment variable name where the dashes have not been encoded as double underscores.

    "},{"location":"docs/scanner/misconfiguration/#skipping-resources-by-inline-comments","title":"Skipping resources by inline comments","text":"

    Trivy supports ignoring misconfigured resources by inline comments for Terraform and CloudFormation configuration files only.

    In cases where Trivy can detect comments of a specific format immediately adjacent to resource definitions, it is possible to ignore findings from a single source of resource definition (in contrast to .trivyignore, which has a directory-wide scope on all of the files scanned). The format for these comments is trivy:ignore:<rule> immediately following the format-specific line-comment token.

    The ignore rule must contain one of the possible check IDs that can be found in its metadata: ID, short code or alias. The id from the metadata is not case-sensitive, so you can specify, for example, AVD-AWS-0089 or avd-aws-0089.

    For example, to ignore a misconfiguration ID AVD-GCP-0051 in a Terraform HCL file:

    #trivy:ignore:AVD-GCP-0051\nresource \"google_container_cluster\" \"example\" {\n  name     = var.cluster_name\n  location = var.region\n}\n

    You can add multiple ignores on the same comment line:

    #trivy:ignore:AVD-GCP-0051 trivy:ignore:AVD-GCP-0053\nresource \"google_container_cluster\" \"example\" {\n  name     = var.cluster_name\n  location = var.region\n}\n

    You can also specify a long ID, which is formed as follows: <provider>-<service>-<short-code>.

    As an example, consider the following check metadata:

    # custom:\n  # id: AVD-AWS-0089\n  # avd_id: AVD-AWS-0089\n  # provider: aws\n  # service: s3\n  # severity: LOW\n  # short_code: enable-logging\n

    Long ID would look like the following: aws-s3-enable-logging.

    Example for CloudFromation:

    AWSTemplateFormatVersion: \"2010-09-09\"\nResources:\n#trivy:ignore:*\n  S3Bucket:\n    Type: 'AWS::S3::Bucket'\n    Properties:\n      BucketName: test-bucket\n

    "},{"location":"docs/scanner/misconfiguration/#expiration-date","title":"Expiration Date","text":"

    You can specify the expiration date of the ignore rule in yyyy-mm-dd format. This is a useful feature when you want to make sure that an ignored issue is not forgotten and worth revisiting in the future. For example:

    #trivy:ignore:aws-s3-enable-logging:exp:2024-03-10\nresource \"aws_s3_bucket\" \"example\" {\n  bucket = \"test\"\n}\n

    The aws-s3-enable-logging check will be ignored until 2024-03-10 until the ignore rule expires.

    "},{"location":"docs/scanner/misconfiguration/#ignoring-by-attributes","title":"Ignoring by attributes","text":"

    You can ignore a resource by its attribute value. This is useful when using the for-each meta-argument. For example:

    locals {\n  ports = [\"3306\", \"5432\"]\n}\n\n#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=3306]\nresource \"aws_security_group_rule\" \"example\" {\n  for_each                 = toset(local.ports)\n  type                     = \"ingress\"\n  from_port                = each.key\n  to_port                  = each.key\n  protocol                 = \"TCP\"\n  cidr_blocks              = [\"0.0.0.0/0\"]\n  security_group_id        = aws_security_group.example.id\n  source_security_group_id = aws_security_group.example.id\n}\n

    The aws-ec2-no-public-ingress-sgr check will be ignored only for the aws_security_group_rule resource with port number 5432. It is important to note that the ignore rule should not enclose the attribute value in quotes, despite the fact that the port is represented as a string.

    If you want to ignore multiple resources on different attributes, you can specify multiple ignore rules:

    #trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=3306]\n#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=5432]\n

    You can also ignore a resource on multiple attributes in the same rule:

    locals {\n  rules = {\n    first = {\n      port = 1000\n      type = \"ingress\"\n    },\n    second = {\n      port = 1000\n      type = \"egress\"\n    }\n  }\n}\n\n#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=1000,type=egress]\nresource \"aws_security_group_rule\" \"example\" {\n  for_each = { for k, v in local.rules : k => v }\n\n  type                     = each.value.type\n  from_port                = each.value.port\n  to_port                  = each.value.port\n  protocol                 = \"TCP\"\n  cidr_blocks              = [\"0.0.0.0/0\"]\n  security_group_id        = aws_security_group.example.id\n  source_security_group_id = aws_security_group.example.id\n}\n

    Checks can also be ignored by nested attributes:

    #trivy:ignore:*[logging_config.prefix=myprefix]\nresource \"aws_cloudfront_distribution\" \"example\" {\n  logging_config {\n    include_cookies = false\n    bucket          = \"mylogs.s3.amazonaws.com\"\n    prefix          = \"myprefix\"\n  }\n}\n
    "},{"location":"docs/scanner/misconfiguration/#ignoring-module-issues","title":"Ignoring module issues","text":"

    Issues in third-party modules cannot be ignored using the method described above, because you may not have access to modify the module source code. In such a situation you can add ignore rules above the module block, for example:

    #trivy:ignore:aws-s3-enable-logging\nmodule \"s3_bucket\" {\n  source = \"terraform-aws-modules/s3-bucket/aws\"\n\n  bucket = \"my-s3-bucket\"\n}\n

    An example of ignoring checks for a specific bucket in a module:

    locals {\n  bucket = [\"test1\", \"test2\"]\n}\n\n#trivy:ignore:*[bucket=test1]\nmodule \"s3_bucket\" {\n  for_each = toset(local.bucket)\n  source   = \"terraform-aws-modules/s3-bucket/aws\"\n  bucket   = each.value\n}\n

    "},{"location":"docs/scanner/misconfiguration/#support-for-wildcards","title":"Support for Wildcards","text":"

    You can use wildcards in the ws (workspace) and ignore sections of the ignore rules.

    # trivy:ignore:aws-s3-*:ws:dev-*\n

    This example ignores all checks starting with aws-s3- for workspaces matching the pattern dev-*.

    "},{"location":"docs/scanner/misconfiguration/check/builtin/","title":"Built-in Checks","text":""},{"location":"docs/scanner/misconfiguration/check/builtin/#checks-sources","title":"Checks Sources","text":"

    Trivy has an extensive library of misconfiguration checks that is maintained at https://github.com/aquasecurity/trivy-checks. Trivy checks are mainly written in Rego, while some checks are written in Go. See here for the list of supported config types.

    "},{"location":"docs/scanner/misconfiguration/check/builtin/#checks-bundle","title":"Checks Bundle","text":"

    When performing a misconfiguration scan, Trivy will automatically download the relevant Checks bundle. The bundle is cached locally and Trivy will reuse it for subsequent scans on the same machine. Trivy takes care of updating the cache automatically, so normally users can be oblivious to it.

    "},{"location":"docs/scanner/misconfiguration/check/builtin/#checks-distribution","title":"Checks Distribution","text":"

    Trivy checks are distributed as an OPA bundle hosted in the following GitHub Container Registry: https://ghcr.io/aquasecurity/trivy-checks. Trivy checks for updates to OPA bundle on GHCR every 24 hours and pulls it if there are any updates.

    "},{"location":"docs/scanner/misconfiguration/check/builtin/#external-connectivity","title":"External connectivity","text":"

    Trivy needs to connect to the internet to download the bundle. If you are running Trivy in an air-gapped environment, or an tightly controlled network, please refer to the Advanced Network Scenarios document. The Checks bundle is also embedded in the Trivy binary (at build time), and will be used as a fallback if Trivy is unable to download the bundle. This means that you can still scan for misconfigurations in an air-gapped environment using the Checks from the time of the Trivy release you are using.

    "},{"location":"docs/scanner/misconfiguration/custom/","title":"Custom Checks","text":""},{"location":"docs/scanner/misconfiguration/custom/#overview","title":"Overview","text":"

    You can write custom checks in Rego. Once you finish writing custom checks, you can pass the check files or the directory where those checks are stored with --config-check` option.

    trivy config --config-check /path/to/policy.rego --config-check /path/to/custom_checks --namespaces user /path/to/config_dir\n

    As for --namespaces option, the detail is described as below.

    "},{"location":"docs/scanner/misconfiguration/custom/#file-formats","title":"File formats","text":"

    If a file name matches the following file patterns, Trivy will parse the file and pass it as input to your Rego policy.

    File format File pattern JSON *.json YAML *.yaml and *.yml Dockerfile Dockerfile, Dockerfile.*, and *.Dockerfile Containerfile Containerfile, Containerfile.*, and *.Containerfile Terraform *.tf and *.tf.json"},{"location":"docs/scanner/misconfiguration/custom/#configuration-languages","title":"Configuration languages","text":"

    In the above general file formats, Trivy automatically identifies the following types of configuration files:

    • CloudFormation (JSON/YAML)
    • Kubernetes (JSON/YAML)
    • Helm (YAML)
    • Terraform Plan (JSON/Snapshot)

    This is useful for filtering inputs, as described below.

    "},{"location":"docs/scanner/misconfiguration/custom/#rego-format","title":"Rego format","text":"

    A single package must contain only one policy.

    Example

    # METADATA\n# title: Deployment not allowed\n# description: Deployments are not allowed because of some reasons.\n# schemas:\n#   - input: schema[\"kubernetes\"]\n# custom:\n#   id: ID001\n#   severity: LOW\n#   input:\n#     selector: \n#     - type: kubernetes\npackage user.kubernetes.ID001\n\ndeny[res] {\n    input.kind == \"Deployment\"\n    msg := sprintf(\"Found deployment '%s' but deployments are not allowed\", [input.metadata.name])\n    res := result.new(msg, input.kind)\n}\n

    In this example, ID001 \"Deployment not allowed\" is defined under user.kubernetes.ID001. If you add a new custom policy, it must be defined under a new package like user.kubernetes.ID002.

    "},{"location":"docs/scanner/misconfiguration/custom/#policy-structure","title":"Policy structure","text":"# METADATA (optional unless the check will be contributed into Trivy)
    • SHOULD be defined for clarity since these values will be displayed in the scan results
    • custom.input SHOULD be set to indicate the input type the policy should be applied to. See list of available types
    package (required)
    • MUST follow the Rego's specification
    • MUST be unique per policy
    • SHOULD include policy id for uniqueness
    • MAY include the group name such as kubernetes for clarity
      • Group name has no effect on policy evaluation
    deny (required)
    • SHOULD be deny or start with deny_
      • Although warn, warn_*, violation, violation_ also work for compatibility, deny is recommended as severity can be defined in __rego_metadata__.
    • SHOULD return ONE OF:
      • The result of a call to result.new(msg, cause). The msg is a string describing the issue occurrence, and the cause is the property/object where the issue occurred. Providing this allows Trivy to ascertain line numbers and highlight code in the output.
      • A string denoting the detected issue
        • Although object with msg field is accepted, other fields are dropped and string is recommended if result.new() is not utilised.
        • e.g. {\"msg\": \"deny message\", \"details\": \"something\"}
    "},{"location":"docs/scanner/misconfiguration/custom/#package","title":"Package","text":"

    A package name must be unique per policy.

    Example

    package user.kubernetes.ID001\n

    By default, only builtin.* packages will be evaluated. If you define custom packages, you have to specify the package prefix via --namespaces option. By default, Trivy only runs in its own namespace, unless specified by the user. Note that the custom namespace does not have to be user as in this example. It could be anything user-defined.

    trivy config --config-check /path/to/custom_checks --namespaces user /path/to/config_dir\n

    In this case, user.* will be evaluated. Any package prefixes such as main and user are allowed.

    "},{"location":"docs/scanner/misconfiguration/custom/#metadata","title":"Metadata","text":"

    The check must contain a Rego Metadata section. Trivy uses standard rego metadata to define the new policy and general information about it.

    Trivy supports extra fields in the custom section as described below.

    Example

    # METADATA\n# title: Deployment not allowed\n# description: Deployments are not allowed because of some reasons.\n# custom:\n#   id: ID001\n#   severity: LOW\n#   input:\n#     selector:\n#     - type: kubernetes\n

    If you are creating checks for your Trivy misconfiguration scans, some fields are optional as referenced in the table below. The schemas field should be used to enable policy validation using a built-in schema. It is recommended to use this to ensure your checks are correct and do not reference incorrect properties/values.

    Field name Allowed values Default value In table In JSON title Any characters N/A :material-check: :material-check: description Any characters :material-close: :material-check: schemas.input schema[\"kubernetes\"], schema[\"dockerfile\"], schema[\"cloud\"] (applied to all input types) :material-close: :material-close: custom.id Any characters N/A :material-check: :material-check: custom.severity LOW, MEDIUM, HIGH, CRITICAL UNKNOWN :material-check: :material-check: custom.recommended_actions Any characters :material-close: :material-check: custom.deprecated true, false false :material-close: :material-check: custom.input.selector.type Any item(s) in this list :material-close: :material-check: url Any characters :material-close: :material-check:"},{"location":"docs/scanner/misconfiguration/custom/#customavd_id-and-customid","title":"custom.avd_id and custom.id","text":"

    The AVD_ID can be used to link the check to the Aqua Vulnerability Database (AVD) entry. For example, the avd_id AVD-AWS-0176 is the ID of the check in the AWS Vulnerability Database. If you are contributing your check to trivy-checks, you need to generate an ID using make id in the trivy-checks repository. The output of the command will provide you the next free IDs for the different providers in Trivy.

    The ID is based on the AVD_ID. For instance if the avd_id is AVD-AWS-0176, the ID is ID0176.

    "},{"location":"docs/scanner/misconfiguration/custom/#customprovider","title":"custom.provider","text":"

    The provider field references the provider available in Trivy. This should be the same as the provider name in the pkg/iac/providers directory, e.g. aws.

    "},{"location":"docs/scanner/misconfiguration/custom/#customservice","title":"custom.service","text":"

    Services are defined within a provider. For instance, RDS is a service and AWS is a provider. This should be the same as the service name in one of the provider directories. (Link), e.g. aws/rds.

    "},{"location":"docs/scanner/misconfiguration/custom/#custominput","title":"custom.input","text":"

    The input tells Trivy what inputs this check should be applied to. Cloud provider checks should always use the selector input, and should always use the type selector with cloud. Check targeting Kubernetes yaml can use kubenetes, RBAC can use rbac, and so on.

    "},{"location":"docs/scanner/misconfiguration/custom/#subtypes-in-the-custom-data","title":"Subtypes in the custom data","text":"

    Subtypes currently only need to be defined for cloud providers as detailed in the documentation.

    "},{"location":"docs/scanner/misconfiguration/custom/#scan-result","title":"Scan Result","text":"

    Some fields are displayed in scan results.

    k.yaml (kubernetes)\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nTests: 32 (SUCCESSES: 31, FAILURES: 1)\nFailures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n\nLOW: Found deployment 'my-deployment' but deployments are not allowed\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nDeployments are not allowed because of some reasons.\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n k.yaml:1-2\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   1 \u250c apiVersion: v1\n   2 \u2514 kind: Deployment\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n
    "},{"location":"docs/scanner/misconfiguration/custom/#input","title":"Input","text":"

    You can specify input format via the custom.input annotation.

    Example

    # METADATA\n# custom:\n#   input:\n#     combine: false\n#     selector:\n#     - type: kubernetes\n
    combine (boolean) The details are here. selector (array)

    This option filters the input by file format or configuration language. In the above example, Trivy passes only Kubernetes files to this policy. Even if a Dockerfile exists in the specified directory, it will not be passed to the policy as input.

    Possible values for input types are:

    • dockerfile (Dockerfile)
    • kubernetes (Kubernetes YAML/JSON)
    • rbac (Kubernetes RBAC YAML/JSON)
    • cloud (Cloud format, as defined by Trivy - this is used for Terraform, CloudFormation, and Cloud/AWS scanning)
    • yaml (Generic YAML)
    • json (Generic JSON)
    • toml (Generic TOML)

    When configuration languages such as Kubernetes are not identified, file formats such as JSON will be used as type. When a configuration language is identified, it will overwrite type.

    Example

    pod.yaml including Kubernetes Pod will be handled as kubernetes, not yaml. type is overwritten by kubernetes from yaml.

    type accepts kubernetes, dockerfile, cloudformation, terraform, terraformplan, json, or yaml.

    "},{"location":"docs/scanner/misconfiguration/custom/#schemas","title":"Schemas","text":"

    See here for the detail.

    "},{"location":"docs/scanner/misconfiguration/custom/combine/","title":"Combined input","text":""},{"location":"docs/scanner/misconfiguration/custom/combine/#overview","title":"Overview","text":"

    Trivy usually scans each configuration file individually. Sometimes it might be useful to compare values from different configuration files simultaneously.

    When combine is set to true, all config files under the specified directory are combined into one input data structure.

    Example

    __rego_input__ := {\n    \"combine\": false,\n}\n

    In \"combine\" mode, the input document becomes an array, where each element is an object with two fields:

    • \"path\": \"path/to/file\": the relative file path of the respective file
    • \"contents\": ...: the parsed content of the respective file

    Now you can ensure that duplicate values match across the entirety of your configuration files.

    "},{"location":"docs/scanner/misconfiguration/custom/combine/#return-value","title":"Return value","text":"

    In \"combine\" mode, the deny entrypoint must return an object with two keys

    filepath (required) the relative file path of the file being evaluated msg (required) the message describing an issue

    Example

    deny[res] {\n    resource := input[i].contents\n    ... some logic ...\n\n    res := {\n        \"filepath\": input[i].path,\n        \"msg\": \"something bad\",\n    }\n}\n
    "},{"location":"docs/scanner/misconfiguration/custom/contribute-checks/","title":"Contribute Checks","text":""},{"location":"docs/scanner/misconfiguration/custom/contribute-checks/#contribute-rego-checks","title":"Contribute Rego Checks","text":"

    The contributing section provides detailed information on how to contribute custom checks to the trivy-checks repository

    This way, they become accessible as default checks.

    "},{"location":"docs/scanner/misconfiguration/custom/data/","title":"Custom Data","text":"

    Custom checks may require additional data in order to make a resolution. You can pass arbitrary data files to Trivy to be used when evaluating rego checks using the --data flag. Trivy recursively searches the specified data paths for JSON (*.json) and YAML (*.yaml) files.

    For example, consider an allowed list of resources that can be created. Instead of hardcoding this information inside your policy, you can maintain the list in a separate file.

    Example data file:

    services:\n  ports:\n    - \"20\"\n    - \"20/tcp\"\n    - \"20/udp\"\n    - \"23\"\n    - \"23/tcp\"\n

    Example usage in a Rego check:

    import data.services\n\nports := services.ports\n

    Example loading the data file:

    trivy config --config-check ./checks --data ./data --namespaces user ./configs\n
    "},{"location":"docs/scanner/misconfiguration/custom/debug/","title":"Debugging checks","text":"

    When working on more complex queries (or when learning Rego), it's useful to see exactly how the policy is applied. For this purpose you can use the --trace flag. This will output a large trace from Open Policy Agent like the following:

    Tip

    Only failed checks show traces. If you want to debug a passed check, you need to make it fail on purpose.

    $ trivy config --trace configs/\n2022-05-16T13:47:58.853+0100    INFO    Detected config files: 1\n\nDockerfile (dockerfile)\n=======================\nTests: 23 (SUCCESSES: 21, FAILURES: 2)\nFailures: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 1, CRITICAL: 0)\n\nMEDIUM: Specify a tag in the 'FROM' statement for image 'alpine'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nWhen using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.\n\nSee https://avd.aquasec.com/misconfig/ds001\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Dockerfile:1\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   1 [ FROM alpine:latest\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nHIGH: Last USER command in Dockerfile should not be 'root'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.\n\nSee https://avd.aquasec.com/misconfig/ds002\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Dockerfile:3\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   3 [ USER root\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n\nID: DS001\nFile: Dockerfile\nNamespace: builtin.dockerfile.DS001\nQuery: data.builtin.dockerfile.DS001.deny\nMessage: Specify a tag in the 'FROM' statement for image 'alpine'\nTRACE  Enter data.builtin.dockerfile.DS001.deny = _\nTRACE  | Eval data.builtin.dockerfile.DS001.deny = _\nTRACE  | Index data.builtin.dockerfile.DS001.deny (matched 1 rule)\nTRACE  | Enter data.builtin.dockerfile.DS001.deny\nTRACE  | | Eval output = data.builtin.dockerfile.DS001.fail_latest[_]\nTRACE  | | Index data.builtin.dockerfile.DS001.fail_latest (matched 1 rule)\nTRACE  | | Enter data.builtin.dockerfile.DS001.fail_latest\nTRACE  | | | Eval output = data.builtin.dockerfile.DS001.image_tags[_]\nTRACE  | | | Index data.builtin.dockerfile.DS001.image_tags (matched 2 rules)\nTRACE  | | | Enter data.builtin.dockerfile.DS001.image_tags\nTRACE  | | | | Eval from = data.lib.docker.from[_]\nTRACE  | | | | Index data.lib.docker.from (matched 1 rule)\nTRACE  | | | | Enter data.lib.docker.from\nTRACE  | | | | | Eval instruction = input.stages[_][_]\nTRACE  | | | | | Eval instruction.Cmd = \"from\"\nTRACE  | | | | | Exit data.lib.docker.from\nTRACE  | | | | Redo data.lib.docker.from\nTRACE  | | | | | Redo instruction.Cmd = \"from\"\nTRACE  | | | | | Redo instruction = input.stages[_][_]\nTRACE  | | | | | Eval instruction.Cmd = \"from\"\nTRACE  | | | | | Fail instruction.Cmd = \"from\"\nTRACE  | | | | | Redo instruction = input.stages[_][_]\nTRACE  | | | | | Eval instruction.Cmd = \"from\"\nTRACE  | | | | | Fail instruction.Cmd = \"from\"\nTRACE  | | | | | Redo instruction = input.stages[_][_]\nTRACE  | | | | Eval name = from.Value[0]\nTRACE  | | | | Eval not startswith(name, \"$\")\nTRACE  | | | | Enter startswith(name, \"$\")\nTRACE  | | | | | Eval startswith(name, \"$\")\nTRACE  | | | | | Fail startswith(name, \"$\")\nTRACE  | | | | Eval data.builtin.dockerfile.DS001.parse_tag(name, __local505__)\nTRACE  | | | | Index data.builtin.dockerfile.DS001.parse_tag (matched 2 rules)\nTRACE  | | | | Enter data.builtin.dockerfile.DS001.parse_tag\nTRACE  | | | | | Eval split(name, \":\", __local504__)\nTRACE  | | | | | Eval [img, tag] = __local504__\nTRACE  | | | | | Exit data.builtin.dockerfile.DS001.parse_tag\nTRACE  | | | | Eval [img, tag] = __local505__\nTRACE  | | | | Eval output = {\"cmd\": from, \"img\": img, \"tag\": tag}\nTRACE  | | | | Exit data.builtin.dockerfile.DS001.image_tags\nTRACE  | | | Redo data.builtin.dockerfile.DS001.image_tags\nTRACE  | | | | Redo output = {\"cmd\": from, \"img\": img, \"tag\": tag}\nTRACE  | | | | Redo [img, tag] = __local505__\nTRACE  | | | | Redo data.builtin.dockerfile.DS001.parse_tag(name, __local505__)\nTRACE  | | | | Redo data.builtin.dockerfile.DS001.parse_tag\nTRACE  | | | | | Redo [img, tag] = __local504__\nTRACE  | | | | | Redo split(name, \":\", __local504__)\nTRACE  | | | | Enter data.builtin.dockerfile.DS001.parse_tag\nTRACE  | | | | | Eval tag = \"latest\"\nTRACE  | | | | | Eval not contains(img, \":\")\nTRACE  | | | | | Enter contains(img, \":\")\nTRACE  | | | | | | Eval contains(img, \":\")\nTRACE  | | | | | | Exit contains(img, \":\")\nTRACE  | | | | | Redo contains(img, \":\")\nTRACE  | | | | | | Redo contains(img, \":\")\nTRACE  | | | | | Fail not contains(img, \":\")\nTRACE  | | | | | Redo tag = \"latest\"\nTRACE  | | | | Redo name = from.Value[0]\nTRACE  | | | | Redo from = data.lib.docker.from[_]\nTRACE  | | | Enter data.builtin.dockerfile.DS001.image_tags\nTRACE  | | | | Eval from = data.lib.docker.from[i]\nTRACE  | | | | Index data.lib.docker.from (matched 1 rule)\nTRACE  | | | | Eval name = from.Value[0]\nTRACE  | | | | Eval cmd_obj = input.stages[j][k]\nTRACE  | | | | Eval possibilities = {\"arg\", \"env\"}\nTRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]\nTRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]\nTRACE  | | | | Redo possibilities = {\"arg\", \"env\"}\nTRACE  | | | | Redo cmd_obj = input.stages[j][k]\nTRACE  | | | | Eval possibilities = {\"arg\", \"env\"}\nTRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]\nTRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]\nTRACE  | | | | Redo possibilities = {\"arg\", \"env\"}\nTRACE  | | | | Redo cmd_obj = input.stages[j][k]\nTRACE  | | | | Eval possibilities = {\"arg\", \"env\"}\nTRACE  | | | | Eval cmd_obj.Cmd = possibilities[l]\nTRACE  | | | | Fail cmd_obj.Cmd = possibilities[l]\nTRACE  | | | | Redo possibilities = {\"arg\", \"env\"}\nTRACE  | | | | Redo cmd_obj = input.stages[j][k]\nTRACE  | | | | Redo name = from.Value[0]\nTRACE  | | | | Redo from = data.lib.docker.from[i]\nTRACE  | | | Eval __local752__ = output.img\nTRACE  | | | Eval neq(__local752__, \"scratch\")\nTRACE  | | | Eval __local753__ = output.img\nTRACE  | | | Eval not data.builtin.dockerfile.DS001.is_alias(__local753__)\nTRACE  | | | Enter data.builtin.dockerfile.DS001.is_alias(__local753__)\nTRACE  | | | | Eval data.builtin.dockerfile.DS001.is_alias(__local753__)\nTRACE  | | | | Index data.builtin.dockerfile.DS001.is_alias (matched 1 rule, early exit)\nTRACE  | | | | Enter data.builtin.dockerfile.DS001.is_alias\nTRACE  | | | | | Eval img = data.builtin.dockerfile.DS001.get_aliases[_]\nTRACE  | | | | | Index data.builtin.dockerfile.DS001.get_aliases (matched 1 rule)\nTRACE  | | | | | Enter data.builtin.dockerfile.DS001.get_aliases\nTRACE  | | | | | | Eval from_cmd = data.lib.docker.from[_]\nTRACE  | | | | | | Index data.lib.docker.from (matched 1 rule)\nTRACE  | | | | | | Eval __local749__ = from_cmd.Value\nTRACE  | | | | | | Eval data.builtin.dockerfile.DS001.get_alias(__local749__, __local503__)\nTRACE  | | | | | | Index data.builtin.dockerfile.DS001.get_alias (matched 1 rule)\nTRACE  | | | | | | Enter data.builtin.dockerfile.DS001.get_alias\nTRACE  | | | | | | | Eval __local748__ = values[i]\nTRACE  | | | | | | | Eval lower(__local748__, __local501__)\nTRACE  | | | | | | | Eval \"as\" = __local501__\nTRACE  | | | | | | | Fail \"as\" = __local501__\nTRACE  | | | | | | | Redo lower(__local748__, __local501__)\nTRACE  | | | | | | | Redo __local748__ = values[i]\nTRACE  | | | | | | Fail data.builtin.dockerfile.DS001.get_alias(__local749__, __local503__)\nTRACE  | | | | | | Redo __local749__ = from_cmd.Value\nTRACE  | | | | | | Redo from_cmd = data.lib.docker.from[_]\nTRACE  | | | | | Fail img = data.builtin.dockerfile.DS001.get_aliases[_]\nTRACE  | | | | Fail data.builtin.dockerfile.DS001.is_alias(__local753__)\nTRACE  | | | Eval output.tag = \"latest\"\nTRACE  | | | Exit data.builtin.dockerfile.DS001.fail_latest\nTRACE  | | Redo data.builtin.dockerfile.DS001.fail_latest\nTRACE  | | | Redo output.tag = \"latest\"\nTRACE  | | | Redo __local753__ = output.img\nTRACE  | | | Redo neq(__local752__, \"scratch\")\nTRACE  | | | Redo __local752__ = output.img\nTRACE  | | | Redo output = data.builtin.dockerfile.DS001.image_tags[_]\nTRACE  | | Eval __local754__ = output.img\nTRACE  | | Eval sprintf(\"Specify a tag in the 'FROM' statement for image '%s'\", [__local754__], __local509__)\nTRACE  | | Eval msg = __local509__\nTRACE  | | Eval __local755__ = output.cmd\nTRACE  | | Eval data.lib.docker.result(msg, __local755__, __local510__)\nTRACE  | | Index data.lib.docker.result (matched 1 rule)\nTRACE  | | Enter data.lib.docker.result\nTRACE  | | | Eval object.get(cmd, \"EndLine\", 0, __local470__)\nTRACE  | | | Eval object.get(cmd, \"Path\", \"\", __local471__)\nTRACE  | | | Eval object.get(cmd, \"StartLine\", 0, __local472__)\nTRACE  | | | Eval result = {\"endline\": __local470__, \"filepath\": __local471__, \"msg\": msg, \"startline\": __local472__}\nTRACE  | | | Exit data.lib.docker.result\nTRACE  | | Eval res = __local510__\nTRACE  | | Exit data.builtin.dockerfile.DS001.deny\nTRACE  | Redo data.builtin.dockerfile.DS001.deny\nTRACE  | | Redo res = __local510__\nTRACE  | | Redo data.lib.docker.result(msg, __local755__, __local510__)\nTRACE  | | Redo data.lib.docker.result\nTRACE  | | | Redo result = {\"endline\": __local470__, \"filepath\": __local471__, \"msg\": msg, \"startline\": __local472__}\nTRACE  | | | Redo object.get(cmd, \"StartLine\", 0, __local472__)\nTRACE  | | | Redo object.get(cmd, \"Path\", \"\", __local471__)\nTRACE  | | | Redo object.get(cmd, \"EndLine\", 0, __local470__)\nTRACE  | | Redo __local755__ = output.cmd\nTRACE  | | Redo msg = __local509__\nTRACE  | | Redo sprintf(\"Specify a tag in the 'FROM' statement for image '%s'\", [__local754__], __local509__)\nTRACE  | | Redo __local754__ = output.img\nTRACE  | | Redo output = data.builtin.dockerfile.DS001.fail_latest[_]\nTRACE  | Exit data.builtin.dockerfile.DS001.deny = _\nTRACE  Redo data.builtin.dockerfile.DS001.deny = _\nTRACE  | Redo data.builtin.dockerfile.DS001.deny = _\nTRACE\n\n\nID: DS002\nFile: Dockerfile\nNamespace: builtin.dockerfile.DS002\nQuery: data.builtin.dockerfile.DS002.deny\nMessage: Last USER command in Dockerfile should not be 'root'\nTRACE  Enter data.builtin.dockerfile.DS002.deny = _\nTRACE  | Eval data.builtin.dockerfile.DS002.deny = _\nTRACE  | Index data.builtin.dockerfile.DS002.deny (matched 2 rules)\nTRACE  | Enter data.builtin.dockerfile.DS002.deny\nTRACE  | | Eval data.builtin.dockerfile.DS002.fail_user_count\nTRACE  | | Index data.builtin.dockerfile.DS002.fail_user_count (matched 1 rule, early exit)\nTRACE  | | Enter data.builtin.dockerfile.DS002.fail_user_count\nTRACE  | | | Eval __local771__ = data.builtin.dockerfile.DS002.get_user\nTRACE  | | | Index data.builtin.dockerfile.DS002.get_user (matched 1 rule)\nTRACE  | | | Enter data.builtin.dockerfile.DS002.get_user\nTRACE  | | | | Eval user = data.lib.docker.user[_]\nTRACE  | | | | Index data.lib.docker.user (matched 1 rule)\nTRACE  | | | | Enter data.lib.docker.user\nTRACE  | | | | | Eval instruction = input.stages[_][_]\nTRACE  | | | | | Eval instruction.Cmd = \"user\"\nTRACE  | | | | | Fail instruction.Cmd = \"user\"\nTRACE  | | | | | Redo instruction = input.stages[_][_]\nTRACE  | | | | | Eval instruction.Cmd = \"user\"\nTRACE  | | | | | Exit data.lib.docker.user\nTRACE  | | | | Redo data.lib.docker.user\nTRACE  | | | | | Redo instruction.Cmd = \"user\"\nTRACE  | | | | | Redo instruction = input.stages[_][_]\nTRACE  | | | | | Eval instruction.Cmd = \"user\"\nTRACE  | | | | | Fail instruction.Cmd = \"user\"\nTRACE  | | | | | Redo instruction = input.stages[_][_]\nTRACE  | | | | Eval username = user.Value[_]\nTRACE  | | | | Exit data.builtin.dockerfile.DS002.get_user\nTRACE  | | | Redo data.builtin.dockerfile.DS002.get_user\nTRACE  | | | | Redo username = user.Value[_]\nTRACE  | | | | Redo user = data.lib.docker.user[_]\nTRACE  | | | Eval count(__local771__, __local536__)\nTRACE  | | | Eval lt(__local536__, 1)\nTRACE  | | | Fail lt(__local536__, 1)\nTRACE  | | | Redo count(__local771__, __local536__)\nTRACE  | | | Redo __local771__ = data.builtin.dockerfile.DS002.get_user\nTRACE  | | Fail data.builtin.dockerfile.DS002.fail_user_count\nTRACE  | Enter data.builtin.dockerfile.DS002.deny\nTRACE  | | Eval cmd = data.builtin.dockerfile.DS002.fail_last_user_root[_]\nTRACE  | | Index data.builtin.dockerfile.DS002.fail_last_user_root (matched 1 rule)\nTRACE  | | Enter data.builtin.dockerfile.DS002.fail_last_user_root\nTRACE  | | | Eval stage_users = data.lib.docker.stage_user[_]\nTRACE  | | | Index data.lib.docker.stage_user (matched 1 rule)\nTRACE  | | | Enter data.lib.docker.stage_user\nTRACE  | | | | Eval stage = input.stages[stage_name]\nTRACE  | | | | Eval users = [cmd | cmd = stage[_]; cmd.Cmd = \"user\"]\nTRACE  | | | | Enter cmd = stage[_]; cmd.Cmd = \"user\"\nTRACE  | | | | | Eval cmd = stage[_]\nTRACE  | | | | | Eval cmd.Cmd = \"user\"\nTRACE  | | | | | Fail cmd.Cmd = \"user\"\nTRACE  | | | | | Redo cmd = stage[_]\nTRACE  | | | | | Eval cmd.Cmd = \"user\"\nTRACE  | | | | | Exit cmd = stage[_]; cmd.Cmd = \"user\"\nTRACE  | | | | Redo cmd = stage[_]; cmd.Cmd = \"user\"\nTRACE  | | | | | Redo cmd.Cmd = \"user\"\nTRACE  | | | | | Redo cmd = stage[_]\nTRACE  | | | | | Eval cmd.Cmd = \"user\"\nTRACE  | | | | | Fail cmd.Cmd = \"user\"\nTRACE  | | | | | Redo cmd = stage[_]\nTRACE  | | | | Exit data.lib.docker.stage_user\nTRACE  | | | Redo data.lib.docker.stage_user\nTRACE  | | | | Redo users = [cmd | cmd = stage[_]; cmd.Cmd = \"user\"]\nTRACE  | | | | Redo stage = input.stages[stage_name]\nTRACE  | | | Eval count(stage_users, __local537__)\nTRACE  | | | Eval len = __local537__\nTRACE  | | | Eval minus(len, 1, __local538__)\nTRACE  | | | Eval last = stage_users[__local538__]\nTRACE  | | | Eval user = last.Value[0]\nTRACE  | | | Eval user = \"root\"\nTRACE  | | | Exit data.builtin.dockerfile.DS002.fail_last_user_root\nTRACE  | | Redo data.builtin.dockerfile.DS002.fail_last_user_root\nTRACE  | | | Redo user = \"root\"\nTRACE  | | | Redo user = last.Value[0]\nTRACE  | | | Redo last = stage_users[__local538__]\nTRACE  | | | Redo minus(len, 1, __local538__)\nTRACE  | | | Redo len = __local537__\nTRACE  | | | Redo count(stage_users, __local537__)\nTRACE  | | | Redo stage_users = data.lib.docker.stage_user[_]\nTRACE  | | Eval msg = \"Last USER command in Dockerfile should not be 'root'\"\nTRACE  | | Eval data.lib.docker.result(msg, cmd, __local540__)\nTRACE  | | Index data.lib.docker.result (matched 1 rule)\nTRACE  | | Enter data.lib.docker.result\nTRACE  | | | Eval object.get(cmd, \"EndLine\", 0, __local470__)\nTRACE  | | | Eval object.get(cmd, \"Path\", \"\", __local471__)\nTRACE  | | | Eval object.get(cmd, \"StartLine\", 0, __local472__)\nTRACE  | | | Eval result = {\"endline\": __local470__, \"filepath\": __local471__, \"msg\": msg, \"startline\": __local472__}\nTRACE  | | | Exit data.lib.docker.result\nTRACE  | | Eval res = __local540__\nTRACE  | | Exit data.builtin.dockerfile.DS002.deny\nTRACE  | Redo data.builtin.dockerfile.DS002.deny\nTRACE  | | Redo res = __local540__\nTRACE  | | Redo data.lib.docker.result(msg, cmd, __local540__)\nTRACE  | | Redo data.lib.docker.result\nTRACE  | | | Redo result = {\"endline\": __local470__, \"filepath\": __local471__, \"msg\": msg, \"startline\": __local472__}\nTRACE  | | | Redo object.get(cmd, \"StartLine\", 0, __local472__)\nTRACE  | | | Redo object.get(cmd, \"Path\", \"\", __local471__)\nTRACE  | | | Redo object.get(cmd, \"EndLine\", 0, __local470__)\nTRACE  | | Redo msg = \"Last USER command in Dockerfile should not be 'root'\"\nTRACE  | | Redo cmd = data.builtin.dockerfile.DS002.fail_last_user_root[_]\nTRACE  | Exit data.builtin.dockerfile.DS002.deny = _\nTRACE  Redo data.builtin.dockerfile.DS002.deny = _\nTRACE  | Redo data.builtin.dockerfile.DS002.deny = _\nTRACE\n
    "},{"location":"docs/scanner/misconfiguration/custom/schema/","title":"Input Schema","text":""},{"location":"docs/scanner/misconfiguration/custom/schema/#overview","title":"Overview","text":"

    Checks can be defined with custom schemas that allow inputs to be verified against them. Adding a policy schema enables Trivy to show more detailed error messages when an invalid input is encountered.

    In Trivy we have been able to define a schema for a Dockerfile Without input schemas, a policy would be as follows:

    Example

    # METADATA\npackage mypackage\n\ndeny {\n    input.evil == \"foo bar\"\n}\n

    If this policy is run against offending Dockerfile(s), there will not be any issues as the policy will fail to evaluate. Although the policy's failure to evaluate is legitimate, this should not result in a positive result for the scan.

    For instance if we have a policy that checks for misconfigurations in a Dockerfile, we could define the schema as such

    Example

    # METADATA\n# schemas:\n# - input: schema[\"dockerfile\"]\npackage mypackage\n\ndeny {\n    input.evil == \"foo bar\"\n}\n

    Here input: schema[\"dockerfile\"] points to a schema that expects a valid Dockerfile as input. An example of this can be found here.

    Now if this policy is evaluated against, a more descriptive error will be available to help fix the problem.

    1 error occurred: testpolicy.rego:8: rego_type_error: undefined ref: input.evil\n        input.evil\n              ^\n              have: \"evil\"\n              want (one of): [\"Stages\"]\n

    Currently, out of the box the following schemas are supported natively:

    1. Docker
    2. Kubernetes
    3. Cloud
    "},{"location":"docs/scanner/misconfiguration/custom/schema/#custom-checks-with-custom-schemas","title":"Custom Checks with Custom Schemas","text":"

    You can also bring a custom policy that defines one or more custom schema.

    Example

    # METADATA\n# schemas:\n# - input: schema[\"fooschema\"]\n# - input: schema[\"barschema\"]\npackage mypackage\n\ndeny {\n    input.evil == \"foo bar\"\n}\n

    The checks can be placed in a structure as follows

    Example

    /Users/user/my-custom-checks\n\u251c\u2500\u2500 my_policy.rego\n\u2514\u2500\u2500 schemas\n    \u2514\u2500\u2500 fooschema.json\n    \u2514\u2500\u2500 barschema.json\n

    To use such a policy with Trivy, use the --config-policy flag that points to the policy file or to the directory where the schemas and checks are contained.

    $ trivy --config-policy=/Users/user/my-custom-checks <path/to/iac>\n

    For more details on how to define schemas within Rego checks, please see the OPA guide that describes it in more detail.

    "},{"location":"docs/scanner/misconfiguration/custom/selectors/","title":"Input Selectors","text":""},{"location":"docs/scanner/misconfiguration/custom/selectors/#overview","title":"Overview","text":"

    Sometimes you might want to limit a certain policy to only be run on certain resources. This can be achieved with input selectors.

    "},{"location":"docs/scanner/misconfiguration/custom/selectors/#use-case","title":"Use case","text":"

    For instance, if you have a custom policy that you only want to be evaluated if a certain resource type is being scanned. In such a case you could utilize input selectors to limit its evaluation on only those resources.

    Example

        # METADATA\n    # title: \"RDS Publicly Accessible\"\n    # description: \"Ensures RDS instances are not launched into the public cloud.\"\n    # custom:\n    #   input:\n    #     selector:\n    #     - type: cloud\n    #       subtypes:\n    #         - provider: aws\n    #           service: rds\n    package builtin.aws.rds.aws0999\n\n    deny[res] {\n    instance := input.aws.rds.instances[_]\n    instance.publicaccess.value\n    res := result.new(\"Instance has Public Access enabled\", instance.publicaccess)\n

    Observe the following subtypes defined:

            #       subtypes:\n        #         - provider: aws\n        #           service: rds\n

    They will ensure that the policy is only run when the input to such a policy contains an RDS instance.

    "},{"location":"docs/scanner/misconfiguration/custom/selectors/#enabling-selectors-and-subtypes","title":"Enabling selectors and subtypes","text":"

    Currently, the following are supported:

    Selector Subtype fields required Example Cloud (AWS, Azure, etc.) provider, service provider: aws, service: rds Kubernetes type: kubernetes Dockerfile type: dockerfile"},{"location":"docs/scanner/misconfiguration/custom/selectors/#default-behaviour","title":"Default behaviour","text":"

    If no subtypes or selectors are specified, the policy will be evaluated regardless of input.

    "},{"location":"docs/scanner/misconfiguration/custom/testing/","title":"Testing","text":"

    It is highly recommended to write tests for your custom checks.

    "},{"location":"docs/scanner/misconfiguration/custom/testing/#rego-testing","title":"Rego testing","text":"

    To help you verify the correctness of your custom checks, OPA gives you a framework that you can use to write tests for your checks. By writing tests for your custom checks you can speed up the development process of new rules and reduce the amount of time it takes to modify rules as requirements evolve.

    For more details, see Policy Testing.

    Example

    package user.dockerfile.ID002\n\ntest_add_denied {\n    r := deny with input as {\"stages\": {\"alpine:3.13\": [\n        {\"Cmd\": \"add\", \"Value\": [\"/target/resources.tar.gz\", \"resources.jar\"]},\n        {\"Cmd\": \"add\", \"Value\": [\"/target/app.jar\", \"app.jar\"]},\n    ]}}\n\n    count(r) == 1\n    r[_] == \"Consider using 'COPY /target/app.jar app.jar' command instead of 'ADD /target/app.jar app.jar'\"\n}\n

    To write tests for custom checks, you can refer to existing tests under [trivy-checks][trivy-checks].

    "},{"location":"docs/scanner/misconfiguration/custom/testing/#go-testing","title":"Go testing","text":"

    Fanal which is a core library of Trivy can be imported as a Go library. You can scan config files in Go and test your custom checks using Go's testing methods, such as table-driven tests. This allows you to use the actual configuration file as input, making it easy to prepare test data and ensure that your custom checks work in practice.

    In particular, Dockerfile and HCL need to be converted to structural data as input, which may be different from the expected input format.

    Tip

    We recommend writing OPA and Go tests both since they have different roles, like unit tests and integration tests.

    The following example stores allowed and denied configuration files in a directory. Successes contains the result of successes, and Failures contains the result of failures.

    {\n    name:  \"disallowed ports\",\n    input: \"configs/\",\n    fields: fields{\n        policyPaths: []string{\"policy\"},\n        dataPaths:   []string{\"data\"},\n        namespaces:  []string{\"user\"},\n    },\n    want: []types.Misconfiguration{\n        {\n            FileType: types.Dockerfile,\n            FilePath: \"Dockerfile.allowed\",\n            Successes: types.MisconfResults{\n                {\n                    Namespace: \"user.dockerfile.ID002\",\n                    PolicyMetadata: types.PolicyMetadata{\n                        ID:          \"ID002\",\n                        Type:        \"Docker Custom Check\",\n                        Title:       \"Disallowed ports exposed\",\n                        Severity:    \"HIGH\",\n                    },\n                },\n            },\n        },\n        {\n            FileType: types.Dockerfile,\n            FilePath: \"Dockerfile.denied\",\n            Failures: types.MisconfResults{\n                {\n                    Namespace: \"user.dockerfile.ID002\",\n                    Message:   \"Port 23 should not be exposed\",\n                    PolicyMetadata: types.PolicyMetadata{\n                        ID:          \"ID002\",\n                        Type:        \"Docker Custom Check\",\n                        Title:       \"Disallowed ports exposed\",\n                        Severity:    \"HIGH\",\n                    },\n                },\n            },\n        },\n    },\n},\n

    Dockerfile.allowed has one successful result in Successes, while Dockerfile.denied has one failure result in Failures.

    "},{"location":"docs/supply-chain/sbom/","title":"SBOM","text":""},{"location":"docs/supply-chain/sbom/#generating","title":"Generating","text":"

    Trivy can generate the following SBOM formats.

    • CycloneDX
    • SPDX
    "},{"location":"docs/supply-chain/sbom/#cli-commands","title":"CLI commands","text":"

    To generate SBOM, you can use the --format option for each subcommand such as image, fs and vm.

    $ trivy image --format spdx-json --output result.json alpine:3.15\n
    $ trivy fs --format cyclonedx --output result.json /app/myproject\n
    Result
    {\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.3\",\n  \"serialNumber\": \"urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2022-02-22T15:11:40.270597Z\",\n    \"tools\": [\n      {\n        \"vendor\": \"aquasecurity\",\n        \"name\": \"trivy\",\n        \"version\": \"dev\"\n      }\n    ],\n    \"component\": {\n      \"bom-ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\",\n      \"type\": \"container\",\n      \"name\": \"alpine:3.15\",\n      \"version\": \"\",\n      \"purl\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:SchemaVersion\",\n          \"value\": \"2\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:ImageID\",\n          \"value\": \"sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:RepoDigest\",\n          \"value\": \"alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:DiffID\",\n          \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:RepoTag\",\n          \"value\": \"alpine:3.15\"\n        }\n      ]\n    }\n  },\n  \"components\": [\n    {\n      \"bom-ref\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\",\n      \"type\": \"library\",\n      \"name\": \"alpine-baselayout\",\n      \"version\": \"3.2.0-r18\",\n      \"licenses\": [\n        {\n          \"expression\": \"GPL-2.0-only\"\n        }\n      ],\n      \"purl\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:SrcName\",\n          \"value\": \"alpine-baselayout\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:SrcVersion\",\n          \"value\": \"3.2.0-r18\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDigest\",\n          \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDiffID\",\n          \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\"\n        }\n      ]\n    },\n    ...(snip)...\n    {\n      \"bom-ref\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\",\n      \"type\": \"library\",\n      \"name\": \"zlib\",\n      \"version\": \"1.2.11-r3\",\n      \"licenses\": [\n        {\n          \"expression\": \"Zlib\"\n        }\n      ],\n      \"purl\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:SrcName\",\n          \"value\": \"zlib\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:SrcVersion\",\n          \"value\": \"1.2.11-r3\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDigest\",\n          \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDiffID\",\n          \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\"\n        }\n      ]\n    },\n    {\n      \"bom-ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\",\n      \"type\": \"operating-system\",\n      \"name\": \"alpine\",\n      \"version\": \"3.15.0\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:Type\",\n          \"value\": \"alpine\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:Class\",\n          \"value\": \"os-pkgs\"\n        }\n      ]\n    }\n  ],\n  \"dependencies\": [\n    {\n      \"ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\",\n      \"dependsOn\": [\n        \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\",\n        \"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0\",\n        \"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0\",\n        \"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0\",\n        \"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\"\n      ]\n    },\n    {\n      \"ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\",\n      \"dependsOn\": [\n        \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\"\n      ]\n    }\n  ]\n}\n
    "},{"location":"docs/supply-chain/sbom/#supported-packages","title":"Supported packages","text":"

    Trivy supports the following packages.

    • OS packages
    • Language-specific packages
    "},{"location":"docs/supply-chain/sbom/#formats","title":"Formats","text":""},{"location":"docs/supply-chain/sbom/#cyclonedx","title":"CycloneDX","text":"

    Trivy can generate SBOM in the CycloneDX format. Note that XML format is not supported at the moment.

    You can use the regular subcommands (like image, fs and rootfs) and specify cyclonedx with the --format option.

    CycloneDX can represent either or both SBOM or BOV.

    • Software Bill of Materials (SBOM)
    • Bill of Vulnerabilities (BOV)

    By default, --format cyclonedx represents SBOM and doesn't include vulnerabilities in the CycloneDX output.

    $ trivy image --format cyclonedx --output result.json alpine:3.15\n2022-07-19T07:47:27.624Z        INFO    \"--format cyclonedx\" disables security scanning. Specify \"--scanners vuln\" explicitly if you want to include vulnerabilities in the CycloneDX report.\n
    Result
    $ cat result.json | jq .\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"serialNumber\": \"urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace\",\n  \"version\": 1,\n  \"metadata\": {\n    \"timestamp\": \"2022-02-22T15:11:40.270597Z\",\n    \"tools\": {\n      \"components\": [\n        {\n          \"type\": \"application\",\n          \"group\": \"aquasecurity\",\n          \"name\": \"trivy\",\n          \"version\": \"dev\"\n        }\n      ]\n    },\n    \"component\": {\n      \"bom-ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\",\n      \"type\": \"container\",\n      \"name\": \"alpine:3.15\",\n      \"version\": \"\",\n      \"purl\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:SchemaVersion\",\n          \"value\": \"2\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:ImageID\",\n          \"value\": \"sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:RepoDigest\",\n          \"value\": \"alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:DiffID\",\n          \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:RepoTag\",\n          \"value\": \"alpine:3.15\"\n        }\n      ]\n    }\n  },\n  \"components\": [\n    {\n      \"bom-ref\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\",\n      \"type\": \"library\",\n      \"name\": \"alpine-baselayout\",\n      \"version\": \"3.2.0-r18\",\n      \"licenses\": [\n        {\n          \"expression\": \"GPL-2.0-only\"\n        }\n      ],\n      \"purl\": \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:SrcName\",\n          \"value\": \"alpine-baselayout\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:SrcVersion\",\n          \"value\": \"3.2.0-r18\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDigest\",\n          \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDiffID\",\n          \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\"\n        }\n      ]\n    },\n    ...(snip)...\n    {\n      \"bom-ref\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\",\n      \"type\": \"library\",\n      \"name\": \"zlib\",\n      \"version\": \"1.2.11-r3\",\n      \"licenses\": [\n        {\n          \"expression\": \"Zlib\"\n        }\n      ],\n      \"purl\": \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:SrcName\",\n          \"value\": \"zlib\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:SrcVersion\",\n          \"value\": \"1.2.11-r3\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDigest\",\n          \"value\": \"sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:LayerDiffID\",\n          \"value\": \"sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759\"\n        }\n      ]\n    },\n    {\n      \"bom-ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\",\n      \"type\": \"operating-system\",\n      \"name\": \"alpine\",\n      \"version\": \"3.15.0\",\n      \"properties\": [\n        {\n          \"name\": \"aquasecurity:trivy:Type\",\n          \"value\": \"alpine\"\n        },\n        {\n          \"name\": \"aquasecurity:trivy:Class\",\n          \"value\": \"os-pkgs\"\n        }\n      ]\n    }\n  ],\n  \"dependencies\": [\n    {\n      \"ref\": \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\",\n      \"dependsOn\": [\n        \"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0\",\n        \"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0\",\n        \"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0\",\n        \"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0\",\n        \"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0\",\n        \"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0\",\n        \"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0\"\n      ]\n    },\n    {\n      \"ref\": \"pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64\",\n      \"dependsOn\": [\n        \"3da6a469-964d-4b4e-b67d-e94ec7c88d37\"\n      ]\n    }\n  ],\n  \"vulnerabilities\": [\n    {\n      \"id\": \"CVE-2021-42386\",\n      \"source\": {\n        \"name\": \"alpine\",\n        \"url\": \"https://secdb.alpinelinux.org/\"\n      },\n      \"ratings\": [\n        {\n          \"source\": {\n            \"name\": \"nvd\"\n          },\n          \"score\": 7.2,\n          \"severity\": \"high\",\n          \"method\": \"CVSSv31\",\n          \"vector\": \"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H\"\n        },\n        {\n          \"source\": {\n            \"name\": \"nvd\"\n          },\n          \"score\": 6.5,\n          \"severity\": \"medium\",\n          \"method\": \"CVSSv2\",\n          \"vector\": \"AV:N/AC:L/Au:S/C:P/I:P/A:P\"\n        },\n        {\n          \"source\": {\n            \"name\": \"redhat\"\n          },\n          \"score\": 6.6,\n          \"severity\": \"medium\",\n          \"method\": \"CVSSv31\",\n          \"vector\": \"CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H\"\n        }\n      ],\n      \"cwes\": [\n        416\n      ],\n      \"description\": \"A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the nvalloc function\",\n      \"advisories\": [\n        {\n          \"url\": \"https://access.redhat.com/security/cve/CVE-2021-42386\"\n        },\n        {\n          \"url\": \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42386\"\n        }\n      ],\n      \"published\": \"2021-11-15 21:15:00 +0000 UTC\",\n      \"updated\": \"2022-01-04 17:14:00 +0000 UTC\",\n      \"affects\": [\n        {\n          \"ref\": \"pkg:apk/alpine/busybox@1.33.1-r3?distro=3.14.2\"\n        },\n        {\n          \"ref\": \"pkg:apk/alpine/ssl_client@1.33.1-r3?distro=3.14.2\"\n        }\n      ]\n    }\n  ]\n}\n

    If you want to include vulnerabilities, you can enable vulnerability scanning via --scanners vuln.

    $ trivy image --scanners vuln --format cyclonedx --output result.json alpine:3.15\n
    "},{"location":"docs/supply-chain/sbom/#spdx","title":"SPDX","text":"

    Trivy can generate SBOM in the SPDX format.

    You can use the regular subcommands (like image, fs and rootfs) and specify spdx with the --format option.

    $ trivy image --format spdx --output result.spdx alpine:3.15\n
    Result
    $ cat result.spdx\nSPDXVersion: SPDX-2.2\nDataLicense: CC0-1.0\nSPDXID: SPDXRef-DOCUMENT\nDocumentName: alpine:3.15\nDocumentNamespace: https://aquasecurity.github.io/trivy/container_image/alpine:3.15-bebf6b19-a94c-4e2c-af44-065f63923f48\nCreator: Organization: aquasecurity\nCreator: Tool: trivy-0.38.1\nCreated: 2022-04-28T07:32:57.142806Z\n\n##### Package: zlib\n\nPackageName: zlib\nSPDXID: SPDXRef-12bc938ac028a5e1\nPackageVersion: 1.2.12-r0\nFilesAnalyzed: false\nPackageLicenseConcluded: Zlib\nPackageLicenseDeclared: Zlib\n\n##### Package: apk-tools\n\nPackageName: apk-tools\nSPDXID: SPDXRef-26c274652190d87f\nPackageVersion: 2.12.7-r3\nFilesAnalyzed: false\nPackageLicenseConcluded: GPL-2.0-only\nPackageLicenseDeclared: GPL-2.0-only\n\n##### Package: libretls\n\nPackageName: libretls\nSPDXID: SPDXRef-2b021966d19a8211\nPackageVersion: 3.3.4-r3\nFilesAnalyzed: false\nPackageLicenseConcluded: ISC AND (BSD-3-Clause OR MIT)\nPackageLicenseDeclared: ISC AND (BSD-3-Clause OR MIT)\n\n##### Package: busybox\n\nPackageName: busybox\nSPDXID: SPDXRef-317ce3476703f20d\nPackageVersion: 1.34.1-r5\nFilesAnalyzed: false\nPackageLicenseConcluded: GPL-2.0-only\nPackageLicenseDeclared: GPL-2.0-only\n\n##### Package: libcrypto1.1\n\nPackageName: libcrypto1.1\nSPDXID: SPDXRef-34f407fb4dbd67f4\nPackageVersion: 1.1.1n-r0\nFilesAnalyzed: false\nPackageLicenseConcluded: OpenSSL\nPackageLicenseDeclared: OpenSSL\n\n##### Package: libc-utils\n\nPackageName: libc-utils\nSPDXID: SPDXRef-4bbc1cb449d54083\nPackageVersion: 0.7.2-r3\nFilesAnalyzed: false\nPackageLicenseConcluded: BSD-2-Clause AND BSD-3-Clause\nPackageLicenseDeclared: BSD-2-Clause AND BSD-3-Clause\n\n##### Package: alpine-keys\n\nPackageName: alpine-keys\nSPDXID: SPDXRef-a3bdd174be1456b6\nPackageVersion: 2.4-r1\nFilesAnalyzed: false\nPackageLicenseConcluded: MIT\nPackageLicenseDeclared: MIT\n\n##### Package: ca-certificates-bundle\n\nPackageName: ca-certificates-bundle\nSPDXID: SPDXRef-ac6472ba26fb991c\nPackageVersion: 20211220-r0\nFilesAnalyzed: false\nPackageLicenseConcluded: MPL-2.0 AND MIT\nPackageLicenseDeclared: MPL-2.0 AND MIT\n\n##### Package: libssl1.1\n\nPackageName: libssl1.1\nSPDXID: SPDXRef-b2d1b1d70fe90f7d\nPackageVersion: 1.1.1n-r0\nFilesAnalyzed: false\nPackageLicenseConcluded: OpenSSL\nPackageLicenseDeclared: OpenSSL\n\n##### Package: scanelf\n\nPackageName: scanelf\nSPDXID: SPDXRef-c617077ba6649520\nPackageVersion: 1.3.3-r0\nFilesAnalyzed: false\nPackageLicenseConcluded: GPL-2.0-only\nPackageLicenseDeclared: GPL-2.0-only\n\n##### Package: musl\n\nPackageName: musl\nSPDXID: SPDXRef-ca80b810029cde0e\nPackageVersion: 1.2.2-r7\nFilesAnalyzed: false\nPackageLicenseConcluded: MIT\nPackageLicenseDeclared: MIT\n\n##### Package: alpine-baselayout\n\nPackageName: alpine-baselayout\nSPDXID: SPDXRef-d782e64751ba9faa\nPackageVersion: 3.2.0-r18\nFilesAnalyzed: false\nPackageLicenseConcluded: GPL-2.0-only\nPackageLicenseDeclared: GPL-2.0-only\n\n##### Package: musl-utils\n\nPackageName: musl-utils\nSPDXID: SPDXRef-e5e8a237f6162e22\nPackageVersion: 1.2.2-r7\nFilesAnalyzed: false\nPackageLicenseConcluded: MIT BSD GPL2+\nPackageLicenseDeclared: MIT BSD GPL2+\n\n##### Package: ssl_client\n\nPackageName: ssl_client\nSPDXID: SPDXRef-fdf0ce84f6337be4\nPackageVersion: 1.34.1-r5\nFilesAnalyzed: false\nPackageLicenseConcluded: GPL-2.0-only\nPackageLicenseDeclared: GPL-2.0-only\n

    SPDX-JSON format is also supported by using spdx-json with the --format option.

    $ trivy image --format spdx-json --output result.spdx.json alpine:3.15\n
    Result
    $ cat result.spdx.json | jq .\n{\n    \"SPDXID\": \"SPDXRef-DOCUMENT\",\n    \"creationInfo\": {\n        \"created\": \"2022-04-28T08:16:55.328255Z\",\n        \"creators\": [\n            \"Tool: trivy-0.38.1\",\n            \"Organization: aquasecurity\"\n        ]\n    },\n    \"dataLicense\": \"CC0-1.0\",\n    \"documentNamespace\": \"http://aquasecurity.github.io/trivy/container_image/alpine:3.15-d9549e3a-a4c5-4ee3-8bde-8c78d451fbe7\",\n    \"name\": \"alpine:3.15\",\n    \"packages\": [\n        {\n            \"SPDXID\": \"SPDXRef-12bc938ac028a5e1\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"Zlib\",\n            \"licenseDeclared\": \"Zlib\",\n            \"name\": \"zlib\",\n            \"versionInfo\": \"1.2.12-r0\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-26c274652190d87f\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"GPL-2.0-only\",\n            \"licenseDeclared\": \"GPL-2.0-only\",\n            \"name\": \"apk-tools\",\n            \"versionInfo\": \"2.12.7-r3\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-2b021966d19a8211\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"ISC AND (BSD-3-Clause OR MIT)\",\n            \"licenseDeclared\": \"ISC AND (BSD-3-Clause OR MIT)\",\n            \"name\": \"libretls\",\n            \"versionInfo\": \"3.3.4-r3\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-317ce3476703f20d\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"GPL-2.0-only\",\n            \"licenseDeclared\": \"GPL-2.0-only\",\n            \"name\": \"busybox\",\n            \"versionInfo\": \"1.34.1-r5\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-34f407fb4dbd67f4\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"OpenSSL\",\n            \"licenseDeclared\": \"OpenSSL\",\n            \"name\": \"libcrypto1.1\",\n            \"versionInfo\": \"1.1.1n-r0\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-4bbc1cb449d54083\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"BSD-2-Clause AND BSD-3-Clause\",\n            \"licenseDeclared\": \"BSD-2-Clause AND BSD-3-Clause\",\n            \"name\": \"libc-utils\",\n            \"versionInfo\": \"0.7.2-r3\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-a3bdd174be1456b6\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"MIT\",\n            \"licenseDeclared\": \"MIT\",\n            \"name\": \"alpine-keys\",\n            \"versionInfo\": \"2.4-r1\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-ac6472ba26fb991c\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"MPL-2.0 AND MIT\",\n            \"licenseDeclared\": \"MPL-2.0 AND MIT\",\n            \"name\": \"ca-certificates-bundle\",\n            \"versionInfo\": \"20211220-r0\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-b2d1b1d70fe90f7d\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"OpenSSL\",\n            \"licenseDeclared\": \"OpenSSL\",\n            \"name\": \"libssl1.1\",\n            \"versionInfo\": \"1.1.1n-r0\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-c617077ba6649520\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"GPL-2.0-only\",\n            \"licenseDeclared\": \"GPL-2.0-only\",\n            \"name\": \"scanelf\",\n            \"versionInfo\": \"1.3.3-r0\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-ca80b810029cde0e\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"MIT\",\n            \"licenseDeclared\": \"MIT\",\n            \"name\": \"musl\",\n            \"versionInfo\": \"1.2.2-r7\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-d782e64751ba9faa\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"GPL-2.0-only\",\n            \"licenseDeclared\": \"GPL-2.0-only\",\n            \"name\": \"alpine-baselayout\",\n            \"versionInfo\": \"3.2.0-r18\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-e5e8a237f6162e22\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"MIT BSD GPL2+\",\n            \"licenseDeclared\": \"MIT BSD GPL2+\",\n            \"name\": \"musl-utils\",\n            \"versionInfo\": \"1.2.2-r7\"\n        },\n        {\n            \"SPDXID\": \"SPDXRef-fdf0ce84f6337be4\",\n            \"filesAnalyzed\": false,\n            \"licenseConcluded\": \"GPL-2.0-only\",\n            \"licenseDeclared\": \"GPL-2.0-only\",\n            \"name\": \"ssl_client\",\n            \"versionInfo\": \"1.34.1-r5\"\n        }\n    ],\n    \"spdxVersion\": \"SPDX-2.2\"\n}\n
    "},{"location":"docs/supply-chain/sbom/#scanning","title":"Scanning","text":""},{"location":"docs/supply-chain/sbom/#sbom-as-target","title":"SBOM as Target","text":"

    Trivy can take SBOM documents as input for scanning, e.g trivy sbom ./sbom.spdx. See here for more details.

    "},{"location":"docs/supply-chain/sbom/#sbom-detection-inside-targets","title":"SBOM Detection inside Targets","text":"

    Trivy searches for SBOM files in container images with the following extensions:

    • .spdx
    • .spdx.json
    • .cdx
    • .cdx.json

    In addition, Trivy automatically detects SBOM files in Bitnami images, see here for more details.

    It is enabled in the following targets.

    Target Enabled Container Image \u2713 Filesystem Rootfs \u2713 Git Repository VM Image \u2713 Kubernetes AWS SBOM"},{"location":"docs/supply-chain/sbom/#sbom-discovery-for-container-images","title":"SBOM Discovery for Container Images","text":"

    When scanning container images, Trivy can discover SBOM for those images. See here for more details.

    "},{"location":"docs/supply-chain/attestation/rekor/","title":"Scan SBOM attestation in Rekor","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    "},{"location":"docs/supply-chain/attestation/rekor/#container-images","title":"Container images","text":"

    Trivy can retrieve SBOM attestation of the specified container image in the Rekor instance and scan it for vulnerabilities.

    "},{"location":"docs/supply-chain/attestation/rekor/#prerequisites","title":"Prerequisites","text":"
    1. SBOM attestation stored in Rekor
      • See the \"Keyless signing\" section if you want to upload your SBOM attestation to Rekor.
    "},{"location":"docs/supply-chain/attestation/rekor/#scanning","title":"Scanning","text":"

    You need to pass --sbom-sources rekor so that Trivy will look for SBOM attestation in Rekor.

    Note

    --sbom-sources can be used only with trivy image at the moment.

    $ trivy image --sbom-sources rekor otms61/alpine:3.7.3                                                                            [~/src/github.com/aquasecurity/trivy]\n2022-09-16T17:37:13.258+0900    INFO    Vulnerability scanning is enabled\n2022-09-16T17:37:13.258+0900    INFO    Secret scanning is enabled\n2022-09-16T17:37:13.258+0900    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning\n2022-09-16T17:37:13.258+0900    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection\n2022-09-16T17:37:14.827+0900    INFO    Detected SBOM format: cyclonedx-json\n2022-09-16T17:37:14.901+0900    INFO    Found SBOM (cyclonedx) attestation in Rekor\n2022-09-16T17:37:14.903+0900    INFO    Detected OS: alpine\n2022-09-16T17:37:14.903+0900    INFO    Detecting Alpine vulnerabilities...\n2022-09-16T17:37:14.907+0900    INFO    Number of language-specific files: 0\n2022-09-16T17:37:14.908+0900    WARN    This OS version is no longer supported by the distribution: alpine 3.7.3\n2022-09-16T17:37:14.908+0900    WARN    The vulnerability detection may be insufficient because security updates are not provided\n\notms61/alpine:3.7.3 (alpine 3.7.3)\n==================================\nTotal: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library   \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                          Title                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 musl       \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1.1.18-r3         \u2502 1.1.18-r4     \u2502 musl libc through 1.1.23 has an x87 floating-point stack \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502 adjustment im ......                                     \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2019-14697               \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502 musl-utils \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

    If you have your own Rekor instance, you can specify the URL via --rekor-url.

    $ trivy image --sbom-sources rekor --rekor-url https://my-rekor.dev otms61/alpine:3.7.3\n
    "},{"location":"docs/supply-chain/attestation/rekor/#non-packaged-binaries","title":"Non-packaged binaries","text":"

    Trivy can retrieve SBOM attestation of non-packaged binaries in the Rekor instance and scan it for vulnerabilities.

    "},{"location":"docs/supply-chain/attestation/rekor/#prerequisites_1","title":"Prerequisites","text":"
    1. SBOM attestation stored in Rekor
      • See the \"Keyless signing\" section if you want to upload your SBOM attestation to Rekor.

    Cosign currently does not support keyless signing for blob attestation, so use our plugin at the moment. This example uses a cat clone bat written in Rust. You need to generate SBOM from lock files like Cargo.lock at first.

    $ git clone -b v0.20.0 https://github.com/sharkdp/bat\n$ trivy fs --format cyclonedx --output bat.cdx ./bat/Cargo.lock\n

    Then our attestation plugin allows you to store the SBOM attestation linking to a bat binary in the Rekor instance.

    $ wget https://github.com/sharkdp/bat/releases/download/v0.20.0/bat-v0.20.0-x86_64-apple-darwin.tar.gz\n$ tar xvf bat-v0.20.0-x86_64-apple-darwin.tar.gz\n$ trivy plugin install github.com/aquasecurity/trivy-plugin-attest\n$ trivy attest --predicate ./bat.cdx --type cyclonedx ./bat-v0.20.0-x86_64-apple-darwin/bat\n

    Note

    The public instance of the Rekor maintained by the Sigstore team limits the attestation size. If you are using the public instance, please make sure that your SBOM is small enough. To get more detail, please refer to the Rekor project's documentation.

    "},{"location":"docs/supply-chain/attestation/rekor/#scan-a-non-packaged-binary","title":"Scan a non-packaged binary","text":"

    Trivy calculates the digest of the bat binary and searches for the SBOM attestation by the digest in Rekor. If it is found, Trivy uses that for vulnerability scanning.

    $ trivy fs --sbom-sources rekor ./bat-v0.20.0-x86_64-apple-darwin/bat\n2022-10-25T13:27:25.950+0300    INFO    Found SBOM attestation in Rekor: bat\n2022-10-25T13:27:25.993+0300    INFO    Number of language-specific files: 1\n2022-10-25T13:27:25.993+0300    INFO    Detecting cargo vulnerabilities...\n\nbat (cargo)\n===========\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library  \u2502   Vulnerability   \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                           Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 regex     \u2502 CVE-2022-24713    \u2502 HIGH     \u2502 1.5.4             \u2502 1.5.5         \u2502 Mozilla: Denial of Service via complex regular expressions \u2502\n\u2502           \u2502                   \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-24713                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

    Also, it is applied to non-packaged binaries even in container images.

    $ trivy image --sbom-sources rekor --scanners vuln alpine-with-bat\n2022-10-25T13:40:14.920+0300    INFO    Vulnerability scanning is enabled\n2022-10-25T13:40:18.047+0300    INFO    Found SBOM attestation in Rekor: bat\n2022-10-25T13:40:18.186+0300    INFO    Detected OS: alpine\n2022-10-25T13:40:18.186+0300    INFO    Detecting Alpine vulnerabilities...\n2022-10-25T13:40:18.199+0300    INFO    Number of language-specific files: 1\n2022-10-25T13:40:18.199+0300    INFO    Detecting cargo vulnerabilities...\n\nalpine-with-bat (alpine 3.15.6)\n===============================\nTotal: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n\n\nbat (cargo)\n===========\nTotal: 4 (UNKNOWN: 3, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library  \u2502   Vulnerability   \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                           Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 regex     \u2502 CVE-2022-24713    \u2502 HIGH     \u2502 1.5.4             \u2502 1.5.5         \u2502 Mozilla: Denial of Service via complex regular expressions \u2502\n\u2502           \u2502                   \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-24713                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

    Note

    The --sbom-sources rekor flag slows down the scanning as it queries Rekor on the Internet for all non-packaged binaries.

    "},{"location":"docs/supply-chain/attestation/sbom/","title":"SBOM attestation","text":"

    Cosign supports generating and verifying in-toto attestations. This tool enables you to sign and verify SBOM attestation. And, Trivy can take an SBOM attestation as input and scan for vulnerabilities

    Note

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    "},{"location":"docs/supply-chain/attestation/sbom/#sign-with-a-local-key-pair","title":"Sign with a local key pair","text":"

    Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs.

    $ cosign generate-key-pair\n

    In the following example, Trivy generates an SBOM in the CycloneDX format, and then Cosign attaches an attestation of the SBOM to a container image with a local key pair.

    # The cyclonedx type is supported in Cosign v1.10.0 or later.\n$ trivy image --format cyclonedx -o sbom.cdx.json <IMAGE>\n$ cosign attest --key /path/to/cosign.key --type cyclonedx --predicate sbom.cdx.json <IMAGE>\n

    Then, you can verify attestations on the image.

    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE>\n

    You can also create attestations of other formatted SBOM.

    # spdx\n$ trivy image --format spdx -o sbom.spdx <IMAGE>\n$ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx <IMAGE>\n\n# spdx-json\n$ trivy image --format spdx-json -o sbom.spdx.json <IMAGE>\n$ cosign attest --key /path/to/cosign.key --type spdx --predicate sbom.spdx.json <IMAGE>\n
    "},{"location":"docs/supply-chain/attestation/sbom/#keyless-signing","title":"Keyless signing","text":"

    You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).

    # The cyclonedx type is supported in Cosign v1.10.0 or later.\n$ trivy image --format cyclonedx -o sbom.cdx.json <IMAGE>\n# The following command uploads SBOM attestation to the public Rekor instance.\n$ COSIGN_EXPERIMENTAL=1 cosign attest --type cyclonedx --predicate sbom.cdx.json <IMAGE>\n

    You can verify attestations.

    $ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type cyclonedx <IMAGE>\n

    "},{"location":"docs/supply-chain/attestation/sbom/#scanning","title":"Scanning","text":"

    Trivy can take an SBOM attestation as input and scan for vulnerabilities. Currently, Trivy supports CycloneDX-type attestation.

    In the following example, Cosign can get an CycloneDX-type attestation and trivy scan it. You must create CycloneDX-type attestation before trying the example. To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the Sign with a local key pair section.

    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE> > sbom.cdx.intoto.jsonl\n$ trivy sbom ./sbom.cdx.intoto.jsonl\n\nsbom.cdx.intoto.jsonl (alpine 3.7.3)\n=========================\nTotal: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library   \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                          Title                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 musl       \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1.1.18-r3         \u2502 1.1.18-r4     \u2502 musl libc through 1.1.23 has an x87 floating-point stack \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502 adjustment im ......                                     \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2019-14697               \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502 musl-utils \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/supply-chain/attestation/vuln/","title":"Cosign Vulnerability Attestation","text":""},{"location":"docs/supply-chain/attestation/vuln/#generate-cosign-vulnerability-scan-record","title":"Generate Cosign Vulnerability Scan Record","text":"

    Trivy generates reports in the Cosign vulnerability scan record format.

    You can use the regular subcommands (like image, fs and rootfs) and specify cosign-vuln with the --format option.

    $ trivy image --format cosign-vuln --output vuln.json alpine:3.10\n
    Result
    {\n  \"invocation\": {\n    \"parameters\": null,\n    \"uri\": \"\",\n    \"event_id\": \"\",\n    \"builder.id\": \"\"\n  },\n  \"scanner\": {\n    \"uri\": \"pkg:github/aquasecurity/trivy@v0.30.1-8-gf9cb8a28\",\n    \"version\": \"v0.30.1-8-gf9cb8a28\",\n    \"db\": {\n      \"uri\": \"\",\n      \"version\": \"\"\n    },\n    \"result\": {\n      \"SchemaVersion\": 2,\n      \"CreatedAt\": 1629894030,\n      \"ArtifactName\": \"alpine:3.10\",\n      \"ArtifactType\": \"container_image\",\n      \"Metadata\": {\n        \"OS\": {\n          \"Family\": \"alpine\",\n          \"Name\": \"3.10.9\",\n          \"EOSL\": true\n        },\n        \"ImageID\": \"sha256:e7b300aee9f9bf3433d32bc9305bfdd22183beb59d933b48d77ab56ba53a197a\",\n        \"DiffIDs\": [\n          \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\"\n        ],\n        \"RepoTags\": [\n          \"alpine:3.10\"\n        ],\n        \"RepoDigests\": [\n          \"alpine@sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98\"\n        ],\n        \"ImageConfig\": {\n          \"architecture\": \"amd64\",\n          \"container\": \"fdb7e80e3339e8d0599282e606c907aa5881ee4c668a68136119e6dfac6ce3a4\",\n          \"created\": \"2021-04-14T19:20:05.338397761Z\",\n          \"docker_version\": \"19.03.12\",\n          \"history\": [\n            {\n              \"created\": \"2021-04-14T19:20:04.987219124Z\",\n              \"created_by\": \"/bin/sh -c #(nop) ADD file:c5377eaa926bf412dd8d4a08b0a1f2399cfd708743533b0aa03b53d14cb4bb4e in / \"\n            },\n            {\n              \"created\": \"2021-04-14T19:20:05.338397761Z\",\n              \"created_by\": \"/bin/sh -c #(nop)  CMD [\\\"/bin/sh\\\"]\",\n              \"empty_layer\": true\n            }\n          ],\n          \"os\": \"linux\",\n          \"rootfs\": {\n            \"type\": \"layers\",\n            \"diff_ids\": [\n              \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\"\n            ]\n          },\n          \"config\": {\n            \"Cmd\": [\n              \"/bin/sh\"\n            ],\n            \"Env\": [\n              \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\n            ],\n            \"Image\": \"sha256:eb2080c455e94c22ae35b3aef9e078c492a00795412e026e4d6b41ef64bc7dd8\"\n          }\n        }\n      },\n      \"Results\": [\n        {\n          \"Target\": \"alpine:3.10 (alpine 3.10.9)\",\n          \"Class\": \"os-pkgs\",\n          \"Type\": \"alpine\",\n          \"Vulnerabilities\": [\n            {\n              \"VulnerabilityID\": \"CVE-2021-36159\",\n              \"PkgName\": \"apk-tools\",\n              \"InstalledVersion\": \"2.10.6-r0\",\n              \"FixedVersion\": \"2.10.7-r0\",\n              \"Layer\": {\n                \"Digest\": \"sha256:396c31837116ac290458afcb928f68b6cc1c7bdd6963fc72f52f365a2a89c1b5\",\n                \"DiffID\": \"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635\"\n              },\n              \"SeveritySource\": \"nvd\",\n              \"PrimaryURL\": \"https://avd.aquasec.com/nvd/cve-2021-36159\",\n              \"DataSource\": {\n                \"ID\": \"alpine\",\n                \"Name\": \"Alpine Secdb\",\n                \"URL\": \"https://secdb.alpinelinux.org/\"\n              },\n              \"Description\": \"libfetch before 2021-07-26, as used in apk-tools, xbps, and other products, mishandles numeric strings for the FTP and HTTP protocols. The FTP passive mode implementation allows an out-of-bounds read because strtol is used to parse the relevant numbers into address bytes. It does not check if the line ends prematurely. If it does, the for-loop condition checks for the '\\\\0' terminator one byte too late.\",\n              \"Severity\": \"CRITICAL\",\n              \"CweIDs\": [\n                \"CWE-125\"\n              ],\n              \"CVSS\": {\n                \"nvd\": {\n                  \"V2Vector\": \"AV:N/AC:L/Au:N/C:P/I:N/A:P\",\n                  \"V3Vector\": \"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H\",\n                  \"V2Score\": 6.4,\n                  \"V3Score\": 9.1\n                }\n              },\n              \"References\": [\n                \"https://github.com/freebsd/freebsd-src/commits/main/lib/libfetch\",\n                \"https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10749\",\n                \"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cdev.kafka.apache.org%3E\",\n                \"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cusers.kafka.apache.org%3E\",\n                \"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cdev.kafka.apache.org%3E\",\n                \"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cusers.kafka.apache.org%3E\"\n              ],\n              \"PublishedDate\": \"2021-08-03T14:15:00Z\",\n              \"LastModifiedDate\": \"2021-10-18T12:19:00Z\"\n            }\n          ]\n        }\n      ]\n    }\n  },\n  \"metadata\": {\n    \"scanStartedOn\": \"2022-07-24T17:14:04.864682+09:00\",\n    \"scanFinishedOn\": \"2022-07-24T17:14:04.864682+09:00\"\n  }\n}\n
    "},{"location":"docs/supply-chain/attestation/vuln/#create-cosign-vulnerability-attestation","title":"Create Cosign Vulnerability Attestation","text":"

    Cosign supports generating and verifying in-toto attestations. This tool enables you to sign and verify Cosign vulnerability attestation.

    Note

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    "},{"location":"docs/supply-chain/attestation/vuln/#sign-with-a-local-key-pair","title":"Sign with a local key pair","text":"

    Cosign can generate key pairs and use them for signing and verification. After you run the following command, you will get a public and private key pair. Read more about how to generate key pairs.

    $ cosign generate-key-pair\n

    In the following example, Trivy generates a cosign vulnerability scan record, and then Cosign attaches an attestation of it to a container image with a local key pair.

    $ trivy image --format cosign-vuln --output vuln.json <IMAGE>\n$ cosign attest --key /path/to/cosign.key --type vuln --predicate vuln.json <IMAGE>\n

    Then, you can verify attestations on the image.

    $ cosign verify-attestation --key /path/to/cosign.pub --type vuln <IMAGE>\n
    "},{"location":"docs/supply-chain/attestation/vuln/#keyless-signing","title":"Keyless signing","text":"

    You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).

    $ trivy image --format cosign-vuln -o vuln.json <IMAGE>\n$ cosign attest --type vuln --predicate vuln.json <IMAGE>\n
    This will provide a certificate in the output section.

    You can verify attestations:

    $ cosign verify-attestation --certificate=path-to-the-certificate --type vuln --certificate-identity Email-used-to-sign  --certificate-oidc-issuer='the-issuer-used' <IMAGE>\n
    "},{"location":"docs/supply-chain/vex/","title":"Vulnerability Exploitability Exchange (VEX)","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy supports filtering detected vulnerabilities using the Vulnerability Exploitability eXchange (VEX), a standardized format for sharing and exchanging information about vulnerabilities. By providing VEX during scanning, it is possible to filter vulnerabilities based on their status.

    "},{"location":"docs/supply-chain/vex/#vex-usage-methods","title":"VEX Usage Methods","text":"

    Trivy currently supports two methods for utilizing VEX:

    1. VEX Repository
    2. Local VEX Files
    3. VEX Attestation
    "},{"location":"docs/supply-chain/vex/#enabling-vex","title":"Enabling VEX","text":"

    To enable VEX, use the --vex option. You can specify the method to use:

    • To enable the VEX Repository: --vex repo
    • To use a local VEX file: --vex /path/to/vex-document.json
    • To enable VEX attestation discovery in OCI registry: --vex oci
    $ trivy image ghcr.io/aquasecurity/trivy:0.52.0 --vex repo\n

    You can enable these methods simultaneously. The order of specification determines the priority:

    • --vex repo --vex /path/to/vex-document.json: VEX Repository has priority
    • --vex /path/to/vex-document.json --vex repo: Local file has priority

    For detailed information on each method, please refer to each page.

    "},{"location":"docs/supply-chain/vex/file/","title":"Local VEX Files","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    In addition to VEX repositories, Trivy also supports the use of local VEX files for vulnerability filtering. This method is useful when you have specific VEX documents that you want to apply to your scans. Currently, Trivy supports the following formats:

    • CycloneDX
    • OpenVEX
    • CSAF
    "},{"location":"docs/supply-chain/vex/file/#cyclonedx","title":"CycloneDX","text":"Target Supported Container Image Filesystem Code Repository VM Image Kubernetes SBOM \u2705

    There are two VEX formats for CycloneDX:

    • Independent BOM and VEX BOM
    • BOM With Embedded VEX

    Trivy only supports the Independent BOM and VEX BOM format, so you need to provide a separate VEX file alongside the SBOM. The input SBOM format must be in CycloneDX format.

    The following steps are required:

    1. Generate a CycloneDX SBOM
    2. Create a VEX based on the SBOM generated in step 1
    3. Provide the VEX when scanning the CycloneDX SBOM
    "},{"location":"docs/supply-chain/vex/file/#generate-the-sbom","title":"Generate the SBOM","text":"

    You can generate a CycloneDX SBOM with Trivy as follows:

    $ trivy image --format cyclonedx --output debian11.sbom.cdx debian:11\n
    "},{"location":"docs/supply-chain/vex/file/#create-the-vex","title":"Create the VEX","text":"

    Next, create a VEX based on the generated SBOM. Multiple vulnerability statuses can be defined under vulnerabilities. Take a look at the example below.

    $ cat <<EOF > trivy.vex.cdx\n{\n  \"bomFormat\": \"CycloneDX\",\n  \"specVersion\": \"1.5\",\n  \"version\": 1,\n  \"vulnerabilities\": [\n    {\n      \"id\": \"CVE-2020-8911\",\n      \"analysis\": {\n        \"state\": \"not_affected\",\n        \"justification\": \"code_not_reachable\",\n        \"response\": [\"will_not_fix\", \"update\"],\n        \"detail\": \"The vulnerable function is not called\"\n      },\n      \"affects\": [\n        {\n          \"ref\": \"urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#pkg:golang/github.com/aws/aws-sdk-go@v1.44.234\"\n        }\n      ]\n    }\n  ]\n}\nEOF\n

    This is a VEX document in the CycloneDX format. The vulnerability ID, such as a CVE-ID or GHSA-ID, should be placed in vulnerabilities.id. When the analysis.state is set to not_affected, Trivy will not detect the vulnerability.

    BOM-Links must be placed in affects.ref. The BOM-Link has the following syntax and consists of three elements:

    urn:cdx:serialNumber/version#bom-ref\n
    • serialNumber
    • version
    • bom-ref

    These values must be obtained from the CycloneDX SBOM. Please note that while the serialNumber starts with urn:uuid:, the BOM-Link starts with urn:cdx:.

    The bom-ref must contain the BOM-Ref of the package affected by the vulnerability. In the example above, since the Go package github.com/aws/aws-sdk-go is affected by CVE-2020-8911, it was necessary to specify the SBOM's BOM-Ref, pkg:golang/github.com/aws/aws-sdk-go@1.44.234.

    For more details on CycloneDX VEX and BOM-Link, please refer to the following links:

    • CycloneDX VEX
    • BOM-Link
    • Examples
    "},{"location":"docs/supply-chain/vex/file/#scan-sbom-with-vex","title":"Scan SBOM with VEX","text":"

    Provide the VEX when scanning the CycloneDX SBOM.

    $ trivy sbom trivy.sbom.cdx --vex trivy.vex.cdx\n...\n2023-04-13T12:55:44.838+0300    INFO    Filtered out the detected vulnerability {\"VEX format\": \"CycloneDX\", \"vulnerability-id\": \"CVE-2020-8911\", \"status\": \"not_affected\", \"justification\": \"code_not_reachable\"}\n\ngo.mod (gomod)\n==============\nTotal: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502          Library          \u2502 Vulnerability \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                           Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 github.com/aws/aws-sdk-go \u2502 CVE-2020-8912 \u2502 LOW      \u2502 v1.44.234         \u2502               \u2502 aws-sdk-go: In-band key negotiation issue in AWS S3 Crypto \u2502\n\u2502                           \u2502               \u2502          \u2502                   \u2502               \u2502 SDK for golang...                                          \u2502\n\u2502                           \u2502               \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2020-8912                  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

    CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document.

    "},{"location":"docs/supply-chain/vex/file/#openvex","title":"OpenVEX","text":"Target Supported Container Image \u2705 Filesystem \u2705 Code Repository \u2705 VM Image \u2705 Kubernetes \u2705 SBOM \u2705

    Trivy also supports OpenVEX that is designed to be minimal, compliant, interoperable, and embeddable. OpenVEX can be used in all Trivy targets, unlike CycloneDX VEX.

    The following steps are required:

    1. Create a VEX document
    2. Provide the VEX when scanning your target
    "},{"location":"docs/supply-chain/vex/file/#create-the-vex-document","title":"Create the VEX document","text":"

    Please see also the example. Trivy requires the Package URL (PURL) as the product identifier.

    $ cat <<EOF > debian11.openvex.json\n{\n  \"@context\": \"https://openvex.dev/ns/v0.2.0\",\n  \"@id\": \"https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f\",\n  \"author\": \"Aqua Security\",\n  \"timestamp\": \"2023-08-29T19:07:16.853479631-06:00\",\n  \"version\": 1,\n  \"statements\": [\n    {\n      \"vulnerability\": {\"name\": \"CVE-2019-8457\"},\n      \"products\": [\n        {\"@id\": \"pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8\"}\n      ],\n      \"status\": \"not_affected\",\n      \"justification\": \"vulnerable_code_not_in_execute_path\"\n    }\n  ]\n}\nEOF\n

    In the above example, PURLs, pkg:deb/debian/libdb5.3@5.3.28+dfsg1-0.8 are used for the product identifier. You can find PURLs in the JSON report generated by Trivy. This VEX statement is applied if the PURL specified in the VEX matches the PURL found during the scan. See here for more details of PURL matching.

    Trivy also supports OpenVEX subcomponents, which allow for more precise specification of the scope of a VEX statement, reducing the risk of incorrect filtering. Let's say you want to suppress vulnerabilities within a container image. If you only specify the PURL of the container image as the product, the resulting VEX would look like this:

    OpenVEX products only
    \"statements\": [\n  {\n    \"vulnerability\": {\"name\": \"CVE-2024-32002\"},\n    \"products\": [\n      {\"@id\": \"pkg:oci/trivy?repository_url=ghcr.io%2Faquasecurity%2Ftrivy\"}\n    ],\n    \"status\": \"not_affected\",\n    \"justification\": \"vulnerable_code_not_in_execute_path\"\n  }\n]\n

    However, this approach would suppress all instances of CVE-2024-32002 within the container image. If the intention is to declare that the git package distributed by Alpine Linux within this image is not affected, subcomponents can be utilized as follows:

    OpenVEX subcomponents
    \"statements\": [\n  {\n    \"vulnerability\": {\"name\": \"CVE-2024-32002\"},\n    \"products\": [\n      {\n        \"@id\": \"pkg:oci/trivy?repository_url=ghcr.io%2Faquasecurity%2Ftrivy\",\n        \"subcomponents\": [\n          {\"@id\": \"pkg:apk/alpine/git\"}\n        ]\n      }\n    ],\n    \"status\": \"not_affected\",\n    \"justification\": \"vulnerable_code_not_in_execute_path\"\n  }\n]\n

    By declaring the subcomponent in this manner, Trivy will filter the results, considering only the git package within the ghcr.io/aquasecurity/trivy container image as not affected. Omitting the version in the PURL applies the statement to all versions of the package. More details about PURL matching can be found here.

    Furthermore, the product specified in a VEX statement does not necessarily need to be the target of the scan. It is possible to specify a component that is included in the scan target as the product. For example, you can designate a specific Go project as the product and its dependent modules as subcomponents.

    In the following example, the VEX statement declares that the github.com/docker/docker module, which is a dependency of the github.com/aquasecurity/trivy Go project, is not affected by CVE-2024-29018.

    OpenVEX intermediate components
    \"statements\": [\n  {\n    \"vulnerability\": {\"name\": \"CVE-2024-29018\"},\n    \"products\": [\n      {\n        \"@id\": \"pkg:golang/github.com/aquasecurity/trivy\",\n        \"subcomponents\": [\n          { \"@id\": \"pkg:golang/github.com/docker/docker\" }\n        ]\n      }\n    ],\n    \"status\": \"not_affected\",\n    \"justification\": \"vulnerable_code_not_in_execute_path\"\n  }\n]\n

    This VEX document can be used when scanning a container image as well as other targets. The VEX statement will be applied when Trivy finds the Go binary within the container image.

    $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex trivy.openvex.json\n

    VEX documents can indeed be reused across different container images, eliminating the need to issue separate VEX documents for each image. This is particularly useful when there is a common component or library that is used across multiple projects or container images.

    You can see the appendix for more details on how VEX is applied in Trivy.

    "},{"location":"docs/supply-chain/vex/file/#scan-with-vex","title":"Scan with VEX","text":"

    Provide the VEX when scanning your target.

    $ trivy image debian:11 --vex debian11.openvex.json\n...\n2023-04-26T17:56:05.358+0300    INFO    Filtered out the detected vulnerability {\"VEX format\": \"OpenVEX\", \"vulnerability-id\": \"CVE-2019-8457\", \"status\": \"not_affected\", \"justification\": \"vulnerable_code_not_in_execute_path\"}\n\ndebian11.spdx.json (debian 11.6)\n================================\nTotal: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)\n

    CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document.

    "},{"location":"docs/supply-chain/vex/file/#csaf","title":"CSAF","text":"Target Supported Container Image \u2705 Filesystem \u2705 Code Repository \u2705 VM Image \u2705 Kubernetes \u2705 SBOM \u2705

    Trivy also supports CSAF format for VEX. Since CSAF aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy.

    The following steps are required:

    1. Create a CSAF document
    2. Provide the CSAF when scanning your target
    "},{"location":"docs/supply-chain/vex/file/#create-the-csaf-document","title":"Create the CSAF document","text":"

    Create a CSAF document in JSON format as follows:

    CSAF VEX
    $ cat <<EOF > debian11.vex.csaf\n{\n  \"document\": {\n    \"category\": \"csaf_vex\",\n    \"csaf_version\": \"2.0\",\n    \"notes\": [\n      {\n        \"category\": \"summary\",\n        \"text\": \"Example Company VEX document. Unofficial content for demonstration purposes only.\",\n        \"title\": \"Author comment\"\n      }\n    ],\n    \"publisher\": {\n      \"category\": \"vendor\",\n      \"name\": \"Example Company ProductCERT\",\n      \"namespace\": \"https://psirt.example.com\"\n    },\n    \"title\": \"AquaSecurity example VEX document\",\n    \"tracking\": {\n      \"current_release_date\": \"2024-01-01T11:00:00.000Z\",\n      \"generator\": {\n        \"date\": \"2024-01-01T11:00:00.000Z\",\n        \"engine\": {\n          \"name\": \"Secvisogram\",\n          \"version\": \"1.11.0\"\n        }\n      },\n      \"id\": \"2024-EVD-UC-01-A-001\",\n      \"initial_release_date\": \"2024-01-01T11:00:00.000Z\",\n      \"revision_history\": [\n        {\n          \"date\": \"2024-01-01T11:00:00.000Z\",\n          \"number\": \"1\",\n          \"summary\": \"Initial version.\"\n        }\n      ],\n      \"status\": \"final\",\n      \"version\": \"1\"\n    }\n  },\n  \"product_tree\": {\n    \"branches\": [\n      {\n        \"branches\": [\n          {\n            \"branches\": [\n              {\n                \"category\": \"product_version\",\n                \"name\": \"5.3\",\n                \"product\": {\n                  \"name\": \"Database Libraries 5.3\",\n                  \"product_id\": \"LIBDB-5328\",\n                  \"product_identification_helper\": {\n                    \"purl\": \"pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.8?arch=amd64\\u0026distro=debian-11.8\"\n                  }\n                }\n              }\n            ],\n            \"category\": \"product_name\",\n            \"name\": \"Database Libraries\"\n          }\n        ],\n        \"category\": \"vendor\",\n        \"name\": \"Debian\"\n      }\n    ]\n  },\n  \"vulnerabilities\": [\n    {\n      \"cve\": \"CVE-2019-8457\",\n      \"notes\": [\n        {\n          \"category\": \"description\",\n          \"text\": \"SQLite3 from 3.6.0 to and including 3.27.2 is vulnerable to heap out-of-bound read in the rtreenode() function when handling invalid rtree tables.\",\n          \"title\": \"CVE description\"\n        }\n      ],\n      \"product_status\": {\n        \"known_not_affected\": [\n          \"LIBDB-5328\"\n        ]\n      },\n      \"threats\": [\n        {\n          \"category\": \"impact\",\n          \"details\": \"Vulnerable code not in execute path.\",\n          \"product_ids\": [\n            \"LIBDB-5328\"\n          ]\n        }\n      ]\n    }\n  ]\n}\nEOF\n

    Trivy also supports CSAF relationships, reducing the risk of incorrect filtering. It works in the same way as OpenVEX subcomponents. At present, the specified relationship category is not taken into account and all the following categories are treated internally as \"depends_on\".

    • default_component_of
    • installed_on
    • installed_with

    You can see the appendix for more details on how VEX is applied in Trivy.

    "},{"location":"docs/supply-chain/vex/file/#scan-with-csaf-vex","title":"Scan with CSAF VEX","text":"

    Provide the CSAF document when scanning your target.

    $ trivy image debian:11 --vex debian11.vex.csaf\n...\n2024-01-02T10:28:26.704+0100    INFO    Filtered out the detected vulnerability {\"VEX format\": \"CSAF\", \"vulnerability-id\": \"CVE-2019-8457\", \"status\": \"not_affected\"}\n\ndebian11.spdx.json (debian 11.6)\n================================\nTotal: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)\n

    CVE-2019-8457 is no longer shown as it is filtered out according to the given CSAF document.

    "},{"location":"docs/supply-chain/vex/file/#appendix","title":"Appendix","text":""},{"location":"docs/supply-chain/vex/file/#purl-matching","title":"PURL matching","text":"

    In the context of VEX, Package URLs (PURLs) are utilized to identify specific software packages and their versions. The PURL matching specification outlines how PURLs are interpreted for vulnerability exception processing, ensuring precise identification and broad coverage of software packages.

    Note

    The following PURL matching rules are not formally defined within the current official PURL specification. Instead, they represent a community consensus on how to interpret PURLs.

    Below are the key aspects of the PURL matching rules:

    "},{"location":"docs/supply-chain/vex/file/#matching-without-version","title":"Matching Without Version","text":"

    A PURL without a specified version (e.g., pkg:maven/com.google.guava/guava) matches all versions of that package. This rule simplifies the application of vulnerability exceptions to all versions of a package.

    Example: pkg:maven/com.google.guava/guava matches:

    • All versions of guava, such as com.google.guava:guava:24.1.1, com.google.guava:guava:30.0.
    "},{"location":"docs/supply-chain/vex/file/#matching-without-qualifiers","title":"Matching Without Qualifiers","text":"

    A PURL without any qualifiers (e.g., pkg:maven/com.google.guava/guava@24.1.1) matches any variation of that package, irrespective of qualifiers. This approach ensures broad matching capabilities, covering all architectural or platform-specific variations of a package version.

    Example: pkg:maven/com.google.guava/guava@24.1.1 matches:

    • pkg:maven/com.google.guava/guava@24.1.1?classifier=x86
    • pkg:maven/com.google.guava/guava@24.1.1?type=pom
    "},{"location":"docs/supply-chain/vex/file/#matching-with-specific-qualifiers","title":"Matching With Specific Qualifiers","text":"

    A PURL that includes specific qualifiers (e.g., pkg:maven/com.google.guava/guava@24.1.1?classifier=x86) matches only those package versions that include the same qualifiers.

    Example: pkg:maven/com.google.guava/guava@24.1.1?classifier=x86 matches:

    • pkg:maven/com.google.guava/guava@24.1.1?classifier=x86&type=dll
      • Extra qualifiers (e.g., type=dll) are ignored.

    does not match:

    • pkg:maven/com.google.guava/guava@24.1.1
      • classifier=x86 is missing.
    • pkg:maven/com.google.guava/guava@24.1.1?classifier=sources
      • classifier must have the same value.
    "},{"location":"docs/supply-chain/vex/file/#applying-vex-to-dependency-trees","title":"Applying VEX to Dependency Trees","text":"

    Trivy internally generates a dependency tree and applies VEX statements to this graph. Let's consider a project with the following dependency tree, where Module C v2.0.0 is assumed to have a vulnerability CVE-XXXX-YYYY:

    graph TD;\n  modRootA(Module Root A v1.0.0)\n  modB(Module B v1.0.0) \n  modC(Module C v2.0.0)\n\n  modRootA-->modB\n  modB-->modC

    Now, suppose a VEX statement is issued for Module B as follows:

    \"statements\": [\n  {\n    \"vulnerability\": {\"name\": \"CVE-XXXX-YYYY\"},\n    \"products\": [\n      {\n        \"@id\": \"pkg:golang/module-b@v1.0.0\",\n        \"subcomponents\": [\n          { \"@id\": \"pkg:golang/module-c@v2.0.0\" }\n        ]\n      }\n    ],\n    \"status\": \"not_affected\",\n    \"justification\": \"vulnerable_code_not_in_execute_path\"  \n  }\n]\n

    It declares that Module B is not affected by CVE-XXXX-YYYY on Module C.

    Note

    The VEX in this example defines the relationship between Module B and Module C. However, as Trivy traverses all parents from vulnerable packages, it is also possible to define a VEX for the relationship between a vulnerable package and any parent, such as Module A and Module C, etc.

    Mapping this VEX onto the dependency tree would look like this:

    graph TD;\n  modRootA(Module Root A v1.0.0)\n\n  subgraph \"VEX (Not Affected)\"\n  modB(Module B v1.0.0)\n  modC(Module C v2.0.0)\n  end\n\n  modRootA-->modB\n  modB-->modC

    In this case, it's clear that Module Root A is also not affected by CVE-XXXX-YYYY, so this vulnerability is suppressed.

    Now, let's consider another project:

    graph TD;\n  modRootZ(Module Root Z v1.0.0)\n  modB'(Module B v1.0.0)\n  modC'(Module C v2.0.0)\n  modD'(Module D v3.0.0)\n\n  modRootZ-->modB'\n  modRootZ-->modD'\n  modB'-->modC'\n  modD'-->modC'

    Assuming the same VEX as before, applying it to this dependency tree would look like:

    graph TD;\n  modRootZ(Module Root Z v1.0.0)\n\n  subgraph \"VEX (Not Affected)\"\n  modB'(Module B v1.0.0)\n  modC'(Module C v2.0.0)\n  end\n\n  modD'(Module D v3.0.0)\n\n  modRootZ-->modB'\n  modRootZ-->modD'\n  modB'-->modC'\n  modD'-->modC'

    Module Root Z depends on Module C via multiple paths. While the VEX tells us that Module B is not affected by the vulnerability, Module D might be. In the absence of a VEX, the default assumption is that it is affected. Taking all of this into account, Trivy determines that Module Root Z is affected by this vulnerability.

    "},{"location":"docs/supply-chain/vex/oci/","title":"Discover VEX Attestation in OCI Registry","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy can discover VEX attestations for container images. This feature allows you to automatically use VEX during container image scanning.

    "},{"location":"docs/supply-chain/vex/oci/#how-it-works","title":"How It Works","text":"

    Trivy can automatically discover and utilize VEX attestations for container images during scanning by using the --vex oci flag. This process enhances vulnerability detection results by incorporating the information from the VEX attestation.

    To use this feature, follow these three steps:

    1. Create a VEX document
    2. Generate and upload a VEX attestation to an OCI registry
    3. Use the VEX attestation with Trivy

    Steps 1 and 2 are not necessary if you are trying to scan a third-party container image and already have VEX attestation attached.

    Let's go through each step in detail.

    Note

    In the following examples, the cosign command will write an attestation to a target OCI registry, so you must have permission to write. If you want to avoid writing an OCI registry and only want to see an attestation, add the --no-upload option to the cosign command.

    "},{"location":"docs/supply-chain/vex/oci/#step-1-create-a-vex-document","title":"Step 1: Create a VEX Document","text":"

    Currently, Trivy does not have a built-in feature to create VEX documents, so you need to create them manually. You can refer to the OpenVEX section for guidance on creating VEX files.

    For container image vulnerabilities, the product ID should be the OCI type in the PURL format. For example:

    pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy\n

    This product ID applies the VEX statement to all tags of the ghcr.io/aquasecurity/trivy container image. If you want to declare a statement for a specific digest only, you can use:

    pkg:oci/trivy@sha256:5bd5ab35814f86783561603ebb35d5d5d99006dcdcd5c3f828ea1afb4c12d159?repository_url=ghcr.io/aquasecurity/trivy\n

    Note

    Using an image tag, like pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy&tag=0.50.0, is not supported in the product ID at the moment.

    Next, specify vulnerable packages as subcomponents, such as pkg:apk/alpine/busybox. You can also include the package version and other qualifiers (e.g., arch) to limit statements, like pkg:apk/alpine/busybox@1.36.1-r29?arch=x86.

    Lastly, include the vulnerability IDs.

    Here's an example VEX document:

    {\n  \"@context\": \"https://openvex.dev/ns/v0.2.0\",\n  \"@id\": \"https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f\",\n  \"author\": \"Aqua Security\",\n  \"timestamp\": \"2024-07-30T19:07:16.853479631-06:00\",\n  \"version\": 1,\n  \"statements\": [\n    {\n      \"vulnerability\": {\n        \"name\": \"CVE-2023-42363\"\n      },\n      \"products\": [\n        {\n          \"@id\": \"pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy\",\n          \"subcomponents\": [\n            {\"@id\": \"pkg:apk/alpine/busybox\"},\n            {\"@id\": \"pkg:apk/alpine/busybox-binsh\"}\n          ]\n        }\n      ],\n      \"status\": \"not_affected\",\n      \"justification\": \"vulnerable_code_cannot_be_controlled_by_adversary\",\n      \"impact_statement\": \"awk is not used\"\n    }\n  ]\n}\n

    You can also refer to Trivy's example for more inspiration.

    "},{"location":"docs/supply-chain/vex/oci/#step-2-generate-and-upload-a-vex-attestation-to-an-oci-registry","title":"Step 2: Generate and Upload a VEX Attestation to an OCI Registry","text":"

    You can use the Cosign command to generate and upload the VEX attestation. Cosign offers methods both with and without keys. For detailed instructions, please refer to the Cosign documentation.

    To generate and attach a VEX attestation to your image, use the following command:

    $ cosign attest --predicate oci.openvex.json --type openvex <IMAGE>\n

    Note that this command attaches the attestation only to the specified image tag. If needed, repeat the process for other tags and digests.

    "},{"location":"docs/supply-chain/vex/oci/#step-3-use-vex-attestation-with-trivy","title":"Step 3: Use VEX Attestation with Trivy","text":"

    Once you've attached the VEX attestation to the container image, Trivy can automatically discover and use it during scanning. Simply add the --vex oci flag when scanning a container image:

    $ trivy image --vex oci <IMAGE>\n

    To see which vulnerabilities were filtered by the VEX attestation, use the --show-suppressed flag:

    $ trivy image --vex oci --show-suppressed <IMAGE>\n

    The <IMAGE> specified in these commands must be the same as the one to which you attached the VEX attestation.

    "},{"location":"docs/supply-chain/vex/repo/","title":"VEX Repository","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    "},{"location":"docs/supply-chain/vex/repo/#using-vex-repository","title":"Using VEX Repository","text":"

    Trivy can download and utilize VEX documents from repositories that comply with the VEX Repository Specification. While it's planned to be enabled by default in the future, currently it can be activated by explicitly specifying --vex repo.

    $ trivy image ghcr.io/aquasecurity/trivy:0.52.0 --vex repo\n2024-07-20T11:22:58+04:00       INFO    [vex] The default repository config has been created    \nfile_path=\"/Users/teppei/.trivy/vex/repository.yaml\"\n2024-07-20T11:23:23+04:00       INFO    [vex] Updating repository...    repo=\"default\" url=\"https://github.com/aquasecurity/vexhub\"\n

    During scanning, Trivy generates PURLs for discovered packages and searches for matching PURLs in the VEX Repository. If a match is found, the corresponding VEX is utilized.

    "},{"location":"docs/supply-chain/vex/repo/#configuration-file","title":"Configuration File","text":""},{"location":"docs/supply-chain/vex/repo/#default-configuration","title":"Default Configuration","text":"

    When --vex repo is specified for the first time, a default configuration file is created at $HOME/.trivy/vex/repository.yaml. The home directory can be configured through environment variable $XDG_DATA_HOME.

    You can also create the configuration file in advance using the trivy vex repo init command and edit it.

    The default configuration file looks like this:

    repositories:\n  - name: default\n    url: https://github.com/aquasecurity/vexhub\n    enabled: true\n    username: \"\"\n    password: \"\"\n    token: \"\"\n

    By default, VEX Hub managed by Aqua Security is used. VEX Hub primarily trusts VEX documents published by the package maintainers.

    "},{"location":"docs/supply-chain/vex/repo/#show-configuration","title":"Show Configuration","text":"

    You can see the config file path and the configured repositories with trivy vex repo list:

    $ trivy vex repo list\nVEX Repositories (config: /home/username/.trivy/vex/repository.yaml)\n\n- Name: default\n  URL: https://github.com/aquasecurity/vexhub\n  Status: Enabled\n
    "},{"location":"docs/supply-chain/vex/repo/#custom-repositories","title":"Custom Repositories","text":"

    If you want to trust VEX documents published by other organizations or use your own VEX repository, you can specify a custom repository that complies with the VEX Repository Specification. You can add a custom repository as below:

    - name: custom\n  url: https://example.com/custom-repo\n  enabled: true\n
    "},{"location":"docs/supply-chain/vex/repo/#authentication","title":"Authentication","text":"

    For private repositories:

    • username/password can be used for Basic authentication
    • token can be used for Bearer authentication
    - name: custom\n  url: https://example.com/custom-repo\n  enabled: true\n  token: \"my-token\"\n
    "},{"location":"docs/supply-chain/vex/repo/#repository-priority","title":"Repository Priority","text":"

    The priority of VEX repositories is determined by their order in the configuration file. You can add repositories with higher priority than the default or even remove the default VEX Hub.

    - name: repo1\n  url: https://example.com/repo1\n- name: repo2\n  url: https://example.com/repo2\n

    In this configuration, when Trivy detects a vulnerability in a package, it generates a PURL for that package and searches for matching VEX documents in the configured repositories. The search process follows this order:

    1. Trivy first looks for a VEX document matching the package's PURL in repo1.
    2. If no matching VEX document is found in repo1, Trivy then searches in repo2.
    3. This process continues through all configured repositories until a match is found.

    If a matching VEX document is found in any repository (e.g., repo1), the search stops, and Trivy uses that VEX document. Subsequent repositories (e.g., repo2) are not checked for that specific vulnerability and package combination.

    It's important to note that the first matching VEX document found determines the final status of the vulnerability. For example, if repo1 states that a package is \"Affected\" by a vulnerability, this status will be used even if repo2 states that the same package is \"Not Affected\" for the same vulnerability. The \"Affected\" status from the higher-priority repository (repo1) takes precedence, and Trivy will consider the package as affected by the vulnerability.

    "},{"location":"docs/supply-chain/vex/repo/#repository-updates","title":"Repository Updates","text":"

    VEX repositories are automatically updated during scanning. Updates are performed based on the update frequency specified by the repository.

    To disable auto-update, pass --skip-vex-repo-update.

    $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex repo --skip-vex-repo-update\n

    To download VEX repositories in advance without scanning, use trivy vex repo download.

    The cache can be cleared with trivy clean --vex-repo.

    "},{"location":"docs/supply-chain/vex/repo/#displaying-filtered-vulnerabilities","title":"Displaying Filtered Vulnerabilities","text":"

    To see which vulnerabilities were filtered and why, use the --show-suppressed option:

    $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex repo --show-suppressed\n...\n\nSuppressed Vulnerabilities (Total: 4)\n=====================================\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502    Library    \u2502 Vulnerability  \u2502 Severity \u2502    Status    \u2502                     Statement                     \u2502                  Source                  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 busybox       \u2502 CVE-2023-42364 \u2502 MEDIUM   \u2502 not_affected \u2502 vulnerable_code_cannot_be_controlled_by_adversary \u2502 VEX Repository: default                  \u2502\n\u2502               \u2502                \u2502          \u2502              \u2502                                                   \u2502 (https://github.com/aquasecurity/vexhub) \u2502\n\u2502               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502               \u2502 CVE-2023-42365 \u2502          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502               \u2502                \u2502          \u2502              \u2502                                                   \u2502                                          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502 busybox-binsh \u2502 CVE-2023-42364 \u2502          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502               \u2502                \u2502          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502               \u2502 CVE-2023-42365 \u2502          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2502               \u2502                \u2502          \u2502              \u2502                                                   \u2502                                          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/supply-chain/vex/repo/#publishing-vex-documents","title":"Publishing VEX Documents","text":""},{"location":"docs/supply-chain/vex/repo/#for-oss-projects","title":"For OSS Projects","text":"

    As an OSS developer or maintainer, you may encounter vulnerabilities in the packages your project depends on. These vulnerabilities might be discovered through your own scans or reported by third parties using your OSS project.

    While Trivy strives to minimize false positives, it doesn't perform code graph analysis, which means it can't evaluate exploitability at the code level. Consequently, Trivy may report vulnerabilities even in cases where:

    1. The vulnerable function in a dependency is never called in your project.
    2. The vulnerable code cannot be controlled by an attacker in the context of your project.

    If you're confident that a reported vulnerability in a dependency doesn't affect your OSS project or container image, you can publish a VEX document to reduce noise in Trivy scans. To assess exploitability, you have several options:

    1. Manual assessment: As a maintainer, you can read the source code and determine if the vulnerability is exploitable in your project's context.
    2. Automated assessment: You can use SAST (Static Application Security Testing) tools or similar tools to analyze the code and determine exploitability.

    By publishing VEX documents in the source repository, Trivy can automatically utilize them through VEX Hub. The main steps are:

    1. Generate a VEX document
    2. Commit the VEX document to the .vex/ directory in the source repository (e.g., Trivy's VEX)
    3. Register your project's PURL in VEX Hub

    Step 3 is only necessary once. After that, updating the VEX file in your repository will automatically be fetched by VEX Hub and utilized by Trivy. See the VEX Hub repository for more information.

    If you want to issue a VEX for an OSS project that you don't maintain, consider first proposing the VEX publication to the original repository. Many OSS maintainers are open to contributions that improve the security posture of their projects. However, if your proposal is not accepted, or if you want to issue a VEX with statements that differ from the maintainer's judgment, you may want to consider creating a custom repository.

    "},{"location":"docs/supply-chain/vex/repo/#for-private-projects","title":"For Private Projects","text":"

    If you're working on private software or personal projects, you have several options:

    1. Local VEX files: You can create local VEX files and have Trivy read them during scans. This is suitable for individual use or small teams.
    2. .trivyignore: For simpler cases, using a .trivyignore file might be sufficient to suppress specific vulnerabilities.
    3. Custom repositories: For large organizations wanting to share VEX information for internally used software across different departments, setting up a custom VEX repository might be the best approach.
    "},{"location":"docs/supply-chain/vex/repo/#hosting-custom-repositories","title":"Hosting Custom Repositories","text":"

    While the principle is to store VEX documents for OSS packages in the source repository, it's possible to create a custom repository if that's difficult.

    There are various use cases for providing custom repositories:

    • A Pull Request to add a VEX document upstream was not merged
    • Consolidating VEX documents output by SAST tools
    • Publishing vendor-specific VEX documents that differ from OSS maintainer statements
    • Creating a private VEX repository to publish common VEX for your company

    In these cases, you can create a repository that complies with the VEX Repository Specification to make it available for use with Trivy.

    "},{"location":"docs/target/container_image/","title":"Container Image","text":"

    Trivy supports two targets for container images.

    • Files inside container images
    • Container image metadata
    "},{"location":"docs/target/container_image/#files-inside-container-images","title":"Files inside container images","text":"

    Container images consist of files. For instance, new files will be installed if you install a package.

    Trivy scans the files inside container images for

    • Vulnerabilities
    • Misconfigurations
    • Secrets
    • Licenses

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    "},{"location":"docs/target/container_image/#vulnerabilities","title":"Vulnerabilities","text":"

    It is enabled by default. You can simply specify your image name (and a tag). It detects known vulnerabilities in your container image. See here for the detail.

    $ trivy image [YOUR_IMAGE_NAME]\n

    For example:

    $ trivy image python:3.4-alpine\n
    Result
    2019-05-16T01:20:43.180+0900    INFO    Updating vulnerability database...\n2019-05-16T01:20:53.029+0900    INFO    Detecting Alpine vulnerabilities...\n\npython:3.4-alpine3.9 (alpine 3.9.2)\n===================================\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)\n\n+---------+------------------+----------+-------------------+---------------+--------------------------------+\n| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |\n+---------+------------------+----------+-------------------+---------------+--------------------------------+\n| openssl | CVE-2019-1543    | MEDIUM   | 1.1.1a-r1         | 1.1.1b-r1     | openssl: ChaCha20-Poly1305     |\n|         |                  |          |                   |               | with long nonces               |\n+---------+------------------+----------+-------------------+---------------+--------------------------------+\n

    To enable only vulnerability scanning, you can specify --scanners vuln.

    $ trivy image --scanners vuln [YOUR_IMAGE_NAME]\n
    "},{"location":"docs/target/container_image/#misconfigurations","title":"Misconfigurations","text":"

    It is supported, but it is not useful in most cases. As mentioned here, Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. If your container image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners misconfig.

    $ trivy image --scanners misconfig [YOUR_IMAGE_NAME]\n
    "},{"location":"docs/target/container_image/#secrets","title":"Secrets","text":"

    It is enabled by default. See here for the detail.

    $ trivy image [YOUR_IMAGE_NAME]\n
    "},{"location":"docs/target/container_image/#licenses","title":"Licenses","text":"

    It is disabled by default. See here for the detail.

    $ trivy image --scanners license [YOUR_IMAGE_NAME]\n
    "},{"location":"docs/target/container_image/#container-image-metadata","title":"Container image metadata","text":"

    Container images have configuration. docker inspect and docker history show the information according to the configuration.

    Trivy scans the configuration of container images for

    • Misconfigurations
    • Secrets

    They are disabled by default. You can enable them with --image-config-scanners.

    Tips

    The configuration can be exported as the JSON file by docker save.

    "},{"location":"docs/target/container_image/#misconfigurations_1","title":"Misconfigurations","text":"

    Trivy detects misconfigurations on the configuration of container images. The image config is converted into Dockerfile and Trivy handles it as Dockerfile. See here for the detail of Dockerfile scanning.

    It is disabled by default. You can enable it with --image-config-scanners misconfig.

    $ trivy image --image-config-scanners misconfig [YOUR_IMAGE_NAME]\n
    Result
    alpine:3.17 (dockerfile)\n========================\nTests: 24 (SUCCESSES: 21, FAILURES: 3)\nFailures: 3 (UNKNOWN: 0, LOW: 2, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n\nHIGH: Specify at least 1 USER command in Dockerfile with non-root user as argument\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.\n\nSee https://avd.aquasec.com/misconfig/ds002\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nLOW: Consider using 'COPY file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /' command instead of 'ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /'\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nYou should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.\n\nSee https://avd.aquasec.com/misconfig/ds005\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n alpine:3.17:1\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   1 [ ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 in /\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nLOW: Add HEALTHCHECK instruction in your Dockerfile\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nYou shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.\n\nSee https://avd.aquasec.com/misconfig/ds026\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n

    Tip

    You can see how each layer is created with docker history.

    The AVD-DS-0016 check is disabled for this scan type, see issue for details.

    "},{"location":"docs/target/container_image/#secrets_1","title":"Secrets","text":"

    Trivy detects secrets on the configuration of container images. The image config is converted into JSON and Trivy scans the file for secrets. It is especially useful for environment variables that are likely to have credentials by accident. See here for the detail.

    $ trivy image --image-config-scanners secret [YOUR_IMAGE_NAME]\n
    Result
    vuln-image (alpine 3.17.1)\n==========================\nTotal: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n\n\nvuln-image (secrets)\n====================\nTotal: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)\n\nCRITICAL: GitHub (github-pat)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nGitHub Personal Access Token\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n test:16\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  14     {\n  15     \"created\": \"2023-01-09T17:05:20Z\",\n  16 [   \"created_by\": \"ENV secret=****************************************\",\n  17     \"comment\": \"buildkit.dockerfile.v0\",\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nCRITICAL: GitHub (github-pat)\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nGitHub Personal Access Token\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n test:34\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  32     \"Env\": [\n  33     \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\n  34 [   \"secret=****************************************\"\n  35     ]\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n

    Tip

    You can see environment variables with docker inspect.

    "},{"location":"docs/target/container_image/#supported","title":"Supported","text":"

    Trivy will look for the specified image in a series of locations. By default, it will first look in the local Docker Engine, then Containerd, Podman, and finally container registry.

    This behavior can be modified with the --image-src flag. For example, the command

    trivy image --image-src podman,containerd alpine:3.7.3\n

    Will first search in Podman. If the image is found there, it will be scanned and the results returned. If the image is not found in Podman, then Trivy will search in Containerd. If the image is not found there either, the scan will fail and no more image sources will be searched.

    "},{"location":"docs/target/container_image/#docker-engine","title":"Docker Engine","text":"

    Trivy tries to looks for the specified image in your local Docker Engine. It will be skipped if Docker Engine is not running locally.

    If your docker socket is not the default path, you can override it via DOCKER_HOST.

    "},{"location":"docs/target/container_image/#containerd","title":"containerd","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy tries to looks for the specified image in your local containerd. It will be skipped if containerd is not running locally.

    Specify your image name in containerd running locally.

    $ nerdctl images\nREPOSITORY        TAG       IMAGE ID        CREATED         PLATFORM       SIZE         BLOB SIZE\naquasec/nginx    latest    2bcabc23b454    3 hours ago     linux/amd64    149.1 MiB    54.1 MiB\n$ trivy image aquasec/nginx\n

    If your containerd socket is not the default path (//run/containerd/containerd.sock), you can override it via CONTAINERD_ADDRESS.

    $ export CONTAINERD_ADDRESS=/run/k3s/containerd/containerd.sock\n$ trivy image aquasec/nginx\n

    If your scan targets are images in a namespace other than containerd's default namespace (default), you can override it via CONTAINERD_NAMESPACE.

    $ export CONTAINERD_NAMESPACE=k8s.io\n$ trivy image aquasec/nginx\n
    "},{"location":"docs/target/container_image/#podman","title":"Podman","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Scan your image in Podman (>=2.0) running locally. The remote Podman is not supported. If you prefer to keep the socket open at all times, then before performing Trivy commands, you can enable the podman.sock systemd service on your machine. For more details, see here.

    $ systemctl --user enable --now podman.socket\n

    Then, you can scan your image in Podman.

    $ cat Dockerfile\nFROM alpine:3.12\nRUN apk add --no-cache bash\n$ podman build -t test .\n$ podman images\nREPOSITORY                TAG     IMAGE ID      CREATED      SIZE\nlocalhost/test            latest  efc372d4e0de  About a minute ago  7.94 MB\n$ trivy image test\n

    If you prefer not to keep the socket open at all times, but to limit the socket opening for your trivy scanning duration only then you can scan your image with the following command:

    podman system service --time=0 \"${TMP_PODMAN_SOCKET}\" &                                                                                                                                                             \nPODMAN_SYSTEM_SERVICE_PID=\"$!\"                                                                                                                                                                                      \ntrivy image --podman-host=\"${TMP_PODMAN_SOCKET}\" --docker-host=\"${TMP_PODMAN_SOCKET}\" test\nkill \"${PODMAN_SYSTEM_SERVICE_PID}\"\n
    "},{"location":"docs/target/container_image/#container-registry","title":"Container Registry","text":"

    Trivy supports registries that comply with the following specifications.

    • Docker Registry HTTP API V2
    • OCI Distribution Specification

    You can configure credentials with trivy registry login. See here for the detail.

    "},{"location":"docs/target/container_image/#tar-files","title":"Tar Files","text":"

    Trivy supports image tar files generated by the following tools.

    • Docker Image Specification
      • Moby Project
      • Buildah
      • Podman
      • img
    • Kaniko
    $ docker pull ruby:3.1-alpine3.15\n$ docker save ruby:3.1-alpine3.15 -o ruby-3.1.tar\n$ trivy image --input ruby-3.1.tar\n
    Result
    2022-02-03T10:08:19.127Z        INFO    Detected OS: alpine\n2022-02-03T10:08:19.127Z        WARN    This OS version is not on the EOL list: alpine 3.15\n2022-02-03T10:08:19.127Z        INFO    Detecting Alpine vulnerabilities...\n2022-02-03T10:08:19.127Z        INFO    Number of language-specific files: 2\n2022-02-03T10:08:19.127Z        INFO    Detecting gemspec vulnerabilities...\n2022-02-03T10:08:19.128Z        INFO    Detecting node-pkg vulnerabilities...\n2022-02-03T10:08:19.128Z        WARN    This OS version is no longer supported by the distribution: alpine 3.15.0\n2022-02-03T10:08:19.128Z        WARN    The vulnerability detection may be insufficient because security updates are not provided\n\nruby-3.1.tar (alpine 3.15.0)\n============================\nTotal: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0)\n\n+----------+------------------+----------+-------------------+---------------+---------------------------------------+\n| LIBRARY  | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |\n+----------+------------------+----------+-------------------+---------------+---------------------------------------+\n| gmp      | CVE-2021-43618   | HIGH     | 6.2.1-r0          | 6.2.1-r1      | gmp: Integer overflow and resultant   |\n|          |                  |          |                   |               | buffer overflow via crafted input     |\n|          |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-43618 |\n+----------+                  +          +                   +               +                                       +\n| gmp-dev  |                  |          |                   |               |                                       |\n|          |                  |          |                   |               |                                       |\n|          |                  |          |                   |               |                                       |\n+----------+                  +          +                   +               +                                       +\n| libgmpxx |                  |          |                   |               |                                       |\n|          |                  |          |                   |               |                                       |\n|          |                  |          |                   |               |                                       |\n+----------+------------------+----------+-------------------+---------------+---------------------------------------+\n\nNode.js (node-pkg)\n==================\nTotal: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n\n\nRuby (gemspec)\n==============\nTotal: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)\n
    "},{"location":"docs/target/container_image/#oci-layout","title":"OCI Layout","text":"

    Trivy supports image directories compliant with Open Container Image Layout Specification.

    Buildah:

    $ buildah push docker.io/library/alpine:3.11 oci:/path/to/alpine\n$ trivy image --input /path/to/alpine\n

    Skopeo:

    $ skopeo copy docker-daemon:alpine:3.11 oci:/path/to/alpine\n$ trivy image --input /path/to/alpine\n

    Referencing specific images can be done by their tag or by their manifest digest:

    # Referenced by tag\n$ trivy image --input /path/to/alpine:3.15\n\n# Referenced by digest\n$ trivy image --input /path/to/alpine@sha256:82389ea44e50c696aba18393b168a833929506f5b29b9d75eb817acceb6d54ba\n

    "},{"location":"docs/target/container_image/#sbom","title":"SBOM","text":"

    Trivy supports the generation of Software Bill of Materials (SBOM) for container images and the search for SBOMs during vulnerability scanning.

    "},{"location":"docs/target/container_image/#generation","title":"Generation","text":"

    Trivy can generate SBOM for container images. See here for the detail.

    "},{"location":"docs/target/container_image/#discovery","title":"Discovery","text":"

    Trivy can search for Software Bill of Materials (SBOMs) that reference container images. If an SBOM is found, the vulnerability scan is performed using the SBOM instead of the container image. By using the SBOM, you can perform a vulnerability scan more quickly, as it allows you to skip pulling the container image and analyzing its layers.

    To enable this functionality, you need to specify the --sbom-sources flag. The following two sources are supported:

    • OCI Registry (oci)
    • Rekor (rekor)

    Example:

    $ trivy image --sbom-sources oci ghcr.io/knqyf263/oci-referrers\n2023-03-05T17:36:55.278+0200    INFO    Vulnerability scanning is enabled\n2023-03-05T17:36:58.103+0200    INFO    Detected SBOM format: cyclonedx-json\n2023-03-05T17:36:58.129+0200    INFO    Found SBOM (cyclonedx) in the OCI referrers\n...\n\nghcr.io/knqyf263/oci-referrers (alpine 3.16.2)\n==============================================\nTotal: 17 (UNKNOWN: 0, LOW: 0, MEDIUM: 5, HIGH: 9, CRITICAL: 3)\n

    The OCI Registry utilizes the Referrers API. For more information about Rekor, please refer to its documentation.

    "},{"location":"docs/target/container_image/#compliance","title":"Compliance","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    This section describes container image specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    "},{"location":"docs/target/container_image/#built-in-reports","title":"Built in reports","text":"

    The following reports are available out of the box:

    Compliance Version Name for command More info CIS Docker Community Edition Benchmark 1.1.0 docker-cis-1.6.0 Link"},{"location":"docs/target/container_image/#examples","title":"Examples","text":"

    Scan a container image configuration and generate a compliance summary report:

    trivy image --compliance docker-cis-1.6.0 [YOUR_IMAGE_NAME]\n

    Note

    The Issues column represent the total number of failed checks for this control.

    "},{"location":"docs/target/container_image/#authentication","title":"Authentication","text":"

    Please reference this page.

    "},{"location":"docs/target/container_image/#options","title":"Options","text":""},{"location":"docs/target/container_image/#scan-image-on-a-specific-architecture-and-os","title":"Scan Image on a specific Architecture and OS","text":"

    By default, Trivy loads an image on a \"linux/amd64\" machine. To customise this, pass a --platform argument in the format OS/Architecture for the image:

    $ trivy image --platform=os/architecture [YOUR_IMAGE_NAME]\n

    For example:

    $ trivy image --platform=linux/arm alpine:3.16.1\n
    Result
    2022-10-25T21:00:50.972+0300    INFO    Vulnerability scanning is enabled\n2022-10-25T21:00:50.972+0300    INFO    Secret scanning is enabled\n2022-10-25T21:00:50.972+0300    INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning\n2022-10-25T21:00:50.972+0300    INFO    Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection\n2022-10-25T21:00:56.190+0300    INFO    Detected OS: alpine\n2022-10-25T21:00:56.190+0300    INFO    Detecting Alpine vulnerabilities...\n2022-10-25T21:00:56.191+0300    INFO    Number of language-specific files: 0\n\nalpine:3.16.1 (alpine 3.16.1)\n=============================\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Library \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                            Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 zlib    \u2502 CVE-2022-37434 \u2502 CRITICAL \u2502 1.2.12-r1         \u2502 1.2.12-r2     \u2502 zlib: heap-based buffer over-read and overflow in inflate() \u2502\n\u2502         \u2502                \u2502          \u2502                   \u2502               \u2502 in inflate.c via a...                                       \u2502\n\u2502         \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-37434                  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/target/container_image/#configure-docker-daemon-socket-to-connect-to","title":"Configure Docker daemon socket to connect to.","text":"

    You can configure Docker daemon socket with DOCKER_HOST or --docker-host.

    $ trivy image --docker-host tcp://127.0.0.1:2375 YOUR_IMAGE\n
    "},{"location":"docs/target/container_image/#configure-podman-daemon-socket-to-connect-to","title":"Configure Podman daemon socket to connect to.","text":"

    You can configure Podman daemon socket with --podman-host.

    $ trivy image --podman-host /run/user/1000/podman/podman.sock YOUR_IMAGE\n
    "},{"location":"docs/target/filesystem/","title":"Filesystem","text":"

    Scan your local projects for

    • Vulnerabilities
    • Misconfigurations
    • Secrets
    • Licenses

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    $ trivy fs /path/to/project\n

    It's also possible to scan a single file.

    $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test/Pipfile.lock\n
    "},{"location":"docs/target/filesystem/#scanners","title":"Scanners","text":""},{"location":"docs/target/filesystem/#vulnerabilities","title":"Vulnerabilities","text":"

    It is enabled by default. Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. See here for the detail.

    $ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test\n
    Result
    2020-06-01T17:06:58.652+0300    WARN    OS is not detected and vulnerabilities in OS packages are not detected.\n2020-06-01T17:06:58.652+0300    INFO    Detecting pipenv vulnerabilities...\n2020-06-01T17:06:58.691+0300    INFO    Detecting cargo vulnerabilities...\n\nPipfile.lock\n============\nTotal: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)\n\n+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+\n|       LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |     FIXED VERSION      |               TITLE                |\n+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+\n| django              | CVE-2020-7471    | HIGH     | 2.0.9             | 3.0.3, 2.2.10, 1.11.28 | django: potential                  |\n|                     |                  |          |                   |                        | SQL injection via                  |\n|                     |                  |          |                   |                        | StringAgg(delimiter)               |\n+                     +------------------+----------+                   +------------------------+------------------------------------+\n|                     | CVE-2019-19844   | MEDIUM   |                   | 3.0.1, 2.2.9, 1.11.27  | Django: crafted email address      |\n|                     |                  |          |                   |                        | allows account takeover            |\n+                     +------------------+          +                   +------------------------+------------------------------------+\n|                     | CVE-2019-3498    |          |                   | 2.1.5, 2.0.10, 1.11.18 | python-django: Content             |\n|                     |                  |          |                   |                        | spoofing via URL path in           |\n|                     |                  |          |                   |                        | default 404 page                   |\n+                     +------------------+          +                   +------------------------+------------------------------------+\n|                     | CVE-2019-6975    |          |                   | 2.1.6, 2.0.11, 1.11.19 | python-django:                     |\n|                     |                  |          |                   |                        | memory exhaustion in               |\n|                     |                  |          |                   |                        | django.utils.numberformat.format() |\n+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+\n...\n
    "},{"location":"docs/target/filesystem/#misconfigurations","title":"Misconfigurations","text":"

    It is disabled by default and can be enabled with --scanners misconfig. See here for the detail.

    $ trivy fs --scanners misconfig /path/to/project\n
    "},{"location":"docs/target/filesystem/#secrets","title":"Secrets","text":"

    It is enabled by default. See here for the detail.

    $ trivy fs /path/to/project\n
    "},{"location":"docs/target/filesystem/#licenses","title":"Licenses","text":"

    It is disabled by default. See here for the detail.

    $ trivy fs --scanners license /path/to/project\n
    "},{"location":"docs/target/filesystem/#sbom-generation","title":"SBOM generation","text":"

    Trivy can generate SBOM for local projects. See here for the detail.

    "},{"location":"docs/target/kubernetes/","title":"Kubernetes","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    Trivy can connect to your Kubernetes cluster and scan it for security issues using the trivy k8s command. This page covers the technical capabilities of Trivy Kubernetes scanning. Trivy can also be installed inside your cluster as a Kubernetes Operator, and continuously scan it. For more about this, please see the Trivy Operator project.

    When scanning a Kubernetes cluster, Trivy differentiates between the following:

    1. Cluster infrastructure (e.g api-server, kubelet, addons)
    2. Cluster configuration (e.g Roles, ClusterRoles).
    3. Application workloads (e.g nginx, postgresql).

    When scanning any of the above, the container image is scanned separately to the Kubernetes resource definition (the YAML manifest) that defines the resource.

    Container image is scanned for:

    • Vulnerabilities
    • Misconfigurations
    • Exposed secrets

    Kubernetes resource definition is scanned for:

    • Vulnerabilities (Open Source Libraries, Control Plane and Node Components)
    • Misconfigurations
    • Exposed secrets
    "},{"location":"docs/target/kubernetes/#kubernetes-target-configurations","title":"Kubernetes target configurations","text":"
    trivy k8s [flags] [CONTEXT] -  if the target name [CONTEXT] is not specified, the default will be used.\n

    for example:

    trivy k8s --report summary\n

    By default Trivy will look for a kubeconfig configuration file in the default location, and use the default cluster that is specified. You can also specify a kubeconfig using the --kubeconfig flag:

    trivy k8s --kubeconfig ~/.kube/config2\n

    By default, all cluster resource images will be downloaded and scanned.

    "},{"location":"docs/target/kubernetes/#skip-images","title":"Skip-images","text":"

    You can control whether Trivy will scan and download the cluster resource images. To disable this feature, add the --skip-images flag.

    • --skip-images flag will prevent the downloading and scanning of images (including vulnerabilities and secrets) in the cluster resources.

    Example:

    trivy k8s --report summary --skip-images\n
    "},{"location":"docs/target/kubernetes/#includeexclude-kinds","title":"Include/Exclude Kinds","text":"

    You can control which kinds of resources will be discovered using the --include-kinds or --exclude-kinds comma-separated flags:

    Note: Both flags (--include-kinds or --exclude-kinds) cannot be set in conjunction.

    • --include-kinds will include the listed kinds in cluster scanning.
    • --exclude-kinds will exclude the listed kinds from cluster scanning.

    By default, all kinds will be included in cluster scanning.

    Example:

    trivy k8s --report summary --exclude-kinds node,pod\n
    "},{"location":"docs/target/kubernetes/#includeexclude-namespaces","title":"Include/Exclude Namespaces","text":"

    You can control which namespaces will be discovered using the --include-namespaces or --exclude-namespaces comma-separated flags:

    Note: Both flags (--include-namespaces or --exclude-namespaces) cannot be set in conjunction.

    • --include-namespaces will include the listed namespaces in cluster scanning.
    • --exclude-namespaces will exclude the listed namespaces from cluster scanning.

    By default, all namespaces will be included in cluster scanning.

    Example:

    trivy k8s --report summary --exclude-namespace dev-system,staging-system\n
    "},{"location":"docs/target/kubernetes/#control-plane-and-node-components-vulnerability-scanning","title":"Control Plane and Node Components Vulnerability Scanning","text":"

    Trivy is capable of discovering Kubernetes control plane (apiserver, controller-manager and etc) and node components(kubelet, kube-proxy and etc), matching them against the official Kubernetes vulnerability database feed, and reporting any vulnerabilities it finds.

    To read more about KBOM, see the documentation for Kubernetes scanning.

    trivy k8s --scanners vuln  --report all\n\nNodeComponents/kind-control-plane (kubernetes)\n\nTotal: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 2, CRITICAL: 0)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502    Library     \u2502 Vulnerability  \u2502 Severity \u2502 Status \u2502 Installed Version \u2502          Fixed Version           \u2502                       Title                       \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 k8s.io/kubelet \u2502 CVE-2023-2431  \u2502 LOW      \u2502 fixed  \u2502 1.21.1            \u2502 1.24.14, 1.25.10, 1.26.5, 1.27.2 \u2502 Bypass of seccomp profile enforcement             \u2502\n\u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                  \u2502 https://avd.aquasec.com/nvd/cve-2023-2431         \u2502\n\u2502                \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524        \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                \u2502 CVE-2021-25741 \u2502 HIGH     \u2502        \u2502                   \u2502 1.19.16, 1.20.11, 1.21.5, 1.22.1 \u2502 Symlink exchange can allow host filesystem access \u2502\n\u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                  \u2502 https://avd.aquasec.com/nvd/cve-2021-25741        \u2502\n\u2502                \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u2502        \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                \u2502 CVE-2021-25749 \u2502          \u2502        \u2502                   \u2502 1.22.14, 1.23.11, 1.24.5         \u2502 runAsNonRoot logic bypass for Windows containers  \u2502\n\u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                  \u2502 https://avd.aquasec.com/nvd/cve-2021-25749        \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/target/kubernetes/#node-collector","title":"Node-Collector","text":"

    Node-collector is a scan job that collects node configuration parameters and permission information. This information will be evaluated against Kubernetes hardening (e.g. CIS benchmark) and best practices values. The scan results will be output in infrastructure assessment and CIS benchmark compliance reports.

    "},{"location":"docs/target/kubernetes/#disable-node-collector","title":"Disable Node Collector","text":"

    You can control whether the node scan-job (node-collector) will run in the cluster. To disable it, add the --disable-node-collector flag

    • --disable-node-collector This flag will exclude findings related to Node (infra assessment) misconfigurations

    By default, the node scan-job (node-collector) will run in the cluster.

    Example:

    trivy k8s --report summary --disable-node-collector\n
    "},{"location":"docs/target/kubernetes/#taints-and-tolerations","title":"Taints and Tolerations","text":"

    The node-collector scan-job will run on every node. In case the node has been tainted, it is possible to add toleration to the scan job for it to be scheduled on the tainted node. for more details see k8s docs

    • --tolerations key1=value1:NoExecute,key2=value2:NoSchedule this flag wil enable node-collector to be schedule on tainted Node

    Example:

    trivy k8s --report summary --tolerations  key1=value1:NoExecute,key2=value2:NoSchedule\n
    "},{"location":"docs/target/kubernetes/#exclude-nodes-by-label","title":"Exclude Nodes by Label","text":"

    You can exclude specific nodes from the scan using the --exclude-nodes flag, which takes a label in the format label-name:label-value and excludes all matching nodes:

    trivy k8s --report summary --exclude-nodes kubernetes.io/arch:arm6\n
    "},{"location":"docs/target/kubernetes/#reporting-and-filtering","title":"Reporting and filtering","text":"

    Since scanning an entire cluster for any security issue can be overwhelming, By default Trivy summarizes the results in a simple \"summary\" view. By scoping the scan on a specific resource, you can see the detailed report. You can always choose the report granularity using the --report summary/--report all flag.

    Scan a full cluster and generate a simple summary report:

    trivy k8s --report=summary\n

    Filter by severity:

    trivy k8s --severity=CRITICAL --report=all\n

    Filter by scanners (Vulnerabilities, Secrets or Misconfigurations):

    trivy k8s --scanners=secret --report=summary\n# or\ntrivy k8s --scanners=misconfig --report=summary\n

    The supported output formats are table, which is the default, and json.

    trivy k8s --format json -o results.json cluster\n
    Result
    {\n  \"ClusterName\": \"minikube\",\n  \"Vulnerabilities\": [\n    {\n      \"Namespace\": \"default\",\n      \"Kind\": \"Deployment\",\n      \"Name\": \"app\",\n      \"Results\": [\n        {\n          \"Target\": \"ubuntu:latest (ubuntu 22.04)\",\n          \"Class\": \"os-pkgs\",\n          \"Type\": \"ubuntu\",\n          \"Vulnerabilities\": [\n            {\n              \"VulnerabilityID\": \"CVE-2016-2781\",\n              \"PkgName\": \"coreutils\",\n              \"InstalledVersion\": \"8.32-4.1ubuntu1\",\n              \"Layer\": {\n                \"Digest\": \"sha256:125a6e411906fe6b0aaa50fc9d600bf6ff9bb11a8651727ce1ed482dc271c24c\",\n                \"DiffID\": \"sha256:e59fc94956120a6c7629f085027578e6357b48061d45714107e79f04a81a6f0c\"\n              },\n              \"SeveritySource\": \"ubuntu\",\n              \"PrimaryURL\": \"https://avd.aquasec.com/nvd/cve-2016-2781\",\n              \"DataSource\": {\n                \"ID\": \"ubuntu\",\n                \"Name\": \"Ubuntu CVE Tracker\",\n                \"URL\": \"https://git.launchpad.net/ubuntu-cve-tracker\"\n              },\n              \"Title\": \"coreutils: Non-privileged session can escape to the parent session in chroot\",\n              \"Description\": \"chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.\",\n              \"Severity\": \"LOW\",\n              \"CweIDs\": [\n                \"CWE-20\"\n              ],\n              \"VendorSeverity\": {\n                \"cbl-mariner\": 2,\n                \"nvd\": 2,\n                \"redhat\": 2,\n                \"ubuntu\": 1\n              },\n              \"CVSS\": {\n                \"nvd\": {\n                  \"V2Vector\": \"AV:L/AC:L/Au:N/C:N/I:P/A:N\",\n                  \"V3Vector\": \"CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N\",\n                  \"V2Score\": 2.1,\n                  \"V3Score\": 6.5\n                },\n                \"redhat\": {\n                  \"V2Vector\": \"AV:L/AC:H/Au:N/C:C/I:C/A:C\",\n                  \"V3Vector\": \"CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H\",\n                  \"V2Score\": 6.2,\n                  \"V3Score\": 8.6\n                }\n              },\n              \"References\": [\n                \"http://seclists.org/oss-sec/2016/q1/452\",\n                \"http://www.openwall.com/lists/oss-security/2016/02/28/2\",\n                \"http://www.openwall.com/lists/oss-security/2016/02/28/3\",\n                \"https://access.redhat.com/security/cve/CVE-2016-2781\",\n                \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2781\",\n                \"https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E\",\n                \"https://lore.kernel.org/patchwork/patch/793178/\",\n                \"https://nvd.nist.gov/vuln/detail/CVE-2016-2781\"\n              ],\n              \"PublishedDate\": \"2017-02-07T15:59:00Z\",\n              \"LastModifiedDate\": \"2021-02-25T17:15:00Z\"\n            }\n          ]\n        }\n      ]\n    }\n  ],\n  \"Misconfigurations\": [\n    {\n      \"Namespace\": \"default\",\n      \"Kind\": \"Deployment\",\n      \"Name\": \"app\",\n      \"Results\": [\n        {\n          \"Target\": \"Deployment/app\",\n          \"Class\": \"config\",\n          \"Type\": \"kubernetes\",\n          \"MisconfSummary\": {\n            \"Successes\": 20,\n            \"Failures\": 19\n          },\n          \"Misconfigurations\": [\n            {\n              \"Type\": \"Kubernetes Security Check\",\n              \"ID\": \"KSV001\",\n              \"Title\": \"Process can elevate its own privileges\",\n              \"Description\": \"A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.\",\n              \"Message\": \"Container 'app' of Deployment 'app' should set 'securityContext.allowPrivilegeEscalation' to false\",\n              \"Namespace\": \"builtin.kubernetes.KSV001\",\n              \"Query\": \"data.builtin.kubernetes.KSV001.deny\",\n              \"Resolution\": \"Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.\",\n              \"Severity\": \"MEDIUM\",\n              \"PrimaryURL\": \"https://avd.aquasec.com/misconfig/ksv001\",\n              \"References\": [\n                \"https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted\",\n                \"https://avd.aquasec.com/misconfig/ksv001\"\n              ],\n              \"Status\": \"FAIL\",\n              \"Layer\": {},\n              \"IacMetadata\": {\n                \"Provider\": \"Kubernetes\",\n                \"Service\": \"general\",\n                \"StartLine\": 121,\n                \"EndLine\": 133\n              }\n            },\n            {\n              \"Type\": \"Kubernetes Security Check\",\n              \"ID\": \"KSV003\",\n              \"Title\": \"Default capabilities not dropped\",\n              \"Description\": \"The container should drop all default capabilities and add only those that are needed for its execution.\",\n              \"Message\": \"Container 'app' of Deployment 'app' should add 'ALL' to 'securityContext.capabilities.drop'\",\n              \"Namespace\": \"builtin.kubernetes.KSV003\",\n              \"Query\": \"data.builtin.kubernetes.KSV003.deny\",\n              \"Resolution\": \"Add 'ALL' to containers[].securityContext.capabilities.drop.\",\n              \"Severity\": \"LOW\",\n              \"PrimaryURL\": \"https://avd.aquasec.com/misconfig/ksv003\",\n              \"References\": [\n                \"https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/\",\n                \"https://avd.aquasec.com/misconfig/ksv003\"\n              ],\n              \"Status\": \"FAIL\",\n              \"Layer\": {},\n              \"IacMetadata\": {\n                \"Provider\": \"Kubernetes\",\n                \"Service\": \"general\",\n                \"StartLine\": 121,\n                \"EndLine\": 133\n              }\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"Namespace\": \"default\",\n      \"Kind\": \"ConfigMap\",\n      \"Name\": \"kube-root-ca.crt\"\n    }\n  ]\n}\n
    "},{"location":"docs/target/kubernetes/#compliance","title":"Compliance","text":"

    This section describes Kubernetes specific compliance reports. For an overview of Trivy's Compliance feature, including working with custom compliance, check out the Compliance documentation.

    The following reports are available out of the box:

    Compliance Name for command More info NSA, CISA Kubernetes Hardening Guidance v1.0 k8s-nsa-1.0 Link CIS Benchmark for Kubernetes v1.23 k8s-cis-1.23 Link CIS Benchmark for RKE2 v1.24 rke2-cis-1.24 Link CIS Benchmark for EKS v1.4 eks-cis-1.4 Link Pod Security Standards, Baseline k8s-pss-baseline-0.1 Link Pod Security Standards, Restricted k8s-pss-restricted-0.1 Link

    Examples:

    Scan the cluster for Kubernetes Pod Security Standards Baseline compliance:

    trivy k8s --compliance=k8s-pss-baseline --report summary\n

    Get the detailed report for checks:

    trivy k8s --compliance=k8s-cis-1.23 --report all\n

    Get summary report in JSON format:

    trivy k8s --compliance=k8s-cis-1.23 --report summary --format json\n

    Get detailed report in JSON format:

    trivy k8s --compliance=k8s-cis-1.23 --report all --format json\n
    "},{"location":"docs/target/kubernetes/#kbom","title":"KBOM","text":"

    KBOM, Kubernetes Bill of Materials, is a manifest of all the important components that make up your Kubernetes cluster \u2013 Control plane components, Node Components, and Addons, including their versions and images. Which \u201capi-server\u201d version are you currently running? Which flavor of \"kubelet\" is running on each node? What kind of etcd or storage are you currently using? And most importantly \u2013 are there any vulnerabilities known to affect these components? These are all questions that KBOM can help you answer. For more background on KBOM, see here.

    Trivy can generate KBOM in CycloneDX format:

    trivy k8s --format cyclonedx --output mykbom.cdx.json\n

    Trivy can also scan that generated KBOM (or any SBOM) for vulnerabilities:

    trivy sbom mykbom.cdx.json\n
    Result
    2023-09-28T22:52:25.707+0300    INFO    Vulnerability scanning is enabled\n 2023-09-28T22:52:25.707+0300    INFO    Detected SBOM format: cyclonedx-json\n 2023-09-28T22:52:25.717+0300    WARN    No OS package is detected. Make sure you haven't deleted any files that contain information about the installed packages.\n 2023-09-28T22:52:25.717+0300    WARN    e.g. files under \"/lib/apk/db/\", \"/var/lib/dpkg/\" and \"/var/lib/rpm\"\n 2023-09-28T22:52:25.717+0300    INFO    Detected OS: debian gnu/linux\n 2023-09-28T22:52:25.717+0300    WARN    unsupported os : debian gnu/linux\n 2023-09-28T22:52:25.717+0300    INFO    Number of language-specific files: 3\n 2023-09-28T22:52:25.717+0300    INFO    Detecting kubernetes vulnerabilities...\n 2023-09-28T22:52:25.718+0300    INFO    Detecting gobinary vulnerabilities...\n Kubernetes (kubernetes)\n Total: 2 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502    Library     \u2502 Vulnerability  \u2502 Severity \u2502 Status \u2502 Installed Version \u2502          Fixed Version          \u2502                      Title                       \u2502\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 k8s.io/kubelet \u2502 CVE-2021-25749 \u2502 HIGH     \u2502 fixed  \u2502 1.24.0            \u2502 1.22.14, 1.23.11, 1.24.5        \u2502 runAsNonRoot logic bypass for Windows containers \u2502\n \u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                 \u2502 https://avd.aquasec.com/nvd/cve-2021-25749       \u2502\n \u2502                \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524        \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502                \u2502 CVE-2023-2431  \u2502 LOW      \u2502        \u2502                   \u2502 1.24.14, 1.25.9, 1.26.4, 1.27.1 \u2502 Bypass of seccomp profile enforcement            \u2502\n \u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                 \u2502 https://avd.aquasec.com/nvd/cve-2023-2431        \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

    Find more in the documentation for SBOM scanning.

    Currently KBOM vulnerability matching works for plain Kubernetes distributions and does not work well for vendor variants, including some cloud managed distributions.

    "},{"location":"docs/target/repository/","title":"Code Repository","text":"

    Scan your local or remote code repositories for

    • Vulnerabilities
    • Misconfigurations
    • Secrets
    • Licenses

    By default, vulnerability and secret scanning are enabled, and you can configure that with --scanners.

    $ trivy repo (REPO_PATH | REPO_URL)\n

    For example, you can scan a local repository as below.

    $ trivy repo ./\n

    It's also possible to scan a single file.

    $ trivy repo ./trivy-ci-test/Pipfile.lock\n

    To scan remote code repositories, you need to specify the URL.

    $ trivy repo https://github.com/aquasecurity/trivy-ci-test\n
    "},{"location":"docs/target/repository/#rationale","title":"Rationale","text":"

    trivy repo is designed to scan code repositories, and it is intended to be used for scanning local/remote repositories in your machine or in your CI environment. Therefore, unlike container/VM image scanning, it targets lock files such as package-lock.json and does not target artifacts like JAR files, binary files, etc. See here for the detail.

    "},{"location":"docs/target/repository/#scanners","title":"Scanners","text":""},{"location":"docs/target/repository/#vulnerabilities","title":"Vulnerabilities","text":"

    It is enabled by default. Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. See here for the detail.

    $ trivy repo ~/src/github.com/aquasecurity/trivy-ci-test\n
    Result
    2020-06-01T17:06:58.652+0300    WARN    OS is not detected and vulnerabilities in OS packages are not detected.\n2020-06-01T17:06:58.652+0300    INFO    Detecting pipenv vulnerabilities...\n2020-06-01T17:06:58.691+0300    INFO    Detecting cargo vulnerabilities...\n\nPipfile.lock\n============\nTotal: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)\n\n+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+\n|       LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION |     FIXED VERSION      |               TITLE                |\n+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+\n| django              | CVE-2020-7471    | HIGH     | 2.0.9             | 3.0.3, 2.2.10, 1.11.28 | django: potential                  |\n|                     |                  |          |                   |                        | SQL injection via                  |\n|                     |                  |          |                   |                        | StringAgg(delimiter)               |\n+                     +------------------+----------+                   +------------------------+------------------------------------+\n|                     | CVE-2019-19844   | MEDIUM   |                   | 3.0.1, 2.2.9, 1.11.27  | Django: crafted email address      |\n|                     |                  |          |                   |                        | allows account takeover            |\n+                     +------------------+          +                   +------------------------+------------------------------------+\n|                     | CVE-2019-3498    |          |                   | 2.1.5, 2.0.10, 1.11.18 | python-django: Content             |\n|                     |                  |          |                   |                        | spoofing via URL path in           |\n|                     |                  |          |                   |                        | default 404 page                   |\n+                     +------------------+          +                   +------------------------+------------------------------------+\n|                     | CVE-2019-6975    |          |                   | 2.1.6, 2.0.11, 1.11.19 | python-django:                     |\n|                     |                  |          |                   |                        | memory exhaustion in               |\n|                     |                  |          |                   |                        | django.utils.numberformat.format() |\n+---------------------+------------------+----------+-------------------+------------------------+------------------------------------+\n...\n
    "},{"location":"docs/target/repository/#misconfigurations","title":"Misconfigurations","text":"

    It is disabled by default and can be enabled with --scanners misconfig. See here for the detail.

    $ trivy repo --scanners misconfig (REPO_PATH | REPO_URL)\n
    "},{"location":"docs/target/repository/#secrets","title":"Secrets","text":"

    It is enabled by default. See here for the detail.

    $ trivy repo (REPO_PATH | REPO_URL)\n
    "},{"location":"docs/target/repository/#licenses","title":"Licenses","text":"

    It is disabled by default. See here for the detail.

    $ trivy repo --scanners license (REPO_PATH | REPO_URL)\n
    "},{"location":"docs/target/repository/#sbom-generation","title":"SBOM generation","text":"

    Trivy can generate SBOM for code repositories. See here for the detail.

    "},{"location":"docs/target/repository/#references","title":"References","text":"

    The following flags and environmental variables are available for remote git repositories.

    "},{"location":"docs/target/repository/#scanning-a-branch","title":"Scanning a Branch","text":"

    Pass a --branch argument with a valid branch name on the remote repository provided:

    $ trivy repo --branch <branch-name> <repo-name>\n
    "},{"location":"docs/target/repository/#scanning-upto-a-commit","title":"Scanning upto a Commit","text":"

    Pass a --commit argument with a valid commit hash on the remote repository provided:

    $ trivy repo --commit <commit-hash> <repo-name>\n
    "},{"location":"docs/target/repository/#scanning-a-tag","title":"Scanning a Tag","text":"

    Pass a --tag argument with a valid tag on the remote repository provided:

    $ trivy repo --tag <tag-name> <repo-name>\n
    "},{"location":"docs/target/repository/#scanning-private-repositories","title":"Scanning Private Repositories","text":"

    In order to scan private GitHub or GitLab repositories, the environment variable GITHUB_TOKEN or GITLAB_TOKEN must be set, respectively, with a valid token that has access to the private repository being scanned.

    The GITHUB_TOKEN environment variable will take precedence over GITLAB_TOKEN, so if a private GitLab repository will be scanned, then GITHUB_TOKEN must be unset.

    You can find how to generate your GitHub Token in the following GitHub documentation.

    For example:

    $ export GITHUB_TOKEN=\"your_private_github_token\"\n$ trivy repo <your private GitHub repo URL>\n\n# or\n$ export GITLAB_TOKEN=\"your_private_gitlab_token\"\n$ trivy repo <your private GitLab repo URL>\n
    "},{"location":"docs/target/rootfs/","title":"Rootfs","text":"

    Rootfs scanning is for special use cases such as

    • Host machine
    • Root filesystem
    • Unpacked filesystem
    $ trivy rootfs /path/to/rootfs\n

    Note

    Rootfs scanning works differently from the Filesystem scanning. You should use trivy fs to scan your local projects in CI/CD. See here for the differences.

    "},{"location":"docs/target/sbom/","title":"SBOM scanning","text":"

    Trivy can take the following SBOM formats as an input and scan for vulnerabilities and licenses.

    • CycloneDX
    • SPDX
    • SPDX JSON
    • CycloneDX-type attestation
    • KBOM in CycloneDX format

    To scan SBOM, you can use the sbom subcommand and pass the path to the SBOM. The input format is automatically detected.

    $ trivy sbom /path/to/sbom_file\n

    By default, vulnerability scan in SBOM is executed. You can use --scanners vuln,license command property to select also license scan, or --scanners license alone.

    Note

    Passing SBOMs generated by tool other than Trivy may result in inaccurate detection because Trivy relies on custom properties in SBOM for accurate scanning.

    "},{"location":"docs/target/sbom/#cyclonedx","title":"CycloneDX","text":"

    Trivy supports CycloneDX as an input.

    Note

    CycloneDX XML is not supported at the moment.

    $ trivy sbom /path/to/cyclonedx.json\n
    "},{"location":"docs/target/sbom/#spdx","title":"SPDX","text":"

    Trivy supports the SPDX SBOM as an input.

    The following SPDX formats are supported:

    • Tag-value (--format spdx)
    • JSON (--format spdx-json)
    $ trivy image --format spdx-json --output spdx.json alpine:3.16.0\n$ trivy sbom spdx.json\n
    Result
    2022-09-15T21:32:27.168+0300    INFO    Vulnerability scanning is enabled\n2022-09-15T21:32:27.169+0300    INFO    Detected SBOM format: spdx-json\n2022-09-15T21:32:27.210+0300    INFO    Detected OS: alpine\n2022-09-15T21:32:27.210+0300    INFO    Detecting Alpine vulnerabilities...\n2022-09-15T21:32:27.211+0300    INFO    Number of language-specific files: 0\n\nspdx.json (alpine 3.16.0)\n=========================\nTotal: 5 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 1)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502   Library    \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                           Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 busybox      \u2502 CVE-2022-30065 \u2502 HIGH     \u2502 1.35.0-r13        \u2502 1.35.0-r15    \u2502 busybox: A use-after-free in Busybox's awk applet leads to \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 denial of service...                                       \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-30065                 \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 libcrypto1.1 \u2502 CVE-2022-2097  \u2502 MEDIUM   \u2502 1.1.1o-r0         \u2502 1.1.1q-r0     \u2502 openssl: AES OCB fails to encrypt some bytes               \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-2097                  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                \u2502          \u2502                   \u2502               \u2502                                                            \u2502\n\u2502 libssl1.1    \u2502                \u2502          \u2502                   \u2502               \u2502                                                            \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502                                                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 ssl_client   \u2502 CVE-2022-30065 \u2502 HIGH     \u2502 1.35.0-r13        \u2502 1.35.0-r15    \u2502 busybox: A use-after-free in Busybox's awk applet leads to \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 denial of service...                                       \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-30065                 \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 zlib         \u2502 CVE-2022-37434 \u2502 CRITICAL \u2502 1.2.12-r1         \u2502 1.2.12-r2     \u2502 zlib: a heap-based buffer over-read or buffer overflow in  \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 inflate in inflate.c...                                    \u2502\n\u2502              \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2022-37434                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/target/sbom/#sbom-attestation","title":"SBOM attestation","text":"

    You can also scan an SBOM attestation. In the following example, Cosign gets an attestation and Trivy scans it. You must create CycloneDX-type attestation before trying the example. To learn more about how to create an CycloneDX-Type attestation and attach it to an image, see the SBOM attestation page.

    $ cosign verify-attestation --key /path/to/cosign.pub --type cyclonedx <IMAGE> > sbom.cdx.intoto.jsonl\n$ trivy sbom ./sbom.cdx.intoto.jsonl\n\nsbom.cdx.intoto.jsonl (alpine 3.7.3)\n=========================\nTotal: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Library   \u2502 Vulnerability  \u2502 Severity \u2502 Installed Version \u2502 Fixed Version \u2502                          Title                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 musl       \u2502 CVE-2019-14697 \u2502 CRITICAL \u2502 1.1.18-r3         \u2502 1.1.18-r4     \u2502 musl libc through 1.1.23 has an x87 floating-point stack \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502 adjustment im ......                                     \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502 https://avd.aquasec.com/nvd/cve-2019-14697               \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502 musl-utils \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2502            \u2502                \u2502          \u2502                   \u2502               \u2502                                                          \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/target/sbom/#kbom","title":"KBOM","text":"

    To read more about KBOM, see the documentation for Kubernetes scanning.

    The supported Kubernetes distributions for core components vulnerability scanning are:

    • Kubernetes upstream
    • Rancher rke2
    $ trivy k8s --format cyclonedx cluster -o kbom.json\n$ trivy sbom kbom.json\n2023-09-28T22:52:25.707+0300    INFO    Vulnerability scanning is enabled\n2023-09-28T22:52:25.717+0300    INFO    Number of language-specific files: 3\n2023-09-28T22:52:25.717+0300    INFO    Detecting kubernetes vulnerabilities...\n2023-09-28T22:52:25.718+0300    INFO    Detecting gobinary vulnerabilities...\n\nKubernetes (kubernetes)\n\nTotal: 2 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\n\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502    Library     \u2502 Vulnerability  \u2502 Severity \u2502 Status \u2502 Installed Version \u2502          Fixed Version         \u2502                 Title                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 k8s.io/kubelet \u2502 CVE-2021-25749 \u2502 HIGH     \u2502 fixed  \u2502 1.24.0            \u2502 1.22.14, 1.23.11, 1.24.5       \u2502 runAsNonRoot logic bypass for Windows containers \u2502\n\u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                \u2502 https://avd.aquasec.com/nvd/cve-2021-25749       \u2502\n\u2502                \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524        \u2502                   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                \u2502 CVE-2023-2431  \u2502 LOW      \u2502        \u2502                   \u25021.24.14, 1.25.9, 1.26.4, 1.27.1 \u2502 Bypass of seccomp profile enforcement            \u2502\n\u2502                \u2502                \u2502          \u2502        \u2502                   \u2502                                \u2502 https://avd.aquasec.com/nvd/cve-2023-2431        \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n
    "},{"location":"docs/target/vm/","title":"Virtual Machine Image","text":"

    EXPERIMENTAL

    This feature might change without preserving backwards compatibility.

    To scan virtual machine (VM) images, you can use the vm subcommand.

    "},{"location":"docs/target/vm/#targets","title":"Targets","text":"

    The following targets are currently supported:

    • Local file
    • AWS EC2
      • Amazon Machine Image (AMI)
      • Amazon Elastic Block Store (EBS) Snapshot
    "},{"location":"docs/target/vm/#local-file","title":"Local file","text":"

    Pass the path to your local VM image file.

    $ trivy vm --scanners vuln disk.vmdk\n
    Result
    disk.vmdk (amazon 2 (Karoo))\n===========================================================================================\nTotal: 802 (UNKNOWN: 0, LOW: 17, MEDIUM: 554, HIGH: 221, CRITICAL: 10)\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502          Library           \u2502 Vulnerability  \u2502 Severity \u2502       Installed Version       \u2502         Fixed Version         \u2502                            Title                             \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 amazon-ssm-agent           \u2502 CVE-2022-24675 \u2502 HIGH     \u2502 3.0.529.0-1.amzn2             \u2502 3.1.1575.0-1.amzn2            \u2502 golang: encoding/pem: fix stack overflow in Decode           \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2022-24675                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524          \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 bind-export-libs           \u2502 CVE-2021-25215 \u2502          \u2502 32:9.11.4-26.P2.amzn2.4       \u2502 32:9.11.4-26.P2.amzn2.5       \u2502 bind: An assertion check can fail while answering queries    \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 for DNAME records...                                         \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2021-25215                   \u2502\n\u2502                            \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                            \u2502 CVE-2021-25214 \u2502 MEDIUM   \u2502                               \u2502 32:9.11.4-26.P2.amzn2.5.2     \u2502 bind: Broken inbound incremental zone update (IXFR) can      \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 cause named to terminate...                                  \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2021-25214                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 bind-libs                  \u2502 CVE-2021-25215 \u2502 HIGH     \u2502                               \u2502 32:9.11.4-26.P2.amzn2.5       \u2502 bind: An assertion check can fail while answering queries    \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 for DNAME records...                                         \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2021-25215                   \u2502\n\u2502                            \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                            \u2502 CVE-2021-25214 \u2502 MEDIUM   \u2502                               \u2502 32:9.11.4-26.P2.amzn2.5.2     \u2502 bind: Broken inbound incremental zone update (IXFR) can      \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 cause named to terminate...                                  \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2021-25214                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 bind-libs-lite             \u2502 CVE-2021-25215 \u2502 HIGH     \u2502                               \u2502 32:9.11.4-26.P2.amzn2.5       \u2502 bind: An assertion check can fail while answering queries    \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 for DNAME records...                                         \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2021-25215                   \u2502\n\u2502                            \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                            \u2502 CVE-2021-25214 \u2502 MEDIUM   \u2502                               \u2502 32:9.11.4-26.P2.amzn2.5.2     \u2502 bind: Broken inbound incremental zone update (IXFR) can      \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 cause named to terminate...                                  \u2502\n\u2502                            \u2502                \u2502          \u2502                               \u2502                               \u2502 https://avd.aquasec.com/nvd/cve-2021-25214                   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524                               \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n...\n
    "},{"location":"docs/target/vm/#amazon-machine-image-ami","title":"Amazon Machine Image (AMI)","text":"

    You can specify your AMI ID with the ami: prefix.

    $ trivy vm ami:${your_ami_id}\n

    Note

    AMIs in the marketplace are not supported because the EBS direct APIs don't support that. See the AWS documentation for the detail.

    "},{"location":"docs/target/vm/#example","title":"Example","text":"
    $ trivy vm --scanners vuln ami:ami-0123456789abcdefg\n

    If you want to scan a AMI of non-default setting region, you can set any region via --aws-region option.

    $ trivy vm --aws-region ap-northeast-1 ami:ami-0123456789abcdefg\n
    "},{"location":"docs/target/vm/#required-actions","title":"Required Actions","text":"

    Some actions on EBS are also necessary since Trivy scans an EBS snapshot tied to the specified AMI under the hood.

    • ec2:DescribeImages
    • ebs:ListSnapshotBlocks
    • ebs:GetSnapshotBlock
    "},{"location":"docs/target/vm/#amazon-elastic-block-store-ebs-snapshot","title":"Amazon Elastic Block Store (EBS) Snapshot","text":"

    You can specify your EBS snapshot ID with the ebs: prefix.

    $ trivy vm ebs:${your_ebs_snapshot_id}\n

    Note

    Public snapshots are not supported because the EBS direct APIs don't support that. See the AWS documentation for the detail.

    "},{"location":"docs/target/vm/#example_1","title":"Example","text":"
    $ trivy vm --scanners vuln ebs:snap-0123456789abcdefg\n

    If you want to scan an EBS Snapshot of non-default setting region, you can set any region via --aws-region option.

    $ trivy vm --aws-region ap-northeast-1 ebs:ebs-0123456789abcdefg\n

    The above command takes a while as it calls EBS API and fetches the EBS blocks. If you want to scan the same snapshot several times, you can download the snapshot locally by using coldsnap maintained by AWS. Then, Trivy can scan the local VM image file.

    $ coldsnap download snap-0123456789abcdefg disk.img\n$ trivy vm ./disk.img\n
    "},{"location":"docs/target/vm/#required-actions_1","title":"Required Actions","text":"
    • ebs:ListSnapshotBlocks
    • ebs:GetSnapshotBlock
    "},{"location":"docs/target/vm/#scanners","title":"Scanners","text":"

    Trivy supports VM image scanning for

    • Vulnerabilities
    • Misconfigurations
    • Secrets
    • Licenses
    "},{"location":"docs/target/vm/#vulnerabilities","title":"Vulnerabilities","text":"

    It is enabled by default. You can simply specify your VM image location. It detects known vulnerabilities in your VM image. See here for the detail.

    $ trivy vm [YOUR_VM_IMAGE]\n
    "},{"location":"docs/target/vm/#misconfigurations","title":"Misconfigurations","text":"

    It is supported, but it is not useful in most cases. As mentioned here, Trivy mainly supports Infrastructure as Code (IaC) files for misconfigurations. If your VM image includes IaC files such as Kubernetes YAML files or Terraform files, you should enable this feature with --scanners misconfig.

    $ trivy vm --scanners misconfig [YOUR_VM_IMAGE]\n
    "},{"location":"docs/target/vm/#secrets","title":"Secrets","text":"

    It is enabled by default. See here for the detail.

    $ trivy vm [YOUR_VM_IMAGE]\n

    Tip

    The scanning could be faster if you enable only vulnerability scanning (--scanners vuln) because Trivy tries to download only necessary blocks for vulnerability detection.

    "},{"location":"docs/target/vm/#licenses","title":"Licenses","text":"

    It is disabled by default. See here for the detail.

    $ trivy vm --scanners license [YOUR_VM_IMAGE]\n
    "},{"location":"docs/target/vm/#sbom-generation","title":"SBOM generation","text":"

    Trivy can generate SBOM for VM images. See here for the detail.

    "},{"location":"docs/target/vm/#supported-architectures","title":"Supported Architectures","text":""},{"location":"docs/target/vm/#virtual-machine-images","title":"Virtual machine images","text":"Image format Support VMDK \u2714 OVA VHD VHDX QCOW2"},{"location":"docs/target/vm/#vmdk-disk-types","title":"VMDK disk types","text":"VMDK disk type Support streamOptimized \u2714 monolithicSparse vmfs vmfsSparse twoGbMaxExtentSparse monolithicFlat twoGbMaxExtentFlat vmfsRaw fullDevice partitionedDevice vmfsRawDeviceMap vmfsPassthroughRawDeviceMap

    Reference: VMware Virtual Disk Format 1.1.pdf

    "},{"location":"docs/target/vm/#disk-partitions","title":"Disk partitions","text":"Disk format Support Master boot record (MBR) \u2714 Extended master boot record GUID partition table (GPT) \u2714 Logical volume manager (LVM)"},{"location":"docs/target/vm/#filesystems","title":"Filesystems","text":"Filesystem format Support XFS \u2714 EXT4 \u2714 EXT2/3 \u2714 ZFS"},{"location":"ecosystem/","title":"Ecosystem","text":"

    Trivy is integrated into many popular tools and applications, so that you can easily add security to your workflow.

    In this section you will find an aggregation of the different integrations. Integrations are listed as either \"official\" or \"community\". Official integrations are developed by the core Trivy team and supported by it. Community integrations are integrations developed by the community, and collected here for your convenience. For support or questions about community integrations, please contact the original developers.

    \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics.

    "},{"location":"ecosystem/#add-missing-integration","title":"Add missing integration","text":"

    We are happy to showcase community integrations in this section. To suggest an addition simply make a Pull Request to add the missing integration.

    "},{"location":"ecosystem/cicd/","title":"CI/CD Integrations","text":""},{"location":"ecosystem/cicd/#azure-devops-official","title":"Azure DevOps (Official)","text":"

    Azure Devops is Microsoft Azure cloud native CI/CD service.

    Trivy has a \"Azure Devops Pipelines Task\" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI.

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-azure-pipelines-task

    "},{"location":"ecosystem/cicd/#github-actions","title":"GitHub Actions","text":"

    GitHub Actions is GitHub's native CI/CD and job orchestration service.

    "},{"location":"ecosystem/cicd/#trivy-action-official","title":"trivy-action (Official)","text":"

    GitHub Action for integrating Trivy into your GitHub pipeline

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-action

    "},{"location":"ecosystem/cicd/#trivy-action-community","title":"trivy-action (Community)","text":"

    GitHub Action to scan vulnerability using Trivy. If vulnerabilities are found by Trivy, it creates a GitHub Issue.

    \ud83d\udc49 Get it at: https://github.com/marketplace/actions/trivy-action

    "},{"location":"ecosystem/cicd/#trivy-github-issues-community","title":"trivy-github-issues (Community)","text":"

    In this action, Trivy scans the dependency files such as package-lock.json and go.sum in your repository, then create GitHub issues according to the result.

    \ud83d\udc49 Get it at: https://github.com/marketplace/actions/trivy-github-issues

    "},{"location":"ecosystem/cicd/#buildkite-plugin-community","title":"Buildkite Plugin (Community)","text":"

    The trivy buildkite plugin provides a convenient mechanism for running the open-source trivy static analysis tool on your project.

    \ud83d\udc49 Get it at: https://github.com/equinixmetal-buildkite/trivy-buildkite-plugin

    "},{"location":"ecosystem/cicd/#dagger-community","title":"Dagger (Community)","text":"

    Dagger is CI/CD as code that runs anywhere.

    The Dagger module for Trivy provides functions for scanning container images from registries as well as Dagger Container objects from any Dagger SDK (e.g. Go, Python, Node.js, etc).

    \ud83d\udc49 Get it at: https://daggerverse.dev/mod/github.com/jpadams/daggerverse/trivy

    "},{"location":"ecosystem/cicd/#semaphore-community","title":"Semaphore (Community)","text":"

    Semaphore is a CI/CD service.

    You can use Trivy in Semaphore for scanning code, containers, infrastructure, and Kubernetes in Semaphore workflow.

    \ud83d\udc49 Get it at: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy

    "},{"location":"ecosystem/cicd/#circleci-community","title":"CircleCI (Community)","text":"

    CircleCI is a CI/CD service.

    You can use the Trivy Orb for Circle CI to introduce security scanning into your workflow.

    \ud83d\udc49 Get it at: https://circleci.com/developer/orbs/orb/fifteen5/trivy-orb Source: https://github.com/15five/trivy-orb

    "},{"location":"ecosystem/cicd/#woodpecker-ci-community","title":"Woodpecker CI (Community)","text":"

    Example Trivy step in pipeline

    pipeline:\n  securitycheck:\n    image: aquasec/trivy:latest\n    commands:\n      # use any trivy command, if exit code is 0 woodpecker marks it as passed, else it assumes it failed\n      - trivy fs --exit-code 1 --skip-dirs web/ --skip-dirs docs/ --severity MEDIUM,HIGH,CRITICAL .\n

    Woodpecker does use Trivy itself so you can see it in use there.

    "},{"location":"ecosystem/cicd/#concourse-ci-community","title":"Concourse CI (Community)","text":"

    Concourse CI is a CI/CD service.

    You can use Trivy Resource in Concourse for scanning containers and introducing security scanning into your workflow. It has capabilities to fail the pipeline, create issues, alert communication channels (using respective resources) based on Trivy scan output.

    \ud83d\udc49 Get it at: https://github.com/Comcast/trivy-resource/

    "},{"location":"ecosystem/cicd/#secobserve-github-actions-and-gitlab-templates-community","title":"SecObserve GitHub actions and GitLab templates (Community)","text":"

    SecObserve GitHub actions and GitLab templates run various vulnerability scanners, providing uniform methods and parameters for launching the tools.

    The Trivy integration supports scanning Docker images and local filesystems for vulnerabilities as well as scanning IaC files for misconfigurations.

    \ud83d\udc49 Get it at: https://github.com/MaibornWolff/secobserve_actions_templates

    "},{"location":"ecosystem/ide/","title":"IDE and developer tools Integrations","text":""},{"location":"ecosystem/ide/#vscode-official","title":"VSCode (Official)","text":"

    Visual Studio Code is an open source versatile code editor and development environment.

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-vscode-extension

    "},{"location":"ecosystem/ide/#jetbrains-official","title":"JetBrains (Official)","text":"

    JetBrains makes IDEs such as Goland, Pycharm, IntelliJ, Webstorm, and more.

    The Trivy plugin for JetBrains IDEs lets you use Trivy right from your development environment.

    \ud83d\udc49 Get it at: https://plugins.jetbrains.com/plugin/18690-trivy-findings-explorer

    "},{"location":"ecosystem/ide/#kubernetes-lens-official","title":"Kubernetes Lens (Official)","text":"

    Kubernetes Lens is a management application for Kubernetes clusters.

    Trivy has an extension for Kubernetes Lens that lets you scan Kubernetes workloads and view the results in the Lens UI.

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-operator-lens-extension

    "},{"location":"ecosystem/ide/#vim-community","title":"Vim (Community)","text":"

    Vim is a terminal based text editor.

    Vim plugin for Trivy to install and run Trivy.

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/vim-trivy

    "},{"location":"ecosystem/ide/#docker-desktop-community","title":"Docker Desktop (Community)","text":"

    Docker Desktop is an easy way to install Docker container engine on your development machine, and manage it in a GUI .

    Trivy Docker Desktop extension for scanning container images for vulnerabilities and generating SBOMs

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-docker-extension

    "},{"location":"ecosystem/ide/#rancher-desktop-community","title":"Rancher Desktop (Community)","text":"

    Rancher Desktop is an easy way to use containers and Kubernetes on your development machine, and manage it in a GUI.

    Trivy is natively integrated with Rancher, no installation is needed. More info in Rancher documentation: https://docs.rancherdesktop.io/ui/images/#scanning-images

    "},{"location":"ecosystem/ide/#lazytrivy-community","title":"LazyTrivy (Community)","text":"

    A terminal native UI for Trivy

    \ud83d\udc49 Get it at: https://github.com/owenrumney/lazytrivy

    "},{"location":"ecosystem/ide/#trivy-vulnerability-explorer-community","title":"Trivy Vulnerability explorer (Community)","text":"

    Web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table

    \ud83d\udc49 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer

    "},{"location":"ecosystem/ide/#trivy-pre-commit-community","title":"Trivy pre-commit (Community)","text":"

    A trivy pre-commit hook that runs a trivy fs in your git repo before commiting, preventing you from commiting secrets in the first place.

    \ud83d\udc49 Get it at: https://github.com/mxab/pre-commit-trivy

    "},{"location":"ecosystem/ide/#aws-cdk","title":"AWS CDK","text":"

    The AWS Cloud Development Kit (AWS CDK) is an open-source software development framework to define cloud infrastructure in code and provision it through AWS CloudFormation.

    "},{"location":"ecosystem/ide/#image-scanner-with-trivy-community","title":"image-scanner-with-trivy (Community)","text":"

    A CDK Construct Library to scan an image with trivy in CDK codes.

    \ud83d\udc49 Get it at: https://constructs.dev/packages/image-scanner-with-trivy

    "},{"location":"ecosystem/ide/#headlamp-plugin-community","title":"Headlamp plugin (Community)","text":"

    Headlamp is a user-friendly Kubernetes UI focused on extensibility. The Kubescape plugin extends Headlamp with views on Trivy reports.

    \ud83d\udc49 Get it at: https://github.com/kubebeam/trivy-headlamp-plugin

    "},{"location":"ecosystem/prod/","title":"Production and cloud Integrations","text":""},{"location":"ecosystem/prod/#kubernetes","title":"Kubernetes","text":"

    Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.

    "},{"location":"ecosystem/prod/#trivy-operator-official","title":"Trivy Operator (Official)","text":"

    Using the Trivy Operator you can install Trivy into a Kubernetes cluster so that it automatically and continuously scan your workloads and cluster for security issues.

    \ud83d\udc49 Get it at: https://github.com/aquasecurity/trivy-operator

    "},{"location":"ecosystem/prod/#harbor-official","title":"Harbor (Official)","text":"

    Harbor is an open source cloud native container and artifact registry.

    Trivy is natively integrated into Harbor, no installation is needed. More info in Harbor documentation: https://goharbor.io/docs/2.6.0/administration/vulnerability-scanning

    "},{"location":"ecosystem/prod/#kyverno-community","title":"Kyverno (Community)","text":"

    Kyverno is a policy management tool for Kubernetes.

    You can use Kyverno to ensure and enforce that deployed workloads' images are scanned for vulnerabilities.

    \ud83d\udc49 Get it at: https://neonmirrors.net/post/2022-07/attesting-image-scans-kyverno

    "},{"location":"ecosystem/prod/#zora-community","title":"Zora (Community)","text":"

    Zora is an open-source solution that scans Kubernetes clusters with multiple plugins at scheduled times.

    Trivy is integrated into Zora as a vulnerability scanner plugin.

    \ud83d\udc49 Get it at: https://zora-docs.undistro.io/latest/plugins/trivy/

    "},{"location":"ecosystem/prod/#helmper-community","title":"Helmper (Community)","text":"

    Helmper is a go program that reads Helm Charts from remote OCI registries and pushes the Helm Charts and the Helm Charts container images to your OCI registries with optional OS level vulnerability patching

    Trivy is integrated into Helmper as a vulnerability scanner in combination with Copacetic to fix detected vulnerabilities.

    \ud83d\udc49 Get it at: https://github.com/ChristofferNissen/helmper

    "},{"location":"ecosystem/reporting/","title":"Reporting","text":""},{"location":"ecosystem/reporting/#defectdojo-community","title":"DefectDojo (Community)","text":"

    DefectDojo can parse Trivy JSON reports. The parser supports deduplication and auto-close features.

    \ud83d\udc49 Get it at: https://github.com/DefectDojo/django-DefectDojo

    "},{"location":"ecosystem/reporting/#secobserve-community","title":"SecObserve (Community)","text":"

    SecObserve can parse Trivy results as CycloneDX reports and provides an unified overview of vulnerabilities from different sources. Vulnerabilities can be evaluated with manual and rule based assessments.

    \ud83d\udc49 Get it at: https://github.com/MaibornWolff/SecObserve

    "},{"location":"ecosystem/reporting/#scan2html-community","title":"Scan2html (Community)","text":"

    A Trivy plugin that scans and outputs the results to an interactive html file.

    \ud83d\udc49 Get it at: https://github.com/fatihtokus/scan2html

    "},{"location":"ecosystem/reporting/#sonarqube-community","title":"SonarQube (Community)","text":"

    A Trivy plugin that converts JSON report to SonarQube generic issues format.

    \ud83d\udc49 Get it at: https://github.com/umax/trivy-plugin-sonarqube

    "},{"location":"ecosystem/reporting/#trivy-streamlit-community","title":"Trivy-Streamlit (Community)","text":"

    Trivy-Streamlit is a Streamlit application that allows you to quickly parse the results from a Trivy JSON report.

    \ud83d\udc49 Get it at: https://github.com/mfreeman451/trivy-streamlit

    "},{"location":"ecosystem/reporting/#trivy-vulnerability-explorer-community","title":"Trivy-Vulnerability-Explorer (Community)","text":"

    This project is a web application that allows to load a Trivy report in json format and displays the vulnerabilities of a single target in an interactive data table.

    \ud83d\udc49 Get it at: https://github.com/dbsystel/trivy-vulnerability-explorer

    "},{"location":"ecosystem/reporting/#plopseccom-community","title":"plopsec.com (Community)","text":"

    This project is a web application designed to help you visualize Trivy image scan reports. It enriches the data with additional exploitability metrics from EPSS, Metasploit, and Exploit-DB, updated daily.

    \ud83d\udc49 Get it at: https://plopsec.com | https://github.com/pl0psec/plopsec.com

    "},{"location":"getting-started/","title":"First steps with Trivy","text":""},{"location":"getting-started/#get-trivy","title":"Get Trivy","text":"

    Trivy is available in most common distribution channels. The complete list of installation options is available in the Installation page. Here are a few popular examples:

    • macOS: brew install trivy
    • Docker: docker run aquasec/trivy
    • Download binary from GitHub Release
    • See Installation for more

    Trivy is integrated with many popular platforms and applications. The complete list of integrations is available in the Ecosystem page. Here are a few popular options examples:

    • GitHub Actions
    • Kubernetes operator
    • VS Code plugin
    • See Ecosystem for more
    "},{"location":"getting-started/#general-usage","title":"General usage","text":"

    Trivy's Command Line Interface pattern follows its major concepts: targets (what you want to scan), and scanners (what you want to scan for):

    trivy <target> [--scanners <scanner1,scanner2>] <subject>\n
    "},{"location":"getting-started/#examples","title":"Examples","text":"

    Scan a container image from registry, with the default scanner which is Vulnerabilities scanner:

    trivy image python:3.4-alpine\n

    Scan a local code repository, for vulnerabilities, exposed secrets and misconfigurations:

    trivy fs --scanners vuln,secret,misconfig /path/to/myproject\n

    Scan a Kubernetes cluster, with all available scanners, and show a summary report:

    trivy k8s --report summary cluster\n

    For a more complete introduction, check out the basic Trivy Demo: https://github.com/itaysk/trivy-demo

    "},{"location":"getting-started/#learn-more","title":"Learn more","text":"

    Now that you up and ready, here are some resources to help you deepen your knowledge:

    • Learn more about Trivy's capabilities by exploring the complete documentation.
    • Explore community questions and under GitHub Discussions.
    • Stay up to date by watching for New Releases & Announcements.
    • Follow Trivy on Twitter/X: @aquatrivy
    • Explore and subscribe to our YouTube channel @AquaSecOSS
    "},{"location":"getting-started/#want-more-check-out-aqua","title":"Want more? Check out Aqua","text":"

    If you liked Trivy, you will love Aqua which builds on top of Trivy to provide even more enhanced capabilities for a complete security management offering. You can find a high level comparison table specific to Trivy users here. In addition, check out the https://aquasec.com website for more information about our products and services. If you'd like to contact Aqua or request a demo, please use this form: https://www.aquasec.com/demo

    "},{"location":"getting-started/faq/","title":"FAQ","text":""},{"location":"getting-started/faq/#faq","title":"FAQ","text":""},{"location":"getting-started/faq/#how-to-pronounce-the-name-trivy","title":"How to pronounce the name \"Trivy\"?","text":"

    tri is pronounced like trigger, vy is pronounced like envy.

    "},{"location":"getting-started/faq/#does-trivy-support-x","title":"Does Trivy support X?","text":"

    Check out the Scanning coverage page.

    "},{"location":"getting-started/faq/#is-there-a-paid-version-of-trivy","title":"Is there a paid version of Trivy?","text":"

    If you liked Trivy, you will love Aqua which builds on top of Trivy to provide even more enhanced capabilities for a complete security management offering. You can find a high level comparison table specific to Trivy users here. In addition check out the https://aquasec.com website for more information about our products and services. If you'd like to contact Aqua or request a demo, please use this form: https://www.aquasec.com/demo

    "},{"location":"getting-started/faq/#how-to-generate-multiple-reports","title":"How to generate multiple reports?","text":"

    See here.

    "},{"location":"getting-started/faq/#how-to-run-trivy-under-air-gapped-environment","title":"How to run Trivy under air-gapped environment?","text":"

    See here.

    "},{"location":"getting-started/faq/#why-trivy-fs-and-trivy-repo-does-not-scan-jar-files-for-vulnerabilities","title":"Why trivy fs and trivy repo does not scan JAR files for vulnerabilities?","text":"

    See here.

    "},{"location":"getting-started/installation/","title":"Installing Trivy","text":"

    In this section you will find an aggregation of the different ways to install Trivy. Installation options are labeled as either \"Official\" or \"Community\". Official installations are developed by the Trivy team and supported by it. Community installations could be developed by anyone from the Trivy community, and collected here for your convenience. For support or questions about community installations, please contact the original developers.

    Note

    If you are looking to integrate Trivy into another system, such as CI/CD, IDE, Kubernetes, etc, please see Ecosystem section to explore integrations of Trivy with other tools.

    "},{"location":"getting-started/installation/#container-image-official","title":"Container image (Official)","text":"

    Use one of the official Trivy images:

    Registry Repository Link Docker Hub docker.io/aquasec/trivy https://hub.docker.com/r/aquasec/trivy GitHub Container Registry (GHCR) ghcr.io/aquasecurity/trivy https://github.com/orgs/aquasecurity/packages/container/package/trivy AWS Elastic Container Registry (ECR) public.ecr.aws/aquasecurity/trivy https://gallery.ecr.aws/aquasecurity/trivy

    Tip

    It is advisable to mount a persistent cache dir on the host into the Trivy container.

    Tip

    For scanning container images with Trivy, mount the container engine socket from the host into the Trivy container.

    Example:

    docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:0.58.0-1-g775f954c3 image python:3.4-alpine\n
    "},{"location":"getting-started/installation/#github-release-official","title":"GitHub Release (Official)","text":"
    1. Download the file for your operating system/architecture from GitHub Release assets.
    2. Unpack the downloaded archive (tar -xzf ./trivy.tar.gz).
    3. Make sure the binary has execution bit turned on (chmod +x ./trivy).
    "},{"location":"getting-started/installation/#install-script-official","title":"Install Script (Official)","text":"

    For convenience, you can use the install script to download and install Trivy from GitHub Release.

    curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.58.0-1-g775f954c3\n
    "},{"location":"getting-started/installation/#rhelcentos-official","title":"RHEL/CentOS (Official)","text":"RepositoryRPM

    Add repository setting to /etc/yum.repos.d.

    cat << EOF | sudo tee -a /etc/yum.repos.d/trivy.repo\n[trivy]\nname=Trivy repository\nbaseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/\\$basearch/\ngpgcheck=1\nenabled=1\ngpgkey=https://aquasecurity.github.io/trivy-repo/rpm/public.key\nEOF\nsudo yum -y update\nsudo yum -y install trivy\n
    rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.58.0-1-g775f954c3/trivy_0.58.0-1-g775f954c3_Linux-64bit.rpm\n
    "},{"location":"getting-started/installation/#debianubuntu-official","title":"Debian/Ubuntu (Official)","text":"RepositoryDEB

    Add repository setting to /etc/apt/sources.list.d.

    sudo apt-get install wget gnupg\nwget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null\necho \"deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main\" | sudo tee -a /etc/apt/sources.list.d/trivy.list\nsudo apt-get update\nsudo apt-get install trivy\n
    wget https://github.com/aquasecurity/trivy/releases/download/v0.58.0-1-g775f954c3/trivy_0.58.0-1-g775f954c3_Linux-64bit.deb\nsudo dpkg -i trivy_0.58.0-1-g775f954c3_Linux-64bit.deb\n
    "},{"location":"getting-started/installation/#homebrew-official","title":"Homebrew (Official)","text":"

    Homebrew for macOS and Linux.

    brew install trivy\n
    "},{"location":"getting-started/installation/#windows-official","title":"Windows (Official)","text":"
    1. Download trivy_x.xx.x_windows-64bit.zip file from releases page.
    2. Unzip file and copy to any folder.
    "},{"location":"getting-started/installation/#arch-linux-community","title":"Arch Linux (Community)","text":"

    Arch Linux Package Repository.

    sudo pacman -S trivy\n

    References: - https://archlinux.org/packages/extra/x86_64/trivy/ - https://gitlab.archlinux.org/archlinux/packaging/packages/trivy/-/blob/main/PKGBUILD

    "},{"location":"getting-started/installation/#macports-community","title":"MacPorts (Community)","text":"

    MacPorts for macOS.

    sudo port install trivy\n

    References: - https://ports.macports.org/port/trivy/details/

    "},{"location":"getting-started/installation/#nixnixos-community","title":"Nix/NixOS (Community)","text":"

    Nix package manager for Linux and macOS.

    Command lineConfigurationHome Manager

    nix-env --install -A nixpkgs.trivy

    # your other config ...\nenvironment.systemPackages = with pkgs; [\n  # your other packages ...\n  trivy\n];\n
    # your other config ...\nhome.packages = with pkgs; [\n  # your other packages ...\n  trivy\n];\n

    References:

    • https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/admin/trivy/default.nix
    "},{"location":"getting-started/installation/#freebsd-official","title":"FreeBSD (Official)","text":"

    Pkg package manager for FreeBSD.

    pkg install trivy\n
    "},{"location":"getting-started/installation/#asdfmise-community","title":"asdf/mise (Community)","text":"

    asdf and mise are quite similar tools you can use to install trivy. See their respective documentation for more information of how to install them and use them:

    • asdf
    • mise

    The plugin used by both tools is developped here

    asdfmise

    A basic global installation is shown below, for specific version or/and local version to a directory see \"asdf\" documentation.

    # Install plugin\nasdf plugin add trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git\n\n# Install latest version\nasdf install trivy latest\n\n# Set a version globally (on your ~/.tool-versions file)\nasdf global trivy latest\n\n# Now trivy commands are available\ntrivy --version\n

    A basic global installation is shown below, for specific version or/and local version to a directory see \"mise\" documentation.

    # Install plugin and install latest version\nmise install trivy@latest\n\n# Set a version globally (on your ~/.tool-versions file)\nmise use -g trivy@latest\n\n# Now trivy commands are available\ntrivy --version\n
    "},{"location":"getting-started/signature-verification/","title":"Signature Verification","text":"

    All binaries and container images are signed by Cosign.

    "},{"location":"getting-started/signature-verification/#verifying-container-image","title":"Verifying container image","text":"

    Use the following command for keyless verification:

    cosign verify aquasec/trivy:<version> \\\n--certificate-identity-regexp 'https://github\\.com/aquasecurity/trivy/\\.github/workflows/.+' \\\n--certificate-oidc-issuer \"https://token.actions.githubusercontent.com\"\n

    You should get the following output

    Verification for index.docker.io/aquasec/trivy:latest --\nThe following checks were performed on each of these signatures:\n   - The cosign claims were validated\n   - Existence of the claims in the transparency log was verified offline\n   - The code-signing certificate was verified using trusted certificate authority certificates\n\n   ....\n
    "},{"location":"getting-started/signature-verification/#verifying-binary","title":"Verifying binary","text":"

    Download the required tarball, associated signature and certificate files from the GitHub Release.

    Use the following command for keyless verification:

    cosign verify-blob <path to binray> \\\n--certificate <path to cert> \\\n--signature <path to sig> \\\n--certificate-identity-regexp 'https://github\\.com/aquasecurity/trivy/\\.github/workflows/.+' \\\n--certificate-oidc-issuer \"https://token.actions.githubusercontent.com\"\n

    You should get the following output

    Verified OK\n
    "},{"location":"getting-started/signature-verification/#verifying-a-gpg-signature","title":"Verifying a GPG signature","text":"

    RPM and Deb packages are also signed by GPG.

    "},{"location":"getting-started/signature-verification/#verifying-rpm","title":"Verifying RPM","text":"

    The public key is available at https://aquasecurity.github.io/trivy-repo/rpm/public.key.

    First, download and import the key:

    curl https://aquasecurity.github.io/trivy-repo/rpm/public.key \\\n--output pub.key\nrpm --import pub.key\nrpm -q --queryformat \"%{SUMMARY}\\n\" $(rpm -q gpg-pubkey)\n

    You should get the following output:

    gpg(trivy)\n

    Then you can verify the signature:

    curl -L https://github.com/aquasecurity/trivy/releases/download/<version>/<file name>.rpm \\\n--output trivy.rpm\nrpm -K trivy.rpm\n

    You should get the following output

    trivy.rpm: digests signatures OK\n
    "},{"location":"tutorials/overview/","title":"Tutorials","text":"

    In this section you can find step-by-step guides that help you accomplish specific tasks.

    \ud83d\udc48 Please use the side-navigation on the left in order to browse the different topics.

    "},{"location":"tutorials/overview/#adding-tutorials","title":"Adding tutorials","text":"

    You are welcome to create tutorials and showcase them here. Tutorials can be either included in here as full articles, or included as external links under external community resources. Before sending PR, please first create an issue (of kind \"Documentation\") and describe the suggestion, if it's external link or article, and what category it's under.

    Guidelines:

    • Focus on a specific use case. Start by clearly describing the use case and when/who it is relevant for.
    • Provide an end-to-end set of instructions. Make sure anyone can easily follow.
    • Describe the expected outcome after each step. Include examples as much as possible.
    "},{"location":"tutorials/additional-resources/cks/","title":"CKS preparation resources","text":"

    The Certified Kubernetes Security Specialist (CKS) Exam is offered by The Linux Foundation. It provides assurance that a CKS has the skills, knowledge, and competence on a broad range of best practices for securing container-based applications and Kubernetes platforms during build, deployment and runtime. CKA certification is required to sit for this exam.

    "},{"location":"tutorials/additional-resources/cks/#community-resources","title":"Community Resources","text":"
    • Trivy Video overview (short)
    • Example questions from the exam
    • More example questions
    • CKS exam study guide
    • Docker Image Vulnerabilities & Trivy Image Scanning Demo | K21Academy
    "},{"location":"tutorials/additional-resources/cks/#aqua-security-blog-posts-to-learn-more","title":"Aqua Security Blog posts to learn more","text":"
    • Supply chain security best practices
    • Supply chain attacks

    If you know of interesting resources, please start a PR to add those to the list.

    "},{"location":"tutorials/additional-resources/community/","title":"Community References","text":"

    Below is a list of additional resources from the community.

    "},{"location":"tutorials/additional-resources/community/#vulnerability-scanning","title":"Vulnerability Scanning","text":"
    • Detecting Spring4Shell with Trivy and Grype
    • Scan OS of your EC2 instances with Trivy
    "},{"location":"tutorials/additional-resources/community/#cicd-pipelines","title":"CI/CD Pipelines","text":"
    • How to use Tekton to set up a CI pipeline with OpenShift Pipelines
    • Continuous Container Vulnerability Testing with Trivy
    • Getting Started With Trivy and Jenkins
    • How to use Tekton to set up a CI pipeline with OpenShift Pipelines
    "},{"location":"tutorials/additional-resources/community/#misconfiguration-scanning","title":"Misconfiguration Scanning","text":"
    • Identifying Misconfigurations in your Terraform
    • How to write custom checks for Trivy
    "},{"location":"tutorials/additional-resources/community/#sbom-attestation-related","title":"SBOM, Attestation & related","text":"
    • Attesting Image Scans With Kyverno
    "},{"location":"tutorials/additional-resources/community/#trivy-kubernetes","title":"Trivy Kubernetes","text":"
    • Using Trivy Kubernetes in OVHCloud documentation.
    "},{"location":"tutorials/additional-resources/community/#comparisons","title":"Comparisons","text":"
    • the vulnerability remediation lifecycle of Alpine containers
    • Open Source CVE Scanner Round-Up: Clair vs Anchore vs Trivy
    • Docker Image Security: Static Analysis Tool Comparison \u2013 Anchore Engine vs Clair vs Trivy
    "},{"location":"tutorials/additional-resources/community/#evaluations","title":"Evaluations","text":"
    • Istio evaluating to use Trivy
    • Research Spike: evaluate Trivy for scanning running containers
    "},{"location":"tutorials/additional-resources/references/","title":"Additional Resources and Tutorials","text":"

    Below is a list of additional resources from Aqua Security.

    "},{"location":"tutorials/additional-resources/references/#announcements","title":"Announcements","text":"
    • Trivy Vulnerability Scanner Joins the Aqua Open-source Family
    • Trivy Image Vulnerability Scanner Now Under Apache 2.0 License
    "},{"location":"tutorials/additional-resources/references/#vulnerability-scanning","title":"Vulnerability Scanning","text":"
    • Using Trivy to Discover Vulnerabilities in VS Code Projects
    • How does a vulnerability scanner identify packages?
    • Handling Container Vulnerabilities with Open Policy Agent - Teppei Fukuda, Aqua Security
    "},{"location":"tutorials/additional-resources/references/#cicd-pipelines","title":"CI/CD Pipelines","text":"
    • DevSecOps with Trivy and GitHub Actions
    • Find Image Vulnerabilities Using GitHub and Aqua Security Trivy Action
    "},{"location":"tutorials/additional-resources/references/#misconfiguration-scanning","title":"Misconfiguration Scanning","text":"
    • Identifying Misconfigurations in your Terraform
    "},{"location":"tutorials/additional-resources/references/#clientserver","title":"Client/Server","text":"
    • Using Trivy in client server mode
    "},{"location":"tutorials/additional-resources/references/#workshops","title":"Workshops","text":"
    • Trivy Live Demo & Q&A
    • First Steps to Full Lifecycle Security with Open Source Tools - Rory McCune & Anais Urlichs
    "},{"location":"tutorials/additional-resources/references/#older-resources","title":"Older Resources","text":"
    • Webinar: Trivy Open Source Scanner for Container Images \u2013 Just Download and Run!
    • Kubernetes Security through GitOps Best Practices: ArgoCD and Starboard
    • Get started with Kubernetes Security and Starboard
    "},{"location":"tutorials/integrations/","title":"Integrations","text":"

    Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify --exit-code 0.

    "},{"location":"tutorials/integrations/aws-codepipeline/","title":"AWS CodePipeline","text":"

    See this blog post for an example of using Trivy within AWS CodePipeline.

    "},{"location":"tutorials/integrations/aws-security-hub/","title":"AWS Security Hub","text":""},{"location":"tutorials/integrations/aws-security-hub/#upload-findings-to-security-hub","title":"Upload findings to Security Hub","text":"

    In the following example using the template asff.tpl, ASFF file can be generated.

    $ AWS_REGION=us-west-1 AWS_ACCOUNT_ID=123456789012 trivy image --format template --template \"@contrib/asff.tpl\" -o report.asff golang:1.12-alpine\n

    ASFF template needs AWS_REGION and AWS_ACCOUNT_ID from environment variables.

    The Product ARN field follows the pattern below to match what AWS requires for the product resource type.

    \"ProductArn\": \"arn:aws:securityhub:{{ env \"AWS_REGION\" }}::product/aquasecurity/aquasecurity\",\n

    In order to upload results you must first run enable-import-findings-for-product like:

    aws securityhub enable-import-findings-for-product --product-arn arn:aws:securityhub:<AWS_REGION>::product/aquasecurity/aquasecurity\n

    The findings are formatted for the API with a key of Findings and a value of the array of findings. In order to upload via the CLI the outer wrapping must be removed being left with only the array of findings. The easiest way of doing this is with the jq library using the command

    cat report.asff | jq '.Findings'\n

    Then, you can upload it with AWS CLI.

    $ aws securityhub batch-import-findings --findings file://report.asff\n
    "},{"location":"tutorials/integrations/aws-security-hub/#note","title":"Note","text":"

    The batch-import-findings command limits the number of findings uploaded to 100 per request. The best known workaround to this problem is using jq to run the following command

    jq '.[:100]' report.asff 1> short_report.asff\n
    "},{"location":"tutorials/integrations/aws-security-hub/#customize","title":"Customize","text":"

    You can customize asff.tpl

    $ export AWS_REGION=us-west-1\n$ export AWS_ACCOUNT_ID=123456789012\n$ trivy image --format template --template \"@your-asff.tpl\" -o report.asff golang:1.12-alpine\n
    "},{"location":"tutorials/integrations/aws-security-hub/#reference","title":"Reference","text":"

    aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/

    "},{"location":"tutorials/integrations/azure-devops/","title":"Azure Devops","text":"
    • Here is the Azure DevOps Pipelines Task for Trivy
    "},{"location":"tutorials/integrations/azure-devops/#use-imagecleaner-to-clean-up-stale-images-on-your-azure-kubernetes-service-cluster","title":"Use ImageCleaner to clean up stale images on your Azure Kubernetes Service cluster","text":"

    It's common to use pipelines to build and deploy images on Azure Kubernetes Service (AKS) clusters. While great for image creation, this process often doesn't account for the stale images left behind and can lead to image bloat on cluster nodes. These images can present security issues as they may contain vulnerabilities. By cleaning these unreferenced images, you can remove an area of risk in your clusters. When done manually, this process can be time intensive, which ImageCleaner can mitigate via automatic image identification and removal.

    Vulnerability is determined based on a trivy scan, after which images with a LOW, MEDIUM, HIGH, or CRITICAL classification are flagged. An updated ImageList will be automatically generated by ImageCleaner based on a set time interval, and can also be supplied manually.

    "},{"location":"tutorials/integrations/azure-devops/#microsoft-defender-for-container-registries-and-trivy","title":"Microsoft Defender for container registries and Trivy","text":"

    This blog explains how to scan your Azure Container Registry-based container images with the integrated vulnerability scanner when they're built as part of your GitHub workflows.

    To set up the scanner, you'll need to enable Microsoft Defender for Containers and the CI/CD integration. When your CI/CD workflows push images to your registries, you can view registry scan results and a summary of CI/CD scan results.

    The findings of the CI/CD scans are an enrichment to the existing registry scan findings by Qualys. Defender for Cloud's CI/CD scanning is powered by Aqua Trivy

    "},{"location":"tutorials/integrations/bitbucket/","title":"Bitbucket Pipelines","text":"

    See trivy-pipe for the details.

    "},{"location":"tutorials/integrations/circleci/","title":"CircleCI","text":"
    $ cat .circleci/config.yml\njobs:\n  build:\n    docker:\n      - image: docker:stable-git\n    steps:\n      - checkout\n      - setup_remote_docker\n      - run:\n          name: Build image\n          command: docker build -t trivy-ci-test:${CIRCLE_SHA1} .\n      - run:\n          name: Install trivy\n          command: |\n            apk add --update-cache --upgrade curl\n            curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin\n      - run:\n          name: Scan the local image with trivy\n          command: trivy image --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1}\nworkflows:\n  version: 2\n  release:\n    jobs:\n      - build\n

    Example Repository

    "},{"location":"tutorials/integrations/github-actions/","title":"GitHub Actions","text":"
    • Here is the Trivy GitHub Action
    • The Microsoft Azure team have written a container-scan action that uses Trivy and Dockle
    • For full control over the options specified to Trivy, this blog post describes adding Trivy into your own GitHub action workflows
    "},{"location":"tutorials/integrations/gitlab-ci/","title":"GitLab CI","text":"

    GitLab 15.0 includes free integration with Trivy.

    To configure container scanning with Trivy in GitLab, simply include the CI template in your .gitlab-ci.yml file:

    include:\n  - template: Security/Container-Scanning.gitlab-ci.yml\n

    If you're a GitLab 14.x Ultimate customer, you can use the same configuration above.

    Alternatively, you can always use the example configurations below.

    stages:\n  - test\n\ntrivy:\n  stage: test\n  image: docker:stable\n  services:\n    - name: docker:dind\n      entrypoint: [\"env\", \"-u\", \"DOCKER_HOST\"]\n      command: [\"dockerd-entrypoint.sh\"]\n  variables:\n    DOCKER_HOST: tcp://docker:2375/\n    DOCKER_DRIVER: overlay2\n    # See https://github.com/docker-library/docker/pull/166\n    DOCKER_TLS_CERTDIR: \"\"\n    IMAGE: trivy-ci-test:$CI_COMMIT_SHA\n    TRIVY_NO_PROGRESS: \"true\"\n    TRIVY_CACHE_DIR: \".trivycache/\"\n  before_script:\n    - export TRIVY_VERSION=$(wget -qO - \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/')\n    - echo $TRIVY_VERSION\n    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -\n  allow_failure: true\n  script:\n    # Build image\n    - docker build -t $IMAGE .\n    # Build report\n    - ./trivy image --exit-code 0 --format template --template \"@/contrib/gitlab.tpl\" -o gl-container-scanning-report.json $IMAGE\n    # Print report\n    - ./trivy image --exit-code 0 --severity HIGH $IMAGE\n    # Fail on severe vulnerabilities\n    - ./trivy image --exit-code 1 --severity CRITICAL $IMAGE\n  cache:\n    paths:\n      - .trivycache/\n  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab Ultimate)\n  artifacts:\n    reports:\n      container_scanning: gl-container-scanning-report.json\n

    Example Repository

    "},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci-using-trivy-container","title":"GitLab CI using Trivy container","text":"

    To scan a previously built image that has already been pushed into the GitLab container registry the following CI job manifest can be used. Note that entrypoint needs to be unset for the script section to work. In case of a non-public GitLab project Trivy additionally needs to authenticate to the registry to be able to pull your application image. Finally, it is not necessary to clone the project repo as we only work with the container image.

    container_scanning:\n  image:\n    name: docker.io/aquasec/trivy:latest\n    entrypoint: [\"\"]\n  variables:\n    # No need to clone the repo, we exclusively work on artifacts. See\n    # https://docs.gitlab.com/ee/ci/runners/configure_runners.html#git-strategy\n    GIT_STRATEGY: none\n    TRIVY_USERNAME: \"$CI_REGISTRY_USER\"\n    TRIVY_PASSWORD: \"$CI_REGISTRY_PASSWORD\"\n    TRIVY_AUTH_URL: \"$CI_REGISTRY\"\n    TRIVY_NO_PROGRESS: \"true\"\n    TRIVY_CACHE_DIR: \".trivycache/\"\n    FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG\n  script:\n    - trivy --version\n    # update vulnerabilities db\n    - time trivy image --download-db-only\n    # Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there\n    - time trivy image --exit-code 0 --format template --template \"@/contrib/gitlab.tpl\"\n        --output \"$CI_PROJECT_DIR/gl-container-scanning-report.json\" \"$FULL_IMAGE_NAME\"\n    # Prints full report\n    - time trivy image --exit-code 0 \"$FULL_IMAGE_NAME\"\n    # Fail on critical vulnerabilities\n    - time trivy image --exit-code 1 --severity CRITICAL \"$FULL_IMAGE_NAME\"\n  cache:\n    paths:\n      - .trivycache/\n  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)\n  artifacts:\n    when:                          always\n    reports:\n      container_scanning:          gl-container-scanning-report.json\n  tags:\n    - docker-runner\n
    "},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci-alternative-template","title":"GitLab CI alternative template","text":"

    Depending on the edition of gitlab you have or your desired workflow, the container scanning template may not meet your needs. As an addition to the above container scanning template, a template for code climate has been included. The key things to update from the above examples are the template and report type. An updated example is below.

    stages:\n  - test\n\ntrivy:\n  stage: test\n  image: docker:stable\n  services:\n    - name: docker:dind\n      entrypoint: [\"env\", \"-u\", \"DOCKER_HOST\"]\n      command: [\"dockerd-entrypoint.sh\"]\n  variables:\n    DOCKER_HOST: tcp://docker:2375/\n    DOCKER_DRIVER: overlay2\n    # See https://github.com/docker-library/docker/pull/166\n    DOCKER_TLS_CERTDIR: \"\"\n    IMAGE: trivy-ci-test:$CI_COMMIT_SHA\n    TRIVY_NO_PROGRESS: \"true\"\n    TRIVY_CACHE_DIR: \".trivycache/\"\n  before_script:\n    - export TRIVY_VERSION=$(wget -qO - \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/')\n    - echo $TRIVY_VERSION\n    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -\n  allow_failure: true\n  script:\n    # Build image\n    - docker build -t $IMAGE .\n    # Image report\n    - ./trivy image --exit-code 0 --format template --template \"@/contrib/gitlab-codequality.tpl\" -o gl-codeclimate-image.json $IMAGE\n    # Filesystem report\n    - ./trivy filesystem --scanners misconfig,vuln --exit-code 0 --format template --template \"@/contrib/gitlab-codequality.tpl\" -o gl-codeclimate-fs.json .\n    # Combine report\n    - apk update && apk add jq\n    - jq -s 'add' gl-codeclimate-image.json gl-codeclimate-fs.json > gl-codeclimate.json\n  cache:\n    paths:\n      - .trivycache/\n  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)\n  artifacts:\n    paths:\n      - gl-codeclimate.json\n    reports:\n      codequality: gl-codeclimate.json\n

    Currently gitlab only supports a single code quality report. There is an open feature request to support multiple reports. Until this has been implemented, if you already have a code quality report in your pipeline, you can use jq to combine reports. Depending on how you name your artifacts, it may be necessary to rename the artifact if you want to reuse the name. To then combine the previous artifact with the output of trivy, the following jq command can be used, jq -s 'add' prev-codeclimate.json trivy-codeclimate.json > gl-codeclimate.json.

    "},{"location":"tutorials/integrations/gitlab-ci/#gitlab-ci-alternative-template-example-report","title":"GitLab CI alternative template example report","text":"

    You'll be able to see a full report in the GitLab pipeline code quality UI, where filesystem vulnerabilities and misconfigurations include links to the flagged files and image vulnerabilities report the image/os or runtime/library that the vulnerability originates from instead.

    "},{"location":"tutorials/integrations/travis-ci/","title":"Travis CI","text":"
    $ cat .travis.yml\nservices:\n  - docker\n\nenv:\n  global:\n    - COMMIT=${TRAVIS_COMMIT::8}\n\nbefore_install:\n  - docker build -t trivy-ci-test:${COMMIT} .\n  - export VERSION=$(curl --silent \"https://api.github.com/repos/aquasecurity/trivy/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"v([^\"]+)\".*/\\1/')\n  - wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz\n  - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz\nscript:\n  - ./trivy image --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT}\n  - ./trivy image --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT}\ncache:\n  directories:\n    - $HOME/.cache/trivy\n

    Example Repository

    "},{"location":"tutorials/kubernetes/cluster-scanning/","title":"Kubernetes Scanning Tutorial","text":""},{"location":"tutorials/kubernetes/cluster-scanning/#prerequisites","title":"Prerequisites","text":"

    To test the following commands yourself, make sure that you\u2019re connected to a Kubernetes cluster. A simple kind, a Docker-Desktop or microk8s cluster will do. In our case, we\u2019ll use a one-node kind cluster. Pro tip: The output of the commands will be even more interesting if you have some workloads running in your cluster.

    "},{"location":"tutorials/kubernetes/cluster-scanning/#cluster-scanning","title":"Cluster Scanning","text":"

    Trivy K8s is great to get an overview of all the vulnerabilities and misconfiguration issues or to scan specific workloads that are running in your cluster. You would want to use the Trivy K8s command either on your own local cluster or in your CI/CD pipeline post deployments.

    The trivy k8s command is part of the Trivy CLI.

    With the following command, we can scan our entire Kubernetes cluster for vulnerabilities and get a summary of the scan:

    trivy k8s --report=summary\n

    To get detailed information for all your resources, just replace \u2018summary\u2019 with \u2018all\u2019:

    trivy k8s --report=all\n

    However, we recommend displaying all information only in case you scan a specific namespace or resource since you can get overwhelmed with additional details.

    Furthermore, we can specify the namespace that Trivy is supposed to scan to focus on specific resources in the scan result:

    trivy k8s --include-namespaces kube-system --report summary\n

    Again, if you\u2019d like to receive additional details, use the \u2018--report=all\u2019 flag:

    trivy k8s --include-namespaces kube-system --report all\n

    Like with scanning for vulnerabilities, we can also filter in-cluster security issues by severity of the vulnerabilities:

    trivy k8s --severity=CRITICAL --report=summary\n

    Note that you can use any of the Trivy flags on the Trivy K8s command.

    "},{"location":"tutorials/kubernetes/cluster-scanning/#trivy-operator","title":"Trivy Operator","text":"

    The Trivy K8s command is an imperative model to scan resources. We wouldn\u2019t want to manually scan each resource across different environments. The larger the cluster and the more workloads are running in it, the more error-prone this process would become. With the Trivy Operator, we can automate the scanning process after the deployment.

    The Trivy Operator follows the Kubernetes Operator Model. Operators automate human actions, and the result of the task is saved as custom resource definitions (CRDs) within your cluster.

    This has several benefits:

    • Trivy Operator is installed CRDs in our cluster. As a result, all our resources, including our security scanner and its scan results, are Kubernetes resources. This makes it much easier to integrate the Trivy Operator directly into our existing processes, such as connecting Trivy with Prometheus, a monitoring system.

    • The Trivy Operator will automatically scan your resources every six hours. You can set up automatic alerting in case new critical security issues are discovered.

    • The CRDs can be both machine and human-readable depending on which applications consume the CRDs. This allows for more versatile applications of the Trivy operator.

    There are several ways that you can install the Trivy Operator in your cluster. In this guide, we\u2019re going to use the Helm installation.

    Please follow the Trivy Operator documentation for further information on:

    • Installation of the Trivy Operator
    • Getting started guide
    "},{"location":"tutorials/kubernetes/gitops/","title":"Installing the Trivy-Operator through GitOps","text":"

    This tutorial shows you how to install the Trivy Operator through GitOps platforms, namely ArgoCD and FluxCD.

    "},{"location":"tutorials/kubernetes/gitops/#argocd","title":"ArgoCD","text":"

    Make sure to have ArgoCD installed and running in your Kubernetes cluster.

    You can either deploy the Trivy Operator through the argocd CLI or by applying a Kubernetes manifest.

    ArgoCD command:

    > kubectl create ns trivy-system\n> argocd app create trivy-operator --repo https://github.com/aquasecurity/trivy-operator --path deploy/helm --dest-server https://kubernetes.default.svc --dest-namespace trivy-system\n
    Note that this installation is directly related to our official Helm Chart. If you want to change any of the value, we'd suggest you to create a separate values.yaml file.

    Kubernetes manifest trivy-operator.yaml:

    apiVersion: argoproj.io/v1alpha1\nkind: Application\nmetadata:\n  name: trivy-operator\n  namespace: argocd\nspec:\n  project: default\n  source:\n    chart: trivy-operator\n    repoURL: https://aquasecurity.github.io/helm-charts/\n    targetRevision: 0.0.3\n    helm:\n      values: |\n        trivy:\n          ignoreUnfixed: true\n  destination:\n    server: https://kubernetes.default.svc\n    namespace: trivy-system\n  syncPolicy:\n    automated:\n      prune: true\n      selfHeal: true\n

    To apply the Kubernetes manifest, if you have the manifest locally, you can use the following command through kubectl:

    > kubectl apply -f trivy-operator.yaml\n\napplication.argoproj.io/trivy-operator created\n

    If you have the manifest in a Git repository, you can apply it to your cluster through the following command:

    > kubectl apply -n argocd -f https://raw.githubusercontent.com/AnaisUrlichs/argocd-starboard/main/starboard/argocd-starboard.yaml\n
    The latter command would allow you to make changes to the YAML manifest that ArgoCD would register automatically.

    Once deployed, you want to tell ArgoCD to sync the application from the actual state to the desired state:

    argocd app sync trivy-operator\n

    Now you can see the deployment in the ArgoCD UI. Have a look at the ArgoCD documentation to know how to access the UI.

    Note that ArgoCD is unable to show the Trivy CRDs as synced.

    "},{"location":"tutorials/kubernetes/gitops/#fluxcd","title":"FluxCD","text":"

    Make sure to have FluxCD installed and running in your Kubernetes cluster.

    You can either deploy the Trivy Operator through the Flux CLI or by applying a Kubernetes manifest.

    Flux command:

    > kubectl create ns trivy-system\n> flux create source helm trivy-operator --url https://aquasecurity.github.io/helm-charts --namespace trivy-system\n> flux create helmrelease trivy-operator --chart trivy-operator\n  --source HelmRepository/trivy-operator\n  --chart-version 0.0.3\n  --namespace trivy-system\n

    Kubernetes manifest trivy-operator.yaml:

    apiVersion: source.toolkit.fluxcd.io/v1beta2\nkind: HelmRepository\nmetadata:\n  name: trivy-operator\n  namespace: flux-system\nspec:\n  interval: 60m\n  url: https://aquasecurity.github.io/helm-charts/\n\n---\napiVersion: helm.toolkit.fluxcd.io/v2beta1\nkind: HelmRelease\nmetadata:\n  name: trivy-operator\n  namespace: trivy-system\nspec:\n  chart:\n    spec:\n      chart: trivy-operator\n      sourceRef:\n        kind: HelmRepository\n        name: trivy-operator\n        namespace: flux-system\n      version: 0.10.1\n  interval: 60m\n  values:\n    trivy:\n      ignoreUnfixed: true\n  install:\n    crds: CreateReplace\n    createNamespace: true\n

    You can then apply the file to your Kubernetes cluster:

    kubectl apply -f trivy-operator.yaml\n

    "},{"location":"tutorials/kubernetes/gitops/#after-the-installation","title":"After the installation","text":"

    After the install, you want to check that the Trivy operator is running in the trivy-system namespace:

    kubectl get deployment -n trivy-system\n

    "},{"location":"tutorials/kubernetes/kyverno/","title":"Attesting Image Scans With Kyverno","text":"

    This tutorial is based on the following blog post by Chip Zoller: Attesting Image Scans With Kyverno

    This tutorial details

    • Verify the container image has an attestation with Kyverno
    "},{"location":"tutorials/kubernetes/kyverno/#prerequisites","title":"Prerequisites","text":"
    1. A running Kubernetes cluster that kubectl is connected to
    2. A Container image signed with Cosign and an attestation generated for a Trivy Vulnerability scan. Follow this tutorial for more information.
    "},{"location":"tutorials/kubernetes/kyverno/#kyverno-policy-to-check-attestation","title":"Kyverno Policy to check attestation","text":"

    The following policy ensures that the attestation is no older than 168h:

    vuln-attestation.yaml

    apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n  name: check-vulnerabilities\nspec:\n  validationFailureAction: Enforce\n  background: false\n  webhookTimeoutSeconds: 30\n  failurePolicy: Fail\n  rules:\n    - name: checking-vulnerability-scan-not-older-than-one-hour\n      match:\n        any:\n        - resources:\n            kinds:\n              - Pod\n      verifyImages:\n      - imageReferences:\n        - \"*\"\n        attestations:\n        - type: https://cosign.sigstore.dev/attestation/vuln/v1\n          conditions:\n          - all:\n            - key: \"{{ time_since('','{{ metadata.scanFinishedOn }}', '') }}\"\n              operator: LessThanOrEquals\n              value: \"1h\"\n          attestors:\n          - count: 1\n            entries:\n            - keys:\n                publicKeys: |-\n                  -----BEGIN PUBLIC KEY-----\n                  abc\n                  xyz\n                  -----END PUBLIC KEY-----\n
    "},{"location":"tutorials/kubernetes/kyverno/#apply-the-policy-to-your-kubernetes-cluster","title":"Apply the policy to your Kubernetes cluster","text":"

    Ensure that you have Kyverno already deployed and running on your cluster -- for instance through he Kyverno Helm Chart.

    Next, apply the above policy:

    kubectl apply -f vuln-attestation.yaml\n

    To ensure that the policy worked, we can deploy an example Kubernetes Pod with our container image:

    kubectl run app-signed --image= docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\u00a0\n
    Note that the image is based on the signing tutorial.

    Once we apply the deployment, it should pass since our attestation is available:

    kubectl apply -f deployment.yaml -n app\ndeployment.apps/cns-website created\n

    However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with docker.io/anaisurlichs/cns-website:0.0.5 and applying the deployment:

    kubectl run app-unsigned --image=docker.io/anaisurlichs/cns-website:0.1.1\u00a0\n\nResource: \"apps/v1, Resource=deployments\", GroupVersionKind: \"apps/v1, Kind=Deployment\"\nName: \"cns-website\", Namespace: \"app\"\nfor: \"deployment-two.yaml\": admission webhook \"mutate.kyverno.svc-fail\" denied the request: \n\nresource Deployment/app/cns-website was blocked due to the following policies\n\ncheck-image:\n  autogen-check-image: |\n    failed to verify signature for docker.io/anaisurlichs/cns-website:0.0.5: .attestors[0].entries[0].keys: no matching signatures:\n

    "},{"location":"tutorials/misconfiguration/custom-checks/","title":"Custom Checks with Rego","text":"

    Trivy can scan configuration files for common security issues (a.k.a IaC misconfiguration scanning). In addition to a comprehensive built in database of checks, you can add your own custom checks. Checks are written in Rego language and the full documentation for checks and customizing them is available here.

    This tutorial will walk you through writing a custom check in Rego that checks for an issue in a Dockerfile.

    When you are writing a check, it's important to understand the input to the check. This will be the IaC file that you are scanning; for example, a Kubernetes YAML resource definition, or an AWS JSON CloudFormation, or in our case a Dockerfile.

    Since Rego is primarily tailored to query JSON objects, all incoming configuration files needs to be first converted to structured objects, which is available to the Rego code as the input variable. This is nothing that users have to do manually in Trivy. Instead, Rego makes it possible to pass in custom Schemas that detail how files are converted. Once Rego has access to a custom Schema, it will know in which format to access configuration files such as a Dockerfile.

    Here you can find the schemas that define how different configuration files are converted to JSON by Trivy. This tutorial will make use of the dockerfile.json schema. The schema will need to be parsed into your custom check.

    Users can also use the Schema Explorer to view the structure of the data provided to Rego.

    "},{"location":"tutorials/misconfiguration/custom-checks/#create-a-rego-file-and-specify-trivy-metadata","title":"Create a Rego file and Specify Trivy metadata","text":"

    First, create a new .rego file e.g. a docker-check.rego file:

    touch docker-check.rego\n

    Next, we need to specify metadata about the check. This is information that helps Trivy load and process the check.

    # METADATA\n# title: Verify Image\n# description: Verify Image is allowed to be used and in the right format\n# schemas:\n#   - input: schema[\"dockerfile\"]\n# custom:\n#   id: ID001\n#   severity: MEDIUM\n#   input:\n#     selector: \n#     - type: dockerfile\n

    Important: The METADATA has to be defined on top of the file.

    More information on the different fields in the metadata can be found in the Trivy documentation.

    "},{"location":"tutorials/misconfiguration/custom-checks/#package-and-imports","title":"Package and imports","text":"
    package custom.dockerfile.ID001\n\nimport future.keywords.in\n

    Every rego check has a package name. In our case, we will call it custom.dockerfile.ID001 to avoid confusion between custom checks and built-in checks. The group name dockerfile has no effect on the package name. Note that each package has to contain only one check. However, we can pass multiple checks into our Trivy scan. The first keyword of the package, in this case custom, will be reused in the trivy command as the --namespace.

    "},{"location":"tutorials/misconfiguration/custom-checks/#allowed-data","title":"Allowed data","text":"

    The check that we are setting up compares the container images used in the Dockerfile with a list of white-listed container images. Thus, we need to add the images that are allowed to be used in the Dockerfile to our check. In our case, we will store them in an array of arrays:

    allowed_images :=  {\n    [\"node:21-alpine3.19\", \"as\", \"build-deps\"],\n    [\"nginx:1.2\"]\n}\n
    "},{"location":"tutorials/misconfiguration/custom-checks/#select-the-images-that-are-used-in-the-dockerfile","title":"Select the images that are used in the Dockerfile","text":"

    Next, we need to iterate over the different commands in our Dockerfile and identify the commands that provide the base container images:

    deny[msg] {\n    input.Stages[m].Commands[l].Cmd == \"from\"\n    val := input.Stages[m].Commands[l].Value\n    not val in allowed_images\n    msg := sprintf(\"The container image '%s' used in the Dockerfile is not allowed\", val)\n}\n

    Let's look at the check line by line:

    1. The rule should always be deny in the Trivy Rego checks
    2. input.Stages[m].Commands[l].Cmd input allows us to access the different commands in the Dockerfile. We need to access the commands that use \"FROM\". Every command will be converted to lowercase.
    3. val := input.Stages[m].Commands[l].Value accesses the value of the FROM command and stores it in val
    4. not val in allowed_images checks whether val is not part of our allowed images list; this part of the check relies on the import statement
    5. In case our check fails, the msg will be printed with the image name used in val

    Note that Rego

    • uses AND automatically to combine conditions in this check
    • automatically iterates through the array of commands in the Dockefile and allowed images
    "},{"location":"tutorials/misconfiguration/custom-checks/#run-the-check-in-a-trivy-misconfiguration-scan","title":"Run the check in a Trivy misconfiguration scan","text":"

    Ensure that you have Trivy installed and run the following command:

    trivy fs --scanners misconf --config-check ./docker-check.rego --namespaces custom ./Dockerfile\n

    Please replace:

    • ./docker-check.rego with the file path to your check
    • custom should be replaced with your package name if different
    • ./Dockerfile is the path to the Dockerfile that should be scanned

    Note: If you define custom packages, you have to specify the package prefix via --namespaces option. In our case, we called the custom package custom.

    "},{"location":"tutorials/misconfiguration/custom-checks/#resources","title":"Resources","text":"
    • Rego provides a long list of courses that can be useful in writing more complex checks
    • The Rego documentation provides detailed information on the different types, iterations etc.
    • Have a look at the built-in checks for Trivy for inspiration on how to write custom checks.
    "},{"location":"tutorials/misconfiguration/terraform/","title":"Scanning Terraform files with Trivy","text":"

    This tutorial is focused on ways Trivy can scan Terraform IaC configuration files.

    A video tutorial on Terraform Misconfiguration scans can be found on the Aqua Open Source YouTube account.

    A note to tfsec users We have been consolidating all of our scanning-related efforts in one place, and that is Trivy. You can read more on the decision in the tfsec discussions.

    "},{"location":"tutorials/misconfiguration/terraform/#trivy-config-command","title":"Trivy Config Command","text":"

    Terraform configuration scanning is available as part of the trivy config command. This command scans all configuration files for misconfiguration issues. You can find the details within misconfiguration scans in the Trivy documentation.

    Command structure:

    trivy config <any flags you want to use> <file or directory that you would like to scan> \n

    The trivy config command can scan Terraform configuration, CloudFormation, Dockerfile, Kubernetes manifests, and Helm Charts for misconfiguration. Trivy will compare the configuration found in the file with a set of best practices.

    • If the configuration is following best practices, the check will pass,
    • If the configuration does not define the resource of some configuration, Trivy will assume the default configuration for the resource creation is used. In this case, the check might fail.
    • If the configuration that has been defined does not follow best practices, the check will fail.
    "},{"location":"tutorials/misconfiguration/terraform/#prerequisites","title":"Prerequisites","text":"

    Install Trivy on your local machines. The documentation provides several different installation options. This tutorial will use this example Terraform tutorial for terraform misconfiguration scanning with Trivy.

    Git clone the tutorial and cd into the directory:

    git clone git@github.com:Cloud-Native-Security/trivy-demo.git\ncd bad_iac/terraform\n
    In this case, the folder only containes Terraform configuration files. However, you could scan a directory that contains several different configurations e.g. Kubernetes YAML manifests, Dockerfile, and Terraform. Trivy will then detect the different configuration files and apply the right rules automatically.

    "},{"location":"tutorials/misconfiguration/terraform/#different-types-of-trivy-config-scans","title":"Different types of trivy config scans","text":"

    Below are several examples of how the trivy config scan can be used.

    General Terraform scan with trivy:

    trivy config <specify the directory> \n

    So if we are already in the directory that we want to scan:

    trivy config ./ \n

    "},{"location":"tutorials/misconfiguration/terraform/#specify-the-scan-format","title":"Specify the scan format","text":"

    The --format flag changes the way that Trivy displays the scan result:

    JSON:

    trivy config -f json terraform-infra \n

    Sarif:

    trivy config -f sarif terraform-infra \n

    "},{"location":"tutorials/misconfiguration/terraform/#specifying-the-output-location","title":"Specifying the output location","text":"

    The --output flag specifies the file location in which the scan result should be saved:

    JSON:

    trivy config -f json -o example.json terraform-infra \n

    Sarif:

    trivy config -f sarif -o example.sarif terraform-infra \n

    "},{"location":"tutorials/misconfiguration/terraform/#filtering-by-severity","title":"Filtering by severity","text":"

    If you are presented with lots and lots of misconfiguration across different files, you might want to filter or the misconfiguration with the highest severity:

    trivy config --severity CRITICAL, MEDIUM terraform-infra \n
    "},{"location":"tutorials/misconfiguration/terraform/#passing-tftfvars-files-into-trivy-config-scans","title":"Passing tf.tfvars files into trivy config scans","text":"

    You can pass terraform values to Trivy to override default values found in the Terraform HCL code. More information are provided in the documentation.

    trivy config --tf-vars terraform.tfvars ./\n
    "},{"location":"tutorials/misconfiguration/terraform/#custom-checks","title":"Custom Checks","text":"

    We have lots of examples in the documentation on how you can write and pass custom Rego checks into terraform misconfiguration scans.

    "},{"location":"tutorials/misconfiguration/terraform/#secret-and-vulnerability-scans","title":"Secret and vulnerability scans","text":"

    The trivy config command does not perform secrete and vulnerability checks out of the box. However, you can specify as part of your trivy fs scan that you would like to scan you terraform files for exposed secrets and misconfiguraction through the following flags:

    trivy fs --scanners secret,misconfig ./\n

    The trivy config command is a sub-command of the trivy fs command. You can learn more about this command in the documentation.

    "},{"location":"tutorials/misconfiguration/terraform/#scanning-terraform-plan-files","title":"Scanning Terraform Plan files","text":"

    Instead of scanning your different Terraform resources individually, you could also scan your Terraform Plan file before it is deployed for misconfiguration. This will give you insights into any misconfiguration of your resources as they would become deployed. Here is the link to the documentation.

    Note that you need to be able to create a terraform init and plan without any errors.

    "},{"location":"tutorials/misconfiguration/terraform/#using-trivy-in-your-cicd-pipeline","title":"Using Trivy in your CI/CD pipeline","text":"

    Similar to tfsec, Trivy can be used either on local developer machines or integrated into your CI/CD pipeline. There are several steps available for different pipelines, including GitHub Actions, Circle CI, GitLab, Travis and more in the tutorials section of the documentation: https://aquasecurity.github.io/trivy/latest/tutorials/integrations/

    "},{"location":"tutorials/shell/shell-completion/","title":"Enable shell completion","text":"

    Below is example steps to enable shell completion feature for trivy cli:

    "},{"location":"tutorials/shell/shell-completion/#1-know-your-current-shell","title":"1. Know your current shell","text":"
    $ echo $SHELL\n/bin/zsh # For this example it is zsh, but will be vary depend on your $SHELL, maybe /bin/bash or /bin/fish\n
    "},{"location":"tutorials/shell/shell-completion/#2-run-completion-command-to-get-sub-commands","title":"2. Run completion command to get sub-commands","text":"
    $ trivy completion zsh -h\nGenerate the autocompletion script for the zsh shell.\n\nIf shell completion is not already enabled in your environment you will need\nto enable it.  You can execute the following once:\n\n    echo \"autoload -U compinit; compinit\" >> ~/.zshrc\n\nTo load completions in your current shell session:\n\n    source <(trivy completion zsh); compdef _trivy trivy\n\nTo load completions for every new session, execute once:\n\n#### Linux:\n\n    trivy completion zsh > \"${fpath[1]}/_trivy\"\n\n#### macOS:\n\n    trivy completion zsh > $(brew --prefix)/share/zsh/site-functions/_trivy\n\nYou will need to start a new shell for this setup to take effect.\n
    "},{"location":"tutorials/shell/shell-completion/#3-run-the-sub-commands-following-the-instruction","title":"3. Run the sub-commands following the instruction","text":"
    echo \"autoload -U compinit; compinit\" >> ~/.zshrc\nsource <(trivy completion zsh); compdef _trivy trivy\ntrivy completion zsh > \"${fpath[1]}/_trivy\"\n
    "},{"location":"tutorials/shell/shell-completion/#4-start-a-new-shell-and-you-can-see-the-shell-completion","title":"4. Start a new shell and you can see the shell completion","text":"
    $ trivy [tab]\ncompletion  -- Generate the autocompletion script for the specified shell\nconfig      -- Scan config files for misconfigurations\nfilesystem  -- Scan local filesystem\nhelp        -- Help about any command\nimage       -- Scan a container image\nkubernetes  -- scan kubernetes cluster\nmodule      -- Manage modules\nplugin      -- Manage plugins\nrepository  -- Scan a repository\nrootfs      -- Scan rootfs\nsbom        -- Scan SBOM for vulnerabilities\nserver      -- Server mode\nversion     -- Print the version\n
    "},{"location":"tutorials/signing/vuln-attestation/","title":"Vulnerability Scan Record Attestation","text":"

    This tutorial details how to

    • Scan container images for vulnerabilities
    • Generate an attestation, using Cosign, with and without generating a separate key pair
    "},{"location":"tutorials/signing/vuln-attestation/#prerequisites","title":"Prerequisites","text":"
    1. Trivy CLI installed
    2. Cosign CLI installed
    3. Ensure that you have access to a container image in a remote container registry that you own/within your account. In this tutorial, we will use DockerHub.
    "},{"location":"tutorials/signing/vuln-attestation/#scan-container-image-for-vulnerabilities","title":"Scan Container Image for vulnerabilities","text":"

    Scan your container image for vulnerabilities and save the scan result to a scan.json file:

    trivy image --ignore-unfixed --format cosign-vuln --output scan.json DockerHubID/imagename:imagetag\n

    For example:

    trivy image --ignore-unfixed --format cosign-vuln --output scan.json anaisurlichs/signed-example:0.1\n

    • --ignore-unfixed: Ensures only the vulnerabilities, which have a already a fix available, are displayed
    • --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal.

    Note: Replace the container image with the container image that you want to scan.

    "},{"location":"tutorials/signing/vuln-attestation/#option-1-signing-and-generating-an-attestation-without-new-key-pair","title":"Option 1: Signing and Generating an attestation without new key pair","text":""},{"location":"tutorials/signing/vuln-attestation/#signing","title":"Signing","text":"

    Sign the container image:

    cosign sign DockerHubID/imagename@imageSHA\n

    The imageSHA can be obtained through the following docker command:

    docker image ls --digests\n
    The SHA will be displayed next to the image name and tag.

    Note that it is better practice to sign the image SHA rather than the tag as the SHA will remain the same for the particular image that we have signed.

    For example:

    cosign sign docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\n

    "},{"location":"tutorials/signing/vuln-attestation/#attestation","title":"Attestation","text":"

    The following command generates an attestation for the vulnerability scan and uploads it to the container image used:

    cosign attest --predicate scan.json --type vuln docker.io/DockerHubID/imagename:imageSHA\n

    For example:

    cosign attest --predicate scan.json --type vuln docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\n

    Note: Replace the container image with the container image that you would like to scan.

    Next, Sigstore will ask you to verify with an account -- Microsoft, GitHub, or Google.

    Once done, the user will be provided with a certificate in the terminal where they ran the command. Example certificate:

    -----BEGIN CERTIFICATE-----\nMIIC1TCCAlygAwIBAgIUfSXI7xTWSLq4nuygd8YPuhPZlEswCgYIKoZIzj0EAwMw\nNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl\ncm1lZGlhdGUwHhcNMjQwMTExMTMzODUzWhcNMjQwMTExMTM0ODUzWjAAMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAETcUNnK76mfo9G3j1c7NN6Vcn6yQPDX5rd3QB\nunkHs1Uk59CWv3qm6sUyRNYaATs9zdHAZqLck8G4P/Pj7+GzCKOCAXswggF3MA4G\n........\n-----END CERTIFICATE-----\n

    "},{"location":"tutorials/signing/vuln-attestation/#option-2-signing-and-generating-an-attestation-with-a-new-cosign-key-pair","title":"Option 2: Signing and Generating an attestation with a new Cosign key pair","text":"

    To generate an attestation for the container image with a separate key pair, we can use Cosign to generate a new key pair:

    cosign generate-key-pair\u00a0\n

    This will generate a cosign.key and a cosign.pub file. The cosign.key file is your private key that should be kept confidential as it is used to sign artefacts. However, the cosign.pub file contains the information of the corresponding public key. This key can be used by third parties to verify the attestation -- basically that this person who claims to have signed the attestation actually is the one who signed it.

    "},{"location":"tutorials/signing/vuln-attestation/#signing_1","title":"Signing","text":"

    Sign the container image:

    cosign sign --key cosign.key docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\n

    "},{"location":"tutorials/signing/vuln-attestation/#attestation_1","title":"Attestation","text":"

    To generate the attestation with the specific key pairs, run the following command:

    cosign attest --key cosign.key --type vuln --predicate scan.json docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\u00a0\n

    "},{"location":"tutorials/signing/vuln-attestation/#verify-the-attestation","title":"Verify the attestation","text":""},{"location":"tutorials/signing/vuln-attestation/#option-1-no-separate-key-pair","title":"Option 1 -- No separate key pair","text":"

    If you have not generated a key pair but received a certificate after the container image was signed, use the following command to verify the attestation:

    cosign verify-attestation --type vuln --certificate-identity Email-used-to-sign  --certificate-oidc-issuer='the-issuer-used' docker.io/DockerHubID/imagename:imageSHA\n

    For example, the command could be like this:

    cosign verify-attestation --type vuln --certificate-identity urlichsanais@gmail.com  --certificate-oidc-issuer='https://github.com/login/oauth' anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\n

    "},{"location":"tutorials/signing/vuln-attestation/#option-2-separate-key-pair","title":"Option 2 -- Separate key pair","text":"

    If you have used a new cosign key pair, the attestation can be verified through the following command:

    cosign verify-attestation --key cosign.pub --type vuln anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd\u00a0\n

    Output The output should look similar to the following:
    Verification for anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd --\nThe following checks were performed on each of these signatures:\n  - The cosign claims were validated\n  - Existence of the claims in the transparency log was verified offline\n  - The signatures were verified against the specified public key\n{\"payloadType\":\"application/vnd.in-toto+json\",\"payload\":\n
    "},{"location":"tutorials/signing/vuln-attestation/#more-information","title":"More information","text":"

    See here for more details.

    "}]} \ No newline at end of file diff --git a/v0.58.0/sitemap.xml b/v0.58.0/sitemap.xml deleted file mode 100644 index 298969ccbf81..000000000000 --- a/v0.58.0/sitemap.xml +++ /dev/null @@ -1,703 +0,0 @@ - - - - https://aquasecurity.github.io/trivy/v0.58.0/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/commercial/compare/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/commercial/contact/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/principles/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/contribute/discussion/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/contribute/issue/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/contribute/pr/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/contribute/checks/overview/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/contribute/checks/service-support/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/maintainer/backporting/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/maintainer/help-wanted/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/maintainer/release-flow/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/community/maintainer/triage/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/air-gap/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/modules/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/self-hosting/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/container/embed-in-dockerfile/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/container/unpacked-filesystem/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/private-registries/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/private-registries/acr/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/private-registries/docker-hub/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/private-registries/ecr/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/private-registries/gcr/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/advanced/private-registries/self/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/compliance/compliance/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/compliance/contrib-compliance/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/cache/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/db/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/filtering/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/others/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/reporting/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/configuration/skipping/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/kubernetes/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/azure-arm/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/cloudformation/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/docker/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/helm/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/kubernetes/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/iac/terraform/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/c/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/dart/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/dotnet/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/elixir/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/golang/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/java/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/julia/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/nodejs/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/php/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/python/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/ruby/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/rust/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/language/swift/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/alma/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/alpine/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/amazon/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/azure/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/centos/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/chainguard/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/debian/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/google-distroless/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/oracle/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/photon/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/rhel/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/rocky/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/suse/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/ubuntu/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/os/wolfi/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/others/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/others/bitnami/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/others/conda/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/coverage/others/rpm/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/plugin/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/plugin/developer-guide/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/plugin/user-guide/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/terminology/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/troubleshooting/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/config-file/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_clean/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_config/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_convert/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_filesystem/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_image/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_kubernetes/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_module/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_module_install/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_module_uninstall/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_info/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_install/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_list/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_run/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_search/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_uninstall/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_update/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_plugin_upgrade/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_registry/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_registry_login/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_registry_logout/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_repository/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_rootfs/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_sbom/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_server/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_version/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_vex/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_vex_repo/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_download/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_init/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_vex_repo_list/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/configuration/cli/trivy_vm/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/modes/client-server/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/references/modes/standalone/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/license/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/secret/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/vulnerability/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/check/builtin/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/combine/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/contribute-checks/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/data/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/debug/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/schema/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/selectors/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/scanner/misconfiguration/custom/testing/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/sbom/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/attestation/rekor/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/attestation/sbom/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/attestation/vuln/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/vex/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/vex/file/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/vex/oci/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/supply-chain/vex/repo/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/container_image/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/filesystem/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/kubernetes/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/repository/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/rootfs/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/sbom/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/docs/target/vm/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/ecosystem/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/ecosystem/cicd/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/ecosystem/ide/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/ecosystem/prod/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/ecosystem/reporting/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/getting-started/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/getting-started/faq/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/getting-started/installation/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/getting-started/signature-verification/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/overview/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/additional-resources/cks/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/additional-resources/community/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/additional-resources/references/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/aws-codepipeline/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/aws-security-hub/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/azure-devops/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/bitbucket/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/circleci/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/github-actions/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/gitlab-ci/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/integrations/travis-ci/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/kubernetes/cluster-scanning/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/kubernetes/gitops/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/kubernetes/kyverno/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/misconfiguration/custom-checks/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/misconfiguration/terraform/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/shell/shell-completion/ - 2024-12-03 - - - https://aquasecurity.github.io/trivy/v0.58.0/tutorials/signing/vuln-attestation/ - 2024-12-03 - - \ No newline at end of file diff --git a/v0.58.0/sitemap.xml.gz b/v0.58.0/sitemap.xml.gz deleted file mode 100644 index b9f6fbf1d988..000000000000 Binary files a/v0.58.0/sitemap.xml.gz and /dev/null differ diff --git a/v0.58.0/tutorials/additional-resources/cks/index.html b/v0.58.0/tutorials/additional-resources/cks/index.html deleted file mode 100644 index 3dd106ba801a..000000000000 --- a/v0.58.0/tutorials/additional-resources/cks/index.html +++ /dev/null @@ -1,7870 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CKS Reference - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    CKS preparation resources

    -

    The Certified Kubernetes Security Specialist (CKS) Exam is offered by The Linux Foundation. It provides assurance that a CKS has the skills, knowledge, and competence on a broad range of best practices for securing container-based applications and Kubernetes platforms during build, deployment and runtime. CKA certification is required to sit for this exam.

    -

    Community Resources

    - -

    Aqua Security Blog posts to learn more

    - -

    If you know of interesting resources, please start a PR to add those to the list.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/additional-resources/community/index.html b/v0.58.0/tutorials/additional-resources/community/index.html deleted file mode 100644 index 28709a4cdf65..000000000000 --- a/v0.58.0/tutorials/additional-resources/community/index.html +++ /dev/null @@ -1,8014 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Community References - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - - - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/additional-resources/references/index.html b/v0.58.0/tutorials/additional-resources/references/index.html deleted file mode 100644 index af01bc2ac4b7..000000000000 --- a/v0.58.0/tutorials/additional-resources/references/index.html +++ /dev/null @@ -1,8001 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Additional Resources - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - - - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/aws-codepipeline/index.html b/v0.58.0/tutorials/integrations/aws-codepipeline/index.html deleted file mode 100644 index 5345fbc6f5d3..000000000000 --- a/v0.58.0/tutorials/integrations/aws-codepipeline/index.html +++ /dev/null @@ -1,7768 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AWS CodePipeline - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    AWS CodePipeline

    -

    See this blog post for an example of using Trivy within AWS CodePipeline.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/aws-security-hub/index.html b/v0.58.0/tutorials/integrations/aws-security-hub/index.html deleted file mode 100644 index d9d302f138a7..000000000000 --- a/v0.58.0/tutorials/integrations/aws-security-hub/index.html +++ /dev/null @@ -1,7944 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AWS Security Hub - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    AWS Security Hub

    -

    Amazon Security Hub

    -

    Upload findings to Security Hub

    -

    In the following example using the template asff.tpl, ASFF file can be generated.

    -
    $ AWS_REGION=us-west-1 AWS_ACCOUNT_ID=123456789012 trivy image --format template --template "@contrib/asff.tpl" -o report.asff golang:1.12-alpine
    -
    -

    ASFF template needs AWS_REGION and AWS_ACCOUNT_ID from environment variables.

    -

    The Product ARN field follows the pattern below to match what AWS requires for the product resource type.

    -
    "ProductArn": "arn:aws:securityhub:{{ env "AWS_REGION" }}::product/aquasecurity/aquasecurity",
    -
    -

    In order to upload results you must first run enable-import-findings-for-product like:

    -
    aws securityhub enable-import-findings-for-product --product-arn arn:aws:securityhub:<AWS_REGION>::product/aquasecurity/aquasecurity
    -
    -

    The findings are formatted for the API with a key of Findings and a value of the array of findings. -In order to upload via the CLI the outer wrapping must be removed being left with only the array of findings. -The easiest way of doing this is with the jq library using the command

    -
    cat report.asff | jq '.Findings'
    -
    -

    Then, you can upload it with AWS CLI.

    -
    $ aws securityhub batch-import-findings --findings file://report.asff
    -
    -

    Note

    -

    The batch-import-findings command limits the number of findings uploaded to 100 per request. -The best known workaround to this problem is using jq to run the following command

    -
    jq '.[:100]' report.asff 1> short_report.asff
    -
    -

    Customize

    -

    You can customize asff.tpl

    -
    $ export AWS_REGION=us-west-1
    -$ export AWS_ACCOUNT_ID=123456789012
    -$ trivy image --format template --template "@your-asff.tpl" -o report.asff golang:1.12-alpine
    -
    -

    Reference

    -

    aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/azure-devops/index.html b/v0.58.0/tutorials/integrations/azure-devops/index.html deleted file mode 100644 index 47bd9da2ee43..000000000000 --- a/v0.58.0/tutorials/integrations/azure-devops/index.html +++ /dev/null @@ -1,7866 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Azure - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Azure Devops

    - -

    trivy-azure

    -

    Use ImageCleaner to clean up stale images on your Azure Kubernetes Service cluster

    -

    It's common to use pipelines to build and deploy images on Azure Kubernetes Service (AKS) clusters. While great for image creation, this process often doesn't account for the stale images left behind and can lead to image bloat on cluster nodes. These images can present security issues as they may contain vulnerabilities. By cleaning these unreferenced images, you can remove an area of risk in your clusters. When done manually, this process can be time intensive, which ImageCleaner can mitigate via automatic image identification and removal.

    -

    Vulnerability is determined based on a trivy scan, after which images with a LOW, MEDIUM, HIGH, or CRITICAL classification are flagged. An updated ImageList will be automatically generated by ImageCleaner based on a set time interval, and can also be supplied manually.

    -

    Microsoft Defender for container registries and Trivy

    -

    This blog explains how to scan your Azure Container Registry-based container images with the integrated vulnerability scanner when they're built as part of your GitHub workflows.

    -

    To set up the scanner, you'll need to enable Microsoft Defender for Containers and the CI/CD integration. When your CI/CD workflows push images to your registries, you can view registry scan results and a summary of CI/CD scan results.

    -

    The findings of the CI/CD scans are an enrichment to the existing registry scan findings by Qualys. Defender for Cloud's CI/CD scanning is powered by Aqua Trivy

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/bitbucket/index.html b/v0.58.0/tutorials/integrations/bitbucket/index.html deleted file mode 100644 index f1011b1cf557..000000000000 --- a/v0.58.0/tutorials/integrations/bitbucket/index.html +++ /dev/null @@ -1,7768 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Bitbucket Pipelines - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Bitbucket Pipelines

    -

    See trivy-pipe for the details.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/circleci/index.html b/v0.58.0/tutorials/integrations/circleci/index.html deleted file mode 100644 index 1c60d5d24921..000000000000 --- a/v0.58.0/tutorials/integrations/circleci/index.html +++ /dev/null @@ -1,7794 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CircleCI - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    CircleCI

    -
    $ cat .circleci/config.yml
    -jobs:
    -  build:
    -    docker:
    -      - image: docker:stable-git
    -    steps:
    -      - checkout
    -      - setup_remote_docker
    -      - run:
    -          name: Build image
    -          command: docker build -t trivy-ci-test:${CIRCLE_SHA1} .
    -      - run:
    -          name: Install trivy
    -          command: |
    -            apk add --update-cache --upgrade curl
    -            curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
    -      - run:
    -          name: Scan the local image with trivy
    -          command: trivy image --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1}
    -workflows:
    -  version: 2
    -  release:
    -    jobs:
    -      - build
    -
    -

    Example -Repository

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/github-actions/index.html b/v0.58.0/tutorials/integrations/github-actions/index.html deleted file mode 100644 index b67cf6f2791c..000000000000 --- a/v0.58.0/tutorials/integrations/github-actions/index.html +++ /dev/null @@ -1,7772 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GitHub Actions - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    GitHub Actions

    -
      -
    • Here is the Trivy GitHub Action
    • -
    • The Microsoft Azure team have written a container-scan action that uses Trivy and Dockle
    • -
    • For full control over the options specified to Trivy, this blog post describes adding Trivy into your own GitHub action workflows
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/gitlab-ci/index.html b/v0.58.0/tutorials/integrations/gitlab-ci/index.html deleted file mode 100644 index 2ac34d47e29a..000000000000 --- a/v0.58.0/tutorials/integrations/gitlab-ci/index.html +++ /dev/null @@ -1,8031 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GitLab CI - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    GitLab CI

    -

    GitLab 15.0 includes free integration with Trivy.

    -

    To configure container scanning with Trivy in GitLab, simply include the CI template in your .gitlab-ci.yml file:

    -
    include:
    -  - template: Security/Container-Scanning.gitlab-ci.yml
    -
    -

    If you're a GitLab 14.x Ultimate customer, you can use the same configuration above.

    -

    Alternatively, you can always use the example configurations below.

    -
    stages:
    -  - test
    -
    -trivy:
    -  stage: test
    -  image: docker:stable
    -  services:
    -    - name: docker:dind
    -      entrypoint: ["env", "-u", "DOCKER_HOST"]
    -      command: ["dockerd-entrypoint.sh"]
    -  variables:
    -    DOCKER_HOST: tcp://docker:2375/
    -    DOCKER_DRIVER: overlay2
    -    # See https://github.com/docker-library/docker/pull/166
    -    DOCKER_TLS_CERTDIR: ""
    -    IMAGE: trivy-ci-test:$CI_COMMIT_SHA
    -    TRIVY_NO_PROGRESS: "true"
    -    TRIVY_CACHE_DIR: ".trivycache/"
    -  before_script:
    -    - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    -    - echo $TRIVY_VERSION
    -    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
    -  allow_failure: true
    -  script:
    -    # Build image
    -    - docker build -t $IMAGE .
    -    # Build report
    -    - ./trivy image --exit-code 0 --format template --template "@/contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
    -    # Print report
    -    - ./trivy image --exit-code 0 --severity HIGH $IMAGE
    -    # Fail on severe vulnerabilities
    -    - ./trivy image --exit-code 1 --severity CRITICAL $IMAGE
    -  cache:
    -    paths:
    -      - .trivycache/
    -  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab Ultimate)
    -  artifacts:
    -    reports:
    -      container_scanning: gl-container-scanning-report.json
    -
    -

    Example -Repository

    -

    GitLab CI using Trivy container

    -

    To scan a previously built image that has already been pushed into the -GitLab container registry the following CI job manifest can be used. -Note that entrypoint needs to be unset for the script section to work. -In case of a non-public GitLab project Trivy additionally needs to -authenticate to the registry to be able to pull your application image. -Finally, it is not necessary to clone the project repo as we only work -with the container image.

    -
    container_scanning:
    -  image:
    -    name: docker.io/aquasec/trivy:latest
    -    entrypoint: [""]
    -  variables:
    -    # No need to clone the repo, we exclusively work on artifacts. See
    -    # https://docs.gitlab.com/ee/ci/runners/configure_runners.html#git-strategy
    -    GIT_STRATEGY: none
    -    TRIVY_USERNAME: "$CI_REGISTRY_USER"
    -    TRIVY_PASSWORD: "$CI_REGISTRY_PASSWORD"
    -    TRIVY_AUTH_URL: "$CI_REGISTRY"
    -    TRIVY_NO_PROGRESS: "true"
    -    TRIVY_CACHE_DIR: ".trivycache/"
    -    FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
    -  script:
    -    - trivy --version
    -    # update vulnerabilities db
    -    - time trivy image --download-db-only
    -    # Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
    -    - time trivy image --exit-code 0 --format template --template "@/contrib/gitlab.tpl"
    -        --output "$CI_PROJECT_DIR/gl-container-scanning-report.json" "$FULL_IMAGE_NAME"
    -    # Prints full report
    -    - time trivy image --exit-code 0 "$FULL_IMAGE_NAME"
    -    # Fail on critical vulnerabilities
    -    - time trivy image --exit-code 1 --severity CRITICAL "$FULL_IMAGE_NAME"
    -  cache:
    -    paths:
    -      - .trivycache/
    -  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
    -  artifacts:
    -    when:                          always
    -    reports:
    -      container_scanning:          gl-container-scanning-report.json
    -  tags:
    -    - docker-runner
    -
    -

    GitLab CI alternative template

    -

    Depending on the edition of gitlab you have or your desired workflow, the -container scanning template may not meet your needs. As an addition to the -above container scanning template, a template for -code climate -has been included. The key things to update from the above examples are -the template and report type. An updated example is below.

    -
    stages:
    -  - test
    -
    -trivy:
    -  stage: test
    -  image: docker:stable
    -  services:
    -    - name: docker:dind
    -      entrypoint: ["env", "-u", "DOCKER_HOST"]
    -      command: ["dockerd-entrypoint.sh"]
    -  variables:
    -    DOCKER_HOST: tcp://docker:2375/
    -    DOCKER_DRIVER: overlay2
    -    # See https://github.com/docker-library/docker/pull/166
    -    DOCKER_TLS_CERTDIR: ""
    -    IMAGE: trivy-ci-test:$CI_COMMIT_SHA
    -    TRIVY_NO_PROGRESS: "true"
    -    TRIVY_CACHE_DIR: ".trivycache/"
    -  before_script:
    -    - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    -    - echo $TRIVY_VERSION
    -    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
    -  allow_failure: true
    -  script:
    -    # Build image
    -    - docker build -t $IMAGE .
    -    # Image report
    -    - ./trivy image --exit-code 0 --format template --template "@/contrib/gitlab-codequality.tpl" -o gl-codeclimate-image.json $IMAGE
    -    # Filesystem report
    -    - ./trivy filesystem --scanners misconfig,vuln --exit-code 0 --format template --template "@/contrib/gitlab-codequality.tpl" -o gl-codeclimate-fs.json .
    -    # Combine report
    -    - apk update && apk add jq
    -    - jq -s 'add' gl-codeclimate-image.json gl-codeclimate-fs.json > gl-codeclimate.json
    -  cache:
    -    paths:
    -      - .trivycache/
    -  # Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
    -  artifacts:
    -    paths:
    -      - gl-codeclimate.json
    -    reports:
    -      codequality: gl-codeclimate.json
    -
    -

    Currently gitlab only supports a single code quality report. There is an -open feature request -to support multiple reports. Until this has been implemented, if you -already have a code quality report in your pipeline, you can use -jq to combine reports. Depending on how you name your artifacts, it may -be necessary to rename the artifact if you want to reuse the name. To then -combine the previous artifact with the output of trivy, the following jq -command can be used, jq -s 'add' prev-codeclimate.json trivy-codeclimate.json > gl-codeclimate.json.

    -

    GitLab CI alternative template example report

    -

    You'll be able to see a full report in the GitLab pipeline code quality UI, where filesystem vulnerabilities and misconfigurations include links to the flagged files and image vulnerabilities report the image/os or runtime/library that the vulnerability originates from instead.

    -

    codequality

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/index.html b/v0.58.0/tutorials/integrations/index.html deleted file mode 100644 index 563dc08db3d9..000000000000 --- a/v0.58.0/tutorials/integrations/index.html +++ /dev/null @@ -1,7768 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Integrations

    -

    Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify --exit-code 0.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/integrations/travis-ci/index.html b/v0.58.0/tutorials/integrations/travis-ci/index.html deleted file mode 100644 index 235789b6c351..000000000000 --- a/v0.58.0/tutorials/integrations/travis-ci/index.html +++ /dev/null @@ -1,7789 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Travis CI - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Travis CI

    -
    $ cat .travis.yml
    -services:
    -  - docker
    -
    -env:
    -  global:
    -    - COMMIT=${TRAVIS_COMMIT::8}
    -
    -before_install:
    -  - docker build -t trivy-ci-test:${COMMIT} .
    -  - export VERSION=$(curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    -  - wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
    -  - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
    -script:
    -  - ./trivy image --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT}
    -  - ./trivy image --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT}
    -cache:
    -  directories:
    -    - $HOME/.cache/trivy
    -
    -

    Example -Repository

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/kubernetes/cluster-scanning/index.html b/v0.58.0/tutorials/kubernetes/cluster-scanning/index.html deleted file mode 100644 index c284579d826e..000000000000 --- a/v0.58.0/tutorials/kubernetes/cluster-scanning/index.html +++ /dev/null @@ -1,7921 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cluster Scanning - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Kubernetes Scanning Tutorial

    -

    Prerequisites

    -

    To test the following commands yourself, make sure that you’re connected to a Kubernetes cluster. A simple kind, a Docker-Desktop or microk8s cluster will do. In our case, we’ll use a one-node kind cluster.
    -Pro tip: The output of the commands will be even more interesting if you have some workloads running in your cluster.

    -

    Cluster Scanning

    -

    Trivy K8s is great to get an overview of all the vulnerabilities and misconfiguration issues or to scan specific workloads that are running in your cluster. You would want to use the Trivy K8s command either on your own local cluster or in your CI/CD pipeline post deployments.

    -

    The trivy k8s command is part of the Trivy CLI.

    -

    With the following command, we can scan our entire Kubernetes cluster for vulnerabilities and get a summary of the scan:

    -
    trivy k8s --report=summary
    -
    -

    To get detailed information for all your resources, just replace ‘summary’ with ‘all’:

    -
    trivy k8s --report=all
    -
    -

    However, we recommend displaying all information only in case you scan a specific namespace or resource since you can get overwhelmed with additional details.

    -

    Furthermore, we can specify the namespace that Trivy is supposed to scan to focus on specific resources in the scan result:

    -
    trivy k8s --include-namespaces kube-system --report summary
    -
    -

    Again, if you’d like to receive additional details, use the ‘--report=all’ flag:

    -
    trivy k8s --include-namespaces kube-system --report all
    -
    -

    Like with scanning for vulnerabilities, we can also filter in-cluster security issues by severity of the vulnerabilities:

    -
    trivy k8s --severity=CRITICAL --report=summary
    -
    -

    Note that you can use any of the Trivy flags on the Trivy K8s command.

    -

    Trivy Operator

    -

    The Trivy K8s command is an imperative model to scan resources. We wouldn’t want to manually scan each resource across different environments. The larger the cluster and the more workloads are running in it, the more error-prone this process would become. With the Trivy Operator, we can automate the scanning process after the deployment.

    -

    The Trivy Operator follows the Kubernetes Operator Model. Operators automate human actions, and the result of the task is saved as custom resource definitions (CRDs) within your cluster.

    -

    This has several benefits:

    -
      -
    • -

      Trivy Operator is installed CRDs in our cluster. As a result, all our resources, including our security scanner and its scan results, are Kubernetes resources. This makes it much easier to integrate the Trivy Operator directly into our existing processes, such as connecting Trivy with Prometheus, a monitoring system.

      -
    • -
    • -

      The Trivy Operator will automatically scan your resources every six hours. You can set up automatic alerting in case new critical security issues are discovered.

      -
    • -
    • -

      The CRDs can be both machine and human-readable depending on which applications consume the CRDs. This allows for more versatile applications of the Trivy operator.

      -
    • -
    -

    There are several ways that you can install the Trivy Operator in your cluster. In this guide, we’re going to use the Helm installation.

    -

    Please follow the Trivy Operator documentation for further information on:

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/kubernetes/gitops/index.html b/v0.58.0/tutorials/kubernetes/gitops/index.html deleted file mode 100644 index 0d0e13a268cc..000000000000 --- a/v0.58.0/tutorials/kubernetes/gitops/index.html +++ /dev/null @@ -1,7976 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GitOps - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Installing the Trivy-Operator through GitOps

    -

    This tutorial shows you how to install the Trivy Operator through GitOps platforms, namely ArgoCD and FluxCD.

    -

    ArgoCD

    -

    Make sure to have ArgoCD installed and running in your Kubernetes cluster.

    -

    You can either deploy the Trivy Operator through the argocd CLI or by applying a Kubernetes manifest.

    -

    ArgoCD command: -

    > kubectl create ns trivy-system
    -> argocd app create trivy-operator --repo https://github.com/aquasecurity/trivy-operator --path deploy/helm --dest-server https://kubernetes.default.svc --dest-namespace trivy-system
    -
    -Note that this installation is directly related to our official Helm Chart. If you want to change any of the value, we'd suggest you to create a separate values.yaml file.

    -

    Kubernetes manifest trivy-operator.yaml: -

    apiVersion: argoproj.io/v1alpha1
    -kind: Application
    -metadata:
    -  name: trivy-operator
    -  namespace: argocd
    -spec:
    -  project: default
    -  source:
    -    chart: trivy-operator
    -    repoURL: https://aquasecurity.github.io/helm-charts/
    -    targetRevision: 0.0.3
    -    helm:
    -      values: |
    -        trivy:
    -          ignoreUnfixed: true
    -  destination:
    -    server: https://kubernetes.default.svc
    -    namespace: trivy-system
    -  syncPolicy:
    -    automated:
    -      prune: true
    -      selfHeal: true
    -

    -

    To apply the Kubernetes manifest, if you have the manifest locally, you can use the following command through kubectl: -

    > kubectl apply -f trivy-operator.yaml
    -
    -application.argoproj.io/trivy-operator created
    -

    -

    If you have the manifest in a Git repository, you can apply it to your cluster through the following command: -

    > kubectl apply -n argocd -f https://raw.githubusercontent.com/AnaisUrlichs/argocd-starboard/main/starboard/argocd-starboard.yaml
    -
    -The latter command would allow you to make changes to the YAML manifest that ArgoCD would register automatically.

    -

    Once deployed, you want to tell ArgoCD to sync the application from the actual state to the desired state: -

    argocd app sync trivy-operator
    -

    -

    Now you can see the deployment in the ArgoCD UI. Have a look at the ArgoCD documentation to know how to access the UI.

    -

    ArgoCD UI after deploying the Trivy Operator

    -

    Note that ArgoCD is unable to show the Trivy CRDs as synced.

    -

    FluxCD

    -

    Make sure to have FluxCD installed and running in your Kubernetes cluster.

    -

    You can either deploy the Trivy Operator through the Flux CLI or by applying a Kubernetes manifest.

    -

    Flux command: -

    > kubectl create ns trivy-system
    -> flux create source helm trivy-operator --url https://aquasecurity.github.io/helm-charts --namespace trivy-system
    -> flux create helmrelease trivy-operator --chart trivy-operator
    -  --source HelmRepository/trivy-operator
    -  --chart-version 0.0.3
    -  --namespace trivy-system
    -

    -

    Kubernetes manifest trivy-operator.yaml: -

    apiVersion: source.toolkit.fluxcd.io/v1beta2
    -kind: HelmRepository
    -metadata:
    -  name: trivy-operator
    -  namespace: flux-system
    -spec:
    -  interval: 60m
    -  url: https://aquasecurity.github.io/helm-charts/
    -
    ----
    -apiVersion: helm.toolkit.fluxcd.io/v2beta1
    -kind: HelmRelease
    -metadata:
    -  name: trivy-operator
    -  namespace: trivy-system
    -spec:
    -  chart:
    -    spec:
    -      chart: trivy-operator
    -      sourceRef:
    -        kind: HelmRepository
    -        name: trivy-operator
    -        namespace: flux-system
    -      version: 0.10.1
    -  interval: 60m
    -  values:
    -    trivy:
    -      ignoreUnfixed: true
    -  install:
    -    crds: CreateReplace
    -    createNamespace: true
    -

    -

    You can then apply the file to your Kubernetes cluster: -

    kubectl apply -f trivy-operator.yaml
    -

    -

    After the installation

    -

    After the install, you want to check that the Trivy operator is running in the trivy-system namespace: -

    kubectl get deployment -n trivy-system
    -

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/kubernetes/kyverno/index.html b/v0.58.0/tutorials/kubernetes/kyverno/index.html deleted file mode 100644 index 868c9934c555..000000000000 --- a/v0.58.0/tutorials/kubernetes/kyverno/index.html +++ /dev/null @@ -1,7953 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kyverno - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    - -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Attesting Image Scans With Kyverno

    -

    This tutorial is based on the following blog post by Chip Zoller: Attesting Image Scans With Kyverno

    -

    This tutorial details

    -
      -
    • Verify the container image has an attestation with Kyverno
    • -
    -

    Prerequisites

    -
      -
    1. A running Kubernetes cluster that kubectl is connected to
    2. -
    3. A Container image signed with Cosign and an attestation generated for a Trivy Vulnerability scan. - Follow this tutorial for more information.
    4. -
    -

    Kyverno Policy to check attestation

    -

    The following policy ensures that the attestation is no older than 168h:

    -

    vuln-attestation.yaml

    -
    apiVersion: kyverno.io/v1
    -kind: ClusterPolicy
    -metadata:
    -  name: check-vulnerabilities
    -spec:
    -  validationFailureAction: Enforce
    -  background: false
    -  webhookTimeoutSeconds: 30
    -  failurePolicy: Fail
    -  rules:
    -    - name: checking-vulnerability-scan-not-older-than-one-hour
    -      match:
    -        any:
    -        - resources:
    -            kinds:
    -              - Pod
    -      verifyImages:
    -      - imageReferences:
    -        - "*"
    -        attestations:
    -        - type: https://cosign.sigstore.dev/attestation/vuln/v1
    -          conditions:
    -          - all:
    -            - key: "{{ time_since('','{{ metadata.scanFinishedOn }}', '') }}"
    -              operator: LessThanOrEquals
    -              value: "1h"
    -          attestors:
    -          - count: 1
    -            entries:
    -            - keys:
    -                publicKeys: |-
    -                  -----BEGIN PUBLIC KEY-----
    -                  abc
    -                  xyz
    -                  -----END PUBLIC KEY-----
    -
    -

    Apply the policy to your Kubernetes cluster

    -

    Ensure that you have Kyverno already deployed and running on your cluster -- for instance through he Kyverno Helm Chart.

    -

    Next, apply the above policy: -

    kubectl apply -f vuln-attestation.yaml
    -

    -

    To ensure that the policy worked, we can deploy an example Kubernetes Pod with our container image:

    -

    kubectl run app-signed --image= docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd 
    -
    -Note that the image is based on the signing tutorial.

    -

    Once we apply the deployment, it should pass since our attestation is available: -

    kubectl apply -f deployment.yaml -n app
    -deployment.apps/cns-website created
    -

    -

    However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with docker.io/anaisurlichs/cns-website:0.0.5 and applying the deployment: -

    kubectl run app-unsigned --image=docker.io/anaisurlichs/cns-website:0.1.1 
    -
    -Resource: "apps/v1, Resource=deployments", GroupVersionKind: "apps/v1, Kind=Deployment"
    -Name: "cns-website", Namespace: "app"
    -for: "deployment-two.yaml": admission webhook "mutate.kyverno.svc-fail" denied the request: 
    -
    -resource Deployment/app/cns-website was blocked due to the following policies
    -
    -check-image:
    -  autogen-check-image: |
    -    failed to verify signature for docker.io/anaisurlichs/cns-website:0.0.5: .attestors[0].entries[0].keys: no matching signatures:
    -

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/misconfiguration/custom-checks/index.html b/v0.58.0/tutorials/misconfiguration/custom-checks/index.html deleted file mode 100644 index 280df7147272..000000000000 --- a/v0.58.0/tutorials/misconfiguration/custom-checks/index.html +++ /dev/null @@ -1,8022 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Custom Checks with Rego - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Custom Checks with Rego

    -

    Trivy can scan configuration files for common security issues (a.k.a IaC misconfiguration scanning). In addition to a comprehensive built in database of checks, you can add your own custom checks. Checks are written in Rego language and the full documentation for checks and customizing them is available here.

    -

    This tutorial will walk you through writing a custom check in Rego that checks for an issue in a Dockerfile.

    -

    When you are writing a check, it's important to understand the input to the check. This will be the IaC file that you are scanning; for example, a Kubernetes YAML resource definition, or an AWS JSON CloudFormation, or in our case a Dockerfile.

    -

    Since Rego is primarily tailored to query JSON objects, all incoming configuration files needs to be first converted to structured objects, which is available to the Rego code as the input variable. This is nothing that users have to do manually in Trivy. Instead, Rego makes it possible to pass in custom Schemas that detail how files are converted. Once Rego has access to a custom Schema, it will know in which format to access configuration files such as a Dockerfile.

    -

    Here you can find the schemas that define how different configuration files are converted to JSON by Trivy. -This tutorial will make use of the dockerfile.json schema. The schema will need to be parsed into your custom check.

    -

    Users can also use the Schema Explorer to view the structure of the data provided to Rego.

    -

    Create a Rego file and Specify Trivy metadata

    -

    First, create a new .rego file e.g. a docker-check.rego file: -

    touch docker-check.rego
    -

    -

    Next, we need to specify metadata about the check. This is information that helps Trivy load and process the check.

    -
    # METADATA
    -# title: Verify Image
    -# description: Verify Image is allowed to be used and in the right format
    -# schemas:
    -#   - input: schema["dockerfile"]
    -# custom:
    -#   id: ID001
    -#   severity: MEDIUM
    -#   input:
    -#     selector: 
    -#     - type: dockerfile
    -
    -

    Important: The METADATA has to be defined on top of the file.

    -

    More information on the different fields in the metadata can be found in the Trivy documentation.

    -

    Package and imports

    -
    package custom.dockerfile.ID001
    -
    -import future.keywords.in
    -
    -

    Every rego check has a package name. In our case, we will call it custom.dockerfile.ID001 to avoid confusion between custom checks and built-in checks. The group name dockerfile has no effect on the package name. Note that each package has to contain only one check. However, we can pass multiple checks into our Trivy scan. -The first keyword of the package, in this case custom, will be reused in the trivy command as the --namespace.

    -

    Allowed data

    -

    The check that we are setting up compares the container images used in the Dockerfile with a list of white-listed container images. Thus, we need to add the images that are allowed to be used in the Dockerfile to our check. In our case, we will store them in an array of arrays:

    -
    allowed_images :=  {
    -    ["node:21-alpine3.19", "as", "build-deps"],
    -    ["nginx:1.2"]
    -}
    -
    -

    Select the images that are used in the Dockerfile

    -

    Next, we need to iterate over the different commands in our Dockerfile and identify the commands that provide the base container images:

    -
    deny[msg] {
    -    input.Stages[m].Commands[l].Cmd == "from"
    -    val := input.Stages[m].Commands[l].Value
    -    not val in allowed_images
    -    msg := sprintf("The container image '%s' used in the Dockerfile is not allowed", val)
    -}
    -
    -

    Let's look at the check line by line:

    -
      -
    1. The rule should always be deny in the Trivy Rego checks
    2. -
    3. input.Stages[m].Commands[l].Cmd input allows us to access the different commands in the Dockerfile. We need to access the commands that use "FROM". Every command will be converted to lowercase.
    4. -
    5. val := input.Stages[m].Commands[l].Value accesses the value of the FROM command and stores it in val
    6. -
    7. not val in allowed_images checks whether val is not part of our allowed images list; this part of the check relies on the import statement
    8. -
    9. In case our check fails, the msg will be printed with the image name used in val
    10. -
    -

    Note that Rego

    -
      -
    • uses AND automatically to combine conditions in this check
    • -
    • automatically iterates through the array of commands in the Dockefile and allowed images
    • -
    -

    Run the check in a Trivy misconfiguration scan

    -

    Ensure that you have Trivy installed and run the following command:

    -
    trivy fs --scanners misconf --config-check ./docker-check.rego --namespaces custom ./Dockerfile
    -
    -

    Please replace:

    -
      -
    • ./docker-check.rego with the file path to your check
    • -
    • custom should be replaced with your package name if different
    • -
    • ./Dockerfile is the path to the Dockerfile that should be scanned
    • -
    -

    Note: If you define custom packages, you have to specify the package prefix via --namespaces option. In our case, we called the custom package custom.

    -

    Resources

    - - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/misconfiguration/terraform/index.html b/v0.58.0/tutorials/misconfiguration/terraform/index.html deleted file mode 100644 index 27853efbf480..000000000000 --- a/v0.58.0/tutorials/misconfiguration/terraform/index.html +++ /dev/null @@ -1,8144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Terraform scanning - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Scanning Terraform files with Trivy

    -

    This tutorial is focused on ways Trivy can scan Terraform IaC configuration files.

    -

    A video tutorial on Terraform Misconfiguration scans can be found on the Aqua Open Source YouTube account.

    -

    A note to tfsec users -We have been consolidating all of our scanning-related efforts in one place, and that is Trivy. You can read more on the decision in the tfsec discussions.

    -

    Trivy Config Command

    -

    Terraform configuration scanning is available as part of the trivy config command. This command scans all configuration files for misconfiguration issues. You can find the details within misconfiguration scans in the Trivy documentation.

    -

    Command structure: -

    trivy config <any flags you want to use> <file or directory that you would like to scan> 
    -

    -

    The trivy config command can scan Terraform configuration, CloudFormation, Dockerfile, Kubernetes manifests, and Helm Charts for misconfiguration. Trivy will compare the configuration found in the file with a set of best practices.

    -
      -
    • If the configuration is following best practices, the check will pass,
    • -
    • If the configuration does not define the resource of some configuration, Trivy will assume the default configuration for the resource creation is used. In this case, the check might fail.
    • -
    • If the configuration that has been defined does not follow best practices, the check will fail.
    • -
    -

    Prerequisites

    -

    Install Trivy on your local machines. The documentation provides several different installation options. -This tutorial will use this example Terraform tutorial for terraform misconfiguration scanning with Trivy.

    -

    Git clone the tutorial and cd into the directory: -

    git clone git@github.com:Cloud-Native-Security/trivy-demo.git
    -cd bad_iac/terraform
    -
    -In this case, the folder only containes Terraform configuration files. However, you could scan a directory that contains several different configurations e.g. Kubernetes YAML manifests, Dockerfile, and Terraform. Trivy will then detect the different configuration files and apply the right rules automatically.

    -

    Different types of trivy config scans

    -

    Below are several examples of how the trivy config scan can be used.

    -

    General Terraform scan with trivy: -

    trivy config <specify the directory> 
    -

    -

    So if we are already in the directory that we want to scan: -

    trivy config ./ 
    -

    -

    Specify the scan format

    -

    The --format flag changes the way that Trivy displays the scan result:

    -

    JSON: -

    trivy config -f json terraform-infra 
    -

    -

    Sarif: -

    trivy config -f sarif terraform-infra 
    -

    -

    Specifying the output location

    -

    The --output flag specifies the file location in which the scan result should be saved:

    -

    JSON: -

    trivy config -f json -o example.json terraform-infra 
    -

    -

    Sarif: -

    trivy config -f sarif -o example.sarif terraform-infra 
    -

    -

    Filtering by severity

    -

    If you are presented with lots and lots of misconfiguration across different files, you might want to filter or the misconfiguration with the highest severity:

    -
    trivy config --severity CRITICAL, MEDIUM terraform-infra 
    -
    -

    Passing tf.tfvars files into trivy config scans

    -

    You can pass terraform values to Trivy to override default values found in the Terraform HCL code. More information are provided in the documentation.

    -
    trivy config --tf-vars terraform.tfvars ./
    -
    -

    Custom Checks

    -

    We have lots of examples in the documentation on how you can write and pass custom Rego checks into terraform misconfiguration scans.

    -

    Secret and vulnerability scans

    -

    The trivy config command does not perform secrete and vulnerability checks out of the box. However, you can specify as part of your trivy fs scan that you would like to scan you terraform files for exposed secrets and misconfiguraction through the following flags:

    -
    trivy fs --scanners secret,misconfig ./
    -
    -

    The trivy config command is a sub-command of the trivy fs command. You can learn more about this command in the documentation.

    -

    Scanning Terraform Plan files

    -

    Instead of scanning your different Terraform resources individually, you could also scan your Terraform Plan file before it is deployed for misconfiguration. This will give you insights into any misconfiguration of your resources as they would become deployed. Here is the link to the documentation.

    -

    Note that you need to be able to create a terraform init and plan without any errors.

    -

    Using Trivy in your CI/CD pipeline

    -

    Similar to tfsec, Trivy can be used either on local developer machines or integrated into your CI/CD pipeline. There are several steps available for different pipelines, including GitHub Actions, Circle CI, GitLab, Travis and more in the tutorials section of the documentation: https://aquasecurity.github.io/trivy/latest/tutorials/integrations/

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/overview/index.html b/v0.58.0/tutorials/overview/index.html deleted file mode 100644 index 4f1e5ce1680f..000000000000 --- a/v0.58.0/tutorials/overview/index.html +++ /dev/null @@ -1,7842 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overview - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    -
    -
    - - - -
    - -
    - - - - - - - - - - - - - -

    Tutorials

    -

    In this section you can find step-by-step guides that help you accomplish specific tasks.

    -

    👈 Please use the side-navigation on the left in order to browse the different topics.

    -

    Adding tutorials

    -

    You are welcome to create tutorials and showcase them here. Tutorials can be either included in here as full articles, or included as external links under external community resources. -Before sending PR, please first create an issue (of kind "Documentation") and describe the suggestion, if it's external link or article, and what category it's under.

    -

    Guidelines:

    -
      -
    • Focus on a specific use case. Start by clearly describing the use case and when/who it is relevant for.
    • -
    • Provide an end-to-end set of instructions. Make sure anyone can easily follow.
    • -
    • Describe the expected outcome after each step. Include examples as much as possible.
    • -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/shell/shell-completion/index.html b/v0.58.0/tutorials/shell/shell-completion/index.html deleted file mode 100644 index 37d40847a6b8..000000000000 --- a/v0.58.0/tutorials/shell/shell-completion/index.html +++ /dev/null @@ -1,7950 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Completion - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Enable shell completion

    -

    Below is example steps to enable shell completion feature for trivy cli:

    -

    1. Know your current shell

    -
    $ echo $SHELL
    -/bin/zsh # For this example it is zsh, but will be vary depend on your $SHELL, maybe /bin/bash or /bin/fish
    -
    -

    2. Run completion command to get sub-commands

    -
    $ trivy completion zsh -h
    -Generate the autocompletion script for the zsh shell.
    -
    -If shell completion is not already enabled in your environment you will need
    -to enable it.  You can execute the following once:
    -
    -    echo "autoload -U compinit; compinit" >> ~/.zshrc
    -
    -To load completions in your current shell session:
    -
    -    source <(trivy completion zsh); compdef _trivy trivy
    -
    -To load completions for every new session, execute once:
    -
    -#### Linux:
    -
    -    trivy completion zsh > "${fpath[1]}/_trivy"
    -
    -#### macOS:
    -
    -    trivy completion zsh > $(brew --prefix)/share/zsh/site-functions/_trivy
    -
    -You will need to start a new shell for this setup to take effect.
    -
    -

    3. Run the sub-commands following the instruction

    -
    echo "autoload -U compinit; compinit" >> ~/.zshrc
    -source <(trivy completion zsh); compdef _trivy trivy
    -trivy completion zsh > "${fpath[1]}/_trivy"
    -
    -

    4. Start a new shell and you can see the shell completion

    -
    $ trivy [tab]
    -completion  -- Generate the autocompletion script for the specified shell
    -config      -- Scan config files for misconfigurations
    -filesystem  -- Scan local filesystem
    -help        -- Help about any command
    -image       -- Scan a container image
    -kubernetes  -- scan kubernetes cluster
    -module      -- Manage modules
    -plugin      -- Manage plugins
    -repository  -- Scan a repository
    -rootfs      -- Scan rootfs
    -sbom        -- Scan SBOM for vulnerabilities
    -server      -- Server mode
    -version     -- Print the version
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/v0.58.0/tutorials/signing/vuln-attestation/index.html b/v0.58.0/tutorials/signing/vuln-attestation/index.html deleted file mode 100644 index 0fa689673a9e..000000000000 --- a/v0.58.0/tutorials/signing/vuln-attestation/index.html +++ /dev/null @@ -1,8206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Vulnerability Scan Record Attestation - Trivy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - -
    -
    -
    - - - - - - - -
    - -
    - - - - - - - - - - - - - -

    Vulnerability Scan Record Attestation

    -

    This tutorial details how to

    -
      -
    • Scan container images for vulnerabilities
    • -
    • Generate an attestation, using Cosign, with and without generating a separate key pair
    • -
    -

    Prerequisites

    -
      -
    1. Trivy CLI installed
    2. -
    3. Cosign CLI installed
    4. -
    5. Ensure that you have access to a container image in a remote container registry that you own/within your account. In this tutorial, we will use DockerHub.
    6. -
    -

    Scan Container Image for vulnerabilities

    -

    Scan your container image for vulnerabilities and save the scan result to a scan.json file: -

    trivy image --ignore-unfixed --format cosign-vuln --output scan.json DockerHubID/imagename:imagetag
    -

    -

    For example: -

    trivy image --ignore-unfixed --format cosign-vuln --output scan.json anaisurlichs/signed-example:0.1
    -

    -
      -
    • --ignore-unfixed: Ensures only the vulnerabilities, which have a already a fix available, are displayed
    • -
    • --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal.
    • -
    -

    Note: Replace the container image with the container image that you want to scan.

    -

    Option 1: Signing and Generating an attestation without new key pair

    -

    Signing

    -

    Sign the container image: -

    cosign sign DockerHubID/imagename@imageSHA
    -

    -

    The imageSHA can be obtained through the following docker command: -

    docker image ls --digests
    -
    -The SHA will be displayed next to the image name and tag.

    -

    Note that it is better practice to sign the image SHA rather than the tag as the SHA will remain the same for the particular image that we have signed.

    -

    For example: -

    cosign sign docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
    -

    -

    Attestation

    -

    The following command generates an attestation for the vulnerability scan and uploads it to the container image used: -

    cosign attest --predicate scan.json --type vuln docker.io/DockerHubID/imagename:imageSHA
    -

    -

    For example: -

    cosign attest --predicate scan.json --type vuln docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
    -

    -

    Note: Replace the container image with the container image that you would like to scan.

    -

    Next, Sigstore will ask you to verify with an account -- Microsoft, GitHub, or Google.

    -

    Once done, the user will be provided with a certificate in the terminal where they ran the command. Example certificate: -

    -----BEGIN CERTIFICATE-----
    -MIIC1TCCAlygAwIBAgIUfSXI7xTWSLq4nuygd8YPuhPZlEswCgYIKoZIzj0EAwMw
    -NzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl
    -cm1lZGlhdGUwHhcNMjQwMTExMTMzODUzWhcNMjQwMTExMTM0ODUzWjAAMFkwEwYH
    -KoZIzj0CAQYIKoZIzj0DAQcDQgAETcUNnK76mfo9G3j1c7NN6Vcn6yQPDX5rd3QB
    -unkHs1Uk59CWv3qm6sUyRNYaATs9zdHAZqLck8G4P/Pj7+GzCKOCAXswggF3MA4G
    -........
    ------END CERTIFICATE-----
    -

    -

    Option 2: Signing and Generating an attestation with a new Cosign key pair

    -

    To generate an attestation for the container image with a separate key pair, we can use Cosign to generate a new key pair: -

    cosign generate-key-pair 
    -

    -

    This will generate a cosign.key and a cosign.pub file. The cosign.key file is your private key that should be kept confidential as it is used to sign artefacts. However, the cosign.pub file contains the information of the corresponding public key. This key can be used by third parties to verify the attestation -- basically that this person who claims to have signed the attestation actually is the one who signed it.

    -

    Signing

    -

    Sign the container image: -

    cosign sign --key cosign.key docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
    -

    -

    Attestation

    -

    To generate the attestation with the specific key pairs, run the following command: -

    cosign attest --key cosign.key --type vuln --predicate scan.json docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd 
    -

    -

    Verify the attestation

    -

    Option 1 -- No separate key pair

    -

    If you have not generated a key pair but received a certificate after the container image was signed, use the following command to verify the attestation:

    -
    cosign verify-attestation --type vuln --certificate-identity Email-used-to-sign  --certificate-oidc-issuer='the-issuer-used' docker.io/DockerHubID/imagename:imageSHA
    -
    -

    For example, the command could be like this: -

    cosign verify-attestation --type vuln --certificate-identity urlichsanais@gmail.com  --certificate-oidc-issuer='https://github.com/login/oauth' anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
    -

    -

    Option 2 -- Separate key pair

    -

    If you have used a new cosign key pair, the attestation can be verified through the following command: -

    cosign verify-attestation --key cosign.pub --type vuln anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd 
    -

    -
    -Output - -The output should look similar to the following: -
    Verification for anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd --
    -The following checks were performed on each of these signatures:
    -  - The cosign claims were validated
    -  - Existence of the claims in the transparency log was verified offline
    -  - The signatures were verified against the specified public key
    -{"payloadType":"application/vnd.in-toto+json","payload":
    -
    -
    - -

    More information

    -

    See here for more details.

    - - - - - - - - - - - - - - - -
    -
    - - - - - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/versions.json b/versions.json index 69e6593ff02a..52fd40c7a684 100644 --- a/versions.json +++ b/versions.json @@ -1,9 +1,4 @@ [ - { - "version": "test", - "title": "test", - "aliases": [] - }, { "version": "dev", "title": "dev", @@ -16,11 +11,6 @@ "latest" ] }, - { - "version": "v0.58.0", - "title": "v0.58.0", - "aliases": [] - }, { "version": "v0.57", "title": "v0.57", @@ -155,27 +145,27 @@ "version": "v0.31.3", "title": "v0.31", "aliases": [ - "v0.31.2", "v0.31.0", - "v0.31.1" + "v0.31.1", + "v0.31.2" ] }, { "version": "v0.30.4", "title": "v0.30", "aliases": [ + "v0.30.0", "v0.30.3", - "v0.30.1", "v0.30.2", - "v0.30.0" + "v0.30.1" ] }, { "version": "v0.29.2", "title": "v0.29", "aliases": [ - "v0.29.0", - "v0.29.1" + "v0.29.1", + "v0.29.0" ] }, { @@ -201,10 +191,10 @@ "version": "v0.25.4", "title": "v0.25", "aliases": [ + "v0.25.3", "v0.25.0", - "v0.25.2", "v0.25.1", - "v0.25.3" + "v0.25.2" ] }, { @@ -212,9 +202,9 @@ "title": "v0.24", "aliases": [ "v0.24.3", + "v0.24.1", "v0.24.0", - "v0.24.2", - "v0.24.1" + "v0.24.2" ] }, { @@ -232,8 +222,8 @@ "title": "v0.21", "aliases": [ "v0.21.2", - "v0.21.1", - "v0.21.0" + "v0.21.0", + "v0.21.1" ] }, { @@ -248,8 +238,8 @@ "version": "v0.19.2", "title": "v0.19", "aliases": [ - "v0.19.0", - "v0.19.1" + "v0.19.1", + "v0.19.0" ] }, { @@ -257,8 +247,8 @@ "title": "v0.18", "aliases": [ "v0.18.2", - "v0.18.1", - "v0.18.0" + "v0.18.0", + "v0.18.1" ] }, {